Skip to content

Commit

Permalink
Dev hackathon refactor server (#68)
Browse files Browse the repository at this point in the history
* [ML4SE-153] routing functions

* [ML4SE-153] some refactor

* [ML4SE-153] fixed comments

* [ML4SE-153] fixed EmotionHandler
  • Loading branch information
mikrise2 authored Oct 17, 2023
1 parent 6319cdf commit f57f804
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 164 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package org.jetbrains.research.tasktracker.handler.emoji

import com.intellij.openapi.project.Project
import org.jetbrains.research.tasktracker.config.emotion.EmotionConfig
import org.jetbrains.research.tasktracker.handler.BaseHandler

class EmotionHandler(override val config: EmotionConfig) : BaseHandler {

override fun setup(project: Project) {
override fun setup() {
// TODO("Setup emojis according to the config")
}
}
2 changes: 1 addition & 1 deletion ijServer/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ kotlin_version=1.9.10
logback_version=1.4.11
kotlin.code.style=official
postgresql_driver_version=42.3.1
exposed_version = 0.41.1
exposed_version = 0.44.0
Original file line number Diff line number Diff line change
@@ -1,23 +1,45 @@
package org.jetbrains.research.tasktracker

import org.jetbrains.research.tasktracker.database.models.ResearchTable
import java.util.concurrent.atomic.AtomicInteger
import io.ktor.http.*
import io.ktor.http.content.*
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.util.*
import io.ktor.util.pipeline.*
import org.jetbrains.research.tasktracker.database.models.Research
import java.io.File
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.io.path.createDirectories

private lateinit var currentUserIdAtomic: AtomicInteger
private lateinit var currentResearchIdAtomic: AtomicInteger
private lateinit var currentSurveyIdAtomic: AtomicInteger

val currentUserId: Int
get() = currentResearchIdAtomic.getAndIncrement()

val currentResearchId: Int
get() = currentResearchIdAtomic.getAndIncrement()
suspend inline fun PipelineContext<Unit, ApplicationCall>.createLogFile(
subDirectory: String,
crossinline insert: (name: String, researchId: Int) -> Unit
) {
val multipartData = call.receiveMultipart()
val researchIndex = call.parameters.getOrFail<Int>("id")
multipartData.forEachPart { part ->
if (part is PartData.FileItem) {
val fileName = part.originalFileName as String
val fileBytes = part.streamProvider().readBytes()
insert(fileName, researchIndex)
val directoryPath = createDirectoryPath(researchIndex, subDirectory)
getAndCreateFile(directoryPath, fileName).writeBytes(fileBytes)
}
part.dispose()
}
call.respond(HttpStatusCode.Accepted)
}

val currentSurveyId: Int
get() = currentResearchIdAtomic.getAndIncrement()
fun createDirectoryPath(researchId: Int, subDirectory: String): Path {
val userId = Research.findById(researchId)?.userId
?: error("There are no research with id `$researchId`")
val directoryPath = Paths.get("files/$researchId/$userId/$subDirectory")
directoryPath.createDirectories()
return directoryPath
}

fun initializeIds() {
currentUserIdAtomic = AtomicInteger(ResearchTable.maxUserId() + 1)
currentResearchIdAtomic = AtomicInteger(ResearchTable.maxId() + 1)
currentSurveyIdAtomic = AtomicInteger(0)
fun getAndCreateFile(root: Path, filename: String): File {
return root.resolve(filename).toFile().also { it.createNewFile() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.research.tasktracker.database.models.ActivityFileTable
import org.jetbrains.research.tasktracker.database.models.DocumentFileTable
import org.jetbrains.research.tasktracker.database.models.ResearchTable
import org.jetbrains.research.tasktracker.initializeIds
import org.jetbrains.research.tasktracker.database.models.Researches

object DatabaseFactory {
fun init() {
Expand All @@ -19,9 +18,8 @@ object DatabaseFactory {
transaction(database) {
SchemaUtils.create(ActivityFileTable)
SchemaUtils.create(DocumentFileTable)
SchemaUtils.create(ResearchTable)
SchemaUtils.create(Researches)
commit()
initializeIds()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import org.jetbrains.exposed.dao.id.IntIdTable

object ActivityFileTable : IntIdTable() {
val name = text("name")
val researchId = integer("research_id").references(ResearchTable.id)
val researchId = integer("research_id").references(Researches.id)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import org.jetbrains.exposed.dao.id.IntIdTable

object DocumentFileTable : IntIdTable() {
val name = text("name")
val researchId = integer("research_id").references(ResearchTable.id)
val researchId = integer("research_id").references(Researches.id)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.jetbrains.research.tasktracker.database.models

import org.jetbrains.exposed.dao.Entity
import org.jetbrains.exposed.dao.EntityClass
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.IntIdTable

class Research(id: EntityID<Int>) : Entity<Int>(id) {
companion object : EntityClass<Int, Research>(Researches)

val userId by Researches.userId
var name by Researches.name
}

object Researches : IntIdTable() {
val userId = integer("user_id").autoIncrement()
val name = text("name")
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,120 +1,13 @@
@file:Suppress("NoWildcardImports", "UnsafeCallOnNullableType")

package org.jetbrains.research.tasktracker.plugins

import io.ktor.http.*
import io.ktor.http.content.*
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.util.pipeline.*
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.research.tasktracker.currentResearchId
import org.jetbrains.research.tasktracker.currentSurveyId
import org.jetbrains.research.tasktracker.currentUserId
import org.jetbrains.research.tasktracker.database.models.ActivityFileTable
import org.jetbrains.research.tasktracker.database.models.DocumentFileTable
import org.jetbrains.research.tasktracker.database.models.ResearchTable
import java.io.File
import java.nio.file.Files
import java.nio.file.Paths
import org.jetbrains.research.tasktracker.plugins.requests.createResearch
import org.jetbrains.research.tasktracker.plugins.requests.uploadFile

@Suppress("LongMethod")
fun Application.configureRouting() {
routing {
get("/get-user-id") {
call.respondText(currentUserId.toString())
call.respond(HttpStatusCode.Accepted)
}
get("/get-research-id") {
call.respondText(currentResearchId.toString())
call.respond(HttpStatusCode.Accepted)
}

post("/create-research") {
val formParameters = call.receiveParameters()
transaction {
ResearchTable.insert {
it[id] = formParameters["id"]!!.toInt()
it[userId] = formParameters["user_id"]!!.toInt()
it[name] = formParameters["name"]!!
}
}
call.respond(HttpStatusCode.Accepted)
}

post("upload-document/{id}") {
this.createLogFile(
call.request.queryParameters["subdir"] ?: "default"
) { name, index ->
run {
transaction {
ActivityFileTable.insert {
it[ActivityFileTable.name] = name
it[researchId] = index
} get ActivityFileTable.id
}
}
}
call.respond(HttpStatusCode.Accepted)
}

post("confirm-survey") {
val researchId = call.request.queryParameters["id"]?.toInt() ?: 0
getFile(researchId, "survey$currentSurveyId.txt", "survey").writeText(
call.receiveParameters().toString()
)
call.respond(HttpStatusCode.Accepted)
}

post("upload-activity/{id}") {
this.createLogFile(
"activity"
) { name, index ->
run {
transaction {
DocumentFileTable.insert {
it[DocumentFileTable.name] = name
it[researchId] = index
} get DocumentFileTable.id
}
}
}
call.respond(HttpStatusCode.Accepted)
}
}
}

suspend inline fun PipelineContext<Unit, ApplicationCall>.createLogFile(
subDirectory: String,
crossinline insert: (name: String, researchId: Int) -> Unit
) {
val multipartData = call.receiveMultipart()
val researchIndex = call.parameters["id"]?.toInt() ?: 0 // TODO
multipartData.forEachPart { part ->
when (part) {
is PartData.FileItem -> {
val fileName = part.originalFileName as String
val fileBytes = part.streamProvider().readBytes()
insert(fileName, researchIndex)
getFile(researchIndex, fileName, subDirectory).writeBytes(fileBytes)
}

else -> {}
}
part.dispose()
}
call.respond(HttpStatusCode.Accepted)
}

fun getFile(researchId: Int, filename: String, subDirectory: String): File {
val userId = transaction { ResearchTable.select { ResearchTable.id.eq(researchId) }.first()[ResearchTable.userId] }
val directoryPath = "files/$userId/$researchId/$subDirectory"
Files.createDirectories(Paths.get(directoryPath))
return File("$directoryPath/$filename").also {
it.createNewFile()
createResearch()
uploadFile()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.jetbrains.research.tasktracker.plugins.requests

import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.research.tasktracker.createLogFile
import org.jetbrains.research.tasktracker.database.models.ActivityFileTable

private const val DEFAULT_FOLDER = "default"

fun Routing.uploadFile() {
post("upload-document/{id}") {
this.createLogFile(
call.request.queryParameters["subdir"] ?: DEFAULT_FOLDER
) { name, index ->
run {
transaction {
ActivityFileTable.insert {
it[ActivityFileTable.name] = name
it[researchId] = index
}
}
}
}
call.respond(HttpStatusCode.Accepted)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.jetbrains.research.tasktracker.plugins.requests

import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.util.*
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.research.tasktracker.database.models.Research

fun Routing.createResearch() {
post("/create-research") {
val formParameters = call.receiveParameters()
transaction {
Research.new {
name = formParameters.getOrFail("name")
}
}
call.respond(HttpStatusCode.Accepted)
}
}

0 comments on commit f57f804

Please sign in to comment.