Skip to content

Commit 7f2414f

Browse files
Merge pull request #33 from JetBrains-Research/store-survey
Store activity tracker key and survey info
2 parents f16d1d1 + c348788 commit 7f2414f

File tree

11 files changed

+252
-86
lines changed

11 files changed

+252
-86
lines changed

build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ dependencies {
4343
implementation("org.controlsfx:controlsfx:11.0.2")
4444
compile("com.google.auto.service:auto-service:1.0-rc7")
4545
implementation("org.eclipse.mylyn.github", "org.eclipse.egit.github.core", "2.1.5")
46+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:0.9.1")
4647

4748
testCompile("junit", "junit", "4.12")
4849
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.jetbrains.research.ml.codetracker
22

3+
import com.intellij.openapi.application.PathManager
34
import com.intellij.openapi.diagnostic.Logger
45
import org.jetbrains.research.ml.codetracker.server.TrackerQueryExecutor
56
import org.jetbrains.research.ml.codetracker.tracking.DocumentLogger
@@ -8,28 +9,12 @@ import org.jetbrains.research.ml.codetracker.tracking.TaskFileHandler
89

910
object Plugin {
1011
const val PLUGIN_ID = "codetracker"
12+
val codeTrackerFolderPath = "${PathManager.getPluginsPath()}/${PLUGIN_ID}"
1113

1214
private val logger: Logger = Logger.getInstance(javaClass)
1315

1416
init {
1517
logger.info("$PLUGIN_ID: init plugin")
1618
}
1719

18-
// fun stopTracking(): Boolean {
19-
// logger.info("$PLUGIN_ID: close IDE")
20-
// logger.info("$PLUGIN_ID: prepare fo sending ${DocumentLogger.getFiles().size} files")
21-
// if (DocumentLogger.getFiles().isNotEmpty()) {
22-
// DocumentLogger.logCurrentDocuments()
23-
// DocumentLogger.flush()
24-
// DocumentLogger.documentsToPrinters.forEach { (d, p) ->
25-
// TrackerQueryExecutor.sendCodeTrackerData(
26-
// p.file,
27-
// { TrackerQueryExecutor.isLastSuccessful }
28-
// ) { DocumentLogger.close(d, p) }
29-
// }
30-
// }
31-
//// TaskFileHandler.stopTracking()
32-
// return TrackerQueryExecutor.isLastSuccessful
33-
// }
34-
3520
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.jetbrains.research.ml.codetracker.models
2+
3+
import kotlinx.serialization.Serializable
4+
5+
@Serializable
6+
data class StoredInfo(
7+
var loggedUIData: Map<String, String> = mapOf(),
8+
var activityTrackerKey: String? = null
9+
)

src/main/kotlin/org/jetbrains/research/ml/codetracker/models/Task.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ data class TaskInfo(
1515

1616
@Serializable
1717
data class Task(
18-
val key: String,
18+
override val key: String,
1919
val id: Int = -1,
2020
val infoTranslation: Map<PaneLanguage, TaskInfo>,
2121
val examples: List<Example> = emptyList()
22-
)
22+
) : Keyed

src/main/kotlin/org/jetbrains/research/ml/codetracker/models/UiModels.kt

+9-5
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,21 @@ package org.jetbrains.research.ml.codetracker.models
22

33
import kotlinx.serialization.Serializable
44

5+
interface Keyed {
6+
val key: String
7+
}
8+
59
@Serializable
6-
data class PaneLanguage(val key: String)
10+
data class PaneLanguage(override val key: String) : Keyed
711

812
@Serializable
913
data class Gender(
10-
val key: String,
14+
override val key: String,
1115
val translation: Map<PaneLanguage, String>
12-
)
16+
) : Keyed
1317

1418
@Serializable
1519
data class Country(
16-
val key: String,
20+
override val key: String,
1721
val translation: Map<PaneLanguage, String>
18-
)
22+
) : Keyed

src/main/kotlin/org/jetbrains/research/ml/codetracker/server/TrackerQueryExecutor.kt

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import okhttp3.Request
1010
import okhttp3.RequestBody.Companion.asRequestBody
1111
import okhttp3.RequestBody.Companion.toRequestBody
1212
import okhttp3.Response
13+
import org.jetbrains.research.ml.codetracker.tracking.StoredInfoWrapper
1314
import java.io.File
1415
import java.lang.IllegalStateException
1516
import java.net.URL
@@ -24,7 +25,12 @@ object TrackerQueryExecutor : QueryExecutor() {
2425
var activityTrackerKey: String? = null
2526

2627
init {
27-
initActivityTrackerInfo()
28+
StoredInfoWrapper.info.activityTrackerKey?.let {
29+
activityTrackerKey = it
30+
} ?: run {
31+
initActivityTrackerInfo()
32+
StoredInfoWrapper.updateStoredInfo(activityTrackerKey = activityTrackerKey)
33+
}
2834
}
2935

3036
private fun initActivityTrackerInfo() {

src/main/kotlin/org/jetbrains/research/ml/codetracker/tracking/DocumentLogger.kt

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.jetbrains.research.ml.codetracker.tracking
22

33
import com.intellij.openapi.application.ApplicationManager
4-
import com.intellij.openapi.application.PathManager
54
import com.intellij.openapi.diagnostic.Logger
65
import com.intellij.openapi.editor.Document
76
import com.intellij.openapi.fileEditor.FileDocumentManager
@@ -13,6 +12,7 @@ import com.intellij.util.messages.Topic
1312
import org.apache.commons.csv.CSVFormat
1413
import org.apache.commons.csv.CSVPrinter
1514
import org.jetbrains.research.ml.codetracker.Plugin
15+
import org.jetbrains.research.ml.codetracker.Plugin.codeTrackerFolderPath
1616
import org.jetbrains.research.ml.codetracker.models.Task
1717
import com.intellij.openapi.progress.Task as IntellijTask
1818
import org.jetbrains.research.ml.codetracker.server.TrackerQueryExecutor
@@ -44,7 +44,6 @@ object DocumentLogger {
4444
private val logger: Logger = Logger.getInstance(javaClass)
4545
private val myDocumentsToPrinters: HashMap<Document, Printer> = HashMap()
4646

47-
private val folderPath = "${PathManager.getPluginsPath()}/codetracker/"
4847
private const val MAX_FILE_SIZE = 50 * 1024 * 1024
4948
private const val MAX_DIF_SIZE = 300
5049

@@ -73,10 +72,10 @@ object DocumentLogger {
7372

7473

7574
private fun createLogFile(document: Document): File {
76-
File(folderPath).mkdirs()
75+
File(codeTrackerFolderPath).mkdirs()
7776
val file = FileDocumentManager.getInstance().getFile(document)
7877
logger.info("${Plugin.PLUGIN_ID}: create log file for file ${file?.name}")
79-
val logFile = File("$folderPath${file?.nameWithoutExtension}_${file.hashCode()}_${document.hashCode()}.csv")
78+
val logFile = File("$codeTrackerFolderPath${file?.nameWithoutExtension}_${file.hashCode()}_${document.hashCode()}.csv")
8079
FileUtil.createIfDoesntExist(logFile)
8180
return logFile
8281
}

src/main/kotlin/org/jetbrains/research/ml/codetracker/tracking/LoggedData.kt

+15-6
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,20 @@ abstract class LoggedData<T, S> {
2020
}
2121
}
2222

23+
enum class UiLoggedDataHeader(val header: String) {
24+
AGE("age"),
25+
GENDER("gender"),
26+
PROGRAM_EXPERIENCE_YEARS("programExperienceYears"),
27+
PROGRAM_EXPERIENCE_MONTHS("programExperienceMonths"),
28+
COUNTRY("country"),
29+
CHOSEN_TASK("chosenTask")
30+
}
31+
2332
object UiLoggedData : LoggedData<Unit, String>() {
2433

2534
override val loggedDataGetters: List<LoggedDataGetter<Unit, String>> = arrayListOf(
26-
LoggedDataGetter("age") { SurveyUiData.age.uiValue.toString() },
27-
LoggedDataGetter("gender") {
35+
LoggedDataGetter(UiLoggedDataHeader.AGE.header) { SurveyUiData.age.uiValue.toString() },
36+
LoggedDataGetter(UiLoggedDataHeader.GENDER.header) {
2837
// Todo: make it better: delete duplicates of code
2938
val currentValue = SurveyUiData.gender.uiValue
3039
if (!isDefaultValue(currentValue)) {
@@ -33,17 +42,17 @@ object UiLoggedData : LoggedData<Unit, String>() {
3342
currentValue.toString()
3443
}
3544
},
36-
LoggedDataGetter("programExperienceYears") { SurveyUiData.peYears.uiValue.toString() },
37-
LoggedDataGetter("programExperienceMonths") { SurveyUiData.peMonths.uiValue.toString() },
38-
LoggedDataGetter("country") {
45+
LoggedDataGetter(UiLoggedDataHeader.PROGRAM_EXPERIENCE_YEARS.header) { SurveyUiData.peYears.uiValue.toString() },
46+
LoggedDataGetter(UiLoggedDataHeader.PROGRAM_EXPERIENCE_MONTHS.header) { SurveyUiData.peMonths.uiValue.toString() },
47+
LoggedDataGetter(UiLoggedDataHeader.COUNTRY.header) {
3948
val currentValue = SurveyUiData.country.uiValue
4049
if (!isDefaultValue(currentValue)) {
4150
SurveyUiData.country.dataList[currentValue].key
4251
} else {
4352
currentValue.toString()
4453
}
4554
},
46-
LoggedDataGetter("chosenTask") {
55+
LoggedDataGetter(UiLoggedDataHeader.CHOSEN_TASK.header) {
4756
val currentValue = TaskChoosingUiData.chosenTask.uiValue
4857
if (!isDefaultValue(currentValue)) {
4958
TaskChoosingUiData.chosenTask.dataList[currentValue].key
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package org.jetbrains.research.ml.codetracker.tracking
2+
3+
import com.intellij.openapi.diagnostic.Logger
4+
import kotlinx.serialization.json.Json
5+
import kotlinx.serialization.json.JsonConfiguration
6+
import org.jetbrains.research.ml.codetracker.Plugin.codeTrackerFolderPath
7+
import org.jetbrains.research.ml.codetracker.models.Keyed
8+
import org.jetbrains.research.ml.codetracker.models.StoredInfo
9+
import java.io.File
10+
import java.io.PrintWriter
11+
12+
13+
object StoredInfoHandler{
14+
15+
val logger: Logger = Logger.getInstance(javaClass)
16+
17+
fun getIntStoredField(field: UiLoggedDataHeader, defaultValue: Int): Int {
18+
return run{
19+
val storedField = StoredInfoWrapper.info.loggedUIData[field.header]?.toIntOrNull()
20+
logger.info("Stored field $storedField for the ${field.header} value has been received successfully")
21+
storedField
22+
} ?: run {
23+
logger.info("Default value $defaultValue for the ${field.header} value has been received successfully")
24+
defaultValue
25+
}
26+
}
27+
28+
fun <T : Keyed> getIndexByStoredKey(field: UiLoggedDataHeader, list: List<T>, defaultValue: Int): Int {
29+
StoredInfoWrapper.info.loggedUIData[field.header]?.let { storedKey ->
30+
val storedKeyIndex = list.indexOfFirst { it.key == storedKey }
31+
logger.info("Stored index $storedKeyIndex for the ${field.header} value has been received successfully")
32+
return storedKeyIndex
33+
}
34+
logger.info("Default value $defaultValue for the ${field.header} value has been received successfully")
35+
return defaultValue
36+
}
37+
}
38+
39+
/*
40+
This class provides storing survey info and activity tracker key
41+
*/
42+
object StoredInfoWrapper {
43+
44+
private const val storedInfoFileName = "storedInfo.txt"
45+
private val storedInfoFilePath = "${codeTrackerFolderPath}/$storedInfoFileName"
46+
private val json by lazy {
47+
Json(JsonConfiguration.Stable)
48+
}
49+
private val serializer = StoredInfo.serializer()
50+
51+
var info: StoredInfo = readStoredInfo()
52+
53+
private fun readStoredInfo(): StoredInfo {
54+
val file = File(storedInfoFilePath)
55+
if (!file.exists()) {
56+
return StoredInfo()
57+
}
58+
return json.parse(serializer, file.readText())
59+
}
60+
61+
fun updateStoredInfo(surveyInfo: Map<String, String>? = null,
62+
activityTrackerKey: String? = null) {
63+
surveyInfo?.let{ info.loggedUIData = it }
64+
activityTrackerKey?.let{ info.activityTrackerKey = it }
65+
writeStoredInfo()
66+
}
67+
68+
private fun writeStoredInfo() {
69+
val file = File(storedInfoFilePath)
70+
val writer = PrintWriter(file)
71+
writer.print(json.stringify(serializer, info))
72+
writer.close()
73+
}
74+
}

0 commit comments

Comments
 (0)