From 93ec5464b450beb159808f4b93e83ccb21717b19 Mon Sep 17 00:00:00 2001 From: Ziedelth Date: Sun, 3 Mar 2024 22:13:05 +0100 Subject: [PATCH 1/3] Fix blank description and titles, and fix no images --- .../kotlin/fr/shikkanime/jobs/FetchDeprecatedEpisodeJob.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/fr/shikkanime/jobs/FetchDeprecatedEpisodeJob.kt b/src/main/kotlin/fr/shikkanime/jobs/FetchDeprecatedEpisodeJob.kt index 73a6015c..f9b2fbef 100644 --- a/src/main/kotlin/fr/shikkanime/jobs/FetchDeprecatedEpisodeJob.kt +++ b/src/main/kotlin/fr/shikkanime/jobs/FetchDeprecatedEpisodeJob.kt @@ -111,6 +111,7 @@ class FetchDeprecatedEpisodeJob : AbstractJob { if (image != episode.image) { episode.image = image ImageService.remove(episode.uuid!!, ImageService.Type.IMAGE) + episodeService.addImage(episode.uuid, image) needUpdate = true } @@ -179,7 +180,7 @@ class FetchDeprecatedEpisodeJob : AbstractJob { title = title?.replace("\n", "") title = title?.replace("\r", "") title = title?.trim() - return title + return title.takeIf { !it.isNullOrBlank() } } fun normalizeDescription(platform: Platform, content: JsonObject): String? { @@ -191,7 +192,7 @@ class FetchDeprecatedEpisodeJob : AbstractJob { description = description?.replace("\n", "") description = description?.replace("\r", "") description = description?.trim() - return description + return description.takeIf { !it.isNullOrBlank() } } fun normalizeImage(platform: Platform, content: JsonObject): String { From b51421f862a7243f64e065531ca9935741b54004 Mon Sep 17 00:00:00 2001 From: Ziedelth Date: Mon, 4 Mar 2024 15:17:21 +0100 Subject: [PATCH 2/3] Fix duplications on platform simulcasts --- src/main/kotlin/fr/shikkanime/Application.kt | 2 + .../CountryCodeNetflixSimulcastKeyCache.kt | 2 +- .../fr/shikkanime/jobs/GarbageCollectorJob.kt | 7 +++ .../configuration/NetflixConfiguration.kt | 43 +++---------- .../configuration/PrimeVideoConfiguration.kt | 46 ++------------ .../ReleaseDayPlatformSimulcast.kt | 48 ++++++++++++++ .../kotlin/fr/shikkanime/utils/JobManager.kt | 4 +- .../controllers/admin/AdminControllerTest.kt | 62 ++++++++++++++++++- 8 files changed, 131 insertions(+), 83 deletions(-) create mode 100644 src/main/kotlin/fr/shikkanime/jobs/GarbageCollectorJob.kt create mode 100644 src/main/kotlin/fr/shikkanime/platforms/configuration/ReleaseDayPlatformSimulcast.kt diff --git a/src/main/kotlin/fr/shikkanime/Application.kt b/src/main/kotlin/fr/shikkanime/Application.kt index eff68f2a..a25b5a98 100644 --- a/src/main/kotlin/fr/shikkanime/Application.kt +++ b/src/main/kotlin/fr/shikkanime/Application.kt @@ -43,6 +43,8 @@ fun initAll(adminPassword: AtomicReference?, port: Int = 37100, wait: Bo JobManager.scheduleJob("*/10 * * * * ?", MetricJob::class.java) // Every minute JobManager.scheduleJob("0 * * * * ?", FetchEpisodesJob::class.java) + // Every 10 minutes + JobManager.scheduleJob("0 */10 * * * ?", GarbageCollectorJob::class.java) // Every hour JobManager.scheduleJob("0 0 * * * ?", SavingImageCacheJob::class.java) JobManager.scheduleJob("0 0 * * * ?", FetchDeprecatedEpisodeJob::class.java) diff --git a/src/main/kotlin/fr/shikkanime/caches/CountryCodeNetflixSimulcastKeyCache.kt b/src/main/kotlin/fr/shikkanime/caches/CountryCodeNetflixSimulcastKeyCache.kt index a358701c..33cb343f 100644 --- a/src/main/kotlin/fr/shikkanime/caches/CountryCodeNetflixSimulcastKeyCache.kt +++ b/src/main/kotlin/fr/shikkanime/caches/CountryCodeNetflixSimulcastKeyCache.kt @@ -5,7 +5,7 @@ import fr.shikkanime.platforms.configuration.NetflixConfiguration data class CountryCodeNetflixSimulcastKeyCache( val countryCode: CountryCode, - val netflixSimulcast: NetflixConfiguration.NetflixSimulcast + val netflixSimulcast: NetflixConfiguration.NetflixSimulcastDay ) { override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/src/main/kotlin/fr/shikkanime/jobs/GarbageCollectorJob.kt b/src/main/kotlin/fr/shikkanime/jobs/GarbageCollectorJob.kt new file mode 100644 index 00000000..b232ab66 --- /dev/null +++ b/src/main/kotlin/fr/shikkanime/jobs/GarbageCollectorJob.kt @@ -0,0 +1,7 @@ +package fr.shikkanime.jobs + +class GarbageCollectorJob : AbstractJob { + override fun run() { + System.gc() + } +} \ No newline at end of file diff --git a/src/main/kotlin/fr/shikkanime/platforms/configuration/NetflixConfiguration.kt b/src/main/kotlin/fr/shikkanime/platforms/configuration/NetflixConfiguration.kt index dcd5fb9c..90887f65 100644 --- a/src/main/kotlin/fr/shikkanime/platforms/configuration/NetflixConfiguration.kt +++ b/src/main/kotlin/fr/shikkanime/platforms/configuration/NetflixConfiguration.kt @@ -2,48 +2,19 @@ package fr.shikkanime.platforms.configuration import io.ktor.http.* -class NetflixConfiguration : PlatformConfiguration() { - data class NetflixSimulcast( - var releaseDay: Int = 1, - var image: String = "", - var releaseTime: String = "", +class NetflixConfiguration : PlatformConfiguration() { + data class NetflixSimulcastDay( + override var releaseDay: Int = 1, + override var image: String = "", + override var releaseTime: String = "", var season: Int = 1, - ) : PlatformSimulcast() { + ) : ReleaseDayPlatformSimulcast(releaseDay, image, releaseTime) { override fun of(parameters: Parameters) { super.of(parameters) - parameters["releaseDay"]?.let { releaseDay = it.toInt() } - parameters["image"]?.let { image = it } - parameters["releaseTime"]?.let { releaseTime = it } parameters["season"]?.let { season = it.toInt() } } override fun toConfigurationFields() = super.toConfigurationFields().apply { - add( - ConfigurationField( - label = "Release day", - caption = "1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday, 5 = Friday, 6 = Saturday, 7 = Sunday", - name = "releaseDay", - type = "number", - value = releaseDay - ), - ) - add( - ConfigurationField( - label = "Image", - name = "image", - type = "text", - value = image - ), - ) - add( - ConfigurationField( - label = "Release time", - caption = "Format: HH:mm:ss (In UTC)", - name = "releaseTime", - type = "time", - value = releaseTime - ), - ) add( ConfigurationField( label = "Season", @@ -55,5 +26,5 @@ class NetflixConfiguration : PlatformConfiguration() { data class PrimeVideoSimulcast( - var releaseDay: Int = 1, - var image: String = "", - var releaseTime: String = "", - ) : PlatformSimulcast() { - override fun of(parameters: Parameters) { - super.of(parameters) - parameters["releaseDay"]?.let { releaseDay = it.toInt() } - parameters["image"]?.let { image = it } - parameters["releaseTime"]?.let { releaseTime = it } - } - - override fun toConfigurationFields() = super.toConfigurationFields().apply { - add( - ConfigurationField( - label = "Release day", - caption = "1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday, 5 = Friday, 6 = Saturday, 7 = Sunday", - name = "releaseDay", - type = "number", - value = releaseDay - ), - ) - add( - ConfigurationField( - label = "Image", - name = "image", - type = "text", - value = image - ), - ) - add( - ConfigurationField( - label = "Release time", - caption = "Format: HH:mm:ss (In UTC)", - name = "releaseTime", - type = "time", - value = releaseTime - ), - ) - } - } + override var releaseDay: Int = 1, + override var image: String = "", + override var releaseTime: String = "", + ) : ReleaseDayPlatformSimulcast(releaseDay, image, releaseTime) override fun newPlatformSimulcast() = PrimeVideoSimulcast() } \ No newline at end of file diff --git a/src/main/kotlin/fr/shikkanime/platforms/configuration/ReleaseDayPlatformSimulcast.kt b/src/main/kotlin/fr/shikkanime/platforms/configuration/ReleaseDayPlatformSimulcast.kt new file mode 100644 index 00000000..a7063ae2 --- /dev/null +++ b/src/main/kotlin/fr/shikkanime/platforms/configuration/ReleaseDayPlatformSimulcast.kt @@ -0,0 +1,48 @@ +package fr.shikkanime.platforms.configuration + +import io.ktor.http.* + +open class ReleaseDayPlatformSimulcast( + @Transient + open var releaseDay: Int, + @Transient + open var image: String, + @Transient + open var releaseTime: String, +) : PlatformSimulcast() { + override fun of(parameters: Parameters) { + super.of(parameters) + parameters["releaseDay"]?.let { releaseDay = it.toInt() } + parameters["image"]?.let { image = it } + parameters["releaseTime"]?.let { releaseTime = it } + } + + override fun toConfigurationFields() = super.toConfigurationFields().apply { + add( + ConfigurationField( + label = "Release day", + caption = "1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday, 5 = Friday, 6 = Saturday, 7 = Sunday", + name = "releaseDay", + type = "number", + value = releaseDay + ), + ) + add( + ConfigurationField( + label = "Image", + name = "image", + type = "text", + value = image + ), + ) + add( + ConfigurationField( + label = "Release time", + caption = "Format: HH:mm:ss (In UTC)", + name = "releaseTime", + type = "time", + value = releaseTime + ), + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/fr/shikkanime/utils/JobManager.kt b/src/main/kotlin/fr/shikkanime/utils/JobManager.kt index 15863e0b..66fa3056 100644 --- a/src/main/kotlin/fr/shikkanime/utils/JobManager.kt +++ b/src/main/kotlin/fr/shikkanime/utils/JobManager.kt @@ -25,8 +25,8 @@ object JobManager { scheduler.start() } - fun stop() { - scheduler.shutdown() + fun invalidate() { + scheduler.clear() } class JobExecutor : Job { diff --git a/src/test/kotlin/fr/shikkanime/controllers/admin/AdminControllerTest.kt b/src/test/kotlin/fr/shikkanime/controllers/admin/AdminControllerTest.kt index eaf1a95f..219f5fc9 100644 --- a/src/test/kotlin/fr/shikkanime/controllers/admin/AdminControllerTest.kt +++ b/src/test/kotlin/fr/shikkanime/controllers/admin/AdminControllerTest.kt @@ -3,6 +3,7 @@ package fr.shikkanime.controllers.admin import com.google.inject.Inject import com.microsoft.playwright.Playwright import fr.shikkanime.entities.enums.Link +import fr.shikkanime.entities.enums.Platform import fr.shikkanime.initAll import fr.shikkanime.services.MemberService import fr.shikkanime.utils.Constant @@ -42,7 +43,7 @@ class AdminControllerTest { Constant.injector.injectMembers(this) server = initAll(password, port, false) - JobManager.stop() + JobManager.invalidate() } @AfterEach @@ -52,7 +53,7 @@ class AdminControllerTest { } @Test - fun `test admin login`() { + fun `test admin login and all links`() { val playwright = Playwright.create() val browser = playwright.chromium().launch() val page = browser.newPage() @@ -80,4 +81,61 @@ class AdminControllerTest { browser.close() playwright.close() } + + @Test + fun `create netflix simulcast`() { + val playwright = Playwright.create() + val browser = playwright.chromium().launch() + val page = browser.newPage() + + page.navigate("http://localhost:$port/admin") + assertEquals("Login - Shikkanime", page.title()) + page.fill("input[name=username]", "admin") + page.fill("input[name=password]", password.get()) + page.click("button[type=submit]") + + page.navigate("http://localhost:$port${Link.PLATFORMS.href}") + page.click("button[data-bs-target='#collapse${Platform.NETF.name}']") + page.click("a[href='${Link.PLATFORMS.href}/${Platform.NETF.name}/simulcasts']") + + page.fill("input[name=name]", "81564899") + page.fill("input[name=releaseDay]", "4") + page.fill("input[name=image]", "https://cdn.myanimelist.net/images/anime/1938/140374.jpg") + page.fill("input[name=releaseTime]", "13:30") + page.fill("input[name=season]", "2") + + page.click("button[type=submit]") + + page.close() + browser.close() + playwright.close() + } + + @Test + fun `create prime video simulcast`() { + val playwright = Playwright.create() + val browser = playwright.chromium().launch() + val page = browser.newPage() + + page.navigate("http://localhost:$port/admin") + assertEquals("Login - Shikkanime", page.title()) + page.fill("input[name=username]", "admin") + page.fill("input[name=password]", password.get()) + page.click("button[type=submit]") + + page.navigate("http://localhost:$port${Link.PLATFORMS.href}") + page.click("button[data-bs-target='#collapse${Platform.PRIM.name}']") + page.click("a[href='${Link.PLATFORMS.href}/${Platform.PRIM.name}/simulcasts']") + + page.fill("input[name=name]", "0QN9ZXJ935YBTNK8U9FV5OAX5B") + page.fill("input[name=releaseDay]", "1") + page.fill("input[name=image]", "https://cdn.myanimelist.net/images/anime/1142/141351.jpg") + page.fill("input[name=releaseTime]", "17:01") + + page.click("button[type=submit]") + + page.close() + browser.close() + playwright.close() + } } \ No newline at end of file From f9c03a36cb6e5c2b1f9e3de81b66384e43b46ac7 Mon Sep 17 00:00:00 2001 From: Ziedelth Date: Mon, 4 Mar 2024 16:37:40 +0100 Subject: [PATCH 3/3] Add for pull request on master --- .github/workflows/global_workflow.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/global_workflow.yml b/.github/workflows/global_workflow.yml index a69462f9..1893ed42 100644 --- a/.github/workflows/global_workflow.yml +++ b/.github/workflows/global_workflow.yml @@ -36,6 +36,10 @@ jobs: SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} run: ./gradlew sonar --info -Dsonar.pullrequest.key=${{ github.event.pull_request.number }} -Dsonar.pullrequest.branch=${{ github.event.pull_request.head.ref }} -Dsonar.pullrequest.base=${{ github.event.pull_request.base.ref }} -Dsonar.qualitygate.wait=true + - name: Test + if: github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'master' + run: ./gradlew clean test --info + - name: Cache gradle dependencies uses: actions/cache@v4 # If author is dependabot, we don't cache dependencies