diff --git a/build.gradle b/build.gradle index bbe3222..d6a397d 100644 --- a/build.gradle +++ b/build.gradle @@ -90,7 +90,6 @@ kotlin { implementation "io.ktor:ktor-client-apache:$ktor_version" implementation 'org.xerial:sqlite-jdbc:3.25.2' - api 'mysql:mysql-connector-java:8.0.16' implementation 'org.jetbrains.exposed:exposed:0.12.2' implementation 'org.mindrot:jbcrypt:0.4' diff --git a/portal.toml b/portal.toml index 9236ca5..74ecea1 100644 --- a/portal.toml +++ b/portal.toml @@ -18,9 +18,3 @@ wiki_url = "https://wiki.kif.rocks/w/index.php?title=KIF470:Arbeitskreise&action [twitter] timeline = "https://twitter.com/kiforbiter?ref_src=twsrc%5Etfw" - -[database] -type = "sqlite" -url = "" -username = "" -password = "" diff --git a/src/commonMain/kotlin/de/kif/common/ConstraintChecking.kt b/src/commonMain/kotlin/de/kif/common/ConstraintChecking.kt index f1e2fa2..097ae7c 100644 --- a/src/commonMain/kotlin/de/kif/common/ConstraintChecking.kt +++ b/src/commonMain/kotlin/de/kif/common/ConstraintChecking.kt @@ -69,10 +69,6 @@ fun checkConstraints( } } - if (schedule.workGroup.interested > schedule.room.places) { - errors += ConstraintError("The work group has more interested then the room has places") - } - for (leader in schedule.workGroup.leader) { for (s in against) { if ( diff --git a/src/jsMain/kotlin/de/kif/frontend/main.kt b/src/jsMain/kotlin/de/kif/frontend/main.kt index 2e59890..aa72d9c 100644 --- a/src/jsMain/kotlin/de/kif/frontend/main.kt +++ b/src/jsMain/kotlin/de/kif/frontend/main.kt @@ -1,8 +1,5 @@ package de.kif.frontend -import de.kif.frontend.repository.RoomRepository -import de.kif.frontend.repository.ScheduleRepository -import de.kif.frontend.repository.WorkGroupRepository import de.kif.frontend.views.board.initBoard import de.kif.frontend.views.calendar.initCalendar import de.kif.frontend.views.initAnnouncement @@ -64,35 +61,4 @@ fun main() = init { } } } - - val url = window.location.pathname - if ("brett" in url || "wand" in url) { - ScheduleRepository.onCreate { - window.location.reload() - } - ScheduleRepository.onUpdate { - window.location.reload() - } - ScheduleRepository.onDelete { - window.location.reload() - } - RoomRepository.onCreate { - window.location.reload() - } - RoomRepository.onUpdate { - window.location.reload() - } - RoomRepository.onDelete { - window.location.reload() - } - WorkGroupRepository.onCreate { - window.location.reload() - } - WorkGroupRepository.onUpdate { - window.location.reload() - } - WorkGroupRepository.onDelete { - window.location.reload() - } - } } diff --git a/src/jsMain/kotlin/de/kif/frontend/views/calendar/Calendar.kt b/src/jsMain/kotlin/de/kif/frontend/views/calendar/Calendar.kt index ec63b6b..c049313 100644 --- a/src/jsMain/kotlin/de/kif/frontend/views/calendar/Calendar.kt +++ b/src/jsMain/kotlin/de/kif/frontend/views/calendar/Calendar.kt @@ -26,12 +26,11 @@ class Calendar(calendar: HTMLElement) : View(calendar) { private val htmlBody = document.body ?: createHtmlView() - val day = (calendarTable.dataset["day"]?.toIntOrNull() ?: -1) - val reloadOnFinish = (calendarTable.dataset["reload"]?.toBoolean() ?: false) - val hideEmpty = (calendarTable.dataset["hide-empty"]?.toBoolean() ?: false) - val referenceDate = (calendarTable.dataset["reference"]?.toLongOrNull() ?: -1L) - val nowDate = (calendarTable.dataset["now"]?.toLongOrNull() ?: -1L) - val timeDifference = (Date.now().toLong() - nowDate) + val day = (calendarTable.dataset["day"]?.toIntOrNull() ?: -1).also { println(it) } + val reloadOnFinish = (calendarTable.dataset["reload"]?.toBoolean() ?: false).also { println(it) } + val referenceDate = (calendarTable.dataset["reference"]?.toLongOrNull() ?: -1L).also { println(it) } + val nowDate = (calendarTable.dataset["now"]?.toLongOrNull() ?: -1L).also { println(it) } + val timeDifference = (Date.now().toLong() - nowDate).also { println(it) } fun scrollVerticalBy(pixel: Double, scrollBehavior: ScrollBehavior = ScrollBehavior.SMOOTH) { scrollAllVerticalBy(pixel, scrollBehavior) diff --git a/src/jsMain/kotlin/de/kif/frontend/views/calendar/CalendarBody.kt b/src/jsMain/kotlin/de/kif/frontend/views/calendar/CalendarBody.kt index a66b0d3..5c34148 100644 --- a/src/jsMain/kotlin/de/kif/frontend/views/calendar/CalendarBody.kt +++ b/src/jsMain/kotlin/de/kif/frontend/views/calendar/CalendarBody.kt @@ -74,12 +74,18 @@ class CalendarBody(val calendar: Calendar, view: HTMLElement) : ViewCollection<C min = (min / 60 - 1) * 60 max = (max / 60 + 2) * 60 + if (min == minTime && max == maxTime) return + minTime = min maxTime = max min = calendarBodies.map { it.minTime }.min() ?: min max = calendarBodies.map { it.maxTime }.max() ?: max + calendarBodies.filter { it != this }.forEach { + it.updateRows() + } + while (isNotEmpty() && min > first().time) { remove(first()) } diff --git a/src/jsMain/kotlin/de/kif/frontend/views/calendar/CalendarRow.kt b/src/jsMain/kotlin/de/kif/frontend/views/calendar/CalendarRow.kt index dde5910..6d84a17 100644 --- a/src/jsMain/kotlin/de/kif/frontend/views/calendar/CalendarRow.kt +++ b/src/jsMain/kotlin/de/kif/frontend/views/calendar/CalendarRow.kt @@ -8,7 +8,7 @@ import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLSpanElement import org.w3c.dom.set -class CalendarRow(val calendar: CalendarBody, view: HTMLElement) : ViewCollection<CalendarCell>(view) { +class CalendarRow(calendar: CalendarBody, view: HTMLElement) : ViewCollection<CalendarCell>(view) { val day = calendar.day val time = dataset["time"]?.toIntOrNull() ?: 0 @@ -49,6 +49,8 @@ class CalendarRow(val calendar: CalendarBody, view: HTMLElement) : ViewCollectio } row.html.appendChild(rowHeader) + row.html + val rooms = RoomRepository.all() for (room in rooms) { diff --git a/src/jsMain/resources/style/components/_calendar.scss b/src/jsMain/resources/style/components/_calendar.scss index 3e9d325..09b1830 100644 --- a/src/jsMain/resources/style/components/_calendar.scss +++ b/src/jsMain/resources/style/components/_calendar.scss @@ -169,10 +169,6 @@ background-color: var(--table-header-color) !important; } -.calendar-cell[data-empty = "true"] { - display: none; -} - .calendar-tools { position: absolute; top: -5rem; diff --git a/src/jvmMain/kotlin/de/kif/backend/Configuration.kt b/src/jvmMain/kotlin/de/kif/backend/Configuration.kt index d29cf67..8bc2773 100644 --- a/src/jvmMain/kotlin/de/kif/backend/Configuration.kt +++ b/src/jvmMain/kotlin/de/kif/backend/Configuration.kt @@ -133,20 +133,6 @@ object Configuration { val time by c(ResoSpec.time) } - private object DatabaseSpec : ConfigSpec("database") { - val type by required<String>() - val url by required<String>() - val username by required<String>() - val password by required<String>() - } - - object Database { - val type by c(DatabaseSpec.type) - val url by c(DatabaseSpec.url) - val username by c(DatabaseSpec.username) - val password by c(DatabaseSpec.password) - } - init { var config = Config { addSpec(ServerSpec) @@ -156,7 +142,6 @@ object Configuration { addSpec(GeneralSpec) addSpec(TwitterSpec) addSpec(ResoSpec) - addSpec(DatabaseSpec) }.from.toml.resource("portal.toml") for (file in Files.list(Paths.get("."))) { diff --git a/src/jvmMain/kotlin/de/kif/backend/database/Connection.kt b/src/jvmMain/kotlin/de/kif/backend/database/Connection.kt index d56496e..f4272be 100644 --- a/src/jvmMain/kotlin/de/kif/backend/database/Connection.kt +++ b/src/jvmMain/kotlin/de/kif/backend/database/Connection.kt @@ -26,39 +26,14 @@ object Connection { ) fun init() { - val type = Configuration.Database.type - val url = Configuration.Database.url - val username = Configuration.Database.username - val password = Configuration.Database.password - when (type) { - "mysql" -> { - Database.connect( - "jdbc:mysql://$url:3306/akplan?user=$username&password=$password&serverTimezone=UTC", - "com.mysql.cj.jdbc.Driver", - username, - password - ) - } - "mariadb" -> { - Database.connect( - "jdbc:mariadb://$url:3306/akplan?user=$username&password=$password&serverTimezone=UTC", - "org.mariadb.jdbc.Driver", - username, - password - ) - } - else -> { - val dbPath = Configuration.Path.databasePath.toString() - Database.connect("jdbc:sqlite:$dbPath", "org.sqlite.JDBC") - } - } - + val dbPath = Configuration.Path.databasePath.toString() + Database.connect("jdbc:sqlite:$dbPath", "org.sqlite.JDBC") TransactionManager.manager.defaultIsolationLevel = TRANSACTION_SERIALIZABLE try { create() } catch (e: ExposedSQLException) { - logger.error(e) { "Cannot initialize the database!" } + logger.error { "Cannot initialize the database!" } print("Do you want to recreate the database (you will lose all data)? [y/N]: ") val result = readLine() diff --git a/src/jvmMain/kotlin/de/kif/backend/database/Schema.kt b/src/jvmMain/kotlin/de/kif/backend/database/Schema.kt index 2b8604e..0b997b1 100644 --- a/src/jvmMain/kotlin/de/kif/backend/database/Schema.kt +++ b/src/jvmMain/kotlin/de/kif/backend/database/Schema.kt @@ -29,7 +29,7 @@ object DbWorkGroup : Table() { val accessible = bool("accessible") val language = enumeration("language", Language::class) - val leader = text("leader") + val leader = text("leader").default("[]") val length = integer("length") val constraints = text("constraints") @@ -49,9 +49,9 @@ object DbRoom : Table() { val whiteboard = bool("whiteboard") val blackboard = bool("blackboard") val accessible = bool("accessible") - val pool = bool("pool") + val pool = bool("pool").default(false) - val blocked = text("blocked") + val blocked = text("blocked").default("[]") val createdAt = long("createdAt") val updatedAt = long("updatedAt") @@ -63,8 +63,8 @@ object DbSchedule : Table() { val roomId = long("room_id").index() val day = integer("day").index() val time = integer("time_slot") - val lockRoom = bool("lock_room") - val lockTime = bool("lock_time") + val lockRoom = bool("lock_room").default(false) + val lockTime = bool("lock_time").default(false) val createdAt = long("createdAt") val updatedAt = long("updatedAt") diff --git a/src/jvmMain/kotlin/de/kif/backend/route/Account.kt b/src/jvmMain/kotlin/de/kif/backend/route/Account.kt index cbe92e3..95ae47c 100644 --- a/src/jvmMain/kotlin/de/kif/backend/route/Account.kt +++ b/src/jvmMain/kotlin/de/kif/backend/route/Account.kt @@ -6,12 +6,10 @@ import de.kif.backend.prefix import de.kif.backend.repository.* import de.kif.backend.route.api.error import de.kif.backend.util.Backup -import de.kif.backend.util.PushService import de.kif.backend.util.WikiImporter import de.kif.backend.view.respondMain import de.kif.common.RepositoryType import de.kif.common.model.Permission -import de.kif.common.model.Post import io.ktor.application.call import io.ktor.http.ContentType import io.ktor.http.HttpStatusCode @@ -53,10 +51,6 @@ fun Route.account() { +"Sicherung" } - a(href = "$prefix/account/reload", classes = "form-btn") { - +"Alle Geräte neu laden" - } - if (user.checkPermission(Permission.SCHEDULE)) { a(href = "$prefix/account/import", classes = "form-btn") { +"Aus Wiki importieren" @@ -522,8 +516,4 @@ fun Route.account() { call.error(HttpStatusCode.Unauthorized) } } - get("/account/reload") { - PushService.signature = Post.generateUrl() - call.respondRedirect("$prefix/account") - } } diff --git a/src/jvmMain/kotlin/de/kif/backend/route/Board.kt b/src/jvmMain/kotlin/de/kif/backend/route/Board.kt index 050565d..6a92f63 100644 --- a/src/jvmMain/kotlin/de/kif/backend/route/Board.kt +++ b/src/jvmMain/kotlin/de/kif/backend/route/Board.kt @@ -175,8 +175,7 @@ fun Route.board() { max, rooms, schedules, - reloadAfterFinish = true, - hideEmptyRooms = true + reloadAfterFinish = true ) } div("board-twitter") { diff --git a/src/jvmMain/kotlin/de/kif/backend/route/Calendar.kt b/src/jvmMain/kotlin/de/kif/backend/route/Calendar.kt index e4f02de..e7b351e 100644 --- a/src/jvmMain/kotlin/de/kif/backend/route/Calendar.kt +++ b/src/jvmMain/kotlin/de/kif/backend/route/Calendar.kt @@ -72,8 +72,7 @@ fun DIV.renderCalendar( to: Int, rooms: List<Room>, schedules: Map<Room, Map<Int, List<Schedule>>>, - reloadAfterFinish: Boolean = false, - hideEmptyRooms: Boolean = false + reloadAfterFinish: Boolean = false ) { val gridLabelWidth = 60 val minutesOfDay = to - from @@ -92,7 +91,6 @@ fun DIV.renderCalendar( attributes["data-reference"] = Configuration.Schedule.referenceDate.time.toString() attributes["data-now"] = now.timeInMillis.toString() attributes["data-reload"] = reloadAfterFinish.toString() - attributes["data-hide-empty"] = hideEmptyRooms.toString() div("calendar-table-box ${orientation.name.toLowerCase().replace("_", "-")}") { div("calendar-header") { @@ -105,7 +103,6 @@ fun DIV.renderCalendar( for (room in rooms) { div("calendar-cell") { attributes["data-room"] = room.id.toString() - attributes["data-empty"] = (hideEmptyRooms && room !in schedules).toString() span { +room.name @@ -150,7 +147,6 @@ fun DIV.renderCalendar( div("calendar-cell") { attributes["data-room"] = room.id.toString() attributes["data-blocked"] = blocked.toString() - attributes["data-empty"] = (hideEmptyRooms && room !in schedules).toString() title = room.name + " - " + timeString diff --git a/src/jvmMain/kotlin/de/kif/backend/route/Wall.kt b/src/jvmMain/kotlin/de/kif/backend/route/Wall.kt index 5dc6b73..25c48e0 100644 --- a/src/jvmMain/kotlin/de/kif/backend/route/Wall.kt +++ b/src/jvmMain/kotlin/de/kif/backend/route/Wall.kt @@ -1,11 +1,11 @@ package de.kif.backend.route +import com.soywiz.klock.* +import com.soywiz.klock.locale.german import de.kif.backend.Configuration import de.kif.backend.repository.RoomRepository import de.kif.backend.repository.ScheduleRepository import de.kif.backend.view.respondMain -import de.kif.common.formatDate -import de.kif.common.formatDateWithoutYear import de.kif.common.model.Room import de.kif.common.model.Schedule import io.ktor.routing.Route @@ -63,8 +63,6 @@ fun Route.wall() { wallStart + 2 ).map { genWallData(it) } - val rooms = RoomRepository.all() - var min = days.mapNotNull { it.min }.min() ?: 12 * 60 val max = days.mapNotNull { it.max }.max() ?: 12 * 60 @@ -72,15 +70,18 @@ fun Route.wall() { min = max } - val refDate = Configuration.Schedule.referenceDate.time + val refDate = DateTime(Configuration.Schedule.referenceDate.time) respondMain(true, true) { content { div("wall") { for (day in days) { - val date = refDate + (day.number * 1000 * 60 * 60 * 24) - val dateString = formatDateWithoutYear(date, Configuration.Schedule.offset) + val date = refDate + day.number.days + val dateString = DateFormat("EEEE, d. MMMM") + .withLocale(KlockLocale.german) + .format(date) + div("wall-box") { div("wall-name") { @@ -94,9 +95,8 @@ fun Route.wall() { day.number, min, max, - rooms, - day.schedules, - hideEmptyRooms = true + day.schedules.keys.toList().sortedBy { it.id }, + day.schedules ) } } diff --git a/src/jvmMain/kotlin/de/kif/backend/util/PushService.kt b/src/jvmMain/kotlin/de/kif/backend/util/PushService.kt index fb632b9..df6ea58 100644 --- a/src/jvmMain/kotlin/de/kif/backend/util/PushService.kt +++ b/src/jvmMain/kotlin/de/kif/backend/util/PushService.kt @@ -18,7 +18,7 @@ import kotlin.concurrent.thread object PushService { internal var leastValidTimestamp = System.currentTimeMillis() - var signature = Post.generateUrl() + val signature = Post.generateUrl() private val messages: MutableList<Pair<Long, Message>> = mutableListOf() diff --git a/src/jvmMain/resources/portal.toml b/src/jvmMain/resources/portal.toml index 9222a60..809ffa1 100644 --- a/src/jvmMain/resources/portal.toml +++ b/src/jvmMain/resources/portal.toml @@ -32,9 +32,3 @@ backup_interval = 3600000 [twitter] timeline = "" - -[database] -type = "sqlite" -url = "" -username = "" -password = ""