mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Refactor CSVExporter
This commit is contained in:
@@ -35,6 +35,7 @@ dependencies {
|
|||||||
compile 'com.android.support:support-v4:23.1.1'
|
compile 'com.android.support:support-v4:23.1.1'
|
||||||
compile 'com.github.paolorotolo:appintro:3.4.0'
|
compile 'com.github.paolorotolo:appintro:3.4.0'
|
||||||
compile 'org.apmem.tools:layouts:1.10@aar'
|
compile 'org.apmem.tools:layouts:1.10@aar'
|
||||||
|
compile 'com.opencsv:opencsv:3.7'
|
||||||
compile project(':libs:drag-sort-listview:library')
|
compile project(':libs:drag-sort-listview:library')
|
||||||
compile files('libs/ActiveAndroid.jar')
|
compile files('libs/ActiveAndroid.jar')
|
||||||
|
|
||||||
|
|||||||
@@ -91,4 +91,9 @@ public class ColorHelper
|
|||||||
hsv[index] = newValue;
|
hsv[index] = newValue;
|
||||||
return Color.HSVToColor(hsv);
|
return Color.HSVToColor(hsv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String toHTML(int color)
|
||||||
|
{
|
||||||
|
return String.format("#%06X", 0xFFFFFF & color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -24,6 +24,7 @@ import android.text.format.DateFormat;
|
|||||||
|
|
||||||
import org.isoron.uhabits.R;
|
import org.isoron.uhabits.R;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -96,6 +97,14 @@ public class DateHelper
|
|||||||
return df.format(date);
|
return df.format(date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SimpleDateFormat getCSVDateFormat()
|
||||||
|
{
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
|
||||||
|
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||||
|
|
||||||
|
return dateFormat;
|
||||||
|
}
|
||||||
|
|
||||||
public static String formatHeaderDate(GregorianCalendar day)
|
public static String formatHeaderDate(GregorianCalendar day)
|
||||||
{
|
{
|
||||||
String dayOfMonth = Integer.toString(day.get(GregorianCalendar.DAY_OF_MONTH));
|
String dayOfMonth = Integer.toString(day.get(GregorianCalendar.DAY_OF_MONTH));
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ import org.isoron.uhabits.commands.ChangeHabitColorCommand;
|
|||||||
import org.isoron.uhabits.commands.DeleteHabitsCommand;
|
import org.isoron.uhabits.commands.DeleteHabitsCommand;
|
||||||
import org.isoron.uhabits.commands.UnarchiveHabitsCommand;
|
import org.isoron.uhabits.commands.UnarchiveHabitsCommand;
|
||||||
import org.isoron.uhabits.fragments.EditHabitFragment;
|
import org.isoron.uhabits.fragments.EditHabitFragment;
|
||||||
import org.isoron.uhabits.io.CSVExporter;
|
import org.isoron.uhabits.io.HabitsExporter;
|
||||||
import org.isoron.uhabits.loaders.HabitListLoader;
|
import org.isoron.uhabits.loaders.HabitListLoader;
|
||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@ public class HabitSelectionCallback implements ActionMode.Callback
|
|||||||
{
|
{
|
||||||
new AsyncTask<Void, Void, Void>()
|
new AsyncTask<Void, Void, Void>()
|
||||||
{
|
{
|
||||||
String filename;
|
String archiveFilename;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPreExecute()
|
protected void onPreExecute()
|
||||||
@@ -241,15 +241,19 @@ public class HabitSelectionCallback implements ActionMode.Callback
|
|||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Void aVoid)
|
protected void onPostExecute(Void aVoid)
|
||||||
{
|
{
|
||||||
if(filename != null)
|
if(archiveFilename != null)
|
||||||
{
|
{
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
intent.setAction(Intent.ACTION_SEND);
|
intent.setAction(Intent.ACTION_SEND);
|
||||||
intent.setType("application/zip");
|
intent.setType("application/zip");
|
||||||
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(filename)));
|
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(archiveFilename)));
|
||||||
|
|
||||||
activity.startActivity(intent);
|
activity.startActivity(intent);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activity.showToast(R.string.could_not_export);
|
||||||
|
}
|
||||||
|
|
||||||
if(progressBar != null)
|
if(progressBar != null)
|
||||||
progressBar.setVisibility(View.GONE);
|
progressBar.setVisibility(View.GONE);
|
||||||
@@ -258,8 +262,10 @@ public class HabitSelectionCallback implements ActionMode.Callback
|
|||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... params)
|
protected Void doInBackground(Void... params)
|
||||||
{
|
{
|
||||||
CSVExporter exporter = new CSVExporter(activity, selectedHabits);
|
String dirName = String.format("%s/export/", activity.getExternalCacheDir());
|
||||||
filename = exporter.writeArchive();
|
HabitsExporter exporter = new HabitsExporter(selectedHabits, dirName);
|
||||||
|
archiveFilename = exporter.writeArchive();
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
|
|||||||
@@ -1,213 +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.content.Context;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.activeandroid.Cache;
|
|
||||||
|
|
||||||
import org.isoron.helpers.DateHelper;
|
|
||||||
import org.isoron.uhabits.models.Habit;
|
|
||||||
import org.isoron.uhabits.models.Score;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
public class CSVExporter
|
|
||||||
{
|
|
||||||
private List<Habit> habits;
|
|
||||||
private Context context;
|
|
||||||
private java.text.DateFormat dateFormat;
|
|
||||||
|
|
||||||
private List<String> generateDirs;
|
|
||||||
private List<String> generateFilenames;
|
|
||||||
|
|
||||||
private String basePath;
|
|
||||||
|
|
||||||
public CSVExporter(Context context, List<Habit> habits)
|
|
||||||
{
|
|
||||||
this.habits = habits;
|
|
||||||
this.context = context;
|
|
||||||
generateDirs = new LinkedList<>();
|
|
||||||
generateFilenames = new LinkedList<>();
|
|
||||||
|
|
||||||
basePath = String.format("%s/export/", context.getFilesDir());
|
|
||||||
|
|
||||||
dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
|
|
||||||
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String formatDate(long timestamp)
|
|
||||||
{
|
|
||||||
return dateFormat.format(new Date(timestamp));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String formatScore(int score)
|
|
||||||
{
|
|
||||||
return String.format("%.2f", ((float) score) / Score.MAX_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeScores(String dirPath, Habit habit) throws IOException
|
|
||||||
{
|
|
||||||
String path = dirPath + "scores.csv";
|
|
||||||
FileWriter out = new FileWriter(basePath + path);
|
|
||||||
generateFilenames.add(path);
|
|
||||||
|
|
||||||
String query = "select timestamp, score from score where habit = ? order by timestamp";
|
|
||||||
String params[] = { habit.getId().toString() };
|
|
||||||
|
|
||||||
SQLiteDatabase db = Cache.openDatabase();
|
|
||||||
Cursor cursor = db.rawQuery(query, params);
|
|
||||||
|
|
||||||
if(!cursor.moveToFirst()) return;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
String timestamp = formatDate(cursor.getLong(0));
|
|
||||||
String score = formatScore(cursor.getInt(1));
|
|
||||||
out.write(String.format("%s,%s\n", timestamp, score));
|
|
||||||
|
|
||||||
} while(cursor.moveToNext());
|
|
||||||
|
|
||||||
out.close();
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeCheckmarks(String dirPath, Habit habit) throws IOException
|
|
||||||
{
|
|
||||||
String path = dirPath + "checkmarks.csv";
|
|
||||||
FileWriter out = new FileWriter(basePath + path);
|
|
||||||
generateFilenames.add(path);
|
|
||||||
|
|
||||||
String query = "select timestamp, value from checkmarks where habit = ? order by timestamp";
|
|
||||||
String params[] = { habit.getId().toString() };
|
|
||||||
|
|
||||||
SQLiteDatabase db = Cache.openDatabase();
|
|
||||||
Cursor cursor = db.rawQuery(query, params);
|
|
||||||
|
|
||||||
if(!cursor.moveToFirst()) return;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
String timestamp = formatDate(cursor.getLong(0));
|
|
||||||
Integer value = cursor.getInt(1);
|
|
||||||
out.write(String.format("%s,%d\n", timestamp, value));
|
|
||||||
|
|
||||||
} while(cursor.moveToNext());
|
|
||||||
|
|
||||||
out.close();
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeFiles(Habit habit) throws IOException
|
|
||||||
{
|
|
||||||
String path = String.format("%s/", habit.name);
|
|
||||||
new File(basePath + path).mkdirs();
|
|
||||||
generateDirs.add(path);
|
|
||||||
|
|
||||||
writeScores(path, habit);
|
|
||||||
writeCheckmarks(path, habit);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeZipFile(String zipFilename) throws IOException
|
|
||||||
{
|
|
||||||
FileOutputStream fos = new FileOutputStream(zipFilename);
|
|
||||||
ZipOutputStream zos = new ZipOutputStream(fos);
|
|
||||||
|
|
||||||
for(String filename : generateFilenames)
|
|
||||||
addFileToZip(zos, filename);
|
|
||||||
|
|
||||||
zos.close();
|
|
||||||
fos.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addFileToZip(ZipOutputStream zos, String filename) throws IOException
|
|
||||||
{
|
|
||||||
FileInputStream fis = new FileInputStream(new File(basePath + 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(basePath + filename).delete();
|
|
||||||
|
|
||||||
for(String filename : generateDirs)
|
|
||||||
new File(basePath + filename).delete();
|
|
||||||
|
|
||||||
new File(basePath).delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String writeArchive()
|
|
||||||
{
|
|
||||||
String date = formatDate(DateHelper.getStartOfToday());
|
|
||||||
|
|
||||||
File dir = context.getExternalCacheDir();
|
|
||||||
|
|
||||||
if(dir == null)
|
|
||||||
{
|
|
||||||
Log.e("CSVExporter", "No suitable directory found.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String zipFilename = String.format("%s/habits-%s.zip", dir, date);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for (Habit h : habits)
|
|
||||||
writeFiles(h);
|
|
||||||
|
|
||||||
writeZipFile(zipFilename);
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return zipFilename;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
159
app/src/main/java/org/isoron/uhabits/io/HabitsExporter.java
Normal file
159
app/src/main/java/org/isoron/uhabits/io/HabitsExporter.java
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.isoron.helpers.DateHelper;
|
||||||
|
import org.isoron.uhabits.models.CheckmarkList;
|
||||||
|
import org.isoron.uhabits.models.Habit;
|
||||||
|
import org.isoron.uhabits.models.ScoreList;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
public class HabitsExporter
|
||||||
|
{
|
||||||
|
private List<Habit> habits;
|
||||||
|
|
||||||
|
private List<String> generateDirs;
|
||||||
|
private List<String> generateFilenames;
|
||||||
|
|
||||||
|
private String exportDirName;
|
||||||
|
|
||||||
|
public HabitsExporter(List<Habit> habits, String exportDirName)
|
||||||
|
{
|
||||||
|
this.habits = habits;
|
||||||
|
this.exportDirName = exportDirName;
|
||||||
|
|
||||||
|
if(!this.exportDirName.endsWith("/"))
|
||||||
|
this.exportDirName += "/";
|
||||||
|
|
||||||
|
generateDirs = new LinkedList<>();
|
||||||
|
generateFilenames = new LinkedList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeHabits() throws IOException
|
||||||
|
{
|
||||||
|
String filename = "habits.csv";
|
||||||
|
new File(exportDirName).mkdirs();
|
||||||
|
FileWriter out = new FileWriter(exportDirName + filename);
|
||||||
|
generateFilenames.add(filename);
|
||||||
|
Habit.writeCSV(habits, out);
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
for(Habit h : habits)
|
||||||
|
{
|
||||||
|
String habitDirName = String.format("%s/", h.name);
|
||||||
|
new File(exportDirName + habitDirName).mkdirs();
|
||||||
|
generateDirs.add(habitDirName);
|
||||||
|
|
||||||
|
writeScores(habitDirName, h.scores);
|
||||||
|
writeCheckmarks(habitDirName, h.checkmarks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String writeZipFile() throws IOException
|
||||||
|
{
|
||||||
|
SimpleDateFormat dateFormat = DateHelper.getCSVDateFormat();
|
||||||
|
String date = dateFormat.format(DateHelper.getStartOfToday());
|
||||||
|
String zipFilename = String.format("%s/habits-%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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String writeArchive()
|
||||||
|
{
|
||||||
|
String zipFilename;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
writeHabits();
|
||||||
|
zipFilename = writeZipFile();
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return zipFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,6 +31,10 @@ import com.activeandroid.query.Select;
|
|||||||
|
|
||||||
import org.isoron.helpers.DateHelper;
|
import org.isoron.helpers.DateHelper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CheckmarkList
|
public class CheckmarkList
|
||||||
@@ -229,4 +233,27 @@ public class CheckmarkList
|
|||||||
if(today != null) return today.value;
|
if(today != null) return today.value;
|
||||||
else return Checkmark.UNCHECKED;
|
else return Checkmark.UNCHECKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void writeCSV(Writer out) throws IOException
|
||||||
|
{
|
||||||
|
SimpleDateFormat dateFormat = DateHelper.getCSVDateFormat();
|
||||||
|
|
||||||
|
String query = "select timestamp, value from checkmarks where habit = ? order by timestamp";
|
||||||
|
String params[] = { habit.getId().toString() };
|
||||||
|
|
||||||
|
SQLiteDatabase db = Cache.openDatabase();
|
||||||
|
Cursor cursor = db.rawQuery(query, params);
|
||||||
|
|
||||||
|
if(!cursor.moveToFirst()) return;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
String timestamp = dateFormat.format(new Date(cursor.getLong(0)));
|
||||||
|
Integer value = cursor.getInt(1);
|
||||||
|
out.write(String.format("%s,%d\n", timestamp, value));
|
||||||
|
|
||||||
|
} while(cursor.moveToNext());
|
||||||
|
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
package org.isoron.uhabits.models;
|
package org.isoron.uhabits.models;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
@@ -33,10 +34,17 @@ import com.activeandroid.query.From;
|
|||||||
import com.activeandroid.query.Select;
|
import com.activeandroid.query.Select;
|
||||||
import com.activeandroid.query.Update;
|
import com.activeandroid.query.Update;
|
||||||
import com.activeandroid.util.SQLiteUtils;
|
import com.activeandroid.util.SQLiteUtils;
|
||||||
|
import com.opencsv.CSVReader;
|
||||||
|
import com.opencsv.CSVWriter;
|
||||||
|
|
||||||
import org.isoron.helpers.ColorHelper;
|
import org.isoron.helpers.ColorHelper;
|
||||||
import org.isoron.helpers.DateHelper;
|
import org.isoron.helpers.DateHelper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@@ -470,4 +478,38 @@ public class Habit extends Model
|
|||||||
reminderMin = null;
|
reminderMin = null;
|
||||||
reminderDays = DateHelper.ALL_WEEK_DAYS;
|
reminderDays = DateHelper.ALL_WEEK_DAYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void writeCSV(List<Habit> habits, Writer out) throws IOException
|
||||||
|
{
|
||||||
|
CSVWriter csv = new CSVWriter(out);
|
||||||
|
|
||||||
|
for(Habit habit : habits)
|
||||||
|
{
|
||||||
|
String[] cols = { habit.name, habit.description, Integer.toString(habit.freqNum),
|
||||||
|
Integer.toString(habit.freqDen), ColorHelper.toHTML(habit.color) };
|
||||||
|
csv.writeAll(Collections.singletonList(cols));
|
||||||
|
}
|
||||||
|
|
||||||
|
csv.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Habit> parseCSV(Reader in)
|
||||||
|
{
|
||||||
|
CSVReader csv = new CSVReader(in);
|
||||||
|
List<Habit> habits = new LinkedList<>();
|
||||||
|
|
||||||
|
for(String cols[] : csv)
|
||||||
|
{
|
||||||
|
Habit habit = new Habit();
|
||||||
|
|
||||||
|
habit.name = cols[0];
|
||||||
|
habit.description = cols[1];
|
||||||
|
habit.freqNum = Integer.parseInt(cols[2]);
|
||||||
|
habit.freqDen = Integer.parseInt(cols[3]);
|
||||||
|
habit.color = Color.parseColor(cols[4]);
|
||||||
|
habits.add(habit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return habits;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import android.database.sqlite.SQLiteDatabase;
|
|||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import com.activeandroid.ActiveAndroid;
|
|
||||||
import com.activeandroid.Cache;
|
import com.activeandroid.Cache;
|
||||||
import com.activeandroid.query.Delete;
|
import com.activeandroid.query.Delete;
|
||||||
import com.activeandroid.query.From;
|
import com.activeandroid.query.From;
|
||||||
@@ -33,6 +32,11 @@ import com.activeandroid.query.Select;
|
|||||||
import org.isoron.helpers.ActiveAndroidHelper;
|
import org.isoron.helpers.ActiveAndroidHelper;
|
||||||
import org.isoron.helpers.DateHelper;
|
import org.isoron.helpers.DateHelper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
public class ScoreList
|
public class ScoreList
|
||||||
{
|
{
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -278,4 +282,27 @@ public class ScoreList
|
|||||||
if(score != null) return score.getStarStatus();
|
if(score != null) return score.getStarStatus();
|
||||||
else return Score.EMPTY_STAR;
|
else return Score.EMPTY_STAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void writeCSV(Writer out) throws IOException
|
||||||
|
{
|
||||||
|
SimpleDateFormat dateFormat = DateHelper.getCSVDateFormat();
|
||||||
|
|
||||||
|
String query = "select timestamp, score from score where habit = ? order by timestamp";
|
||||||
|
String params[] = { habit.getId().toString() };
|
||||||
|
|
||||||
|
SQLiteDatabase db = Cache.openDatabase();
|
||||||
|
Cursor cursor = db.rawQuery(query, params);
|
||||||
|
|
||||||
|
if(!cursor.moveToFirst()) return;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
String timestamp = dateFormat.format(new Date(cursor.getLong(0)));
|
||||||
|
String score = String.format("%.2f", ((float) cursor.getInt(1)) / Score.MAX_VALUE);
|
||||||
|
out.write(String.format("%s,%s\n", timestamp, score));
|
||||||
|
|
||||||
|
} while(cursor.moveToNext());
|
||||||
|
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,4 +138,5 @@
|
|||||||
<string name="five_times_per_week">5 times per week</string>
|
<string name="five_times_per_week">5 times per week</string>
|
||||||
<string name="custom_frequency">Custom …</string>
|
<string name="custom_frequency">Custom …</string>
|
||||||
<string name="help">Help & FAQ</string>
|
<string name="help">Help & FAQ</string>
|
||||||
|
<string name="could_not_export">Failed to export data.</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user