Move ExportCSVTask to uhabits-core

This commit is contained in:
2017-05-25 12:23:09 -04:00
parent 370e7343d7
commit cb4ab3b436
26 changed files with 126 additions and 96 deletions

View File

@@ -33,8 +33,8 @@ android {
}
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
testOptions {
@@ -52,7 +52,6 @@ android {
}
dependencies {
implementation project(":uhabits-core")
implementation 'com.android.support:appcompat-v7:25.3.1'
@@ -61,7 +60,6 @@ dependencies {
implementation 'com.android.support:support-v4:25.3.1'
implementation 'com.getpebble:pebblekit:3.0.0'
implementation 'com.github.paolorotolo:appintro:3.4.0'
implementation 'com.google.auto.factory:auto-factory:1.0-beta3'
implementation 'com.google.dagger:dagger:2.11-rc2'
implementation 'com.jakewharton:butterknife:8.6.1-SNAPSHOT'
implementation 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'
@@ -75,18 +73,21 @@ dependencies {
testImplementation 'org.hamcrest:hamcrest-library:1.4-atlassian-1'
testImplementation 'org.mockito:mockito-core:2.8.9'
testImplementation 'org.json:json:20160810'
testImplementation 'org.robolectric:robolectric:3.4-rc2'
androidTestImplementation 'com.android.support:support-annotations:25.3.1'
androidTestImplementation 'com.android.support.test:rules:0.5'
androidTestImplementation 'com.android.support.test:runner:0.5'
androidTestImplementation 'com.google.auto.factory:auto-factory:1.0-beta3'
androidTestImplementation "com.google.dexmaker:dexmaker:1.2"
androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:1.2'
androidTestImplementation 'org.mockito:mockito-core:1.10.19'
androidTestImplementation 'com.google.guava:guava:20.0'
compileOnly 'javax.annotation:jsr250-api:1.0'
compileOnly 'com.google.auto.factory:auto-factory:1.0-beta3'
androidTestCompileOnly 'com.google.auto.factory:auto-factory:1.0-beta3'
annotationProcessor 'com.google.dagger:dagger-compiler:2.11-rc2'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.1-SNAPSHOT'
@@ -99,12 +100,10 @@ dependencies {
androidTestAnnotationProcessor 'com.google.dagger:dagger-compiler:2.11-rc2'
androidTestAnnotationProcessor 'com.google.auto.factory:auto-factory:1.0-beta3'
androidTestAnnotationProcessor 'com.jakewharton:butterknife-compiler:8.6.1-SNAPSHOT'
implementation ('com.opencsv:opencsv:3.9') {
implementation('com.opencsv:opencsv:3.9') {
exclude group: 'commons-logging', module: 'commons-logging'
}
implementation ('io.socket:socket.io-client:+') {
implementation('io.socket:socket.io-client:+') {
exclude group: 'org.json', module: 'json'
}
}

View File

@@ -28,6 +28,7 @@ import android.support.test.*;
import android.util.*;
import org.isoron.androidbase.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.tasks.*;
@@ -68,6 +69,8 @@ public class BaseAndroidTest
protected ModelFactory modelFactory;
protected BaseSystem baseSystem;
@Before
public void setUp()
{
@@ -90,6 +93,8 @@ public class BaseAndroidTest
.appModule(new AppModule(targetContext.getApplicationContext()))
.build();
baseSystem = new BaseSystem(targetContext);
HabitsApplication.setComponent(component);
prefs = component.getPreferences();
habitList = component.getHabitList();

View File

@@ -24,6 +24,8 @@ import android.support.annotation.*;
import android.view.*;
import android.widget.*;
import org.isoron.androidbase.activities.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.utils.*;
import org.isoron.uhabits.widgets.*;
@@ -170,7 +172,7 @@ public class BaseViewTest extends BaseAndroidTest
{
File dir = FileUtils.getSDCardDir("test-screenshots");
if (dir == null)
dir = FileUtils.getFilesDir(targetContext, "test-screenshots");
dir = baseSystem.getFilesDir("test-screenshots");
if (dir == null) throw new RuntimeException(
"Could not find suitable dir for screenshots");

View File

@@ -24,9 +24,9 @@ import android.support.test.*;
import android.support.test.runner.*;
import android.test.suitebuilder.annotation.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import org.junit.runner.*;

View File

@@ -24,6 +24,7 @@ import android.support.test.*;
import android.support.test.runner.*;
import android.test.suitebuilder.annotation.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.utils.*;

View File

@@ -54,9 +54,11 @@ public class ExportCSVTaskTest extends BaseAndroidTest
List<Habit> selected = new LinkedList<>();
for (Habit h : habitList) selected.add(h);
File outputDir = baseSystem.getFilesDir("CSV");
assertNotNull(outputDir);
taskRunner.execute(
new ExportCSVTask(targetContext,habitList, selected, archiveFilename -> {
new ExportCSVTask(habitList, selected, outputDir, archiveFilename -> {
assertThat(archiveFilename, is(not(nullValue())));
File f = new File(archiveFilename);
assertTrue(f.exists());

View File

@@ -23,20 +23,19 @@ import android.support.test.runner.*;
import android.test.suitebuilder.annotation.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.tasks.android.*;
import org.junit.*;
import org.junit.runner.*;
import java.io.*;
import static junit.framework.Assert.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.core.IsNot.not;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class ExportDBTaskTest extends BaseAndroidTest
{
@Override
@Before
public void setUp()
{
@@ -46,13 +45,13 @@ public class ExportDBTaskTest extends BaseAndroidTest
@Test
public void testExportCSV() throws Throwable
{
ExportDBTask task = new ExportDBTask(targetContext, filename -> {
assertThat(filename, is(not(nullValue())));
File f = new File(filename);
assertTrue(f.exists());
assertTrue(f.canRead());
});
ExportDBTask task =
new ExportDBTask(targetContext, baseSystem, filename -> {
assertNotNull(filename);
File f = new File(filename);
assertTrue(f.exists());
assertTrue(f.canRead());
});
taskRunner.execute(task);
}

View File

@@ -41,6 +41,12 @@ public abstract class BaseMenu
this.activity = activity;
}
@NonNull
public BaseActivity getActivity()
{
return activity;
}
/**
* Declare that the menu has changed, and should be recreated.
*/

View File

@@ -22,8 +22,11 @@ package org.isoron.androidbase.activities;
import android.content.*;
import android.os.*;
import android.support.annotation.*;
import android.support.v4.content.*;
import android.util.*;
import android.view.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.utils.*;
@@ -52,6 +55,19 @@ public class BaseSystem
this.context = context;
}
@Nullable
public File getFilesDir(@Nullable String relativePath)
{
File externalFilesDirs[] = ContextCompat.getExternalFilesDirs(context, null);
if (externalFilesDirs == null)
{
Log.e("BaseSystem", "getFilesDir: getExternalFilesDirs returned null");
return null;
}
return FileUtils.getDir(externalFilesDirs, relativePath);
}
/**
* Captures a bug report and saves it to a file in the SD card.
* <p>
@@ -70,7 +86,7 @@ public class BaseSystem
if (context == null) throw new RuntimeException(
"application context should not be null");
File dir = FileUtils.getFilesDir(context, "Logs");
File dir = getFilesDir("Logs");
if (dir == null) throw new IOException("log dir should not be null");
File logFile =

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
@@ -17,12 +17,10 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.utils;
package org.isoron.androidbase.utils;
import android.content.*;
import android.os.*;
import android.support.annotation.*;
import android.support.v4.content.*;
import android.util.*;
import java.io.*;
@@ -52,8 +50,8 @@ public abstract class FileUtils
}
@Nullable
private static File getDir(@NonNull File potentialParentDirs[],
@Nullable String relativePath)
public static File getDir(@NonNull File potentialParentDirs[],
@Nullable String relativePath)
{
if (relativePath == null) relativePath = "";
@@ -67,7 +65,7 @@ public abstract class FileUtils
if (chosenDir == null)
{
Log.e("DatabaseHelper",
Log.e("FileUtils",
"getDir: all potential parents are null or non-writable");
return null;
}
@@ -76,7 +74,7 @@ public abstract class FileUtils
String.format("%s/%s/", chosenDir.getAbsolutePath(), relativePath));
if (!dir.exists() && !dir.mkdirs())
{
Log.e("DatabaseHelper",
Log.e("FileUtils",
"getDir: chosen dir does not exist and cannot be created");
return null;
}
@@ -84,22 +82,6 @@ public abstract class FileUtils
return dir;
}
@Nullable
public static File getFilesDir(@NonNull Context context, @Nullable String relativePath)
{
File externalFilesDirs[] =
ContextCompat.getExternalFilesDirs(context, null);
if (externalFilesDirs == null)
{
Log.e("DatabaseHelper",
"getFilesDir: getExternalFilesDirs returned null");
return null;
}
return getDir(externalFilesDirs, relativePath);
}
@Nullable
public static File getSDCardDir(@Nullable String relativePath)
{

View File

@@ -32,6 +32,7 @@ import org.isoron.uhabits.notifications.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.sync.*;
import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.tasks.android.*;
import org.isoron.uhabits.utils.*;
import org.isoron.uhabits.widgets.*;

View File

@@ -29,6 +29,7 @@ import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.tasks.android.*;
import org.isoron.uhabits.utils.*;
import org.isoron.uhabits.widgets.*;
@@ -105,11 +106,13 @@ public class ListHabitsController
{
List<Habit> selected = new LinkedList<>();
for (Habit h : habitList) selected.add(h);
File outputDir = system.getFilesDir("CSV");
taskRunner.execute(exportCSVFactory.create(selected, filename -> {
if (filename != null) screen.showSendFileScreen(filename);
else screen.showMessage(R.string.could_not_export);
}));
taskRunner.execute(
exportCSVFactory.create(selected, outputDir, filename -> {
if (filename != null) screen.showSendFileScreen(filename);
else screen.showMessage(R.string.could_not_export);
}));
}
public void onExportDB()

View File

@@ -29,6 +29,7 @@ import android.view.*;
import android.widget.*;
import org.isoron.androidbase.activities.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.common.dialogs.*;

View File

@@ -27,6 +27,7 @@ import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*;
import java.io.*;
import java.util.*;
import javax.inject.*;
@@ -34,6 +35,9 @@ import javax.inject.*;
@ActivityScope
public class ShowHabitsMenu extends BaseMenu
{
@NonNull
private final BaseSystem system;
@NonNull
private final ShowHabitScreen screen;
@@ -48,12 +52,14 @@ public class ShowHabitsMenu extends BaseMenu
@Inject
public ShowHabitsMenu(@NonNull BaseActivity activity,
@NonNull BaseSystem system,
@NonNull ShowHabitScreen screen,
@NonNull Habit habit,
@NonNull ExportCSVTaskFactory exportCSVFactory,
@NonNull TaskRunner taskRunner)
{
super(activity);
this.system = system;
this.screen = screen;
this.habit = habit;
this.taskRunner = taskRunner;
@@ -64,7 +70,9 @@ public class ShowHabitsMenu extends BaseMenu
{
List<Habit> selected = new LinkedList<>();
selected.add(habit);
ExportCSVTask task = exportCSVFactory.create(selected, filename -> {
File outputDir = system.getFilesDir("CSV");
ExportCSVTask task = exportCSVFactory.create(selected,
outputDir, filename -> {
if (filename != null) screen.showSendFileScreen(filename);
else screen.showMessage(R.string.could_not_export);
});

View File

@@ -68,41 +68,41 @@ public class CommandParser
}
@NonNull
public Command parse(@NonNull JSONObject json) throws JSONException
public Command parse(@NonNull String json) throws JSONException
{
String event = json.getString("event");
String event = new JSONObject(json).getString("event");
Gson gson = new GsonBuilder().create();
if (event.equals("Archive")) return gson
.fromJson(json.toString(), ArchiveHabitsCommand.Record.class)
.fromJson(json, ArchiveHabitsCommand.Record.class)
.toCommand(habitList);
if (event.equals("ChangeColor")) return gson
.fromJson(json.toString(), ChangeHabitColorCommand.Record.class)
.fromJson(json, ChangeHabitColorCommand.Record.class)
.toCommand(habitList);
if (event.equals("CreateHabit")) return gson
.fromJson(json.toString(), CreateHabitCommand.Record.class)
.fromJson(json, CreateHabitCommand.Record.class)
.toCommand(modelFactory, habitList);
if (event.equals("CreateRep")) return gson
.fromJson(json.toString(), CreateRepetitionCommand.Record.class)
.fromJson(json, CreateRepetitionCommand.Record.class)
.toCommand(habitList);
if (event.equals("DeleteHabit")) return gson
.fromJson(json.toString(), DeleteHabitsCommand.Record.class)
.fromJson(json, DeleteHabitsCommand.Record.class)
.toCommand(habitList);
if (event.equals("EditHabit")) return gson
.fromJson(json.toString(), EditHabitCommand.Record.class)
.fromJson(json, EditHabitCommand.Record.class)
.toCommand(modelFactory, habitList);
if (event.equals("Toggle")) return gson
.fromJson(json.toString(), ToggleRepetitionCommand.Record.class)
.fromJson(json, ToggleRepetitionCommand.Record.class)
.toCommand(habitList);
if (event.equals("Unarchive")) return gson
.fromJson(json.toString(), UnarchiveHabitsCommand.Record.class)
.fromJson(json, UnarchiveHabitsCommand.Record.class)
.toCommand(habitList);
throw new IllegalStateException("Unknown command");

View File

@@ -1,275 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.io;
import android.support.annotation.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.utils.*;
import java.io.*;
import java.text.*;
import java.util.*;
import java.util.zip.*;
/**
* Class that exports the application data to CSV files.
*/
public class HabitsCSVExporter
{
private List<Habit> selectedHabits;
private List<String> generateDirs;
private List<String> generateFilenames;
private String exportDirName;
/**
* Delimiter used in a CSV file.
*/
private final String DELIMITER = ",";
@NonNull
private final HabitList allHabits;
public HabitsCSVExporter(@NonNull HabitList allHabits,
@NonNull List<Habit> selectedHabits,
@NonNull File dir)
{
this.allHabits = allHabits;
this.selectedHabits = selectedHabits;
this.exportDirName = dir.getAbsolutePath() + "/";
generateDirs = new LinkedList<>();
generateFilenames = new LinkedList<>();
}
public String writeArchive() throws IOException
{
String zipFilename;
writeHabits();
zipFilename = writeZipFile();
cleanup();
return zipFilename;
}
private void addFileToZip(ZipOutputStream zos, String filename)
throws IOException
{
FileInputStream fis =
new FileInputStream(new File(exportDirName + filename));
ZipEntry ze = new ZipEntry(filename);
zos.putNextEntry(ze);
int length;
byte bytes[] = new byte[1024];
while ((length = fis.read(bytes)) >= 0) zos.write(bytes, 0, length);
zos.closeEntry();
fis.close();
}
private void cleanup()
{
for (String filename : generateFilenames)
new File(exportDirName + filename).delete();
for (String filename : generateDirs)
new File(exportDirName + filename).delete();
new File(exportDirName).delete();
}
@NonNull
private String sanitizeFilename(String name)
{
String s = name.replaceAll("[^ a-zA-Z0-9\\._-]+", "");
return s.substring(0, Math.min(s.length(), 100));
}
private void writeHabits() throws IOException
{
String filename = "Habits.csv";
new File(exportDirName).mkdirs();
FileWriter out = new FileWriter(exportDirName + filename);
generateFilenames.add(filename);
allHabits.writeCSV(out);
out.close();
for (Habit h : selectedHabits)
{
String sane = sanitizeFilename(h.getName());
String habitDirName =
String.format("%03d %s", allHabits.indexOf(h) + 1, sane);
habitDirName = habitDirName.trim() + "/";
new File(exportDirName + habitDirName).mkdirs();
generateDirs.add(habitDirName);
writeScores(habitDirName, h.getScores());
writeCheckmarks(habitDirName, h.getCheckmarks());
}
writeMultipleHabits();
}
private void writeScores(String habitDirName, ScoreList scores)
throws IOException
{
String path = habitDirName + "Scores.csv";
FileWriter out = new FileWriter(exportDirName + path);
generateFilenames.add(path);
scores.writeCSV(out);
out.close();
}
private void writeCheckmarks(String habitDirName, CheckmarkList checkmarks)
throws IOException
{
String filename = habitDirName + "Checkmarks.csv";
FileWriter out = new FileWriter(exportDirName + filename);
generateFilenames.add(filename);
checkmarks.writeCSV(out);
out.close();
}
/**
* Writes a scores file and a checkmarks file containing scores and checkmarks of every habit.
* The first column corresponds to the date. Subsequent columns correspond to a habit.
* Habits are taken from the list of selected habits.
* Dates are determined from the oldest repetition date to the newest repetition date found in
* the list of habits.
*
* @throws IOException if there was problem writing the files
*/
private void writeMultipleHabits() throws IOException
{
String scoresFileName = "Scores.csv";
String checksFileName = "Checkmarks.csv";
generateFilenames.add(scoresFileName);
generateFilenames.add(checksFileName);
FileWriter scoresWriter = new FileWriter(exportDirName + scoresFileName);
FileWriter checksWriter = new FileWriter(exportDirName + checksFileName);
writeMultipleHabitsHeader(scoresWriter);
writeMultipleHabitsHeader(checksWriter);
long[] timeframe = getTimeframe();
long oldest = timeframe[0];
long newest = DateUtils.getStartOfToday();
List<int[]> checkmarks = new ArrayList<>();
List<double[]> scores = new ArrayList<>();
for (Habit h : selectedHabits)
{
checkmarks.add(h.getCheckmarks().getValues(oldest, newest));
scores.add(h.getScores().getValues(oldest, newest));
}
int days = DateUtils.getDaysBetween(oldest, newest);
SimpleDateFormat dateFormat = DateFormats.getCSVDateFormat();
for (int i = 0; i <= days; i++)
{
Date day = new Date(newest - i * DateUtils.millisecondsInOneDay);
String date = dateFormat.format(day);
StringBuilder sb = new StringBuilder();
sb.append(date).append(DELIMITER);
checksWriter.write(sb.toString());
scoresWriter.write(sb.toString());
for(int j = 0; j < selectedHabits.size(); j++)
{
checksWriter.write(String.valueOf(checkmarks.get(j)[i]));
checksWriter.write(DELIMITER);
String score =
String.format("%.4f", ((float) scores.get(j)[i]));
scoresWriter.write(score);
scoresWriter.write(DELIMITER);
}
checksWriter.write("\n");
scoresWriter.write("\n");
}
scoresWriter.close();
checksWriter.close();
}
/**
* Writes the first row, containing header information, using the given writer.
* This consists of the date title and the names of the selected habits.
*
* @param out the writer to use
* @throws IOException if there was a problem writing
*/
private void writeMultipleHabitsHeader(Writer out) throws IOException
{
out.write("Date" + DELIMITER);
for (Habit h : selectedHabits) {
out.write(h.getName());
out.write(DELIMITER);
}
out.write("\n");
}
/**
* Gets the overall timeframe of the selected habits.
* The timeframe is an array containing the oldest timestamp among the habits and the
* newest timestamp among the habits.
* Both timestamps are in milliseconds.
*
* @return the timeframe containing the oldest timestamp and the newest timestamp
*/
private long[] getTimeframe()
{
long oldest = Long.MAX_VALUE;
long newest = -1;
for (Habit h : selectedHabits)
{
if(h.getRepetitions().getOldest() == null || h.getRepetitions().getNewest() == null)
continue;
long currOld = h.getRepetitions().getOldest().getTimestamp();
long currNew = h.getRepetitions().getNewest().getTimestamp();
oldest = currOld > oldest ? oldest : currOld;
newest = currNew < newest ? newest : currNew;
}
return new long[]{oldest, newest};
}
private String writeZipFile() throws IOException
{
SimpleDateFormat dateFormat = DateFormats.getCSVDateFormat();
String date = dateFormat.format(DateUtils.getStartOfToday());
String zipFilename =
String.format("%s/Loop Habits CSV %s.zip", exportDirName, date);
FileOutputStream fos = new FileOutputStream(zipFilename);
ZipOutputStream zos = new ZipOutputStream(fos);
for (String filename : generateFilenames)
addFileToZip(zos, filename);
zos.close();
fos.close();
return zipFilename;
}
}

View File

@@ -28,10 +28,10 @@ import android.util.*;
import com.activeandroid.*;
import org.isoron.androidbase.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.utils.DatabaseUtils;
import org.isoron.uhabits.utils.*;
import java.io.*;

View File

@@ -316,7 +316,7 @@ public class SyncManager implements CommandRunner.Listener
private void executeCommand(JSONObject root) throws JSONException
{
Command received = commandParser.parse(root);
Command received = commandParser.parse(root.toString());
received.setRemote(true);
for (Event e : pendingConfirmation)

View File

@@ -1,91 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.tasks;
import android.content.Context;
import android.support.annotation.*;
import com.google.auto.factory.*;
import org.isoron.androidbase.AppContext;
import org.isoron.uhabits.io.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.utils.*;
import java.io.*;
import java.util.*;
@AutoFactory(allowSubclasses = true)
public class ExportCSVTask implements Task
{
private String archiveFilename;
@NonNull
private final Context context;
@NonNull
private final List<Habit> selectedHabits;
@NonNull
private final ExportCSVTask.Listener listener;
@NonNull
private final HabitList habitList;
public ExportCSVTask(@Provided @AppContext @NonNull Context context,
@Provided @NonNull HabitList habitList,
@NonNull List<Habit> selectedHabits,
@NonNull Listener listener)
{
this.context = context;
this.listener = listener;
this.habitList = habitList;
this.selectedHabits = selectedHabits;
}
@Override
public void doInBackground()
{
try
{
File dir = FileUtils.getFilesDir(context, "CSV");
if (dir == null) return;
HabitsCSVExporter exporter;
exporter = new HabitsCSVExporter(habitList, selectedHabits, dir);
archiveFilename = exporter.writeArchive();
}
catch (IOException e)
{
e.printStackTrace();
}
}
@Override
public void onPostExecute()
{
listener.onExportCSVFinished(archiveFilename);
}
public interface Listener
{
void onExportCSVFinished(@Nullable String archiveFilename);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
@@ -17,11 +17,12 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.tasks;
package org.isoron.uhabits.tasks.android;
import android.os.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.tasks.*;
import java.util.*;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
@@ -17,15 +17,16 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.tasks;
package org.isoron.uhabits.tasks.android;
import android.content.Context;
import android.content.*;
import android.support.annotation.*;
import com.google.auto.factory.AutoFactory;
import com.google.auto.factory.Provided;
import com.google.auto.factory.*;
import org.isoron.androidbase.AppContext;
import org.isoron.androidbase.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.utils.*;
import java.io.*;
@@ -38,11 +39,16 @@ public class ExportDBTask implements Task
@NonNull
private Context context;
private BaseSystem system;
@NonNull
private final Listener listener;
public ExportDBTask(@Provided @AppContext @NonNull Context context, @NonNull Listener listener)
public ExportDBTask(@Provided @AppContext @NonNull Context context,
@Provided @NonNull BaseSystem system,
@NonNull Listener listener)
{
this.system = system;
this.listener = listener;
this.context = context;
}
@@ -54,7 +60,7 @@ public class ExportDBTask implements Task
try
{
File dir = FileUtils.getFilesDir(context, "Backups");
File dir = system.getFilesDir("Backups");
if (dir == null) return;
filename = DatabaseUtils.saveDatabaseCopy(context, dir);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
@@ -17,13 +17,14 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.tasks;
package org.isoron.uhabits.tasks.android;
import android.support.annotation.*;
import com.google.auto.factory.*;
import org.isoron.uhabits.io.*;
import org.isoron.uhabits.tasks.*;
import java.io.*;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
@@ -21,4 +21,4 @@
* Provides async tasks for useful operations such as {@link
* org.isoron.uhabits.tasks.ExportCSVTask}.
*/
package org.isoron.uhabits.tasks;
package org.isoron.uhabits.tasks.android;

View File

@@ -24,6 +24,7 @@ import android.support.annotation.*;
import com.activeandroid.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.sqlite.*;
import org.isoron.uhabits.models.sqlite.records.*;

View File

@@ -21,6 +21,7 @@ package org.isoron.uhabits.activities.habits.show;
import android.view.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*;
@@ -43,19 +44,20 @@ public class ShowHabitsMenuTest extends BaseUnitTest
private TaskRunner taskRunner;
private ExportCSVTask task;
private BaseSystem system;
@Override
public void setUp()
{
super.setUp();
activity = mock(ShowHabitActivity.class);
system = mock(BaseSystem.class);
screen = mock(ShowHabitScreen.class);
habit = mock(Habit.class);
exportCSVFactory = mock(ExportCSVTaskFactory.class);
taskRunner = mock(TaskRunner.class);
menu = new ShowHabitsMenu(activity, screen, habit, exportCSVFactory,
taskRunner);
menu = new ShowHabitsMenu(activity, system, screen, habit,
exportCSVFactory, taskRunner);
}
@Test