Skip to content

Commit

Permalink
improve gpx backup
Browse files Browse the repository at this point in the history
  • Loading branch information
mg4gh committed Jan 16, 2025
1 parent 3229149 commit 48c6edf
Show file tree
Hide file tree
Showing 8 changed files with 340 additions and 141 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ public class MGMapActivity extends MapViewerBase implements XmlRenderThemeMenuCa
private MapDataStoreUtil mapDataStoreUtil = null;
private GGraphTileFactory gGraphTileFactory = null;
private final Runnable ttUploadGpxTrigger = () -> prefCache.get(R.string.preferences_sftp_uploadGpxTrigger, false).toggle();
private final Runnable ttCheckFullBackup = () ->
BackupUtil.checkFullBackup(MGMapActivity.this, application.getPersistenceManager(), prefCache.get(R.string.preferences_last_full_backup_time, 0L));
private final PropertyChangeListener prefGpsObserver = (e) -> triggerTrackLoggerService();
private Pref<Boolean> prefTracksVisible;
private List<String> recreatePreferences;
Expand Down Expand Up @@ -256,7 +258,7 @@ protected void onCreate(Bundle savedInstanceState) {
application.prefGps.addObserver(prefGpsObserver);
application.prefGps.onChange();
prefCache.get(R.string.preferences_sftp_uploadGpxTrigger, false).addObserver((e) -> {
FeatureService.getTimer().postDelayed(()->BackupUtil.trigger(MGMapActivity.this, application.getPersistenceManager()), 10);
FeatureService.getTimer().postDelayed(()->BackupUtil.trigger(MGMapActivity.this, application.getPersistenceManager(), true, null), 10);
FeatureService.getTimer().postDelayed(()->new GpxSyncUtil().trySynchronisation(application), 1000);
});
prefTracksVisible = prefCache.get(R.string.preferences_tracks_visible, true);
Expand Down Expand Up @@ -308,6 +310,7 @@ protected void onResume() {
application.lastPositionsObservable.changed();

FeatureService.getTimer().postDelayed(ttUploadGpxTrigger, 25*1000);
FeatureService.getTimer().postDelayed(ttCheckFullBackup, 100*1000);
application.finishAlarm(); // just in case there is one
}

Expand Down Expand Up @@ -337,6 +340,7 @@ protected void onPause() {
}
}
FeatureService.getTimer().removeCallbacks(ttUploadGpxTrigger);
FeatureService.getTimer().removeCallbacks(ttCheckFullBackup);
super.onPause();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.invoke.MethodHandles;
Expand Down Expand Up @@ -83,7 +82,7 @@ public MGTileStoreDB(File storeDir, AssetManager am, GraphicFactory graphicFacto
} else if (storeRW == null){ // store found, but is not writeable - create a clone that is writeable
mgLog.i(prefix+"store found ("+store.getName()+"), but is not writeable - create a clone that is writeable");
storeRW = new File(store.getAbsolutePath().replaceFirst("\\.mbtiles", "_rw.mbtiles"));
IOUtil.copyStreams(new FileInputStream(store), new FileOutputStream(storeRW));
IOUtil.copyFile(store, storeRW);
} else {
mgLog.i(prefix+"store found with read/write access found: "+storeRW.getName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ void _init(BaseConfig baseConfig){
mgLog.i("init finished!");
}).start();

BackupUtil.restore2(this, persistenceManager);
BackupUtil.restore2(this, persistenceManager, true);

// initialize MetaData (as used from AvailableTrackLogs service and statistic)
new Thread(() -> {
Expand Down
11 changes: 6 additions & 5 deletions mgmap/src/main/java/mg/mgmap/application/util/ExtrasUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,14 @@ public static ArrayList<String> checkCreateMeta(MGMapApplication mgMapApplicatio
}
} catch (Exception e){ mgLog.e(e); }
}
// mgLog.d(String.format(Locale.ENGLISH, "load metaData trackLog=%s currentRun=%s app.currentRun=%s",name, currentRun, mgMapApplication.currentRun ));
if (mgMapApplication.currentRun != currentRun) break; // check correct run immediately before adding to metaData
mgMapApplication.addMetaDataTrackLog(trackLog);
if (trackLog != null){ // might be null, if gpx is corrupted
if (mgMapApplication.currentRun != currentRun) break; // check correct run immediately before adding to metaData
mgMapApplication.addMetaDataTrackLog(trackLog);
}
}
mgLog.d(String.format(Locale.ENGLISH,"checkCreateMeta summary gpxNames=%d cntMetaLoaded=%d cntMetaCreated=%d",gpxNames.size(),cntMetaLoaded,cntMetaCreated));
mgLog.i(String.format(Locale.ENGLISH,"checkCreateMeta summary gpxNames=%d cntMetaLoaded=%d cntMetaCreated=%d",gpxNames.size(),cntMetaLoaded,cntMetaCreated));
for (String name : metaNames){
mgLog.i("Delete meta file for "+name);
mgLog.d("Delete meta file for "+name);
persistenceManager.deleteTrack(name);
}
mgLog.i("checkCreateMeta finished - currentRun="+currentRun);
Expand Down
138 changes: 109 additions & 29 deletions mgmap/src/main/java/mg/mgmap/application/util/PersistenceManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
import java.lang.invoke.MethodHandles;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

Expand All @@ -46,6 +48,101 @@ public class PersistenceManager {

private static final MGLog mgLog = new MGLog(MethodHandles.lookup().lookupClass().getName());

public static final String SUFFIX_GPX = ".gpx";
public static final String SUFFIX_META = ".meta";


private static ArrayList<File> getFilesRecursive(File dir, String nameEndsWith, ArrayList<File> matchedList){
File[] entries = dir.listFiles();
if (entries != null){
for (File entry : entries) {
if (entry.isDirectory()) {
getFilesRecursive(entry, nameEndsWith, matchedList);
} else {
if (entry.getName().endsWith(nameEndsWith)) {
matchedList.add(entry);
}
}
}
}
return matchedList;
}

public static ArrayList<File> getFilesRecursive(File dir, String suffix){
return getFilesRecursive(dir, suffix, new ArrayList<>());
}

public static List<String> getNamesRecursive(File dir, String suffix){
return getFilesRecursive(dir, suffix, new ArrayList<>())
.stream().map(f->f.getAbsolutePath()
.substring(dir.getAbsolutePath().length() + File.separator.length(), f.getAbsolutePath().length()-suffix.length()) )
.collect(Collectors.toList());
}

public static boolean forceDelete(File file){
File[] contents = file.listFiles();
if (contents != null) {
for (File f : contents) {
if (! Files.isSymbolicLink(f.toPath())) {
forceDelete(f);
}
}
}
return file.delete();
}

public static void mergeDir(File mergeFrom, File mergeTo){ // recursive merge dir
assert mergeFrom.exists();
assert mergeTo.exists();
File[] fromArray = mergeFrom.listFiles();
if (fromArray != null){
for (File file : fromArray){
if (Files.isSymbolicLink(file.toPath())) continue;
File toFile = new File(mergeTo, file.getName());

if (toFile.exists() && (file.isFile() != toFile.isFile())){
mgLog.e("cannot merge "+file.getAbsolutePath()+" with type "+(file.isFile()?"file":"directory")+" to "+toFile.getAbsolutePath()+" with type "+(toFile.isFile()?"file":"directory"));
continue;
}
if (file.isFile()){
if (toFile.exists()){
if ( file.lastModified() > toFile.lastModified() ){
if (!toFile.delete()) mgLog.e("failed to delete "+toFile.getAbsolutePath());
if (!file.renameTo(toFile)) mgLog.e("failed to rename from "+file.getAbsolutePath()+" to "+toFile.getAbsolutePath());
}
} else {
if (!file.renameTo(toFile)) mgLog.e("failed to rename from "+file.getAbsolutePath()+" to "+toFile.getAbsolutePath());
}
} else { // file is directory
if (!toFile.exists()){
if (!toFile.mkdir()) mgLog.e("failed to create "+toFile.getAbsolutePath());
}
mergeDir(file, toFile);
}
} // for (File file : fromArray){
} // if (fromArray != null){
}

public static boolean checkFilesOlderThan(File dir, long timestamp){
File[] entries = dir.listFiles();
if (entries != null){
for (File entry : entries) {
if (entry.isDirectory()) {
checkFilesOlderThan(entry, timestamp);
} else {
if (entry.lastModified() >= timestamp) {
return false;
}
}
}
}
return true;
}





private final MGMapApplication application;
private final Context context;

Expand Down Expand Up @@ -263,12 +360,12 @@ private void checkCreatePath(File file){
}

public boolean existsGpx(String filename) {
File file = getAbsoluteFile(trackGpxDir, filename, ".gpx");
File file = getAbsoluteFile(trackGpxDir, filename, SUFFIX_GPX);
return file.exists();
}
public boolean isGpxOlderThanMeta(String filename){
File gpxFile = getAbsoluteFile(trackGpxDir, filename, ".gpx");
File metaFile = getAbsoluteFile(trackMetaDir, filename, ".meta");
File gpxFile = getAbsoluteFile(trackGpxDir, filename, SUFFIX_GPX);
File metaFile = getAbsoluteFile(trackMetaDir, filename, SUFFIX_META);
assert gpxFile.exists();
if (metaFile.exists()){
return gpxFile.lastModified() <= metaFile.lastModified();
Expand All @@ -278,7 +375,7 @@ public boolean isGpxOlderThanMeta(String filename){
}
public PrintWriter openGpxOutput(String filename) {
try {
File file = getAbsoluteFile(trackGpxDir, filename, ".gpx");
File file = getAbsoluteFile(trackGpxDir, filename, SUFFIX_GPX);
checkCreatePath(file);
return new PrintWriter(file);
} catch (FileNotFoundException e) {
Expand All @@ -288,7 +385,7 @@ public PrintWriter openGpxOutput(String filename) {
}
public InputStream openGpxInput(String filename) {
try {
File file = getAbsoluteFile(trackGpxDir, filename, ".gpx");
File file = getAbsoluteFile(trackGpxDir, filename, SUFFIX_GPX);
return new FileInputStream(file);
} catch (FileNotFoundException e) {
mgLog.e(e);
Expand All @@ -297,7 +394,7 @@ public InputStream openGpxInput(String filename) {
}
public Uri getGpxUri(String filename) {
try {
File file = getAbsoluteFile(trackGpxDir, filename, ".gpx");
File file = getAbsoluteFile(trackGpxDir, filename, SUFFIX_GPX);
return FileProvider.getUriForFile(context, context.getPackageName() + ".provider", file);
} catch (Exception e) {
mgLog.e(e);
Expand All @@ -307,7 +404,7 @@ public Uri getGpxUri(String filename) {

public FileOutputStream openMetaOutput(String filename) {
try {
File file = getAbsoluteFile(trackMetaDir, filename, ".meta");
File file = getAbsoluteFile(trackMetaDir, filename, SUFFIX_META);
checkCreatePath(file);
return new FileOutputStream(file);
} catch (FileNotFoundException e) {
Expand All @@ -318,37 +415,20 @@ public FileOutputStream openMetaOutput(String filename) {

public FileInputStream openMetaInput(String filename) {
try {
File file = getAbsoluteFile(trackMetaDir, filename, ".meta");
File file = getAbsoluteFile(trackMetaDir, filename, SUFFIX_META);
return new FileInputStream(file);
} catch (FileNotFoundException e) {
mgLog.e(e);
}
return null;
}

/** Retruns a list of relative path name, but without extension */
public ArrayList<String> getNames(File baseDir, File dir, String endsWith, ArrayList<String> matchedList) {
File[] entries = dir.listFiles();
if (entries != null){
for (File entry : entries) {
if (entry.isDirectory()) {
getNames(baseDir, entry, endsWith, matchedList);
} else {
if (entry.getName().endsWith(endsWith)) {
String sPath = entry.getAbsolutePath();
matchedList.add(sPath.substring((baseDir.getAbsolutePath()+File.pathSeparator ).length(), sPath.length() - endsWith.length()));
}
}
}
}
return matchedList;
}

public ArrayList<String> getGpxNames() {
return getNames(trackGpxDir, trackGpxDir, ".gpx", new ArrayList<>());
public List<String> getGpxNames() {
return getNamesRecursive(trackGpxDir, SUFFIX_GPX);
}
public ArrayList<String> getMetaNames() {
return getNames(trackMetaDir, trackMetaDir, ".meta", new ArrayList<>());
public List<String> getMetaNames() {
return getNamesRecursive(trackMetaDir, SUFFIX_META);
}

public File getThemesDir(){
Expand Down
Loading

0 comments on commit 48c6edf

Please sign in to comment.