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