Skip to content

Commit

Permalink
Merge pull request #249 from Shikkanime/dev
Browse files Browse the repository at this point in the history
Merge simulcasts and image in dashboard
  • Loading branch information
Ziedelth authored Mar 5, 2024
2 parents 2cd66c5 + 3e476b6 commit 3faa750
Show file tree
Hide file tree
Showing 15 changed files with 187 additions and 134 deletions.
41 changes: 12 additions & 29 deletions src/main/kotlin/fr/shikkanime/controllers/admin/AdminController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import fr.shikkanime.converters.AbstractConverter
import fr.shikkanime.dtos.TokenDto
import fr.shikkanime.entities.Anime
import fr.shikkanime.entities.Episode
import fr.shikkanime.entities.Simulcast
import fr.shikkanime.entities.enums.EpisodeType
import fr.shikkanime.entities.enums.LangType
import fr.shikkanime.entities.enums.Link
Expand Down Expand Up @@ -82,55 +83,37 @@ class AdminController {
@Get
@AdminSessionAuthenticated
private fun getDashboard(): Response {
return Response.template(Link.DASHBOARD)
}

@Path("/images")
@Get
@AdminSessionAuthenticated
private fun getImages(): Response {
return Response.template(
Link.IMAGES,
mutableMapOf(
Link.DASHBOARD,
mapOf(
"simulcasts" to simulcastCacheService.findAll(),
"size" to ImageService.size,
"originalSize" to ImageService.originalSize,
"compressedSize" to ImageService.compressedSize,
)
)
}

@Path("/images/save")
@Path("/images-save")
@Get
@AdminSessionAuthenticated
private fun saveImages(): Response {
ImageService.saveCache()
return Response.redirect(Link.IMAGES.href)
return Response.redirect(Link.DASHBOARD.href)
}

@Path("/images/invalidate")
@Path("/images-invalidate")
@Get
@AdminSessionAuthenticated
private fun invalidateImages(): Response {
ImageService.invalidate()
return Response.redirect(Link.IMAGES.href)
}

@Path("/simulcasts")
@Get
@AdminSessionAuthenticated
private fun getSimulcasts(): Response {
return Response.template(
Link.SIMULCASTS,
mutableMapOf(
"simulcasts" to simulcastCacheService.findAll()
)
)
return Response.redirect(Link.DASHBOARD.href)
}

@Path("/simulcasts/recalculate")
@Path("/simulcasts-invalidate")
@Get
@AdminSessionAuthenticated
private fun recalculateSimulcasts(): Response {
private fun invalidateSimulcasts(): Response {
animeService.findAll().forEach { anime ->
anime.simulcasts.clear()
animeService.update(anime)
Expand All @@ -147,7 +130,7 @@ class AdminController {
}
}

MapCache.invalidate(Anime::class.java, Episode::class.java)
return Response.redirect(Link.SIMULCASTS.href)
MapCache.invalidate(Anime::class.java, Episode::class.java, Simulcast::class.java)
return Response.redirect(Link.DASHBOARD.href)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ class EpisodeToEpisodeDtoConverter : AbstractConverter<Episode, EpisodeDto>() {
from.image.isNullOrBlank() ||
from.description.isNullOrBlank() ||
from.description?.startsWith("(") == true ||
languageDetector.detect(from.description).language.lowercase() != from.anime!!.countryCode!!.name.lowercase()
languageDetector.detect(from.description).language.lowercase() != from.anime!!.countryCode!!.name.lowercase() ||
from.url?.contains("media-", true) == true
) Status.INVALID else Status.VALID

return EpisodeDto(
Expand Down
2 changes: 0 additions & 2 deletions src/main/kotlin/fr/shikkanime/entities/enums/Link.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ enum class Link(
ANIMES("/admin/animes", "/admin/animes/list.ftl", "bi bi-file-earmark-play", "Animes"),
EPISODES("/admin/episodes", "/admin/episodes/list.ftl", "bi bi-collection-play", "Episodes"),
CONFIG("/admin/config", "/admin/config/list.ftl", "bi bi-gear", "Configurations"),
IMAGES("/admin/images", "/admin/images.ftl", "bi bi-images", "Images"),
SIMULCASTS("/admin/simulcasts", "/admin/simulcasts.ftl", "bi bi-calendar-event", "Simulcasts"),

// Site
HOME("/", "/site/home.ftl", "", "Accueil", "${Constant.NAME} : Ne manquez plus jamais un épisode d'animé !"),
Expand Down
60 changes: 38 additions & 22 deletions src/main/kotlin/fr/shikkanime/jobs/FetchDeprecatedEpisodeJob.kt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ class FetchDeprecatedEpisodeJob : AbstractJob {
MapCache.invalidate(Episode::class.java)
}

private fun getIdentifier(episode: Episode) = "${episode.anime?.name} - S${episode.season} ${
when (episode.episodeType!!) {
EpisodeType.EPISODE -> "EP"
EpisodeType.SPECIAL -> "SP"
EpisodeType.FILM -> "MOV"
}
}${episode.number}"

private fun update(
episode: Episode,
httpRequest: HttpRequest,
Expand All @@ -84,22 +92,15 @@ class FetchDeprecatedEpisodeJob : AbstractJob {
now: ZonedDateTime,
): Boolean {
var needUpdate = false

val s = "${episode.anime?.name} - S${episode.season} ${
when (episode.episodeType!!) {
EpisodeType.EPISODE -> "EP"
EpisodeType.SPECIAL -> "SP"
EpisodeType.FILM -> "MOV"
}
}${episode.number}"
val identifier = getIdentifier(episode)

try {
val content =
runBlocking { normalizeContent(episode, httpRequest, anonymousAccessToken, cms) } ?: return false
val title = normalizeTitle(episode.platform!!, content)
val description = normalizeDescription(episode.platform!!, content)
val image = normalizeImage(episode.platform!!, content)
logger.config("$s : $title - $description - $image")
logger.config("$identifier : $title - $description - $image")

if (title != null && title != episode.title) {
episode.title = title
Expand All @@ -123,7 +124,7 @@ class FetchDeprecatedEpisodeJob : AbstractJob {
episodeService.update(episode)
}
} catch (e: Exception) {
logger.log(Level.SEVERE, "Error while fetching episode description for $s", e)
logger.log(Level.SEVERE, "Error while fetching episode description for $identifier", e)
}

return needUpdate
Expand Down Expand Up @@ -154,19 +155,11 @@ class FetchDeprecatedEpisodeJob : AbstractJob {
}

Platform.CRUN -> {
try {
httpRequest.getBrowser(
normalizeUrl(
episode.platform!!,
episode.anime!!.countryCode!!,
episode.url!!
)
)
} catch (e: Exception) {
return null
val id = getCrunchyrollId(episode.url!!) ?: return run {
logger.warning("Please update the episode URL for ${getIdentifier(episode)}")
crunchyrollExternalIdToId(httpRequest, episode, accessToken, cms)
}

val id = normalizeUrl(httpRequest.lastPageUrl!!)
CrunchyrollWrapper.getObject(episode.anime!!.countryCode!!.locale, accessToken, cms, id)[0]
}

Expand All @@ -184,7 +177,30 @@ class FetchDeprecatedEpisodeJob : AbstractJob {
}
}

fun normalizeUrl(url: String) = "/watch/([A-Z0-9]+)".toRegex().find(url)!!.groupValues[1]
@Deprecated("This method is deprecated due to Crunchyroll no redirecting to the correct page")
private suspend fun crunchyrollExternalIdToId(
httpRequest: HttpRequest,
episode: Episode,
accessToken: String,
cms: CrunchyrollWrapper.CMS
): JsonObject? {
try {
httpRequest.getBrowser(
normalizeUrl(
episode.platform!!,
episode.anime!!.countryCode!!,
episode.url!!
)
)
} catch (e: Exception) {
return null
}

val id = getCrunchyrollId(httpRequest.lastPageUrl!!) ?: return null
return CrunchyrollWrapper.getObject(episode.anime!!.countryCode!!.locale, accessToken, cms, id)[0]
}

fun getCrunchyrollId(url: String) = "/watch/([A-Z0-9]+)".toRegex().find(url)?.groupValues?.get(1)

fun normalizeTitle(platform: Platform, content: JsonObject): String? {
var title = when (platform) {
Expand Down
1 change: 1 addition & 0 deletions src/main/kotlin/fr/shikkanime/modules/Routing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ fun Application.configureRouting() {
context.response.header("X-Content-Type-Options", "nosniff")
context.response.header("Referrer-Policy", "no-referrer")
context.response.header("Permissions-Policy", "geolocation=(), microphone=()")
context.response.header("X-XSS-Protection", "1; mode=block")
}
}

Expand Down
12 changes: 9 additions & 3 deletions src/main/kotlin/fr/shikkanime/platforms/CrunchyrollPlatform.kt
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,14 @@ class CrunchyrollPlatform : AbstractPlatform<CrunchyrollConfiguration, CountryCo

val langType = if (isDubbed) LangType.VOICE else LangType.SUBTITLES

val id = requireNotNull(jsonObject.getAsString("external_id")?.split(".")?.last()) { "Id is null" }
val hash = "${countryCode}-${getPlatform()}-$id-$langType"
// @DEPRECATED
val externalId = jsonObject.getAsString("external_id")?.split(".")?.last() ?: ""
val deprecatedHash = "${countryCode}-${getPlatform()}-$externalId-$langType"
if (hashCache.contains(deprecatedHash)) throw EpisodeAlreadyReleasedException()
// @DEPRECATED

val id = requireNotNull(jsonObject.getAsString("id")) { "Id is null" }
val hash = "${countryCode}-${getPlatform()}-$id-$langType"
if (hashCache.contains(hash)) throw EpisodeAlreadyReleasedException()

val releaseDate =
Expand All @@ -316,7 +321,8 @@ class CrunchyrollPlatform : AbstractPlatform<CrunchyrollConfiguration, CountryCo
EpisodeType.EPISODE

val title = jsonObject.getAsString("title")
val url = "https://www.crunchyroll.com/media-$id"
val slugTitle = jsonObject.getAsString("slug_title")
val url = "https://www.crunchyroll.com/${countryCode.name.lowercase()}/watch/$id/$slugTitle"

val thumbnailArray = jsonObject.getAsJsonObject("images")?.getAsJsonArray("thumbnail")
val biggestImage = thumbnailArray?.get(0)?.asJsonArray?.maxByOrNull { it.asJsonObject.getAsInt("width") ?: 0 }
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/assets/css/purged/bootstrap.min.css

Large diffs are not rendered by default.

14 changes: 12 additions & 2 deletions src/main/resources/assets/js/home_chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const cpuChart = new Chart(cpuChartElement, {
{
label: '% CPU',
data: [],
backgroundColor: ['rgba(33,37,41, .2)'],
fill: false,
borderColor: ['rgba(33,37,41, 1)'],
tension: 0.1
}
Expand All @@ -30,6 +30,11 @@ const cpuChart = new Chart(cpuChartElement, {
},
animation: {
duration: 0
},
plugins: {
legend: {
display: false
}
}
}
});
Expand All @@ -42,7 +47,7 @@ const memoryChart = new Chart(memoryChartElement, {
{
label: 'RAM in MB',
data: [],
backgroundColor: ['rgba(33,37,41, .2)'],
fill: false,
borderColor: ['rgba(33,37,41, 1)'],
tension: 0.1
}
Expand All @@ -62,6 +67,11 @@ const memoryChart = new Chart(memoryChartElement, {
},
animation: {
duration: 0
},
plugins: {
legend: {
display: false
}
}
}
});
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/purgecss.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = {
content: ['**/*.ftl', '**/*.js'],
content: ['**/site/*.ftl', '**/site/**/*.ftl', '**/*.js'],
css: ['**/*.css',],
output: 'assets/css/purged',
}
2 changes: 2 additions & 0 deletions src/main/resources/templates/admin/_layout.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
overflow-x: auto;
}
</style>

<script defer src="/assets/js/alpinejs.min.js" crossorigin="anonymous"></script>
</head>
<body>
<main>
Expand Down
Loading

0 comments on commit 3faa750

Please sign in to comment.