Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Configurable filename for export: used for all automatic exports aft…
…er recording, exporting all, and sharing tracks. Fixes #512.
- Loading branch information
1 parent
8a2d1c4
commit 0d3cf4c
Showing
11 changed files
with
253 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGeneratorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package de.dennisguse.opentracks.io.file; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
|
||
import androidx.test.core.app.ApplicationProvider; | ||
|
||
import org.junit.Rule; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.junit.runners.Parameterized; | ||
|
||
import java.time.Instant; | ||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.TimeZone; | ||
import java.util.UUID; | ||
|
||
import de.dennisguse.opentracks.R; | ||
import de.dennisguse.opentracks.TimezoneRule; | ||
import de.dennisguse.opentracks.data.models.Track; | ||
|
||
@RunWith(Parameterized.class) | ||
public class TrackFilenameGeneratorTest { | ||
|
||
@Rule | ||
public TimezoneRule timezoneRule = new TimezoneRule(TimeZone.getTimeZone("Europe/Berlin")); | ||
|
||
@Parameterized.Parameters | ||
public static Collection<String[]> data() { | ||
return Arrays.asList(new String[][]{ | ||
{"{uuid}_{name}", "0000fee0_Best Track.gpx" }, | ||
{"{name}_{uuid}", "Best Track_0000fee0.gpx" }, | ||
{"{time}_{name}", "2020-02-02T02_02_02Z_Best Track.gpx" }, | ||
{ApplicationProvider.getApplicationContext().getString(R.string.export_filename_format_default), "2020-02-02T02_02_02Z_Best Track.gpx" }, | ||
}); | ||
} | ||
|
||
private final TrackFilenameGenerator subject; | ||
private final String expected; | ||
|
||
public TrackFilenameGeneratorTest(String template, String expected) { | ||
this.subject = new TrackFilenameGenerator(template); | ||
this.expected = expected; | ||
} | ||
|
||
@Test | ||
public void testFilenameTemplate() { | ||
// given | ||
Track track = new Track(); | ||
track.setName("Best Track"); | ||
track.setUuid(UUID.fromString("0000fee0-0000-1000-8000-00805f9b34fb")); | ||
track.getTrackStatistics().setStartTime(Instant.parse("2020-02-02T02:02:02Z")); | ||
|
||
// when | ||
String filename = subject.format(track, TrackFileFormat.GPX); | ||
|
||
// then | ||
assertEquals(expected, filename); | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGeneratorTest2.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package de.dennisguse.opentracks.io.file; | ||
|
||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.junit.runners.Parameterized; | ||
|
||
import java.time.Instant; | ||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.UUID; | ||
|
||
import de.dennisguse.opentracks.data.models.Track; | ||
|
||
//TODO Merge with TrackFilenameGeneratorTest whenever Junit5 gets available. | ||
//https://github.com/android/android-test/issues/224 | ||
@RunWith(Parameterized.class) | ||
public class TrackFilenameGeneratorTest2 { | ||
|
||
@Parameterized.Parameters | ||
public static Collection<String> data() { | ||
return Arrays.asList( | ||
"{name}_{starime}", | ||
"{name", | ||
"name}"); | ||
} | ||
|
||
private final TrackFilenameGenerator subject; | ||
|
||
public TrackFilenameGeneratorTest2(String template) { | ||
this.subject = new TrackFilenameGenerator(template); | ||
} | ||
|
||
@Test(expected = TrackFilenameGenerator.TemplateInvalidException.class) | ||
public void testFilenameTemplate() { | ||
// given | ||
Track track = new Track(); | ||
track.setName("Best Track"); | ||
track.setUuid(UUID.fromString("0000fee0-0000-1000-8000-00805f9b34fb")); | ||
track.getTrackStatistics().setStartTime(Instant.parse("2020-02-02T02:02:02Z")); | ||
|
||
// when | ||
String filename = subject.format(track, TrackFileFormat.GPX); | ||
} | ||
} |
105 changes: 105 additions & 0 deletions
105
src/main/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package de.dennisguse.opentracks.io.file; | ||
|
||
import androidx.annotation.NonNull; | ||
|
||
import java.time.Instant; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.UUID; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
import de.dennisguse.opentracks.data.models.Track; | ||
import de.dennisguse.opentracks.util.FileUtils; | ||
|
||
public class TrackFilenameGenerator { | ||
|
||
public static final String UUID_KEY = "{uuid}"; | ||
public static final String TRACKNAME_KEY = "{name}"; | ||
public static final String CATEGORY_KEY = "{category}"; | ||
public static final String STARTTIME_KEY = "{time}"; | ||
|
||
public static String getAllOptions() { | ||
return Stream.of(UUID_KEY, TRACKNAME_KEY, CATEGORY_KEY, STARTTIME_KEY) | ||
.collect(Collectors.joining(", ")); | ||
} | ||
|
||
private final String template; | ||
|
||
public TrackFilenameGenerator(@NonNull String template) { | ||
this.template = template; | ||
} | ||
|
||
public String format(@NonNull Track track, @NonNull TrackFileFormat trackFileFormat) { | ||
Map<String, String> values = new HashMap<>(); | ||
|
||
values.put(UUID_KEY, track.getUuid().toString().substring(0, 8)); | ||
values.put(TRACKNAME_KEY, track.getName()); | ||
values.put(CATEGORY_KEY, track.getCategory()); | ||
values.put(STARTTIME_KEY, track.getStartTime().toString()); | ||
|
||
return FileUtils.sanitizeFileName(format(template, values)) + "." + trackFileFormat.getExtension(); | ||
} | ||
|
||
private static String format(String template, Map<String, String> values) { | ||
StringBuilder templateCompiler = new StringBuilder(template); | ||
List<String> valueList = new ArrayList<>(); | ||
|
||
Matcher keyMatcher = Pattern | ||
.compile("\\{(\\w+)\\}") | ||
.matcher(template); | ||
|
||
while (keyMatcher.find()) { | ||
String key = keyMatcher.group(); | ||
|
||
if (!values.containsKey(key)) { | ||
throw new TemplateInvalidException(key); | ||
} | ||
|
||
int index = templateCompiler.indexOf(key); | ||
if (index != -1) { | ||
templateCompiler.replace(index, index + key.length(), "%s"); | ||
valueList.add(values.get(key)); | ||
} | ||
} | ||
|
||
String templateCompiled = templateCompiler.toString(); | ||
if (templateCompiled.contains("{") || templateCompiled.contains("}")) { | ||
throw new TemplateInvalidException(template); | ||
} | ||
|
||
return String.format(templateCompiled, valueList.toArray()); | ||
} | ||
|
||
public String getTemplate() { | ||
return template; | ||
} | ||
|
||
public boolean isValid() { | ||
try { | ||
getExample(); | ||
return !template.isEmpty(); | ||
} catch (TemplateInvalidException e) { | ||
return false; | ||
} | ||
} | ||
|
||
public String getExample() { | ||
Track track = new Track(); | ||
track.setName("Berlin"); | ||
track.setUuid(UUID.fromString("fefefefefe-0000-1000-8000-00805f9b34fb")); | ||
track.getTrackStatistics().setStartTime(Instant.ofEpochMilli(0)); | ||
|
||
return format(track, TrackFileFormat.GPX); | ||
} | ||
|
||
public static class TemplateInvalidException extends RuntimeException { | ||
public TemplateInvalidException(String invalidTemplate) { | ||
super(invalidTemplate); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters