Skip to content

Commit

Permalink
Merge pull request #230 from Shikkanime/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
Ziedelth authored Mar 1, 2024
2 parents 2071dc0 + 3a8a065 commit b422f96
Show file tree
Hide file tree
Showing 41 changed files with 318 additions and 452 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,7 @@ class AdminConfigController {
@AdminSessionAuthenticated
private fun postConfig(@PathParam("uuid") uuid: UUID, @BodyParam parameters: Parameters): Response {
configService.update(uuid, parameters)

Constant.abstractSocialNetworks.forEach {
it.logout()
it.login()
}

Constant.abstractSocialNetworks.forEach { it.logout() }
return Response.redirect(Link.CONFIG.href)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,15 @@ class EpisodeController : HasPageableRoute() {
@QueryParam("desc") descParam: String?,
): Response {
val (page, limit, sortParameters) = pageableRoute(pageParam, limitParam, sortParam, descParam)
return Response.ok(episodeCacheService.findAllBy(CountryCode.fromNullable(countryParam) ?: CountryCode.FR, animeParam, sortParameters, page, limit))
return Response.ok(
episodeCacheService.findAllBy(
CountryCode.fromNullable(countryParam) ?: CountryCode.FR,
animeParam,
sortParameters,
page,
limit
)
)
}

@Path("/{uuid}/media-image")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ enum class ConfigPropertyKey(val key: String) {
THREADS_USERNAME("threads_username"),
THREADS_PASSWORD("threads_password"),
THREADS_MESSAGE("threads_message"),
BSKY_MESSAGE("bsky_message"),
BSKY_SESSION_TIMEOUT("bsky_session_timeout"),
THREADS_SESSION_TIMEOUT("threads_session_timeout"),
}
9 changes: 8 additions & 1 deletion src/main/kotlin/fr/shikkanime/entities/enums/Link.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ package fr.shikkanime.entities.enums

import fr.shikkanime.utils.Constant

enum class Link(var href: String, val template: String, val icon: String, val label: String, val title: String = label, val footer: Boolean = false) {
enum class Link(
var href: String,
val template: String,
val icon: String,
val label: String,
val title: String = label,
val footer: Boolean = false
) {
// Admin
DASHBOARD("/admin/dashboard", "/admin/dashboard.ftl", "bi bi-pc-display", "Dashboard"),
PLATFORMS("/admin/platforms", "/admin/platforms/list.ftl", "bi bi-display", "Platforms"),
Expand Down
19 changes: 16 additions & 3 deletions src/main/kotlin/fr/shikkanime/jobs/FetchDeprecatedEpisodeJob.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ class FetchDeprecatedEpisodeJob : AbstractJob {

val takeSize = configCacheService.getValueAsInt(ConfigPropertyKey.FETCH_OLD_EPISODE_DESCRIPTION_SIZE, 0)
val now = ZonedDateTime.now().withSecond(0).withNano(0).withUTC()
val deprecatedDateTime = now.minusDays(configCacheService.getValueAsInt(ConfigPropertyKey.FETCH_DEPRECATED_EPISODE_DATE, 30).toLong())
val deprecatedDateTime = now.minusDays(
configCacheService.getValueAsInt(ConfigPropertyKey.FETCH_DEPRECATED_EPISODE_DATE, 30).toLong()
)
val crunchyrollEpisodes = episodeService.findAllByPlatformDeprecatedEpisodes(Platform.CRUN, deprecatedDateTime)
val adnEpisodes = episodeService.findAllByPlatformDeprecatedEpisodes(Platform.ANIM, deprecatedDateTime)
val episodes = (crunchyrollEpisodes + adnEpisodes).shuffled().take(takeSize)
Expand Down Expand Up @@ -134,11 +136,22 @@ class FetchDeprecatedEpisodeJob : AbstractJob {
}
}

private suspend fun normalizeContent(episode: Episode, httpRequest: HttpRequest, accessToken: String, cms: CrunchyrollWrapper.CMS): JsonObject? {
private suspend fun normalizeContent(
episode: Episode,
httpRequest: HttpRequest,
accessToken: String,
cms: CrunchyrollWrapper.CMS
): JsonObject? {
return when (episode.platform) {
Platform.CRUN -> {
try {
httpRequest.getBrowser(normalizeUrl(episode.platform!!, episode.anime!!.countryCode!!, episode.url!!))
httpRequest.getBrowser(
normalizeUrl(
episode.platform!!,
episode.anime!!.countryCode!!,
episode.url!!
)
)
} catch (e: Exception) {
return null
}
Expand Down
15 changes: 12 additions & 3 deletions src/main/kotlin/fr/shikkanime/modules/Routing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,12 @@ private suspend fun handleMultipartResponse(call: ApplicationCall, response: Res
call.respondBytes(map["image"] as ByteArray, map["contentType"] as ContentType)
}

private suspend fun handleTemplateResponse(call: ApplicationCall, controller: Any, replacedPath: String, response: Response) {
private suspend fun handleTemplateResponse(
call: ApplicationCall,
controller: Any,
replacedPath: String,
response: Response
) {
val configCacheService = Constant.injector.getInstance(ConfigCacheService::class.java)
val simulcastCacheService = Constant.injector.getInstance(SimulcastCacheService::class.java)

Expand Down Expand Up @@ -288,7 +293,8 @@ private suspend fun handleTemplateResponse(call: ApplicationCall, controller: An
} ?: Constant.NAME

modelMap["seoDescription"] = configCacheService.getValueAsString(ConfigPropertyKey.SEO_DESCRIPTION)
configCacheService.getValueAsString(ConfigPropertyKey.GOOGLE_SITE_VERIFICATION_ID)?.let { modelMap["googleSiteVerification"] = it }
configCacheService.getValueAsString(ConfigPropertyKey.GOOGLE_SITE_VERIFICATION_ID)
?.let { modelMap["googleSiteVerification"] = it }
simulcastCacheService.currentSimulcast?.let { modelMap["currentSimulcast"] = it }

call.respond(response.status, FreeMarkerContent(map["template"] as String, modelMap, "", response.contentType))
Expand Down Expand Up @@ -341,7 +347,10 @@ private fun handleQueryParam(kParameter: KParameter, call: ApplicationCall): Any
Int::class.starProjectedType.withNullability(true) -> queryParamValue?.toIntOrNull()
String::class.starProjectedType.withNullability(true) -> queryParamValue
CountryCode::class.starProjectedType.withNullability(true) -> CountryCode.fromNullable(queryParamValue)
UUID::class.starProjectedType.withNullability(true) -> if (queryParamValue.isNullOrBlank()) null else UUID.fromString(queryParamValue)
UUID::class.starProjectedType.withNullability(true) -> if (queryParamValue.isNullOrBlank()) null else UUID.fromString(
queryParamValue
)

else -> throw Exception("Unknown type ${kParameter.type}")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ class AnimationDigitalNetworkPlatform :
val show = requireNotNull(jsonObject.getAsJsonObject("show")) { "Show is null" }
val season = jsonObject.getAsString("season")?.toIntOrNull() ?: 1

var animeName = requireNotNull(show.getAsString("shortTitle") ?: show.getAsString("title")) { "Anime name is null" }
var animeName =
requireNotNull(show.getAsString("shortTitle") ?: show.getAsString("title")) { "Anime name is null" }
animeName = animeName.replace(Regex("Saison \\d"), "").trim()
animeName = animeName.replace(season.toString(), "").trim()
animeName = animeName.replace(Regex(" -.*"), "").trim()
Expand All @@ -71,7 +72,12 @@ class AnimationDigitalNetworkPlatform :
val genres = show.getAsJsonArray("genres") ?: JsonArray()

val contains = configuration!!.simulcasts.map { it.name.lowercase() }.contains(animeName.lowercase())
if ((genres.isEmpty || !genres.any { it.asString.startsWith("Animation ", true) }) && !contains) throw Exception("Anime is not an animation")
if ((genres.isEmpty || !genres.any {
it.asString.startsWith(
"Animation ",
true
)
}) && !contains) throw Exception("Anime is not an animation")

var isSimulcasted = show.getAsBoolean("simulcast") == true ||
show.getAsString("firstReleaseYear") in (0..1).map { (zonedDateTime.year - it).toString() } ||
Expand All @@ -90,7 +96,10 @@ class AnimationDigitalNetworkPlatform :
val releaseDate = ZonedDateTime.parse(releaseDateString)

val numberAsString = jsonObject.getAsString("shortNumber")
if (numberAsString?.startsWith("Bande-annonce") == true || numberAsString?.startsWith("Bande annonce") == true || numberAsString?.startsWith("Court-métrage") == true) throw Exception(
if (numberAsString?.startsWith("Bande-annonce") == true || numberAsString?.startsWith("Bande annonce") == true || numberAsString?.startsWith(
"Court-métrage"
) == true
) throw Exception(
"Anime is a trailer"
)

Expand All @@ -102,7 +111,8 @@ class AnimationDigitalNetworkPlatform :
else -> EpisodeType.EPISODE
}

if (numberAsString?.contains(".") == true || show.getAsString("type") == "OAV") episodeType = EpisodeType.SPECIAL
if (numberAsString?.contains(".") == true || show.getAsString("type") == "OAV") episodeType =
EpisodeType.SPECIAL

val id = jsonObject.getAsInt("id")
val title = jsonObject.getAsString("name")?.ifBlank { null }
Expand Down
23 changes: 16 additions & 7 deletions src/main/kotlin/fr/shikkanime/platforms/CrunchyrollPlatform.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ class CrunchyrollPlatform : AbstractPlatform<CrunchyrollConfiguration, CountryCo

if (configCacheService.getValueAsBoolean(ConfigPropertyKey.USE_CRUNCHYROLL_API)) {
val accessToken = identifiers[it]!!.first
val simulcasts = runBlocking { CrunchyrollWrapper.getSimulcasts(it.locale, accessToken) }.take(2).map { simulcast -> simulcast.getAsString("id") }
val simulcasts = runBlocking { CrunchyrollWrapper.getSimulcasts(it.locale, accessToken) }.take(2)
.map { simulcast -> simulcast.getAsString("id") }

val series = simulcasts.flatMap { simulcastId ->
runBlocking {
Expand Down Expand Up @@ -79,7 +80,8 @@ class CrunchyrollPlatform : AbstractPlatform<CrunchyrollConfiguration, CountryCo
val currentSimulcastCode = getSimulcastCode(currentSimulcast)
logger.info("Current simulcast code for $it: $currentSimulcast > $currentSimulcastCode")
val currentSimulcastAnimes =
currentSimulcastContent.select(simulcastAnimesSelector).map { a -> a.text().lowercase() }.toSet()
currentSimulcastContent.select(simulcastAnimesSelector).map { a -> a.text().lowercase() }
.toSet()
logger.info("Found ${currentSimulcastAnimes.size} animes for the current simulcast")

val previousSimulcastCode = getPreviousSimulcastCode(currentSimulcastCode)
Expand All @@ -90,7 +92,8 @@ class CrunchyrollPlatform : AbstractPlatform<CrunchyrollConfiguration, CountryCo
simulcastSelector
)
val previousSimulcastAnimes =
previousSimulcastContent.select(simulcastAnimesSelector).map { a -> a.text().lowercase() }.toSet()
previousSimulcastContent.select(simulcastAnimesSelector).map { a -> a.text().lowercase() }
.toSet()
logger.info("Found ${previousSimulcastAnimes.size} animes for the previous simulcast")

val combinedSimulcasts = (currentSimulcastAnimes + previousSimulcastAnimes).toSet()
Expand Down Expand Up @@ -277,14 +280,17 @@ class CrunchyrollPlatform : AbstractPlatform<CrunchyrollConfiguration, CountryCo
val animeName = requireNotNull(episodeMetadata.getAsString("series_title")) { "Anime name is null" }
if (configuration!!.blacklistedSimulcasts.contains(animeName.lowercase())) throw AnimeException("\"$animeName\" is blacklisted")

val eligibleRegion = requireNotNull(episodeMetadata.getAsString("eligible_region")) { "Eligible region is null" }
val eligibleRegion =
requireNotNull(episodeMetadata.getAsString("eligible_region")) { "Eligible region is null" }
if (!eligibleRegion.contains(countryCode.name)) throw EpisodeNotAvailableInCountryException("Episode of $animeName is not available in ${countryCode.name}")

val audio = episodeMetadata.getAsString("audio_locale")?.takeIf { it.isNotBlank() }
val isDubbed = audio == countryCode.locale
val subtitles = episodeMetadata.getAsJsonArray("subtitle_locales").map { it.asString!! }

if (!isDubbed && (subtitles.isEmpty() || !subtitles.contains(countryCode.locale))) throw EpisodeNoSubtitlesOrVoiceException("Episode is not available in ${countryCode.name} with subtitles or voice")
if (!isDubbed && (subtitles.isEmpty() || !subtitles.contains(countryCode.locale))) throw EpisodeNoSubtitlesOrVoiceException(
"Episode is not available in ${countryCode.name} with subtitles or voice"
)

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

Expand All @@ -294,7 +300,9 @@ class CrunchyrollPlatform : AbstractPlatform<CrunchyrollConfiguration, CountryCo
if (hashCache.contains(hash)) throw EpisodeAlreadyReleasedException()

val releaseDate =
requireNotNull(episodeMetadata.getAsString("premium_available_date")?.let { ZonedDateTime.parse(it) }) { "Release date is null" }
requireNotNull(
episodeMetadata.getAsString("premium_available_date")
?.let { ZonedDateTime.parse(it) }) { "Release date is null" }

val season = episodeMetadata.getAsInt("season_number") ?: 1
val number = episodeMetadata.getAsInt("episode_number") ?: -1
Expand All @@ -317,7 +325,8 @@ class CrunchyrollPlatform : AbstractPlatform<CrunchyrollConfiguration, CountryCo

var duration = episodeMetadata.getAsLong("duration_ms", -1000) / 1000

val checkCrunchyrollSimulcasts = configCacheService.getValueAsBoolean(ConfigPropertyKey.CHECK_CRUNCHYROLL_SIMULCASTS, true)
val checkCrunchyrollSimulcasts =
configCacheService.getValueAsBoolean(ConfigPropertyKey.CHECK_CRUNCHYROLL_SIMULCASTS, true)
val isConfigurationSimulcast = configuration!!.simulcasts.any { it.name.lowercase() == animeName.lowercase() }

if (checkCrunchyrollSimulcasts && !(isConfigurationSimulcast || simulcasts[countryCode]!!.contains(animeName.lowercase())))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class DisneyPlusPlatform :
?.getAsJsonObject("series")?.getAsJsonObject("default")?.getAsString("url")
?: throw Exception("Anime image is null")
val animeDescription = descriptions?.getAsJsonObject("series")
?.getAsJsonObject("default")?.getAsString("content")?.replace('\n', ' ') ?: ""
?.getAsJsonObject("default")?.getAsString("content")?.replace('\n', ' ') ?: ""

val season = jsonObject.getAsInt("seasonSequenceNumber")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import java.io.File
import java.time.LocalTime
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.util.*

class PrimeVideoPlatform :
AbstractPlatform<PrimeVideoConfiguration, CountryCodePrimeVideoSimulcastKeyCache, Set<Episode>>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,11 @@ class AnimeRepository : AbstractRepository<Anime>() {

fun findAllByLikeName(countryCode: CountryCode, name: String?): List<Anime> {
return inTransaction {
createReadOnlyQuery(it, "FROM Anime WHERE countryCode = :countryCode AND LOWER(name) LIKE :name", getEntityClass())
createReadOnlyQuery(
it,
"FROM Anime WHERE countryCode = :countryCode AND LOWER(name) LIKE :name",
getEntityClass()
)
.setParameter("countryCode", countryCode)
.setParameter("name", "%${name?.lowercase()}%")
.resultList
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package fr.shikkanime.repositories
import fr.shikkanime.entities.Member
import fr.shikkanime.entities.enums.Role
import org.hibernate.Hibernate
import java.util.UUID
import java.util.*

class MemberRepository : AbstractRepository<Member>() {
private fun Member.initialize(): Member {
Expand Down Expand Up @@ -31,7 +31,11 @@ class MemberRepository : AbstractRepository<Member>() {

fun findByUsernameAndPassword(username: String, password: ByteArray): Member? {
return inTransaction {
createReadOnlyQuery(it, "FROM Member WHERE username = :username AND encryptedPassword = :password", getEntityClass())
createReadOnlyQuery(
it,
"FROM Member WHERE username = :username AND encryptedPassword = :password",
getEntityClass()
)
.setParameter("username", username)
.setParameter("password", password)
.resultList
Expand Down
3 changes: 2 additions & 1 deletion src/main/kotlin/fr/shikkanime/services/EpisodeService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ class EpisodeService : AbstractService<Episode, EpisodeRepository>() {

override fun save(entity: Episode): Episode {
val copy = entity.anime!!.copy()
val anime = animeService.findAllByLikeName(copy.countryCode!!, copy.name!!).firstOrNull() ?: animeService.save(copy)
val anime =
animeService.findAllByLikeName(copy.countryCode!!, copy.name!!).firstOrNull() ?: animeService.save(copy)

if (anime.banner.isNullOrBlank() && !copy.banner.isNullOrBlank()) {
anime.banner = copy.banner
Expand Down
7 changes: 6 additions & 1 deletion src/main/kotlin/fr/shikkanime/services/ImageService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,12 @@ object ImageService {
file.writeBytes(FileManager.toGzip(ObjectParser.toJson(cache).toByteArray()))
}

logger.info("Saved images cache part in $take ms (${toHumanReadable(cache.sumOf { it.originalSize })} -> ${toHumanReadable(cache.sumOf { it.size })})")
logger.info(
"Saved images cache part in $take ms (${toHumanReadable(cache.sumOf { it.originalSize })} -> ${
toHumanReadable(
cache.sumOf { it.size })
})"
)
}

fun add(uuid: UUID, type: Type, url: String, width: Int, height: Int) {
Expand Down
8 changes: 7 additions & 1 deletion src/main/kotlin/fr/shikkanime/services/MemberService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@ class MemberService : AbstractService<Member, MemberRepository>() {
check(adminUsers.isEmpty()) { "Admin user already exists" }
val password = RandomManager.generateRandomString(32)
logger.info("Default admin password: $password")
save(Member(username = "admin", encryptedPassword = EncryptionManager.generate(password), roles = mutableSetOf(Role.ADMIN)))
save(
Member(
username = "admin",
encryptedPassword = EncryptionManager.generate(password),
roles = mutableSetOf(Role.ADMIN)
)
)
return password
}
}
3 changes: 2 additions & 1 deletion src/main/kotlin/fr/shikkanime/services/SimulcastService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ class SimulcastService : AbstractService<Simulcast, SimulcastRepository>() {

override fun getRepository() = simulcastRepository

override fun findAll() = super.findAll().sortedWith(compareBy({ it.year }, { Constant.seasons.indexOf(it.season) })).reversed()
override fun findAll() =
super.findAll().sortedWith(compareBy({ it.year }, { Constant.seasons.indexOf(it.season) })).reversed()

fun findBySeasonAndYear(season: String, year: Int) = simulcastRepository.findBySeasonAndYear(season, year)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ class AnimeCacheService : AbstractCacheService {
)
}

private val findAllByNameCache = MapCache<CountryCodeNamePaginationKeyCache, PageableDto<AnimeDto>>(classes = listOf(Anime::class.java)) {
PageableDto.fromPageable(
animeService.findAllByName(it.name, it.countryCode, it.page, it.limit),
AnimeDto::class.java
)
}
private val findAllByNameCache =
MapCache<CountryCodeNamePaginationKeyCache, PageableDto<AnimeDto>>(classes = listOf(Anime::class.java)) {
PageableDto.fromPageable(
animeService.findAllByName(it.name, it.countryCode, it.page, it.limit),
AnimeDto::class.java
)
}

private val findBySlugCache = MapCache<String, AnimeDto>(classes = listOf(Anime::class.java)) {
AbstractConverter.convert(animeService.findBySlug(it), AnimeDto::class.java)
Expand Down
Loading

0 comments on commit b422f96

Please sign in to comment.