@@ -9,13 +9,17 @@ import org.jetbrains.kotlinx.dataframe.io.writeCSV
9
9
import java.io.File
10
10
import java.time.OffsetDateTime
11
11
import java.time.format.DateTimeFormatter
12
+ import java.time.format.DateTimeParseException
12
13
import kotlin.io.path.createDirectories
13
14
import kotlin.io.path.exists
14
15
16
+ @Suppress(" TooManyFunctions" )
15
17
class ProgsnapParser (private val taskTrackerData : TaskTrackerData ) {
16
18
17
19
companion object {
18
- private val DATE_FORMAT : DateTimeFormatter = DateTimeFormatter .ofPattern(" yyyy-MM-dd HH:mm:ss.SSSSSS XXX" )
20
+ private val DATE_FORMAT_WITH_MICROS = DateTimeFormatter .ofPattern(" yyyy-MM-dd HH:mm:ss.SSSSSSXXX" )
21
+ private val DATE_WITHOUT_MICROS = DateTimeFormatter .ofPattern(" yyyy-MM-dd HH:mm:ssXXX" )
22
+ private val DATE_FORMATS = listOf (DATE_FORMAT_WITH_MICROS , DATE_WITHOUT_MICROS )
19
23
private val DIRECTORIES_DELIMITERS = arrayOf(" /" , " \\ " )
20
24
private const val CODE_STATES_DIRECTORY_NAME = " CodeStates"
21
25
private const val MAIN_TABLE_FILENAME = " MainTable.csv"
@@ -29,6 +33,17 @@ class ProgsnapParser(private val taskTrackerData: TaskTrackerData) {
29
33
createMainTableFile(destinationDirectory, researchGroups)
30
34
}
31
35
36
+ private fun parseDate (dateString : String ): OffsetDateTime {
37
+ for (formatter in DATE_FORMATS ) {
38
+ try {
39
+ return OffsetDateTime .parse(dateString, formatter)
40
+ } catch (_: DateTimeParseException ) {
41
+ // Ignore and try the next format
42
+ }
43
+ }
44
+ error(" Invalid date format: $dateString " )
45
+ }
46
+
32
47
private fun createMetaFile (destinationDirectory : File ) {
33
48
val metaDataFile = destinationDirectory.resolve(META_DATA_FILENAME )
34
49
taskTrackerData.metaData.toDataFrame().writeCSV(metaDataFile)
@@ -63,13 +78,9 @@ class ProgsnapParser(private val taskTrackerData: TaskTrackerData) {
63
78
private var researches =
64
79
taskTrackerData.researches.toDataFrame()
65
80
.convert(" id" ).to<Int >()
66
- private var surveyData =
67
- taskTrackerData.surveyData.toDataFrame()
68
81
private var toolWindowData =
69
82
taskTrackerData.toolWindowData.toDataFrame()
70
83
.add(" data_type" ) { " toolWindowData" }
71
- private var users =
72
- taskTrackerData.users.toDataFrame()
73
84
74
85
private fun File.toDataFrame () = DataFrame .readCSV(this )
75
86
@@ -78,7 +89,7 @@ class ProgsnapParser(private val taskTrackerData: TaskTrackerData) {
78
89
private fun DataFrame <* >.convertDate () = this
79
90
.dropNA(" date" )
80
91
.update(" date" )
81
- .with { OffsetDateTime .parse (it.toString(), DATE_FORMAT ).toString() }
92
+ .with { parseDate (it.toString()).toString() }
82
93
.convert(" research_id" ).to<Int >()
83
94
.fullJoin(researches) { " research_id" match " id" }
84
95
.dropNA(" date" )
@@ -159,6 +170,9 @@ class ProgsnapParser(private val taskTrackerData: TaskTrackerData) {
159
170
" KeyPressed" -> " X-KeyPressed"
160
171
" KeyReleased" -> " X-KeyReleased"
161
172
" Action" -> " X-Action"
173
+ " MouseClicked" -> " X-MouseClicked"
174
+ " MouseMoved" -> " X-MouseMoved"
175
+ " MouseWheel" -> " X-MouseWheel"
162
176
else -> error(" Undefined activity data type has been detected in the data `$type `" )
163
177
}
164
178
}
0 commit comments