diff --git a/app/src/main/java/net/osmtracker/activity/GitHubUpload.java b/app/src/main/java/net/osmtracker/activity/GitHubUpload.java
index 52961655..0415267a 100644
--- a/app/src/main/java/net/osmtracker/activity/GitHubUpload.java
+++ b/app/src/main/java/net/osmtracker/activity/GitHubUpload.java
@@ -32,7 +32,9 @@
import net.osmtracker.GitHubUser;
import net.osmtracker.R;
import net.osmtracker.db.DbGitHubUser;
+import net.osmtracker.util.Callback;
import net.osmtracker.util.DialogUtils;
+import net.osmtracker.util.GitHubUtils;
import org.json.JSONArray;
import org.json.JSONException;
@@ -106,7 +108,22 @@ private void uploadCommit() {
}
}
- startUploadGitHub(encondedFile.toString(), file.getName(), commitMsj);
+ String repoOwner = getRepoName().substring(0, getRepoName().indexOf("/")).replace(".base64", "");
+ String repoName = getRepoName().substring(getRepoName().indexOf("/") + 1);
+ String repoFilePath = file.getName().replace(".base64", "");
+ GitHubUtils.getGHFilenameAsync(repoOwner, repoName, repoFilePath, gitHubUser.getToken(),
+ new Callback() {
+ @Override
+ public String onResult(String result) {
+ if (result != null) {
+ System.out.println("uploading to GitHub: " + result);
+ startUploadGitHub(encondedFile.toString(), result, commitMsj);
+ } else {
+ System.out.println("Error while getting filename.");
+ }
+ return result;
+ }
+ });
} catch (IOException e) {
Toast.makeText(GitHubUpload.this, R.string.gpx_file_read_error, Toast.LENGTH_SHORT).show();
e.printStackTrace();
@@ -151,7 +168,6 @@ private void openActivityOnClick(int btnId, Class extends Activity> destinatio
* Either starts uploading directly if we are authenticated against GitHub
*/
private void startUploadGitHub(final String fileInBase64, String filename, String commitMsj){
- filename = filename.substring(0, filename.lastIndexOf("."));
String fullURL = getBaseURL()+"/repos/"+getRepoName()+"/contents/"+filename;
ProgressDialog progressDialog = new ProgressDialog(this);
diff --git a/app/src/main/java/net/osmtracker/util/Callback.java b/app/src/main/java/net/osmtracker/util/Callback.java
new file mode 100644
index 00000000..78df7286
--- /dev/null
+++ b/app/src/main/java/net/osmtracker/util/Callback.java
@@ -0,0 +1,17 @@
+package net.osmtracker.util;
+
+/**
+ * A generic callback interface used for asynchronous operations.
+ * Implementations of this interface should define how to handle the result
+ * of an asynchronous task.
+ */
+public interface Callback {
+ /**
+ * Called when the asynchronous operation is completed.
+ * Implementations should handle the provided result accordingly.
+ *
+ * @param result The result of the operation, which may be {@code null} if an error occurs.
+ * @return A string value that may be used by the calling function, if applicable.
+ */
+ String onResult(String result);
+}
diff --git a/app/src/main/java/net/osmtracker/util/GitHubUtils.java b/app/src/main/java/net/osmtracker/util/GitHubUtils.java
new file mode 100644
index 00000000..460a3144
--- /dev/null
+++ b/app/src/main/java/net/osmtracker/util/GitHubUtils.java
@@ -0,0 +1,125 @@
+package net.osmtracker.util;
+
+import android.os.AsyncTask;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+/**
+ * Utility class for interacting with the GitHub API.
+ * Provides methods to retrieve file information and manage file uploads.
+ *
+ *
This class includes methods to:
+ *
+ * - Generate a unique filename within a GitHub repository.
+ * - Retrieve the SHA hash of a file stored in a GitHub repository.
+ *
+ *
+ *
+ * It requires a valid GitHub authentication token for API requests.
+ */
+public class GitHubUtils {
+ /**
+ * Retrieves the SHA hash of a file in a GitHub repository.
+ * If the file does not exist, it returns {@code null}.
+ *
+ * @param repoOwner The owner of the repository (user or organization).
+ * @param repoName The name of the GitHub repository.
+ * @param repoFilePath The file path in the repository.
+ * @param token The GitHub authentication token with appropriate permissions.
+ * @return The SHA hash of the file if it exists, or {@code null} if the file is not found.
+ * @throws IOException If an I/O error occurs while making the request.
+ * @throws JSONException If an error occurs while parsing the JSON response.
+ */
+ public static void getFileSHAAsync(String repoOwner, String repoName, String repoFilePath, String token, Callback callback) {
+ new AsyncTask() {
+ @Override
+ protected String doInBackground(Void... voids) {
+ try {
+ String apiUrl = "https://api.github.com/repos/" + repoOwner + "/" + repoName + "/contents/" + repoFilePath;
+ System.out.println("Fetching SHA: " + apiUrl);
+ HttpURLConnection connection = (HttpURLConnection) new URL(apiUrl).openConnection();
+ connection.setRequestMethod("GET");
+ connection.setRequestProperty("Authorization", "Bearer " + token);
+ connection.setRequestProperty("Accept", "application/vnd.github.v3+json");
+
+ if (connection.getResponseCode() == 200) {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+ StringBuilder response = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ response.append(line);
+ }
+ reader.close();
+ JSONObject jsonResponse = new JSONObject(response.toString());
+ return jsonResponse.getString("sha");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(String sha) {
+ callback.onResult(sha); // Return result via callback
+ }
+ }.execute();
+ }
+
+ /**
+ * Asynchronously generates a unique filename in a GitHub repository.
+ * If the file already exists, a number is appended before the extension.
+ *
+ * @param repoOwner The owner of the repository.
+ * @param repoName The name of the GitHub repository.
+ * @param repoFilePath The initial file path in the repository.
+ * @param token The GitHub authentication token.
+ * @param callback Callback to return the generated filename.
+ */
+ public static void getGHFilenameAsync(String repoOwner, String repoName, final String repoFilePath, String token, Callback callback) {
+ String filename = repoFilePath.substring(0, repoFilePath.lastIndexOf("."));
+ String extension = repoFilePath.substring(repoFilePath.lastIndexOf("."));
+ checkFileExists(repoOwner, repoName, filename, extension, 0, token, callback);
+ }
+
+ /**
+ * Recursively checks if a file exists and generates a unique filename.
+ *
+ * @param repoOwner The owner of the repository.
+ * @param repoName The GitHub repository name.
+ * @param filename The base filename (without extension).
+ * @param extension The file extension.
+ * @param count The current attempt number for uniqueness.
+ * @param token The GitHub authentication token.
+ * @param callback Callback to return the final unique filename.
+ */
+ private static void checkFileExists(String repoOwner, String repoName, String filename, String extension, int count, String token, Callback callback) {
+ String newFilename;// (count == 0) ? filename + extension : filename + "(" + count + ")" + extension;
+ if (count == 0) {
+ newFilename = filename + extension;
+ } else {
+ newFilename = filename + "(" + count + ")" + extension;
+ }
+
+ getFileSHAAsync(repoOwner, repoName, newFilename, token, new Callback() {
+ @Override
+ public String onResult(String sha) {
+ if (sha == null) {
+ // File does not exist, return the new unique filename
+ callback.onResult(newFilename);
+ } else {
+ // File exists, recursively try with the next count
+ checkFileExists(repoOwner, repoName, filename, extension, count + 1, token, callback);
+ }
+ return null;
+ }
+ });
+ }
+}
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 0f746a92..6baa11ac 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -40,7 +40,6 @@
Exportar como GPX
Compartir GPX
Subir a OpenStreetMap
- Subir a GitHub
Visualizar
Detalles
Traza #{0}
@@ -175,53 +174,6 @@
Repositorio de GitHub válido
Repositorio de GitHub inválido
-
- Creado exitosamente
- Error al crear
- Error en base de datos
- Guardado exitosamente
- Error al guardar
- Estado del pull request:
- Error al obtener información del repositorio
- Subido exitosamente"
- Error al subir
- Error al leer el archivo GPX
- No se encontró el archivo GPX
- Subiendo:
- Selecciono el elemento:
- Privado:
- Indique el nombre del repositorio
- Campo requerido
-
- Configurar
- Token de GitHub:
- Obtener token
- Cómo obtener un token de GitHub:
- 1. Haga clic en el botón para abrir el sitio web de GitHub y crear un token. Inicie sesión con su cuenta de GitHub si es necesario.
- 2. Seleccione \"Tokens (Clásicos)\" y haga clic en el botón \"Generar nuevo token\".
- 3. Asigne un nombre descriptivo a su token.
- 4. Seleccione una fecha de expiración. Recomendamos \"Sin expiración\" para evitar repetir este paso.
- 5. Seleccione los permisos que desee otorgar al token (OSMTracker solo necesita el permiso de repositorio).
- 6. Haga clic en el botón \"Generar token\".
- 7. Copie el token generado y péguelo en el campo \"Token de GitHub\".
- ⚠️ Puede guardar en blanco para borrar sus credenciales.
-
- Mensaje del commit:
- Crear\nfork
- Abrir pull request
- Seleccione un repositorio
- Crear repositorio
- Hacer commit
- Configurar
-
- Usuario del repositorio original
- Nombre del repositorio original
- Crear
-
- Título del Pull Request
- Descripción del Pull Request
-
-
Introducción a OSMTracker para Android ™
@@ -231,4 +183,4 @@
Feliz trazado 🗺 😎
OSMTracker para Android usará su ubicación GPS para registrar puntos de traza y puntos, incluso cuando la aplicación se está ejecutando en segundo plano.
Tus datos no se utilizan para respaldar anuncios.
-
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e6f2e803..c4534692 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -211,9 +211,9 @@
Error with repository information
Successfully uploaded"
Error uploading
+ Uploading file:
Error reading the GPX file
GPX file not found
- Uploading file:
Item Selected:
Private:
You must specify a repository name