Skip to content

Commit

Permalink
[ML4SE-168] Connection between server and client. Uploading log files.
Browse files Browse the repository at this point in the history
  • Loading branch information
mikrise2 committed Dec 6, 2023
1 parent fd12b94 commit 27128ff
Show file tree
Hide file tree
Showing 19 changed files with 137 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package org.jetbrains.research.tasktracker.config
import com.intellij.openapi.diagnostic.Logger
import org.jetbrains.research.tasktracker.config.agreement.AgreementConfig
import org.jetbrains.research.tasktracker.config.content.FinalPageContentConfig
import org.jetbrains.research.tasktracker.config.content.MainPageContentConfig
import org.jetbrains.research.tasktracker.config.content.PluginInfoConfig
import org.jetbrains.research.tasktracker.config.content.ServerErrorPageConfig
import org.jetbrains.research.tasktracker.config.content.TaskContentConfig
import org.jetbrains.research.tasktracker.config.emotion.EmotionConfig
Expand All @@ -28,7 +28,7 @@ object DefaultConfigsFactory {
TaskContentConfig.CONFIG_FILE_PREFIX,
ScenarioConfig.CONFIG_FILE_PREFIX,
WebCamTrackingConfig.CONFIG_FILE_PREFIX,
MainPageContentConfig.CONFIG_FILE_PREFIX,
PluginInfoConfig.CONFIG_FILE_PREFIX,
FinalPageContentConfig.CONFIG_FILE_PREFIX,
ServerErrorPageConfig.CONFIG_FILE_PREFIX,
SurveyConfig.CONFIG_FILE_PREFIX,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.intellij.openapi.application.PathManager
import com.intellij.openapi.diagnostic.Logger
import org.jetbrains.research.tasktracker.config.agreement.AgreementConfig
import org.jetbrains.research.tasktracker.config.content.FinalPageContentConfig
import org.jetbrains.research.tasktracker.config.content.MainPageContentConfig
import org.jetbrains.research.tasktracker.config.content.PluginInfoConfig
import org.jetbrains.research.tasktracker.config.content.ServerErrorPageConfig
import org.jetbrains.research.tasktracker.config.content.TaskContentConfig
import org.jetbrains.research.tasktracker.config.emotion.EmotionConfig
Expand All @@ -29,7 +29,7 @@ data class MainTaskTrackerConfig(
var activityTrackingConfig: ActivityTrackingConfig? = null,
var codeTrackingConfig: CodeTrackingConfig? = null,
var webCamConfig: WebCamTrackingConfig? = null,
var mainPageConfig: MainPageContentConfig? = null,
var pluginInfoConfig: PluginInfoConfig? = null,
var finalPageConfig: FinalPageContentConfig? = null,
var serverErrorPageConfig: ServerErrorPageConfig? = null,
var emotionConfig: EmotionConfig? = null,
Expand All @@ -45,7 +45,7 @@ data class MainTaskTrackerConfig(
codeTrackingConfig,
scenarioConfig,
webCamConfig,
mainPageConfig,
pluginInfoConfig,
finalPageConfig,
serverErrorPageConfig,
emotionConfig,
Expand All @@ -60,6 +60,9 @@ data class MainTaskTrackerConfig(
val agreementFilePath = "$pluginFolderPath/agreement/agreement.json"
val logFilesFolder = "$pluginFolderPath/logs"
const val PLUGIN_PROPERTIES_FILE = "$PLUGIN_NAME.properties"
private const val DOMAIN = "http://0.0.0.0:8080"

fun getRoute(path: String) = "$DOMAIN/$path"

private fun File.isConfigFile() = this.extension == "yaml"

Expand Down Expand Up @@ -103,9 +106,9 @@ data class MainTaskTrackerConfig(
)
}

fileName.startsWith(MainPageContentConfig.CONFIG_FILE_PREFIX) -> {
mainConfig.mainPageConfig = buildBaseConfig(
mainConfig.mainPageConfig, configFile, MainPageContentConfig::buildConfig, logger
fileName.startsWith(PluginInfoConfig.CONFIG_FILE_PREFIX) -> {
mainConfig.pluginInfoConfig = buildBaseConfig(
mainConfig.pluginInfoConfig, configFile, PluginInfoConfig::buildConfig, logger
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import org.jetbrains.research.tasktracker.config.YamlConfigLoadStrategy
import java.io.File

@Serializable
class MainPageContentConfig(val pluginName: String, val pluginDescription: String) : BaseConfig {
class PluginInfoConfig(val pluginName: String, val pluginDescription: String) : BaseConfig {
override val configName: String
get() = CONFIG_FILE_PREFIX

companion object {
const val CONFIG_FILE_PREFIX: String = "main_page"
const val CONFIG_FILE_PREFIX: String = "info"

fun buildConfig(configFile: File): MainPageContentConfig =
fun buildConfig(configFile: File): PluginInfoConfig =
YamlConfigLoadStrategy.load(configFile.readText(), serializer())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,25 @@ import io.ktor.client.engine.cio.*
import io.ktor.client.request.forms.*
import io.ktor.http.*
import kotlinx.coroutines.runBlocking
import org.jetbrains.research.tasktracker.tracking.Loggable
import org.jetbrains.research.tasktracker.ui.main.panel.storage.MainPanelStorage
import org.apache.http.client.utils.URIBuilder
import org.jetbrains.research.tasktracker.config.MainTaskTrackerConfig.Companion.getRoute
import org.jetbrains.research.tasktracker.ui.main.panel.storage.GlobalPluginStorage
import java.io.File

object FileRequests {

private val client = HttpClient(CIO)
private val logger: Logger = Logger.getInstance(FileRequests::class.java)

fun Loggable.send() = this.getLogFiles().all {
sendFile(it, this.subDir)
}

@Suppress("TooGenericExceptionCaught")
private fun sendFile(file: File, subdir: String) = runBlocking {
fun sendFile(file: File, logFileType: String) = runBlocking {
try {
val researchId = GlobalPluginStorage.currentResearchId
?: error("ResearchId is undefined")
val url = URIBuilder(getRoute("upload-log-file")).addParameter("logFileType", logFileType)
.addParameter("id", researchId.toString()).build().toString()
client.submitFormWithBinaryData(
url = "$DOMAIN/upload-document/${MainPanelStorage.currentResearchId}?subdir=$subdir",
url = url,
formData = formData {
append(
"file",
Expand All @@ -37,11 +38,12 @@ object FileRequests {
}
)
true
} catch (e: IllegalStateException) {
logger.error(e.localizedMessage)
false
} catch (e: Exception) {
logger.warn("Server interaction error! File to send: ${file.path}", e)
logger.error("Server interaction error! File to send: ${file.path}", e)
false
}
}

const val DOMAIN = "http://3.249.245.244:8888"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.jetbrains.research.tasktracker.requests

import com.intellij.openapi.diagnostic.Logger
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.forms.*
import io.ktor.http.*
import kotlinx.coroutines.runBlocking
import org.jetbrains.research.tasktracker.TaskTrackerPlugin
import org.jetbrains.research.tasktracker.config.MainTaskTrackerConfig.Companion.getRoute
import org.jetbrains.research.tasktracker.ui.main.panel.storage.GlobalPluginStorage

object IdRequests {
private val client = HttpClient(CIO)
private val logger = Logger.getInstance(IdRequests::class.java)

@Suppress("TooGenericExceptionCaught")
fun getUserId(name: String, email: String): Int? =
runBlocking {
val url = getRoute("create-user")
try {
return@runBlocking client.submitForm(
url = url,
formParameters = parameters {
append("name", name)
append("email", email)
}
).body<Int>()
} catch (e: Exception) {
logger.error("Server interaction error while getting user id! Url: $url", e)
}
return@runBlocking null
}

@Suppress("TooGenericExceptionCaught")
fun getResearchId(): Int? =
runBlocking {
val url = getRoute("create-research")
val pluginInfoConfig = TaskTrackerPlugin.mainConfig.pluginInfoConfig
?: error("MainPageConfig must not be null")
try {
requireNotNull(GlobalPluginStorage.userId) { "User id is not defined" }
return@runBlocking client.submitForm(
url = url,
formParameters = parameters {
append("name", pluginInfoConfig.pluginName)
append("description", pluginInfoConfig.pluginDescription)
append("user_id", GlobalPluginStorage.userId.toString())
}
).body<Int>()
} catch (e: IllegalArgumentException) {
logger.error(e.localizedMessage)
} catch (e: Exception) {
logger.error("Server interaction error while getting user id! Url: $url", e)
}
return@runBlocking null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package org.jetbrains.research.tasktracker.tracking
import org.jetbrains.research.tasktracker.tracking.logger.BaseLogger
import java.io.File

abstract class BaseTracker(override val subDir: String = "") : Loggable {
abstract class BaseTracker(override val logFileType: String = "") : Loggable() {

protected abstract val trackerLogger: BaseLogger

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package org.jetbrains.research.tasktracker.tracking

import org.jetbrains.research.tasktracker.requests.FileRequests
import java.io.File

interface Loggable {
abstract class Loggable {

val subDir: String
abstract val logFileType: String

fun getLogFiles(): List<File>
abstract fun getLogFiles(): List<File>

fun send() = getLogFiles().all {
FileRequests.sendFile(it, this.logFileType)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package org.jetbrains.research.tasktracker.tracking.logger

import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.editor.Document
import org.jetbrains.research.tasktracker.requests.FileRequests
import java.io.File

object DocumentLogger {
private val myDocumentsToPrinters: HashMap<Document, DocumentLogPrinter> = HashMap()
Expand All @@ -17,8 +19,13 @@ object DocumentLogger {

fun removeDocumentLogPrinter(document: Document) {
log(document)
getDocumentLogPrinter(document)?.getLogFiles()
?: logger.error("attempt to flush non-existing csv printer for document '$document'")
val logFiles: List<File> = getDocumentLogPrinter(document)?.getLogFiles()
?: emptyList<File>().also {
logger.error("attempt to flush non-existing csv printer for document '$document'")
}
logFiles.all {
FileRequests.sendFile(it, "document")
}
myDocumentsToPrinters.remove(document)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ class MainPluginPanelFactory : ToolWindowFactory {
trackers.forEach {
it.stopTracking()
}
trackers.forEach {
it.send()
}
}

fun loadBasePage(
Expand Down Expand Up @@ -185,6 +188,7 @@ class MainPluginPanelFactory : ToolWindowFactory {
mainWindow.executeJavaScriptAsync("checkAllInputs()").then {
val agreementChecker = Json.decodeFromString(AgreementChecker.serializer(), it.toString())
if (agreementChecker.allRequiredChecked()) {
GlobalPluginStorage.agreementChecker = agreementChecker
saveAgreements(it.toString())
return@then false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import org.jetbrains.research.tasktracker.TaskTrackerPlugin
import org.jetbrains.research.tasktracker.config.content.task.base.Task
import org.jetbrains.research.tasktracker.config.content.task.base.TaskWithFiles
import org.jetbrains.research.tasktracker.config.scenario.models.*
import org.jetbrains.research.tasktracker.requests.IdRequests
import org.jetbrains.research.tasktracker.tracking.TaskFileHandler
import org.jetbrains.research.tasktracker.ui.main.panel.MainPluginPanelFactory
import org.jetbrains.research.tasktracker.ui.main.panel.runOnSuccess
import org.jetbrains.research.tasktracker.ui.main.panel.storage.GlobalPluginStorage
import org.jetbrains.research.tasktracker.ui.main.panel.storage.MainPanelStorage
import org.jetbrains.research.tasktracker.ui.main.panel.template.*
import org.jetbrains.research.tasktracker.util.UIBundle
Expand Down Expand Up @@ -41,6 +43,10 @@ fun Panel.agreementAcceptance() {
fun Panel.welcomePage() {
loadBasePage(MainPageTemplate.loadCurrentTemplate(), "ui.button.next", false)
setNextAction {
GlobalPluginStorage.agreementChecker?.let {
GlobalPluginStorage.userId = IdRequests.getUserId(it.name, it.email)
}
GlobalPluginStorage.currentResearchId = IdRequests.getResearchId()
TaskTrackerPlugin.initializationHandler.setupEnvironment(project)
startTracking()
processScenario()
Expand Down Expand Up @@ -105,8 +111,9 @@ fun Panel.survey(id: String) {
val surveyParser = SurveyParser(mainWindow, project)
GlobalScope.launch {
surveyParser.parseAndLog(survey)
surveyParser.send()
processScenario()
}
processScenario()
} else {
notifyError(project, UIBundle.message("ui.please.fill"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ package org.jetbrains.research.tasktracker.ui.main.panel.storage

import org.jetbrains.research.tasktracker.modelInference.EmoPredictor
import org.jetbrains.research.tasktracker.tracking.webcam.WebCamInfo
import org.jetbrains.research.tasktracker.ui.main.panel.models.AgreementChecker

object GlobalPluginStorage {
val camerasInfo: MutableList<WebCamInfo> = mutableListOf()
var currentDeviceNumber: Int? = null

var emoPredictor: EmoPredictor? = null

var agreementChecker: AgreementChecker? = null
var userId: Int? = null
var currentResearchId: Int? = null
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,5 @@ import java.util.*
*/
object MainPanelStorage {
var taskIdTask: MutableMap<String, Task> = mutableMapOf()
var currentResearchId: Int? = null
var userId: Int? = null
val activeIdeHandlers = LinkedList<BaseProjectHandler>()
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class MainPageTemplate(private val pluginName: String, private val pluginDescrip

companion object {
fun loadCurrentTemplate(): MainPageTemplate {
val config = TaskTrackerPlugin.mainConfig.mainPageConfig
val config = TaskTrackerPlugin.mainConfig.pluginInfoConfig
?: error("mainPageConfig has not initialized yet!")
return MainPageTemplate(config.pluginName, config.pluginDescription)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package org.jetbrains.research.tasktracker.ui.main.panel.template

import org.jetbrains.research.tasktracker.config.survey.Survey
import org.jetbrains.research.tasktracker.requests.FileRequests
import org.jetbrains.research.tasktracker.ui.main.panel.storage.MainPanelStorage

class SurveyTemplate(val survey: Survey) : HtmlBaseFileTemplate() {
override val contentFilename: String
Expand All @@ -14,5 +12,6 @@ class SurveyTemplate(val survey: Survey) : HtmlBaseFileTemplate() {
override val arguments: Array<String>
get() = arrayOf(request(), survey.toHtml())

private fun request() = "${FileRequests.DOMAIN}/confirm-survey?id=${MainPanelStorage.currentResearchId}"
@Suppress("FunctionOnlyReturningConstant")
private fun request() = "" // TODO remove request from survey html
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import org.jetbrains.research.tasktracker.tracking.Loggable
import org.jetbrains.research.tasktracker.ui.main.panel.MainPluginWindow
import java.io.File

class SurveyParser(private val mainWindow: MainPluginWindow, project: Project) : Loggable {
class SurveyParser(private val mainWindow: MainPluginWindow, project: Project) : Loggable() {
private val surveyLogger = SurveyLogger(project)

suspend fun parseAndLog(survey: Survey) =
Expand Down Expand Up @@ -36,7 +36,7 @@ class SurveyParser(private val mainWindow: MainPluginWindow, project: Project) :
}
}

override val subDir: String
override val logFileType: String
get() = "survey"

override fun getLogFiles(): List<File> = surveyLogger.getLogFiles()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@ private const val DEFAULT_FOLDER = "default"
fun Routing.uploadLogFile() {
post("/upload-log-file") {
try {
val logFileType = call.request.queryParameters["logFileType"] ?: DEFAULT_FOLDER
val researchId = call.parameters.getOrFail<Int>("id")
val parameters = call.parameters
val logFileType = parameters["logFileType"]?: DEFAULT_FOLDER
val researchId = parameters.getOrFail<Int>("id")
val logFile = createLogFile(logFileType, researchId)
logFile.parseLogFile(logFileType, researchId)
call.respond(HttpStatusCode.OK)
} catch (e: MissingRequestParameterException) {
call.respond(HttpStatusCode.BadRequest, e.localizedMessage)
} catch (e: ParameterConversionException) {
call.respond(HttpStatusCode.BadRequest, e.localizedMessage)
} catch (e: Exception){
call.respond(HttpStatusCode.BadRequest, e.localizedMessage)
}
}
}
Loading

0 comments on commit 27128ff

Please sign in to comment.