mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-05 16:58:52 -06:00
CSV export: Use formatted values, add notes & header
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Date,Value,Notes
|
||||
|
||||
|
@@ -1 +1,2 @@
|
||||
Date,Score
|
||||
2015-01-25,0.0000
|
||||
|
||||
|
@@ -1,10 +1,11 @@
|
||||
2015-01-25,2
|
||||
2015-01-24,0
|
||||
2015-01-23,1
|
||||
2015-01-22,2
|
||||
2015-01-21,2
|
||||
2015-01-20,2
|
||||
2015-01-19,1
|
||||
2015-01-18,1
|
||||
2015-01-17,2
|
||||
2015-01-16,2
|
||||
Date,Value,Notes
|
||||
2015-01-25,YES_MANUAL,
|
||||
2015-01-24,NO,Sick
|
||||
2015-01-23,YES_AUTO,"Forgot to do it, really"
|
||||
2015-01-22,YES_MANUAL,
|
||||
2015-01-21,YES_MANUAL,
|
||||
2015-01-20,YES_MANUAL,
|
||||
2015-01-19,YES_AUTO,"""Vacation"""
|
||||
2015-01-18,YES_AUTO,
|
||||
2015-01-17,YES_MANUAL,
|
||||
2015-01-16,YES_MANUAL,
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
Date,Score
|
||||
2015-01-25,0.2557
|
||||
2015-01-24,0.2226
|
||||
2015-01-23,0.1991
|
||||
|
||||
|
@@ -1,11 +1,11 @@
|
||||
Date,Meditate,Wake up early,
|
||||
2015-01-25,-1,2,
|
||||
2015-01-24,-1,0,
|
||||
2015-01-23,-1,1,
|
||||
2015-01-22,-1,2,
|
||||
2015-01-21,-1,2,
|
||||
2015-01-20,-1,2,
|
||||
2015-01-19,-1,1,
|
||||
2015-01-18,-1,1,
|
||||
2015-01-17,-1,2,
|
||||
2015-01-16,-1,2,
|
||||
2015-01-25,UNKNOWN,YES_MANUAL,
|
||||
2015-01-24,UNKNOWN,NO,
|
||||
2015-01-23,UNKNOWN,YES_AUTO,
|
||||
2015-01-22,UNKNOWN,YES_MANUAL,
|
||||
2015-01-21,UNKNOWN,YES_MANUAL,
|
||||
2015-01-20,UNKNOWN,YES_MANUAL,
|
||||
2015-01-19,UNKNOWN,YES_AUTO,
|
||||
2015-01-18,UNKNOWN,YES_AUTO,
|
||||
2015-01-17,UNKNOWN,YES_MANUAL,
|
||||
2015-01-16,UNKNOWN,YES_MANUAL,
|
||||
|
||||
|
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.io
|
||||
|
||||
import com.opencsv.CSVWriter
|
||||
import org.isoron.uhabits.core.models.Entry
|
||||
import org.isoron.uhabits.core.models.EntryList
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
@@ -32,7 +33,6 @@ import java.io.FileOutputStream
|
||||
import java.io.FileWriter
|
||||
import java.io.IOException
|
||||
import java.io.Writer
|
||||
import java.util.ArrayList
|
||||
import java.util.LinkedList
|
||||
import java.util.Locale
|
||||
import java.util.zip.ZipEntry
|
||||
@@ -109,11 +109,14 @@ class HabitsCSVExporter(
|
||||
var oldest = today
|
||||
val known = habit.computedEntries.getKnown()
|
||||
if (known.isNotEmpty()) oldest = known[known.size - 1].timestamp
|
||||
val csv = CSVWriter(out)
|
||||
csv.writeNext(arrayOf("Date", "Score"), false)
|
||||
for ((timestamp1, value) in habit.scores.getByInterval(oldest, today)) {
|
||||
val timestamp = dateFormat.format(timestamp1.unixTime)
|
||||
val score = String.format(Locale.US, "%.4f", value)
|
||||
out.write(String.format("%s,%s\n", timestamp, score))
|
||||
csv.writeNext(arrayOf(timestamp, score), false)
|
||||
}
|
||||
csv.close()
|
||||
out.close()
|
||||
}
|
||||
|
||||
@@ -122,10 +125,20 @@ class HabitsCSVExporter(
|
||||
val out = FileWriter(exportDirName + filename)
|
||||
generatedFilenames.add(filename)
|
||||
val dateFormat = DateFormats.getCSVDateFormat()
|
||||
for ((timestamp, value) in entries.getKnown()) {
|
||||
val date = dateFormat.format(timestamp.toJavaDate())
|
||||
out.write(String.format(Locale.US, "%s,%d\n", date, value))
|
||||
val csv = CSVWriter(out)
|
||||
csv.writeNext(arrayOf("Date", "Value", "Notes"), false)
|
||||
for (entry in entries.getKnown()) {
|
||||
val date = dateFormat.format(entry.timestamp.toJavaDate())
|
||||
csv.writeNext(
|
||||
arrayOf(
|
||||
date,
|
||||
entry.formattedValue,
|
||||
entry.notes
|
||||
),
|
||||
false
|
||||
)
|
||||
}
|
||||
csv.close()
|
||||
out.close()
|
||||
}
|
||||
|
||||
@@ -167,7 +180,7 @@ class HabitsCSVExporter(
|
||||
checksWriter.write(sb.toString())
|
||||
scoresWriter.write(sb.toString())
|
||||
for (j in selectedHabits.indices) {
|
||||
checksWriter.write(checkmarks[j][i].value.toString())
|
||||
checksWriter.write(checkmarks[j][i].formattedValue)
|
||||
checksWriter.write(delimiter)
|
||||
val score = String.format(Locale.US, "%.4f", scores[j][i].value)
|
||||
scoresWriter.write(score)
|
||||
|
||||
@@ -23,6 +23,16 @@ data class Entry(
|
||||
val value: Int,
|
||||
val notes: String = ""
|
||||
) {
|
||||
val formattedValue: String
|
||||
get() = when (value) {
|
||||
YES_MANUAL -> "YES_MANUAL"
|
||||
YES_AUTO -> "YES_AUTO"
|
||||
NO -> "NO"
|
||||
SKIP -> "SKIP"
|
||||
UNKNOWN -> "UNKNOWN"
|
||||
else -> value.toString()
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Value indicating that the habit is not applicable for this timestamp.
|
||||
|
||||
@@ -35,6 +35,10 @@ class HabitFixtures(private val modelFactory: ModelFactory, private val habitLis
|
||||
true, false, false, true, true, true, false, false, true, true
|
||||
)
|
||||
|
||||
private var NON_DAILY_HABIT_NOTES = arrayOf(
|
||||
"", "Sick", "Forgot to do it, really", "", "", "", "\"Vacation\"", "", "", ""
|
||||
)
|
||||
|
||||
fun createEmptyHabit(
|
||||
name: String = "Meditate",
|
||||
color: PaletteColor = PaletteColor(3),
|
||||
@@ -141,10 +145,10 @@ class HabitFixtures(private val modelFactory: ModelFactory, private val habitLis
|
||||
habit.frequency = Frequency(2, 3)
|
||||
saveIfSQLite(habit)
|
||||
var timestamp = getToday()
|
||||
for (c in NON_DAILY_HABIT_CHECKS) {
|
||||
for (i in NON_DAILY_HABIT_CHECKS.indices) {
|
||||
var value = Entry.NO
|
||||
if (c) value = Entry.YES_MANUAL
|
||||
habit.originalEntries.add(Entry(timestamp, value))
|
||||
if (NON_DAILY_HABIT_CHECKS[i]) value = Entry.YES_MANUAL
|
||||
habit.originalEntries.add(Entry(timestamp, value, NON_DAILY_HABIT_NOTES[i]))
|
||||
timestamp = timestamp.minus(1)
|
||||
}
|
||||
habit.recompute()
|
||||
|
||||
@@ -108,12 +108,12 @@ class HabitsCSVExporterTest : BaseUnitTest() {
|
||||
|
||||
private fun assertFileAndReferenceAreEqual(s: String) {
|
||||
val assetFilename = String.format("csv_export/%s", s)
|
||||
val expectedFile = File(String.format("%s/%s", baseDir.absolutePath, s))
|
||||
val actualFile = File.createTempFile("asset", "")
|
||||
actualFile.deleteOnExit()
|
||||
copyAssetToFile(assetFilename, actualFile)
|
||||
val expectedContents = expectedFile.readText()
|
||||
val actualFile = File(String.format("%s/%s", baseDir.absolutePath, s))
|
||||
val expectedFile = File.createTempFile("asset", "")
|
||||
expectedFile.deleteOnExit()
|
||||
copyAssetToFile(assetFilename, expectedFile)
|
||||
val actualContents = actualFile.readText()
|
||||
val expectedContents = expectedFile.readText()
|
||||
assertEquals(expectedContents, actualContents, "content mismatch for $s")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user