package cgeo.geocaching.export;
import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.R;
import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.connector.IConnector;
import cgeo.geocaching.connector.capability.FieldNotesCapability;
import cgeo.geocaching.log.LogEntry;
import cgeo.geocaching.models.Geocache;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.storage.DataStore;
import cgeo.geocaching.storage.LocalStorage;
import cgeo.geocaching.utils.AsyncTaskWithProgress;
import cgeo.geocaching.utils.Formatter;
import cgeo.geocaching.utils.Log;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import butterknife.ButterKnife;
/**
* Exports offline logs in the Groundspeak Field Note format.
*
*/
public class FieldNoteExport extends AbstractExport {
private static final File exportLocation = LocalStorage.getFieldNotesDirectory();
private static int fieldNotesCount = 0;
private final String fileName;
public FieldNoteExport() {
super(R.string.export_fieldnotes);
final SimpleDateFormat fileNameDateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
fileName = fileNameDateFormat.format(new Date()) + ".txt";
}
@Override
public void export(@NonNull final List<Geocache> cachesList, @Nullable final Activity activity) {
final Geocache[] caches = cachesList.toArray(new Geocache[cachesList.size()]);
if (activity == null) {
// No activity given, so no user interaction possible.
// Start export with default parameters.
new ExportTask(null, false, false).execute(caches);
} else {
// Show configuration dialog
getExportOptionsDialog(caches, activity).show();
}
}
private Dialog getExportOptionsDialog(final Geocache[] caches, final Activity activity) {
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(activity.getString(R.string.export_confirm_title, activity.getString(R.string.export_fieldnotes)));
final View layout = View.inflate(activity, R.layout.fieldnote_export_dialog, null);
builder.setView(layout);
final TextView text = ButterKnife.findById(layout, R.id.info);
text.setText(activity.getString(R.string.export_confirm_message, exportLocation.getAbsolutePath(), fileName));
final CheckBox uploadOption = ButterKnife.findById(layout, R.id.upload);
uploadOption.setChecked(Settings.getFieldNoteExportUpload());
final CheckBox onlyNewOption = ButterKnife.findById(layout, R.id.onlynew);
onlyNewOption.setChecked(Settings.getFieldNoteExportOnlyNew());
if (Settings.getFieldnoteExportDate() > 0) {
onlyNewOption.setText(activity.getString(R.string.export_fieldnotes_onlynew) + " (" + Formatter.formatDateTime(Settings.getFieldnoteExportDate()) + ')');
}
builder.setPositiveButton(R.string.export, new DialogInterface.OnClickListener() {
@Override
public void onClick(final DialogInterface dialog, final int which) {
final boolean upload = uploadOption.isChecked();
final boolean onlyNew = onlyNewOption.isChecked();
Settings.setFieldNoteExportUpload(upload);
Settings.setFieldNoteExportOnlyNew(onlyNew);
dialog.dismiss();
new ExportTask(activity, upload, onlyNew).execute(caches);
}
});
return builder.create();
}
private class ExportTask extends AsyncTaskWithProgress<Geocache, Boolean> {
private final boolean upload;
private final boolean onlyNew;
private File exportFile;
private static final int STATUS_UPLOAD = -1;
/**
* Instantiates and configures the task for exporting field notes.
*
* @param activity
* optional: Show a progress bar and toasts
* @param upload
* Upload the Field Note to geocaching.com
* @param onlyNew
* Upload/export only new logs since last export
*/
ExportTask(@Nullable final Activity activity, final boolean upload, final boolean onlyNew) {
super(activity, getProgressTitle(), CgeoApplication.getInstance().getString(R.string.export_fieldnotes_creating), true);
this.upload = upload;
this.onlyNew = onlyNew;
}
@Override
protected Boolean doInBackgroundInternal(final Geocache[] caches) {
// export all field notes, without any filtering by connector
final FieldNotes fieldNotes = createFieldNotes(caches);
if (fieldNotes == null) {
return false;
}
// write to file
exportFile = fieldNotes.writeToDirectory(exportLocation, fileName);
if (exportFile == null) {
return false;
}
fieldNotesCount = fieldNotes.size();
// upload same file to multiple connectors, if they support the upload
return uploadFieldNotes();
}
private Boolean uploadFieldNotes() {
boolean uploadResult = true;
if (upload) {
publishProgress(STATUS_UPLOAD);
for (final IConnector connector : ConnectorFactory.getConnectors()) {
if (connector instanceof FieldNotesCapability) {
uploadResult &= ((FieldNotesCapability) connector).uploadFieldNotes(exportFile);
}
}
}
return uploadResult;
}
@Nullable
private FieldNotes createFieldNotes(final Geocache[] caches) {
final FieldNotes fieldNotes = new FieldNotes();
try {
for (final Geocache cache : caches) {
if (cache.isLogOffline()) {
final LogEntry log = DataStore.loadLogOffline(cache.getGeocode());
if (log != null && (!onlyNew || log.date > Settings.getFieldnoteExportDate())) {
fieldNotes.add(cache, log);
}
}
publishProgress(fieldNotes.size());
}
} catch (final Exception e) {
Log.e("FieldNoteExport.ExportTask generation", e);
return null;
}
return fieldNotes;
}
@Override
protected void onPostExecuteInternal(final Boolean result) {
if (activity != null) {
final Context nonNullActivity = activity;
if (result) {
Settings.setFieldnoteExportDate(System.currentTimeMillis());
ActivityMixin.showToast(activity, getName() + ' ' + nonNullActivity.getString(R.string.export_exportedto) + ": " + exportFile.toString());
if (upload) {
ActivityMixin.showToast(activity, nonNullActivity.getString(R.string.export_fieldnotes_upload_success));
}
} else {
ActivityMixin.showToast(activity, nonNullActivity.getString(R.string.export_failed));
}
}
}
@Override
protected void onProgressUpdateInternal(final Integer status) {
if (activity != null) {
setMessage(activity.getString(status == STATUS_UPLOAD ? R.string.export_fieldnotes_uploading : R.string.export_fieldnotes_creating) + " (" + fieldNotesCount + ')');
}
}
}
}