diff --git a/build.gradle.kts b/build.gradle.kts index c72126b..2f83557 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,7 @@ plugins { application kotlin("jvm") version "1.6.10" + kotlin("plugin.serialization") version "1.6.10" } group = "eu.fosil" diff --git a/docker/synapse/config/homeserver.yaml b/docker/synapse/config/homeserver.yaml index 0f3df5b..43f706d 100755 --- a/docker/synapse/config/homeserver.yaml +++ b/docker/synapse/config/homeserver.yaml @@ -13,7 +13,7 @@ database: name: sqlite3 args: database: /data/homeserver.db -log_config: "/config/localhost.log.config" +log_config: "/config/localhost.log.yaml" media_store_path: "/data/media_store" signing_key_path: "/config/localhost.signing.key" macaroon_secret_key: "6VvBQj_TedGcDDB_z,-qXV1W3:.CXrRG6AWF&4p:~iGNguy&_h" diff --git a/docker/synapse/config/localhost.log.config b/docker/synapse/config/localhost.log.yaml similarity index 96% rename from docker/synapse/config/localhost.log.config rename to docker/synapse/config/localhost.log.yaml index f78346a..7b6999f 100755 --- a/docker/synapse/config/localhost.log.config +++ b/docker/synapse/config/localhost.log.yaml @@ -18,7 +18,7 @@ handlers: loggers: synapse: - level: WARNING + level: INFO synapse.storage.SQL: # beware: increasing this to DEBUG will make synapse log sensitive diff --git a/gradle.properties b/gradle.properties index 61a0b52..f94bfb4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,5 @@ kotlin.code.style=official + exposedVersion=0.37.3 ktorVersion=2.0.0-beta-1 jacksonVersion=2.13.1 \ No newline at end of file diff --git a/src/main/kotlin/eu/fosil/okupamicoche/Main.kt b/src/main/kotlin/eu/fosil/okupamicoche/Main.kt index 7cebc3d..b68e6ad 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/Main.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/Main.kt @@ -1,7 +1,9 @@ package eu.fosil.okupamicoche import eu.fosil.okupamicoche.config.ConfigReader -import io.ktor.http.* +import eu.fosil.okupamicoche.matrix.createAppService +import eu.fosil.okupamicoche.matrix.event.TravelEventContentSerializerMappings +import eu.fosil.okupamicoche.matrix.matrixApiClient import io.ktor.server.engine.* import io.ktor.server.netty.* import kotlinx.coroutines.coroutineScope @@ -11,7 +13,6 @@ import kotlinx.coroutines.launch import mu.KotlinLogging import net.folivo.trixnity.appservice.MatrixAppserviceProperties import net.folivo.trixnity.appservice.rest.matrixAppserviceModule -import net.folivo.trixnity.clientserverapi.client.MatrixClientServerApiClient import net.folivo.trixnity.clientserverapi.model.rooms.Visibility import net.folivo.trixnity.core.model.RoomAliasId @@ -21,17 +22,8 @@ suspend fun main() { val config = ConfigReader.load() - if (config === null) { - logger.error { "Unable to load config" } - return - } - - val matrixApiClient = MatrixClientServerApiClient( - baseUrl = Url( - (if (config.homeserver.secure) "https" else "http") + - "://${config.homeserver.host}:${config.homeserver.port}" - ), - ).apply { accessToken.value = config.tokens.appService } + requireNotNull(config) + requireNotNull(matrixApiClient) coroutineScope { launch { @@ -62,7 +54,7 @@ suspend fun main() { matrixAppserviceModule( properties = MatrixAppserviceProperties(config.tokens.homeserver), appserviceService = createAppService(matrixApiClient), - customMappings = null + customMappings = TravelEventContentSerializerMappings ) }.start(wait = true) } diff --git a/src/main/kotlin/eu/fosil/okupamicoche/cli/CommandParser.kt b/src/main/kotlin/eu/fosil/okupamicoche/cli/CommandParser.kt index ba1d085..f1fa9de 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/cli/CommandParser.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/cli/CommandParser.kt @@ -1,12 +1,13 @@ package eu.fosil.okupamicoche.cli import eu.fosil.okupamicoche.config.ConfigReader.config -import eu.fosil.okupamicoche.db +import eu.fosil.okupamicoche.db.TravelEntity +import eu.fosil.okupamicoche.matrix.db +import eu.fosil.okupamicoche.matrix.event.NewTravelEventContent +import eu.fosil.okupamicoche.matrix.matrixApiClient import eu.fosil.okupamicoche.model.Travel -import io.ktor.http.* import mu.KotlinLogging -import net.folivo.trixnity.client.api.MatrixApiClient -import net.folivo.trixnity.client.api.model.rooms.Visibility +import net.folivo.trixnity.clientserverapi.model.rooms.Visibility import net.folivo.trixnity.core.model.RoomAliasId import net.folivo.trixnity.core.model.RoomId import net.folivo.trixnity.core.model.UserId @@ -16,13 +17,8 @@ import java.time.LocalDateTime import java.time.ZoneOffset import java.time.format.DateTimeFormatter - private val logger = KotlinLogging.logger {} -val matrixApiClient = MatrixApiClient( - baseUrl = Url("http://okupamicoche-synapse:8008/"), -).apply { accessToken.value = "30c05ae90a248a4188e620216fa72e349803310ec83e2a77b34fe90be6081f46" } - object CommandParser { fun isCommand(body: String) = body.matches("![a-zA-Z]+( .*)?".toRegex()) @@ -50,7 +46,8 @@ object CommandParser { "create" -> handleCreate(user, room, args) } } catch (e: Exception) { - logger.error { "Exception captured" } + logger.error { "Exception captured: $e" } + e.printStackTrace() } } @@ -59,8 +56,10 @@ object CommandParser { roomId: RoomId, args: List ) { - val origin = args[0] - val destination = args[1] + requireNotNull(matrixApiClient) + + val from = args[0] + val to = args[1] val date = args[2] val time = args[3] val formatter = DateTimeFormatter.ofPattern("yyyy/M/d H:mm") @@ -68,24 +67,26 @@ object CommandParser { val places = args[4].toIntOrNull() ?: 0 val description = args[5] - val newRoomAliasId = RoomAliasId("#viaje_$origin-${destination}_${date}_$time:${config?.homeserver}") + val newRoomAliasId = RoomAliasId("#viaje_$from-${to}_${date}_$time:${config?.homeserver}") val newRoomId = matrixApiClient.rooms.createRoom( visibility = Visibility.PUBLIC, roomAliasId = newRoomAliasId ).getOrThrow() + val newTravel = Travel( + newRoomId, + userId, + from, + to, + unixTime, + places, + description + ) + transaction(db) { - Travel.new { - this.roomId = newRoomId.full - this.driver = userId.full - this.origin = origin - this.destination = destination - this.time = unixTime - this.places = places - this.description = description - } - Travel.all().forEachIndexed { index, travel -> - logger.info("#$index: travel id=${travel.id} origin=${travel.origin} dest=${travel.destination} travel=$travel") + TravelEntity.insert(newTravel) + TravelEntity.all().forEachIndexed { index, travel -> + logger.info("#$index: travel id=${travel.id} origin=${travel.from} dest=${travel.to} travel=$travel") } } @@ -93,15 +94,14 @@ object CommandParser { val displayName = matrixApiClient.users.getDisplayName(userId).getOrNull() ?: userId.full matrixApiClient.rooms.sendMessageEvent( roomId, - RoomMessageEventContent.TextMessageEventContent("$displayName created a new travel! $origin-$destination on $date $time with $places free places.") + RoomMessageEventContent.TextMessageEventContent("$displayName created a new travel! $from-$to on $date $time with $places free places.") ) // Send new travel event -// matrixApiClient.rooms.sendMessageEvent( -// roomId, -// -// ) - + matrixApiClient.rooms.sendMessageEvent( + roomId, + NewTravelEventContent(newTravel) + ) } diff --git a/src/main/kotlin/eu/fosil/okupamicoche/config/Config.kt b/src/main/kotlin/eu/fosil/okupamicoche/config/Config.kt index 7b9fab0..c059eca 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/config/Config.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/config/Config.kt @@ -9,7 +9,7 @@ data class Config( data class HomeserverConfig( val host: String, val secure: Boolean, - val port: Number + val port: Int ) data class TokensConfig( diff --git a/src/main/kotlin/eu/fosil/okupamicoche/config/ConfigReader.kt b/src/main/kotlin/eu/fosil/okupamicoche/config/ConfigReader.kt index 6c3ef94..01ad116 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/config/ConfigReader.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/config/ConfigReader.kt @@ -6,7 +6,6 @@ import com.fasterxml.jackson.module.kotlin.KotlinModule import com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException import mu.KotlinLogging import java.nio.file.Files -import java.nio.file.Paths import kotlin.io.path.Path private val logger = KotlinLogging.logger {} @@ -17,7 +16,6 @@ object ConfigReader { fun load(): Config? { val path = this.javaClass.getResource("/config.yaml")?.path - val path2 = Paths.get("/", "config.yaml") val mapper = ObjectMapper(YAMLFactory()) mapper.registerModule(KotlinModule()) diff --git a/src/main/kotlin/eu/fosil/okupamicoche/db/TravelEntity.kt b/src/main/kotlin/eu/fosil/okupamicoche/db/TravelEntity.kt new file mode 100644 index 0000000..82337c0 --- /dev/null +++ b/src/main/kotlin/eu/fosil/okupamicoche/db/TravelEntity.kt @@ -0,0 +1,38 @@ +package eu.fosil.okupamicoche.db + +import eu.fosil.okupamicoche.model.Travel +import org.jetbrains.exposed.dao.IntEntity +import org.jetbrains.exposed.dao.IntEntityClass +import org.jetbrains.exposed.dao.id.EntityID +import org.jetbrains.exposed.dao.id.IntIdTable + +object TravelsTable: IntIdTable() { + val roomId = varchar("room_id", 255) + val driver = varchar("driver", 255) + val from = varchar("from", 255) + val to = varchar("to", 255) + val time = long("time") + val places = integer("places") + val description = varchar("description", 1023) +} + +class TravelEntity(id: EntityID) : IntEntity(id) { + companion object : IntEntityClass(TravelsTable) { + fun insert(travel: Travel) = TravelEntity.new { + this.roomId = travel.room.full + this.driver = travel.driver.full + this.from = travel.from + this.to = travel.to + this.time = travel.time + this.places = travel.places + this.description = travel.description + } + } + var roomId by TravelsTable.roomId + var driver by TravelsTable.driver + var from by TravelsTable.from + var to by TravelsTable.to + var time by TravelsTable.time + var places by TravelsTable.places + var description by TravelsTable.description +} diff --git a/src/main/kotlin/eu/fosil/okupamicoche/matrix/MatrixApiClient.kt b/src/main/kotlin/eu/fosil/okupamicoche/matrix/MatrixApiClient.kt new file mode 100644 index 0000000..cbb1973 --- /dev/null +++ b/src/main/kotlin/eu/fosil/okupamicoche/matrix/MatrixApiClient.kt @@ -0,0 +1,16 @@ +package eu.fosil.okupamicoche.matrix + +import eu.fosil.okupamicoche.config.ConfigReader +import eu.fosil.okupamicoche.matrix.event.TravelEventContentSerializerMappings +import io.ktor.http.* +import net.folivo.trixnity.clientserverapi.client.MatrixClientServerApiClient +import net.folivo.trixnity.core.serialization.events.DefaultEventContentSerializerMappings + +val config = ConfigReader.load() +val matrixApiClient = if (config == null) null else MatrixClientServerApiClient( + baseUrl = Url( + (if (config.homeserver.secure) "https" else "http") + + "://${config.homeserver.host}:${config.homeserver.port}" + ), + eventContentSerializerMappings = DefaultEventContentSerializerMappings + TravelEventContentSerializerMappings +).apply { accessToken.value = config.tokens.appService } \ No newline at end of file diff --git a/src/main/kotlin/eu/fosil/okupamicoche/createAppService.kt b/src/main/kotlin/eu/fosil/okupamicoche/matrix/createAppService.kt similarity index 78% rename from src/main/kotlin/eu/fosil/okupamicoche/createAppService.kt rename to src/main/kotlin/eu/fosil/okupamicoche/matrix/createAppService.kt index b427359..7a38cc4 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/createAppService.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/matrix/createAppService.kt @@ -1,10 +1,11 @@ -package eu.fosil.okupamicoche +package eu.fosil.okupamicoche.matrix import eu.fosil.okupamicoche.cli.CommandParser -import eu.fosil.okupamicoche.model.Travels -import eu.fosil.okupamicoche.services.EventTnxService -import eu.fosil.okupamicoche.services.RoomService -import eu.fosil.okupamicoche.services.UserService +import eu.fosil.okupamicoche.db.TravelsTable +import eu.fosil.okupamicoche.matrix.event.NewTravelEventContent +import eu.fosil.okupamicoche.matrix.services.EventTnxService +import eu.fosil.okupamicoche.matrix.services.RoomService +import eu.fosil.okupamicoche.matrix.services.UserService import mu.KotlinLogging import net.folivo.trixnity.appservice.AppserviceService import net.folivo.trixnity.appservice.DefaultAppserviceService @@ -23,7 +24,7 @@ private val logger = KotlinLogging.logger {} fun createAppService(matrixClientServerApiClient: MatrixClientServerApiClient): AppserviceService { transaction(db) { - SchemaUtils.create(Travels) + SchemaUtils.create(TravelsTable) logger.info { "Travels table created" } } @@ -38,6 +39,10 @@ fun createAppService(matrixClientServerApiClient: MatrixClientServerApiClient): logger.info("${it.content.creator} created room ${it.roomId}") } } + subscribe { event-> + logger.info("NEW TRAVEL CREATED EVENT!!") + logger.info("$event") + } subscribe { event -> require(event is Event.MessageEvent) val roomId = event.roomId diff --git a/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/NewTravelEventContent.kt b/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/NewTravelEventContent.kt index 6513a8a..ce7ed9f 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/NewTravelEventContent.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/NewTravelEventContent.kt @@ -1,13 +1,41 @@ package eu.fosil.okupamicoche.matrix.event +import eu.fosil.okupamicoche.model.Travel import kotlinx.serialization.SerialName -import net.folivo.trixnity.core.model.UserId +import kotlinx.serialization.Serializable import net.folivo.trixnity.core.model.events.MessageEventContent import net.folivo.trixnity.core.model.events.RelatesTo +@Serializable data class NewTravelEventContent( - @SerialName("to") val to: UserId, -// @SerialName("body") override val body: String = "Attempting verification request. (m.key.verification.request) Apparently your client doesn't support this.", - @SerialName("m.relates_to") override val relatesTo: RelatesTo? = null, + @SerialName("room") + val room: String, + @SerialName("driver") + val driver: String, + @SerialName("from") + val from: String, + @SerialName("to") + val to: String, + @SerialName("time") + val time: Long, + @SerialName("places") + val places: Int, + @SerialName("description") + val description: String, + + @SerialName("body") + val body: String = "New travel created", + @SerialName("m.relates_to") + override val relatesTo: RelatesTo.Reference? = null, ) : MessageEventContent { + constructor(travel: Travel) : this( + travel.room.full, + travel.driver.full, + travel.from, + travel.to, + travel.time, + travel.places, + travel.description, + "New travel created2", + ) } \ No newline at end of file diff --git a/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/TravelEventContentSerializerMappings.kt b/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/TravelEventContentSerializerMappings.kt new file mode 100644 index 0000000..603f9b2 --- /dev/null +++ b/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/TravelEventContentSerializerMappings.kt @@ -0,0 +1,16 @@ +package eu.fosil.okupamicoche.matrix.event + +import net.folivo.trixnity.core.model.events.* +import net.folivo.trixnity.core.serialization.events.EventContentSerializerMapping +import net.folivo.trixnity.core.serialization.events.EventContentSerializerMappings + +object TravelEventContentSerializerMappings : EventContentSerializerMappings { + override val message: Set> = setOf( + EventContentSerializerMapping.of("eu.fosil.travel.create") + ) + override val state: Set> = setOf() + override val ephemeral: Set> = setOf() + override val globalAccountData: Set> = setOf() + override val roomAccountData: Set> = setOf() + override val toDevice: Set> = setOf() +} \ No newline at end of file diff --git a/src/main/kotlin/eu/fosil/okupamicoche/services/EventTnxService.kt b/src/main/kotlin/eu/fosil/okupamicoche/matrix/services/EventTnxService.kt similarity index 93% rename from src/main/kotlin/eu/fosil/okupamicoche/services/EventTnxService.kt rename to src/main/kotlin/eu/fosil/okupamicoche/matrix/services/EventTnxService.kt index aeb7f70..13ca502 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/services/EventTnxService.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/matrix/services/EventTnxService.kt @@ -1,4 +1,4 @@ -package eu.fosil.okupamicoche.services +package eu.fosil.okupamicoche.matrix.services import mu.KotlinLogging import net.folivo.trixnity.appservice.event.AppserviceEventTnxService diff --git a/src/main/kotlin/eu/fosil/okupamicoche/services/RoomService.kt b/src/main/kotlin/eu/fosil/okupamicoche/matrix/services/RoomService.kt similarity index 96% rename from src/main/kotlin/eu/fosil/okupamicoche/services/RoomService.kt rename to src/main/kotlin/eu/fosil/okupamicoche/matrix/services/RoomService.kt index 0ebbefb..b104ef4 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/services/RoomService.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/matrix/services/RoomService.kt @@ -1,4 +1,4 @@ -package eu.fosil.okupamicoche.services +package eu.fosil.okupamicoche.matrix.services import mu.KotlinLogging import net.folivo.trixnity.appservice.room.AppserviceRoomService diff --git a/src/main/kotlin/eu/fosil/okupamicoche/services/UserService.kt b/src/main/kotlin/eu/fosil/okupamicoche/matrix/services/UserService.kt similarity index 95% rename from src/main/kotlin/eu/fosil/okupamicoche/services/UserService.kt rename to src/main/kotlin/eu/fosil/okupamicoche/matrix/services/UserService.kt index 99acc22..814f7e3 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/services/UserService.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/matrix/services/UserService.kt @@ -1,4 +1,4 @@ -package eu.fosil.okupamicoche.services +package eu.fosil.okupamicoche.matrix.services import net.folivo.trixnity.appservice.user.AppserviceUserService import net.folivo.trixnity.appservice.user.RegisterUserParameter diff --git a/src/main/kotlin/eu/fosil/okupamicoche/model/Travel.kt b/src/main/kotlin/eu/fosil/okupamicoche/model/Travel.kt index 5f70954..504a02c 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/model/Travel.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/model/Travel.kt @@ -1,27 +1,18 @@ package eu.fosil.okupamicoche.model +import net.folivo.trixnity.core.model.RoomId +import net.folivo.trixnity.core.model.UserId import org.jetbrains.exposed.dao.IntEntity import org.jetbrains.exposed.dao.IntEntityClass import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.dao.id.IntIdTable -object Travels: IntIdTable() { - val roomId = varchar("room_id", 255) - val driver = varchar("driver", 255) - val origin = varchar("origin", 255) - val destination = varchar("destination", 255) - val time = long("time") - val places = integer("places") - val description = varchar("description", 1023) -} - -class Travel(id: EntityID) : IntEntity(id) { - companion object : IntEntityClass(Travels) - var roomId by Travels.roomId - var driver by Travels.driver - var origin by Travels.origin - var destination by Travels.destination - var time by Travels.time - var places by Travels.places - var description by Travels.description -} +class Travel( + var room: RoomId, + var driver: UserId, + var from: String, + var to: String, + var time: Long, + var places: Int, + var description: String +)