Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix IGC date parsing to support the new format. #74

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,19 +1,4 @@
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}

dependencies {
classpath 'io.fabric.tools:gradle:1.+'
}
}

apply plugin: 'com.android.application'
apply plugin: 'io.fabric'

repositories {
maven { url 'https://maven.fabric.io/public' }
}

android {
compileSdkVersion 24
Expand Down Expand Up @@ -57,11 +42,6 @@ dependencies {
compile 'org.greenrobot:eventbus:3.0.0'
compile 'com.github.PhilJay:MPAndroidChart:v3.0.1'

compile('com.crashlytics.sdk.android:crashlytics:2.6.5@aar') {
transitive = true;
}


compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,10 @@
import android.app.Application;
import android.content.Context;

import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.core.CrashlyticsCore;
import com.shollmann.android.igcparser.model.IGCFile;
import com.shollmann.android.igcparser.model.TaskConfig;
import com.shollmann.igcparser.util.PreferencesHelper;

import io.fabric.sdk.android.Fabric;

public class IGCViewerApplication extends Application {
private static IGCFile currentIGCFile;

Expand All @@ -54,11 +50,6 @@ private void setupTaskConfig() {
}

private void setupCrashlytics() {
Crashlytics crashlyticsKit = new Crashlytics.Builder()
.core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
.build();

Fabric.with(this, crashlyticsKit);
}

public Context getApplication() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,8 @@

package com.shollmann.igcparser.tracking;

import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;

public class AnswersHelper {

public static void trackEvent(String eventName){
Answers.getInstance().logCustom(new CustomEvent(eventName));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import android.widget.TextView;
import android.widget.Toast;

import com.crashlytics.android.Crashlytics;
import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.data.Entry;
Expand Down Expand Up @@ -81,7 +80,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
if (igcFile != null) {
showInformation();
} else {
Crashlytics.log("FlightInformationActivity :: IGC File is null");
Toast.makeText(getApplication().getBaseContext(), R.string.sorry_error_happen, Toast.LENGTH_SHORT).show();
finish();
}
Expand All @@ -101,7 +99,7 @@ private void findViews() {
}

private void showInformation() {
insertField(R.drawable.ic_calendar, R.string.date, igcFile.getDate());
insertField(R.drawable.ic_calendar, R.string.date, igcFile.getDate().toString());
insertField(R.drawable.ic_person, R.string.pilot_in_charge, Utilities.capitalizeText(igcFile.getPilotInCharge()));
insertField(R.drawable.ic_plane, R.string.glider, igcFile.getGliderTypeAndId());
insertField(R.drawable.ic_speed, R.string.avg_speed, igcFile.getAverageSpeed() + "km/h");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
import android.widget.TextView;
import android.widget.Toast;

import com.crashlytics.android.Crashlytics;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
Expand Down Expand Up @@ -266,8 +265,6 @@ private void displayTrack() {
try {
googleMap.addPolyline(polyline);
} catch (Throwable t) {
Crashlytics.log("FlightPreviewActivity :: Tried to draw polyline when googleMap is null");
Crashlytics.logException(t);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
import android.widget.TextView;
import android.widget.Toast;

import com.crashlytics.android.Crashlytics;
import com.shollmann.android.igcparser.Parser;
import com.shollmann.android.igcparser.model.IGCFile;
import com.shollmann.android.igcparser.util.Logger;
Expand Down Expand Up @@ -145,8 +144,6 @@ private List<IGCFile> getListIGCFiles(File parentDir) {
Collections.sort(inFiles, Comparators.compareByDate);
} catch (Throwable t) {
final String message = "Couldn't open files";
Crashlytics.log(message);
Crashlytics.logException(t);
Logger.logError(message);
}

Expand Down Expand Up @@ -369,7 +366,6 @@ private void handleFinishFilesLoad(Boolean isEntireFolder) {
if (!isEntireFolder) {
final String message = "No IGC files found on XCSoar folder. Searching on other folders";
Logger.log(message);
Crashlytics.log(message);
txtLoading.setText(getString(R.string.searching_igc_files));
new FindIGCFilesAsyncTask(activity.get()).execute(Utilities.getSdCardFolder());
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public void onClick(View view) {
txtFileName.setText(igcFile.getFileName());
txtPilot.setText(Utilities.capitalizeText(igcFile.getPilotInCharge()));
txtPilot.setVisibility(TextUtils.isEmpty(igcFile.getPilotInCharge()) ? View.GONE : View.VISIBLE);
txtDate.setText(igcFile.getDate());
txtDate.setText(igcFile.getDate().toString());
txtGlider.setText(igcFile.getGliderTypeAndId());
txtGlider.setVisibility(TextUtils.isEmpty(igcFile.getGliderTypeAndId()) ? View.GONE : View.VISIBLE);
}
Expand Down
10 changes: 1 addition & 9 deletions app/src/main/java/com/shollmann/igcparser/util/Comparators.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@

import com.shollmann.android.igcparser.model.IGCFile;

import java.text.SimpleDateFormat;
import java.util.Comparator;

public class Comparators {
Expand Down Expand Up @@ -65,16 +64,9 @@ public int compare(IGCFile file0, IGCFile file1) {
};

public static Comparator<IGCFile> compareByDate = new Comparator<IGCFile>() {
private SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy");

@Override
public int compare(IGCFile file0, IGCFile file1) {
try {
return sdf.parse(file1.getDate()).compareTo(sdf.parse(file0.getDate()));
} catch (Throwable t) {
return 0;
}

return file0.getDate().compareTo(file1.getDate());
}
};
}
Expand Down
4 changes: 3 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.1'
classpath 'com.android.tools.build:gradle:4.1.3'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand All @@ -16,6 +17,7 @@ allprojects {
repositories {
jcenter()
maven { url "https://jitpack.io" }
google()
}
}

Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.google.maps.android.SphericalUtil;
import com.shollmann.android.igcparser.model.BRecord;
import com.shollmann.android.igcparser.model.CRecordWayPoint;
import com.shollmann.android.igcparser.model.IGCDate;
import com.shollmann.android.igcparser.model.IGCFile;
import com.shollmann.android.igcparser.util.Constants;
import com.shollmann.android.igcparser.util.CoordinatesUtilities;
Expand Down Expand Up @@ -104,7 +105,7 @@ public static IGCFile parse(Uri filePath) {
}

if (isDateRecord(line)) {
igcFile.setDate(parseDate(line));
igcFile.setDate(new IGCDate(line));
}
}
}
Expand Down Expand Up @@ -182,7 +183,7 @@ public static IGCFile quickParse(Uri filePath) {
}

if (isDateRecord(line)) {
igcFile.setDate(parseDate(line));
igcFile.setDate(new IGCDate(line));
}
}
}
Expand All @@ -209,19 +210,6 @@ public static IGCFile quickParse(Uri filePath) {
return igcFile;
}

private static String parseDate(String line) {
StringBuilder sb = new StringBuilder();
line = line.toUpperCase().replace(Constants.GeneralRecord.DATE, Constants.EMPTY_STRING);
try {
sb.append(line.substring(0, 2)).append(Constants.SLASH);
sb.append(line.substring(2, 4)).append(Constants.SLASH);
sb.append(line.substring(4));
} catch (Throwable t) {
Logger.logError("Unable to parse date");
}
return sb.toString();
}

@NonNull
private static String getValueOfColonField(String line) {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.shollmann.android.igcparser.model;

import android.support.annotation.NonNull;

import com.shollmann.android.igcparser.util.Logger;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Models a date for an IGC track-log.
* Created by Thomas Fischer on 02/05/2021.
*/
public class IGCDate implements Comparable<IGCDate> {
/**
* Regular expression that matches encoded date strings as specified by the IGC data format.
* <p>
* There are two possible formats for the encoded date
* The original FAI-IGC FlightRecorder specification for the DTE record was 'HFDTE{DD}{MM}{YY}'
* while after the 2015/09 specification changes it became 'HFDTEDATE:{DD}{MM}{YY},{NN}'.
* Both formats are supported here.
* E.g. a date for the first flight on the 2nd of May 2021 would be encoded as 'HFDTE020521'
* or 'HFDTEDATE:020521,01' using the old and new formats respectively.
* <p>
* See: http://vali.fai-civl.org/faq.html
*/
private static final Pattern pattern = Pattern.compile("(?:HFDTE(?:DATE:)?)(\\d{2}\\d{2}\\d{2})(?:,(\\d{2}))?");
private static final DateFormat dateFormatInput = new SimpleDateFormat("ddMMyy", Locale.getDefault());
private static final DateFormat dateFormatDisplay = new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());
private Date date;
private Integer flightNumber;

public IGCDate(String str) {
Matcher matcher = pattern.matcher(str);
if (matcher.find()) {
try {
date = dateFormatInput.parse(matcher.group(1));
} catch (ParseException e) {
e.printStackTrace();
String errorMessage = "IGCDate :: Unable to parse date string. Not a date.";
Logger.logError(errorMessage);
}
try {
// Note: Flight number will be null for old format strings that don't specify it.
flightNumber = matcher.group(2) != null ? Integer.parseInt(matcher.group(2)) : null;
} catch (NumberFormatException e) {
e.printStackTrace();
String errorMessage = "IGCDate :: Unable to parse date string. Not a number.";
Logger.logError(errorMessage);
}
} else {
String errorMessage = "IGCDate :: Unable to parse date string. Unexpected format.";
Logger.logError(errorMessage);
}
}

public Date getDate() {
return date;
}

public Integer getFlightNumber() {
return flightNumber;
}

@Override
public String toString() {
return dateFormatDisplay.format(date) + (flightNumber == null ? "" : String.format(" %02d", flightNumber));
}

@Override
public int compareTo(@NonNull IGCDate igcDate) {
int result = date.compareTo(igcDate.date);
if (result != 0)
return result;
return flightNumber.compareTo(igcDate.flightNumber);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class IGCFile implements Serializable {
private String pilotInCharge;
private String gliderId;
private String gliderType;
private String date;
private IGCDate date;
private String fileName;
private String filePath;
private boolean isTaskCompleted;
Expand Down Expand Up @@ -152,11 +152,11 @@ public void setPilotInCharge(String pilotInCharge) {
this.pilotInCharge = pilotInCharge;
}

public String getDate() {
public IGCDate getDate() {
return date;
}

public void setDate(String date) {
public void setDate(IGCDate date) {
this.date = date;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.shollmann.android.igcparser;

import com.shollmann.android.igcparser.model.IGCDate;

import org.junit.Before;
import org.junit.Test;

import java.text.SimpleDateFormat;
import java.util.Date;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

public class IGCDateUnitTest {

private static Date targetDate;

@Before
public void setUp() throws Exception {
targetDate = new SimpleDateFormat("dd/MM/yyyy").parse("02/05/2021");
}

@Test
public void parseOldFormat() {
String str = "HFDTE020521";
IGCDate igcDate = new IGCDate(str);

assertEquals(igcDate.getDate(), targetDate);
assertNull(igcDate.getFlightNumber());
}

@Test
public void parseNewFormat() {
String str = "HFDTEDATE:020521,01";
IGCDate igcDate = new IGCDate(str);

assertEquals(igcDate.getDate(), targetDate);
assertEquals(igcDate.getFlightNumber(), (Integer)1);
}
}