From 9434d2ffa3829a4f7a74d20b41e7af38b645f682 Mon Sep 17 00:00:00 2001 From: Milton Barrera Date: Tue, 11 Feb 2025 19:39:21 -0600 Subject: [PATCH 01/13] New GitHubUtils class to interact with GitHub API --- .../java/net/osmtracker/util/Callback.java | 17 +++++ .../java/net/osmtracker/util/GitHubUtils.java | 75 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 app/src/main/java/net/osmtracker/util/Callback.java create mode 100644 app/src/main/java/net/osmtracker/util/GitHubUtils.java 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 000000000..78df72862 --- /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 000000000..27d5421a5 --- /dev/null +++ b/app/src/main/java/net/osmtracker/util/GitHubUtils.java @@ -0,0 +1,75 @@ +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: + *

+ *

+ * + *

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(); + } +} From 4cd91ad674c9490e9dd4eb45e7f4c11bd7f0f89d Mon Sep 17 00:00:00 2001 From: Milton Barrera Date: Tue, 11 Feb 2025 19:41:53 -0600 Subject: [PATCH 02/13] methods to get a unique name for a file in a GitHub repository --- .../java/net/osmtracker/util/GitHubUtils.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/app/src/main/java/net/osmtracker/util/GitHubUtils.java b/app/src/main/java/net/osmtracker/util/GitHubUtils.java index 27d5421a5..460a31443 100644 --- a/app/src/main/java/net/osmtracker/util/GitHubUtils.java +++ b/app/src/main/java/net/osmtracker/util/GitHubUtils.java @@ -72,4 +72,54 @@ protected void onPostExecute(String sha) { } }.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; + } + }); + } } From 28cc6c7fe660f575a5d74d8159e02640097cf178 Mon Sep 17 00:00:00 2001 From: Milton Barrera Date: Tue, 11 Feb 2025 19:45:25 -0600 Subject: [PATCH 03/13] Using unique name for the file on commit --- .../net/osmtracker/activity/GitHubUpload.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/net/osmtracker/activity/GitHubUpload.java b/app/src/main/java/net/osmtracker/activity/GitHubUpload.java index d2265cf34..7b1a2ae98 100644 --- a/app/src/main/java/net/osmtracker/activity/GitHubUpload.java +++ b/app/src/main/java/net/osmtracker/activity/GitHubUpload.java @@ -31,7 +31,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; @@ -102,7 +104,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(); @@ -147,7 +164,6 @@ private void openActivityOnClick(int btnId, Class 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); From 832d812d79f60de0e91ac95ba8bc2840c910923d Mon Sep 17 00:00:00 2001 From: Milton Barrera Date: Tue, 11 Feb 2025 19:53:42 -0600 Subject: [PATCH 04/13] Using R.string for progress dialog --- app/src/main/java/net/osmtracker/activity/GitHubUpload.java | 2 +- app/src/main/res/values-es/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/net/osmtracker/activity/GitHubUpload.java b/app/src/main/java/net/osmtracker/activity/GitHubUpload.java index 7b1a2ae98..d815bdad7 100644 --- a/app/src/main/java/net/osmtracker/activity/GitHubUpload.java +++ b/app/src/main/java/net/osmtracker/activity/GitHubUpload.java @@ -167,7 +167,7 @@ private void startUploadGitHub(final String fileInBase64, String filename, Strin String fullURL = getBaseURL()+"/repos/"+getRepoName()+"/contents/"+filename; ProgressDialog progressDialog = new ProgressDialog(this); - progressDialog.setMessage("Subiendo el archivo " + filename + "..."); + progressDialog.setMessage(R.string.uploading_file + filename); progressDialog.setCancelable(true); progressDialog.show(); diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 05f78ac18..49294af61 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -185,6 +185,7 @@ Error al obtener información del repositorio Subido exitosamente" Error al subir + Subiendo: Error al leer el archivo GPX No se encontró el archivo GPX Selecciono el elemento: diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fa17520a3..c45346923 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -211,6 +211,7 @@ Error with repository information Successfully uploaded" Error uploading + Uploading file: Error reading the GPX file GPX file not found Item Selected: From 474c3069576de7de793b698c36656683ac696617 Mon Sep 17 00:00:00 2001 From: Milton Barrera Date: Sat, 3 May 2025 15:37:04 -0600 Subject: [PATCH 05/13] New progress dialog when creating a new repo --- .../java/net/osmtracker/activity/GitHubNewRepo.java | 10 +++++++--- app/src/main/res/values/strings.xml | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/osmtracker/activity/GitHubNewRepo.java b/app/src/main/java/net/osmtracker/activity/GitHubNewRepo.java index 34db5ee78..8f3fa3e71 100644 --- a/app/src/main/java/net/osmtracker/activity/GitHubNewRepo.java +++ b/app/src/main/java/net/osmtracker/activity/GitHubNewRepo.java @@ -1,6 +1,7 @@ package net.osmtracker.activity; import android.app.Activity; +import android.app.ProgressDialog; import android.content.pm.ActivityInfo; import android.os.Bundle; import android.view.View; @@ -80,6 +81,11 @@ public void onClick(View v) { private void createNewRepo(String repoName, boolean isPrivate) { String fullURL = getBaseURL()+"/user/repos"; + ProgressDialog progressDialog = new ProgressDialog(this); + progressDialog.setMessage(this.getResources().getString(R.string.github_creating_repository)); + progressDialog.setCancelable(true); + progressDialog.show(); + JsonObjectRequest postResquest= new JsonObjectRequest( Request.Method.POST, fullURL, @@ -88,11 +94,9 @@ private void createNewRepo(String repoName, boolean isPrivate) { @Override public void onResponse(JSONObject response) { try { - System.out.println("=========================" + response.getString("full_name")); setNewRepoFullName(response.getString("full_name")); Toast.makeText(GitHubNewRepo.this, R.string.successfully_created, Toast.LENGTH_SHORT).show(); } catch (JSONException e) { - System.out.println("=========================Error"); Toast.makeText(GitHubNewRepo.this, R.string.error_creating, Toast.LENGTH_SHORT).show(); e.printStackTrace(); } @@ -100,7 +104,7 @@ public void onResponse(JSONObject response) { }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { - + Toast.makeText(GitHubNewRepo.this, R.string.error_creating, Toast.LENGTH_SHORT).show(); } }){ @Override diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e31b325b2..d4b71fa6e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -229,6 +229,7 @@ GPX file not found Item Selected: Private: + Creating repository You must specify a repository name You must specify a value for this field From 0377092403267a64666b1238075c21a599f68dba Mon Sep 17 00:00:00 2001 From: Milton Barrera Date: Sun, 4 May 2025 12:00:52 -0600 Subject: [PATCH 06/13] Unnecessary xmls comments removed --- .../res/layout/git_trackdetail_fields.xml | 24 ------------------- .../res/layout/github_configuration_token.xml | 1 - 2 files changed, 25 deletions(-) diff --git a/app/src/main/res/layout/git_trackdetail_fields.xml b/app/src/main/res/layout/git_trackdetail_fields.xml index fd2586590..405eb74c8 100644 --- a/app/src/main/res/layout/git_trackdetail_fields.xml +++ b/app/src/main/res/layout/git_trackdetail_fields.xml @@ -9,30 +9,6 @@ android:inputType="text" android:singleLine="false" /> - - - Date: Fri, 28 Feb 2025 10:21:48 -0600 Subject: [PATCH 07/13] Version code 66 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 204ee9ca2..2b40ea3ad 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,7 @@ android { multiDexEnabled true // Version code should be increased after each release - versionCode 65 + versionCode 66 versionName new Date().format('yyyy.MM.dd') testApplicationId "net.osmtracker.test" From c737f85926558c853591928fb1c6606cc98e5dbb Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 12:03:38 -0600 Subject: [PATCH 08/13] Translate strings-preferences.xml in it (#551) 100% translated source file: 'strings-preferences.xml' on 'it'. Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- app/src/main/res/values-it/strings-preferences.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-it/strings-preferences.xml b/app/src/main/res/values-it/strings-preferences.xml index 1fad30f9d..ec55c4994 100644 --- a/app/src/main/res/values-it/strings-preferences.xml +++ b/app/src/main/res/values-it/strings-preferences.xml @@ -56,7 +56,7 @@ Mostra OpenStreetMap sotto la traccia. È necessaria una connessione dati Mostra sempre lo sfondo OpenStreetMap? Richiede una connessione dati Salvataggio file GPX - Cartella di archiviazione nei documenti + Cartella di archiviazione in ‘documents’ Valido per la traccia successiva (non per quella attuale) Una directory per traccia Salva ogni traccia e i file associati nella propria directory From 101e4fb0c63122927381d0f1761eec7e2e69bc42 Mon Sep 17 00:00:00 2001 From: Andy Porras Date: Sun, 9 Mar 2025 16:56:55 -0600 Subject: [PATCH 09/13] fix: Waypoint preview does not work --- .../main/java/net/osmtracker/activity/WaypointList.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/net/osmtracker/activity/WaypointList.java b/app/src/main/java/net/osmtracker/activity/WaypointList.java index 0c046c7ee..5d0f34c68 100644 --- a/app/src/main/java/net/osmtracker/activity/WaypointList.java +++ b/app/src/main/java/net/osmtracker/activity/WaypointList.java @@ -2,6 +2,7 @@ import android.app.AlertDialog; import android.app.ListActivity; +import android.content.ActivityNotFoundException; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; @@ -140,7 +141,12 @@ public void onClick(View view) { } if (intent.resolveActivity(getPackageManager()) != null) { - startActivity(intent); + try{ + startActivity(intent); + } catch (ActivityNotFoundException e) { + // Handle the case where no app can handle the intent + // this means the user has not installed an app that can handle the file type + } } } alert.dismiss(); From 88bd77bacf67b9ea86acbbd467a776d20f1de0e1 Mon Sep 17 00:00:00 2001 From: Andy Porras Date: Sun, 9 Mar 2025 17:29:45 -0600 Subject: [PATCH 10/13] Enhancement: Show alert when there are no apps to handle the file --- .../net/osmtracker/activity/WaypointList.java | 15 ++++++++------- app/src/main/res/values/strings.xml | 1 + 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/net/osmtracker/activity/WaypointList.java b/app/src/main/java/net/osmtracker/activity/WaypointList.java index 5d0f34c68..73dce3f77 100644 --- a/app/src/main/java/net/osmtracker/activity/WaypointList.java +++ b/app/src/main/java/net/osmtracker/activity/WaypointList.java @@ -16,6 +16,7 @@ import android.widget.CursorAdapter; import android.widget.EditText; import android.widget.ListView; +import android.widget.Toast; import androidx.core.content.FileProvider; import net.osmtracker.R; import net.osmtracker.db.DataHelper; @@ -140,13 +141,13 @@ public void onClick(View view) { intent.setDataAndType(fileUri, DataHelper.MIME_TYPE_AUDIO); } - if (intent.resolveActivity(getPackageManager()) != null) { - try{ - startActivity(intent); - } catch (ActivityNotFoundException e) { - // Handle the case where no app can handle the intent - // this means the user has not installed an app that can handle the file type - } + try{ + startActivity(intent); + } catch (ActivityNotFoundException e) { + // Handle the case where no app can handle the intent + // this means the user has not installed an app that can handle the file type + //Log.e(TAG, "No app found to handle the file type: " + filePath, e); + Toast.makeText(WaypointList.this, getString(R.string.no_app_to_handle_file_type), Toast.LENGTH_LONG).show(); } } alert.dismiss(); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d4b71fa6e..d8a5c920b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -271,4 +271,5 @@ Happy tracking 🗺 😎 OSMTracker for Android will use your GPS location to record trackpoints and waypoints, even when the App is running in background. \nYour data is not used to support ads. + No application was found to open this file. From 5ba27fb32fc77a5ed5788dc7158f0647d33cdfff Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 07:09:03 -0600 Subject: [PATCH 11/13] Translate strings.xml in zh_TW (#562) 100% translated source file: 'strings.xml' on 'zh_TW'. Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- app/src/main/res/values-zh-rTW/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 80f5fbc82..d01c3648a 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -204,4 +204,5 @@ 記錄快樂🗺 😎 OSMTracker for Android 會使用你的 GPS 位置來記錄航點和路徑,即便 App 在背景執行。 \n你的資料並不會拿來給廣告使用。 + 沒有找到能開啟檔案的應用程式。 From eb0651a481dbfc12c9f501fe635978932f5ffc46 Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 07:09:37 -0600 Subject: [PATCH 12/13] Translate strings.xml in pl (#561) 97% of minimum 80% translated source file: 'strings.xml' on 'pl'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- app/src/main/res/values-pl/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 343eb922c..f63039d7e 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -87,6 +87,12 @@ głosową Zrób zdjęcie Notka + Otwórz plik + Ratować + Usuwać + Anulować + Usuwać + Anulować Ustawienia Punkty nawigacji @@ -150,6 +156,7 @@ głosową Oczekuję na kierunek... Kierunek nie może zostać określony Proces eksportu zakończony sukcesem + Stanowisko niedostępne {0} {1} / {2} {3} Podgląd śladu w OpenStreetMap From c35fccf3dd1c5b88759f20cf69cb4cbe713ca567 Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 15:05:59 +0000 Subject: [PATCH 13/13] Translate strings.xml in cs_CZ 100% translated source file: 'strings.xml' on 'cs_CZ'. --- app/src/main/res/values-cs-rCZ/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index e1959ca64..020a38004 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -203,4 +203,5 @@ Šťastné trasování 🗺 😎 OSMTracker pro Android použije vaši polohu GPS k záznamu trasových bodů a bodů cest, i když je aplikace spuštěna na pozadí. \nVaše data se nepoužívají k podpoře reklam. + Nebyla nalezena žádná aplikace k otevření tohoto souboru.