diff --git a/uhabits-core/assets/test/csv_export/001 Meditate/Checkmarks.csv b/uhabits-core/assets/test/csv_export/001 Meditate/Checkmarks.csv index e69de29bb..6033c92f7 100644 --- a/uhabits-core/assets/test/csv_export/001 Meditate/Checkmarks.csv +++ b/uhabits-core/assets/test/csv_export/001 Meditate/Checkmarks.csv @@ -0,0 +1 @@ +Date,Value,Notes diff --git a/uhabits-core/assets/test/csv_export/001 Meditate/Scores.csv b/uhabits-core/assets/test/csv_export/001 Meditate/Scores.csv index 6004f60bc..8d3f97177 100644 --- a/uhabits-core/assets/test/csv_export/001 Meditate/Scores.csv +++ b/uhabits-core/assets/test/csv_export/001 Meditate/Scores.csv @@ -1 +1,2 @@ +Date,Score 2015-01-25,0.0000 diff --git a/uhabits-core/assets/test/csv_export/002 Wake up early/Checkmarks.csv b/uhabits-core/assets/test/csv_export/002 Wake up early/Checkmarks.csv index 89f788f68..7b3da3855 100644 --- a/uhabits-core/assets/test/csv_export/002 Wake up early/Checkmarks.csv +++ b/uhabits-core/assets/test/csv_export/002 Wake up early/Checkmarks.csv @@ -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, diff --git a/uhabits-core/assets/test/csv_export/002 Wake up early/Scores.csv b/uhabits-core/assets/test/csv_export/002 Wake up early/Scores.csv index 7f4fa4780..fb91385ff 100644 --- a/uhabits-core/assets/test/csv_export/002 Wake up early/Scores.csv +++ b/uhabits-core/assets/test/csv_export/002 Wake up early/Scores.csv @@ -1,3 +1,4 @@ +Date,Score 2015-01-25,0.2557 2015-01-24,0.2226 2015-01-23,0.1991 diff --git a/uhabits-core/assets/test/csv_export/Checkmarks.csv b/uhabits-core/assets/test/csv_export/Checkmarks.csv index c0788570b..f03bece31 100644 --- a/uhabits-core/assets/test/csv_export/Checkmarks.csv +++ b/uhabits-core/assets/test/csv_export/Checkmarks.csv @@ -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, diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/io/HabitsCSVExporter.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/io/HabitsCSVExporter.kt index 43dad6954..34bd58467 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/io/HabitsCSVExporter.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/io/HabitsCSVExporter.kt @@ -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) diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/Entry.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/Entry.kt index 99eb81950..078c11b9c 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/Entry.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/Entry.kt @@ -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. diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/test/HabitFixtures.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/test/HabitFixtures.kt index fffe4ac85..9abe5546d 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/test/HabitFixtures.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/test/HabitFixtures.kt @@ -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() diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/io/HabitsCSVExporterTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/io/HabitsCSVExporterTest.kt index 5362e640e..55d16b2d9 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/io/HabitsCSVExporterTest.kt +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/io/HabitsCSVExporterTest.kt @@ -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") } }