Compare commits

..

10 Commits

Author SHA1 Message Date
semantic-release-bot
712ab3be8c chore: Release v1.6.0-dev.2 [skip ci]
# [1.6.0-dev.2](https://github.com/ReVanced/revanced-api/compare/v1.6.0-dev.1...v1.6.0-dev.2) (2024-12-20)

### Features

* Make some announcements schema fields nullable ([db22874](db22874f06))
2024-12-20 23:27:48 +00:00
oSumAtrIX
db22874f06 feat: Make some announcements schema fields nullable 2024-12-21 00:25:26 +01:00
semantic-release-bot
5d5533a920 chore: Release v1.6.0-dev.1 [skip ci]
# [1.6.0-dev.1](https://github.com/ReVanced/revanced-api/compare/v1.5.0...v1.6.0-dev.1) (2024-11-23)

### Features

* Allow setting `Announcement.createdAt` when creating an announcement ([7f6e29d](7f6e29de52))
2024-11-23 18:26:28 +00:00
oSumAtrIX
7f6e29de52 feat: Allow setting Announcement.createdAt when creating an announcement 2024-11-13 22:23:05 +01:00
semantic-release-bot
48469d32c2 chore: Release v1.5.0 [skip ci]
# [1.5.0](https://github.com/ReVanced/revanced-api/compare/v1.4.0...v1.5.0) (2024-11-06)

### Features

* Allow updating `createdAt` field for announcements ([58ba4cb](58ba4cb11c))
* Move spec url to versioned path ([e871b23](e871b23210))
* Simplify log pattern ([d5d9e04](d5d9e04325))
2024-11-06 21:17:51 +00:00
oSumAtrIX
7f9159fef1 chore: Merge branch dev to main(#195) 2024-11-06 22:15:06 +01:00
semantic-release-bot
b063b4daf2 chore: Release v1.5.0-dev.2 [skip ci]
# [1.5.0-dev.2](https://github.com/ReVanced/revanced-api/compare/v1.5.0-dev.1...v1.5.0-dev.2) (2024-11-06)

### Features

* Allow updating `createdAt` field for announcements ([58ba4cb](58ba4cb11c))
* Simplify log pattern ([d5d9e04](d5d9e04325))
2024-11-06 15:36:26 +00:00
oSumAtrIX
58ba4cb11c feat: Allow updating createdAt field for announcements 2024-11-06 16:34:18 +01:00
semantic-release-bot
55e3774f07 chore: Release v1.5.0-dev.1 [skip ci]
# [1.5.0-dev.1](https://github.com/ReVanced/revanced-api/compare/v1.4.0...v1.5.0-dev.1) (2024-11-06)

### Features

* Move spec url to versioned path ([e871b23](e871b23210))
* Simplify log pattern ([d5d9e04](d5d9e04325))
2024-11-06 04:41:55 +00:00
oSumAtrIX
d5d9e04325 feat: Simplify log pattern 2024-11-06 05:39:39 +01:00
6 changed files with 80 additions and 31 deletions

View File

@@ -1,3 +1,42 @@
# [1.6.0-dev.2](https://github.com/ReVanced/revanced-api/compare/v1.6.0-dev.1...v1.6.0-dev.2) (2024-12-20)
### Features
* Make some announcements schema fields nullable ([db22874](https://github.com/ReVanced/revanced-api/commit/db22874f063bae0c9e7f0c99a20cdf1b16addd89))
# [1.6.0-dev.1](https://github.com/ReVanced/revanced-api/compare/v1.5.0...v1.6.0-dev.1) (2024-11-23)
### Features
* Allow setting `Announcement.createdAt` when creating an announcement ([7f6e29d](https://github.com/ReVanced/revanced-api/commit/7f6e29de5205f63ac4aaea490c844b58e14000c8))
# [1.5.0](https://github.com/ReVanced/revanced-api/compare/v1.4.0...v1.5.0) (2024-11-06)
### Features
* Allow updating `createdAt` field for announcements ([58ba4cb](https://github.com/ReVanced/revanced-api/commit/58ba4cb11c789507826cd70ac548943a94da4223))
* Move spec url to versioned path ([e871b23](https://github.com/ReVanced/revanced-api/commit/e871b23210798723c34bce93c7567d8fbcf4e060))
* Simplify log pattern ([d5d9e04](https://github.com/ReVanced/revanced-api/commit/d5d9e04325fa93540be0438e7b51243e2aeeab3d))
# [1.5.0-dev.2](https://github.com/ReVanced/revanced-api/compare/v1.5.0-dev.1...v1.5.0-dev.2) (2024-11-06)
### Features
* Allow updating `createdAt` field for announcements ([58ba4cb](https://github.com/ReVanced/revanced-api/commit/58ba4cb11c789507826cd70ac548943a94da4223))
* Simplify log pattern ([d5d9e04](https://github.com/ReVanced/revanced-api/commit/d5d9e04325fa93540be0438e7b51243e2aeeab3d))
# [1.5.0-dev.1](https://github.com/ReVanced/revanced-api/compare/v1.4.0...v1.5.0-dev.1) (2024-11-06)
### Features
* Move spec url to versioned path ([e871b23](https://github.com/ReVanced/revanced-api/commit/e871b23210798723c34bce93c7567d8fbcf4e060))
* Simplify log pattern ([d5d9e04](https://github.com/ReVanced/revanced-api/commit/d5d9e04325fa93540be0438e7b51243e2aeeab3d))
# [1.5.0-dev.1](https://github.com/ReVanced/revanced-api/compare/v1.4.0...v1.5.0-dev.1) (2024-11-06) # [1.5.0-dev.1](https://github.com/ReVanced/revanced-api/compare/v1.4.0...v1.5.0-dev.1) (2024-11-06)

View File

@@ -1,4 +1,4 @@
org.gradle.parallel = true org.gradle.parallel = true
org.gradle.caching = true org.gradle.caching = true
kotlin.code.style = official kotlin.code.style = official
version = 1.5.0-dev.1 version = 1.6.0-dev.2

View File

@@ -1,6 +1,9 @@
package app.revanced.api.configuration package app.revanced.api.configuration
import kotlinx.datetime.Clock
import kotlinx.datetime.LocalDateTime import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
interface ApiUser { interface ApiUser {
@@ -60,9 +63,10 @@ class ApiAnnouncement(
val title: String, val title: String,
val content: String? = null, val content: String? = null,
// Using a list instead of a set because set semantics are unnecessary here. // Using a list instead of a set because set semantics are unnecessary here.
val attachments: List<String> = emptyList(), val attachments: List<String>? = null,
// Using a list instead of a set because set semantics are unnecessary here. // Using a list instead of a set because set semantics are unnecessary here.
val tags: List<String> = emptyList(), val tags: List<String>? = null,
val createdAt: LocalDateTime = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()),
val archivedAt: LocalDateTime? = null, val archivedAt: LocalDateTime? = null,
val level: Int = 0, val level: Int = 0,
) )
@@ -74,9 +78,9 @@ class ApiResponseAnnouncement(
val title: String, val title: String,
val content: String? = null, val content: String? = null,
// Using a list instead of a set because set semantics are unnecessary here. // Using a list instead of a set because set semantics are unnecessary here.
val attachments: List<String> = emptyList(), val attachments: List<String>? = null,
// Using a list instead of a set because set semantics are unnecessary here. // Using a list instead of a set because set semantics are unnecessary here.
val tags: List<String> = emptyList(), val tags: List<String>? = null,
val createdAt: LocalDateTime, val createdAt: LocalDateTime,
val archivedAt: LocalDateTime? = null, val archivedAt: LocalDateTime? = null,
val level: Int = 0, val level: Int = 0,

View File

@@ -69,8 +69,7 @@ internal class AnnouncementRepository(private val database: Database) {
fun latestId() = latestAnnouncement?.id?.value.toApiResponseAnnouncementId() fun latestId() = latestAnnouncement?.id?.value.toApiResponseAnnouncementId()
fun latestId(tags: Set<String>) = fun latestId(tags: Set<String>) = tags.map { tag -> latestAnnouncementByTag[tag]?.id?.value }.toApiResponseAnnouncementId()
tags.map { tag -> latestAnnouncementByTag[tag]?.id?.value }.toApiResponseAnnouncementId()
suspend fun paged(cursor: Int, count: Int, tags: Set<String>?) = transaction { suspend fun paged(cursor: Int, count: Int, tags: Set<String>?) = transaction {
Announcement.find { Announcement.find {
@@ -100,13 +99,16 @@ internal class AnnouncementRepository(private val database: Database) {
author = new.author author = new.author
title = new.title title = new.title
content = new.content content = new.content
createdAt = new.createdAt
archivedAt = new.archivedAt archivedAt = new.archivedAt
level = new.level level = new.level
tags = SizedCollection( if (new.tags != null) {
new.tags.map { tag -> Tag.find { Tags.name eq tag }.firstOrNull() ?: Tag.new { name = tag } }, tags = SizedCollection(
) new.tags.map { tag -> Tag.find { Tags.name eq tag }.firstOrNull() ?: Tag.new { name = tag } },
)
}
}.apply { }.apply {
new.attachments.map { attachmentUrl -> new.attachments?.map { attachmentUrl ->
Attachment.new { Attachment.new {
url = attachmentUrl url = attachmentUrl
announcement = this@apply announcement = this@apply
@@ -120,27 +122,32 @@ internal class AnnouncementRepository(private val database: Database) {
it.author = new.author it.author = new.author
it.title = new.title it.title = new.title
it.content = new.content it.content = new.content
it.createdAt = new.createdAt
it.archivedAt = new.archivedAt it.archivedAt = new.archivedAt
it.level = new.level it.level = new.level
// Get the old tags, create new tags if they don't exist, if (new.tags != null) {
// and delete tags that are not in the new tags, after updating the announcement. // Get the old tags, create new tags if they don't exist,
val oldTags = it.tags.toList() // and delete tags that are not in the new tags, after updating the announcement.
val updatedTags = new.tags.map { name -> val oldTags = it.tags.toList()
Tag.find { Tags.name eq name }.firstOrNull() ?: Tag.new { this.name = name } val updatedTags = new.tags.map { name ->
} Tag.find { Tags.name eq name }.firstOrNull() ?: Tag.new { this.name = name }
it.tags = SizedCollection(updatedTags) }
oldTags.forEach { tag -> it.tags = SizedCollection(updatedTags)
if (tag in updatedTags || !tag.announcements.empty()) return@forEach oldTags.forEach { tag ->
tag.delete() if (tag in updatedTags || !tag.announcements.empty()) return@forEach
tag.delete()
}
} }
// Delete old attachments and create new attachments. // Delete old attachments and create new attachments.
it.attachments.forEach { attachment -> attachment.delete() } if (new.attachments != null) {
new.attachments.map { attachment -> it.attachments.forEach { attachment -> attachment.delete() }
Attachment.new { new.attachments.map { attachment ->
url = attachment Attachment.new {
announcement = it url = attachment
announcement = it
}
} }
} }
}?.let(::updateLatestAnnouncement) ?: Unit }?.let(::updateLatestAnnouncement) ?: Unit
@@ -173,8 +180,7 @@ internal class AnnouncementRepository(private val database: Database) {
Tag.all().toList().toApiTag() Tag.all().toList().toApiTag()
} }
private suspend fun <T> transaction(statement: suspend Transaction.() -> T) = private suspend fun <T> transaction(statement: suspend Transaction.() -> T) = newSuspendedTransaction(Dispatchers.IO, database, statement = statement)
newSuspendedTransaction(Dispatchers.IO, database, statement = statement)
private object Announcements : IntIdTable() { private object Announcements : IntIdTable() {
val author = varchar("author", 32).nullable() val author = varchar("author", 32).nullable()

View File

@@ -1,7 +1,7 @@
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> <pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} %-5level %msg%n</pattern>
</encoder> </encoder>
</appender> </appender>
<root level="\${LOG_LEVEL:-INFO}"> <root level="\${LOG_LEVEL:-INFO}">

View File

@@ -135,7 +135,7 @@ private object AnnouncementServiceTest {
val latestAnnouncement = announcementService.latest()!! val latestAnnouncement = announcementService.latest()!!
val latestId = latestAnnouncement.id val latestId = latestAnnouncement.id
val attachments = latestAnnouncement.attachments val attachments = latestAnnouncement.attachments!!
assertEquals(2, attachments.size) assertEquals(2, attachments.size)
assert(attachments.any { it == "attachment1" }) assert(attachments.any { it == "attachment1" })
assert(attachments.any { it == "attachment2" }) assert(attachments.any { it == "attachment2" })
@@ -144,7 +144,7 @@ private object AnnouncementServiceTest {
latestId, latestId,
ApiAnnouncement(title = "title", attachments = listOf("attachment1", "attachment3")), ApiAnnouncement(title = "title", attachments = listOf("attachment1", "attachment3")),
) )
assert(announcementService.get(latestId)!!.attachments.any { it == "attachment3" }) assert(announcementService.get(latestId)!!.attachments!!.any { it == "attachment3" })
} }
@Test @Test