fix: i got sick of anitomyscript, its now all an array

This commit is contained in:
ThaUnknown 2025-05-02 21:51:25 +02:00
parent 40fee5ffcc
commit 3ff14a94c6
No known key found for this signature in database
5 changed files with 42 additions and 49 deletions

View file

@ -1,6 +1,6 @@
{
"name": "ui",
"version": "6.1.13",
"version": "6.1.14",
"license": "BUSL-1.1",
"private": true,
"packageManager": "pnpm@9.14.4",

View file

@ -43,7 +43,7 @@ importers:
version: 1.0.16
anitomyscript:
specifier: github:thaunknown/anitomyscript
version: https://codeload.github.com/thaunknown/anitomyscript/tar.gz/6214b582127f16b3e50fc12b9cdb2fcf650f7aa6
version: https://codeload.github.com/thaunknown/anitomyscript/tar.gz/fc00888d69ba59258167f2fac9e86576b29863b7
bottleneck:
specifier: ^2.19.5
version: 2.19.5
@ -812,9 +812,9 @@ packages:
ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
anitomyscript@https://codeload.github.com/thaunknown/anitomyscript/tar.gz/6214b582127f16b3e50fc12b9cdb2fcf650f7aa6:
resolution: {tarball: https://codeload.github.com/thaunknown/anitomyscript/tar.gz/6214b582127f16b3e50fc12b9cdb2fcf650f7aa6}
version: 2.0.8
anitomyscript@https://codeload.github.com/thaunknown/anitomyscript/tar.gz/fc00888d69ba59258167f2fac9e86576b29863b7:
resolution: {tarball: https://codeload.github.com/thaunknown/anitomyscript/tar.gz/fc00888d69ba59258167f2fac9e86576b29863b7}
version: 2.0.10
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
@ -3212,7 +3212,7 @@ snapshots:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
anitomyscript@https://codeload.github.com/thaunknown/anitomyscript/tar.gz/6214b582127f16b3e50fc12b9cdb2fcf650f7aa6: {}
anitomyscript@https://codeload.github.com/thaunknown/anitomyscript/tar.gz/fc00888d69ba59258167f2fac9e86576b29863b7: {}
ansi-regex@5.0.1: {}

View file

@ -34,27 +34,20 @@
// termMapping.HDTV = termMapping.HDTVRIP = termMapping.TVRIP = termMapping['TV-RIP'] = { text: 'TV', color: '#ab1b31' }
// termMapping.WEBCAST = termMapping.WEBRIP = { text: 'WEB', color: '#ab1b31' }
function sanitiseTerms ({ video_term: vid, audio_term: aud, video_resolution: resolution, source: src }: AnitomyResult) {
const video = !Array.isArray(vid) ? [vid] : vid
const audio = !Array.isArray(aud) ? [aud] : aud
const source = !Array.isArray(src) ? [src] : src
const terms = [...new Set([...video, ...audio, ...source].map(term => termMapping[term?.toUpperCase()]).filter(t => t))] as Array<{text: string, color: string}>
if (resolution) terms.unshift({ text: resolution, color: '#c6ec58' })
function sanitiseTerms ({ video_term: video, audio_term: audio, video_resolution: resolution, source }: AnitomyResult) {
const terms = [...new Set([...video ?? [], ...audio ?? [], ...source ?? []].map(term => termMapping[term.toUpperCase() ?? '']).filter(t => t))] as Array<{text: string, color: string}>
if (resolution?.length) terms.unshift({ text: resolution[0]!, color: '#c6ec58' })
return terms
}
function simplifyFilename ({ video_term: vid, audio_term: aud, video_resolution: resolution, file_name: name, release_group: group, file_checksum: checksum }: AnitomyResult) {
const video = !Array.isArray(vid) ? [vid] : vid
const audio = !Array.isArray(aud) ? [aud] : aud
let simpleName = name
if (group) simpleName = simpleName.replace(group, '')
if (resolution) simpleName = simpleName.replace(resolution, '')
if (checksum) simpleName = simpleName.replace(checksum, '')
for (const term of video) simpleName = simpleName.replace(term, '')
for (const term of audio) simpleName = simpleName.replace(term, '')
function simplifyFilename ({ video_term: video, audio_term: audio, video_resolution: resolution, file_name: name, release_group: group, file_checksum: checksum }: AnitomyResult) {
let simpleName = name[0]!
if (group?.length) simpleName = simpleName.replace(group[0]!, '')
if (resolution?.length) simpleName = simpleName.replace(resolution[0]!, '')
if (checksum?.length) simpleName = simpleName.replace(checksum[0]!, '')
for (const term of video ?? []) simpleName = simpleName.replace(term[0]!, '')
for (const term of audio ?? []) simpleName = simpleName.replace(term[0]!, '')
return simpleName.replace(/[[{(]\s*[\]})]/g, '').replace(/\s+/g, ' ').trim()
}
@ -214,7 +207,7 @@
{#if search && media}
{@const { results, errors } = search}
{#each filterAndSortResults(results, inputText, downloaded) as result (result.hash)}
<div class='p-3 flex cursor-pointer mb-2 relative rounded-md overflow-hidden border border-border select:ring-1 select:ring-ring select:bg-accent select:text-accent-foreground select:scale-[1.02] select:shadow-lg scale-100 transition-all' class:opacity-40={result.accuracy === 'low'} use:click={() => play(result)} title={result.parseObject.file_name}>
<div class='p-3 flex cursor-pointer mb-2 relative rounded-md overflow-hidden border border-border select:ring-1 select:ring-ring select:bg-accent select:text-accent-foreground select:scale-[1.02] select:shadow-lg scale-100 transition-all' class:opacity-40={result.accuracy === 'low'} use:click={() => play(result)} title={result.parseObject.file_name[0]}>
{#if result.accuracy === 'high'}
<div class='absolute top-0 left-0 w-full h-full -z-10'>
<Banner {media} class='object-cover w-full h-full' />
@ -230,7 +223,7 @@
{:else if result.accuracy === 'high'}
<BadgeCheck class='mr-2 text-[#53da33]' size='1.2rem' />
{/if}
<div class='text-xl font-bold text-nowrap'>{result.parseObject.release_group && result.parseObject.release_group.length < 20 ? result.parseObject.release_group : 'No Group'}</div>
<div class='text-xl font-bold text-nowrap'>{result.parseObject.release_group[0] && result.parseObject.release_group[0].length < 20 ? result.parseObject.release_group[0] : 'No Group'}</div>
<div class='ml-auto flex gap-2 self-start'>
{#each result.extension as id (id)}
{#if $saved[id]}

View file

@ -39,14 +39,14 @@ export async function resolveFilesPoorly (promise: Promise<{media: Media, id: st
const resolvedFiles: ResolvedFile[] = videoFiles.map(file => {
return {
...file,
metadata: resolved.find(({ parseObject }) => file.name.includes(parseObject.file_name))
metadata: resolved.find(({ parseObject }) => file.name.includes(parseObject.file_name[0]!))
}
}).filter(file => file.metadata && !TYPE_EXCLUSIONS.includes(file.metadata.parseObject.anime_type?.toUpperCase() ?? '')) as ResolvedFile[] // assertion because of file metadata
}).filter(file => file.metadata && !TYPE_EXCLUSIONS.includes(file.metadata.parseObject.anime_type?.[0]?.toUpperCase() ?? '')) as ResolvedFile[] // assertion because of file metadata
let targetAnimeFiles = resolvedFiles.filter(file => file.metadata.media.id && file.metadata.media.id === list.media.id)
if (!targetAnimeFiles.length) {
const max = highestOccurence(resolvedFiles, file => file.metadata.parseObject.anime_title!).metadata.parseObject.anime_title
const max = highestOccurence(resolvedFiles, file => file.metadata.parseObject.anime_title?.[0] ?? '').metadata.parseObject.anime_title
targetAnimeFiles = resolvedFiles.filter(file => file.metadata.parseObject.anime_title === max)
}
@ -151,9 +151,9 @@ const AnimeResolver = new class AnimeResolver {
animeNameCache: Record<string, number> = {}
getCacheKeyForTitle (obj: AnitomyResult): string {
let key = obj.anime_title
if (obj.anime_year) key += obj.anime_year
return key!
let key = obj.anime_title?.[0] ?? ''
if (obj.anime_year) key += obj.anime_year[0]
return key
}
alternativeTitles (title: string): string[] {
@ -199,7 +199,7 @@ const AnimeResolver = new class AnimeResolver {
if (!parseObjects.length) return
const titleObjects = parseObjects.map(obj => {
const key = this.getCacheKeyForTitle(obj)
const titleObjects: Array<{key: string, title: string, year?: string, isAdult: boolean}> = this.alternativeTitles(obj.anime_title!).map(title => ({ title, year: obj.anime_year, key, isAdult: false }))
const titleObjects: Array<{key: string, title: string, year?: string, isAdult: boolean}> = this.alternativeTitles(obj.anime_title?.[0] ?? '').map(title => ({ title, year: obj.anime_year?.[0], key, isAdult: false }))
// @ts-expect-error cba fixing this for now, but this is correct
titleObjects.push({ ...titleObjects.at(-1), isAdult: true })
return titleObjects
@ -228,7 +228,7 @@ const AnimeResolver = new class AnimeResolver {
for (const obj of parseObjs) {
const key = this.getCacheKeyForTitle(obj)
if (key in this.animeNameCache) continue // skip already resolved
if (obj.anime_type && TYPE_EXCLUSIONS.includes(obj.anime_type.toUpperCase())) continue // skip non-episode media
if (obj.anime_type && TYPE_EXCLUSIONS.includes(obj.anime_type[0]?.toUpperCase() ?? '')) continue // skip non-episode media
uniq[key] = obj
}
await this.findAnimesByTitle(Object.values(uniq))
@ -242,31 +242,31 @@ const AnimeResolver = new class AnimeResolver {
let media = await this.getAnimeById(id)
// resolve episode, if movie, dont.
const maxep = episodes(media)
if ((media.format !== 'MOVIE' || maxep) && parseObj.episode_number) {
if (Array.isArray(parseObj.episode_number)) {
if ((media.format !== 'MOVIE' || maxep) && parseObj.episode_number.length) {
if (parseObj.episode_number.length > 1) {
// is an episode range
if (parseInt(parseObj.episode_number[0]) === 1) {
if (parseInt(parseObj.episode_number[0]!) === 1) {
// if it starts with #1 and overflows then it includes more than 1 season in a batch, cant fix this cleanly, name is parsed per file basis so this shouldnt be an issue
episode = `${parseObj.episode_number[0]} ~ ${parseObj.episode_number[1]}`
} else {
if (maxep && parseInt(parseObj.episode_number[1]) > maxep) {
if (maxep && parseInt(parseObj.episode_number[1]!) > maxep) {
// get root media to start at S1, instead of S2 or some OVA due to parsing errors
// this is most likely safe, if it was relative episodes then it would likely use an accurate title for the season
// if they didnt use an accurate title then its likely an absolute numbering scheme
// parent check is to break out of those incorrectly resolved OVA's
// if we used anime season to resolve anime name, then there's no need to march into prequel!
const prequel = !parseObj.anime_season && (this.findEdge(media, 'PREQUEL')?.node ?? ((media.format === 'OVA' || media.format === 'ONA') && this.findEdge(media, 'PARENT')?.node))
const prequel = !parseObj.anime_season[0] && (this.findEdge(media, 'PREQUEL')?.node ?? ((media.format === 'OVA' || media.format === 'ONA') && this.findEdge(media, 'PARENT')?.node))
// debug(`Prequel ${prequel?.id}:${prequel?.title.userPreferred}`)
const root = prequel && (await this.resolveSeason({ media: await this.getAnimeById(prequel.id), force: true })).media
// debug(`Root ${root?.id}:${root?.title.userPreferred}`)
// if highest value is bigger than episode count or latest streamed episode +1 for safety, parseint to math.floor a number like 12.5 - specials - in 1 go
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const result = await this.resolveSeason({ media: root || media, episode: parseObj.episode_number[1], increment: !parseObj.anime_season ? null : true })
const result = await this.resolveSeason({ media: root || media, episode: Number(parseObj.episode_number[1]!), increment: !parseObj.anime_season[0] ? null : true })
// debug(`Found rootMedia for ${parseObj.anime_title}: ${result.rootMedia.id}:${result.rootMedia.title.userPreferred} from ${media.id}:${media.title.userPreferred}`)
media = result.rootMedia
const diff = parseObj.episode_number[1] - result.episode
episode = `${parseObj.episode_number[0] - diff} ~ ${result.episode}`
const diff = Number(parseObj.episode_number[1]!) - result.episode
episode = `${Number(parseObj.episode_number[0]!) - diff} ~ ${result.episode}`
failed = !!result.failed
// if (failed) debug(`Failed to resolve ${parseObj.anime_title} ${parseObj.episode_number} ${media.title.userPreferred}`)
} else {
@ -275,16 +275,16 @@ const AnimeResolver = new class AnimeResolver {
}
}
} else {
if (maxep && parseInt(parseObj.episode_number) > maxep) {
if (maxep && parseInt(parseObj.episode_number[0]!) > maxep) {
// see big comment above
const prequel = !parseObj.anime_season && (this.findEdge(media, 'PREQUEL')?.node ?? ((media.format === 'OVA' || media.format === 'ONA') && this.findEdge(media, 'PARENT')?.node))
const prequel = !parseObj.anime_season[0] && (this.findEdge(media, 'PREQUEL')?.node ?? ((media.format === 'OVA' || media.format === 'ONA') && this.findEdge(media, 'PARENT')?.node))
// debug(`Prequel ${prequel?.id}:${prequel?.title.userPreferred}`)
const root = prequel && (await this.resolveSeason({ media: await this.getAnimeById(prequel.id), force: true })).media
// debug(`Root ${root?.id}:${root?.title.userPreferred}`)
// value bigger than episode count
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const result = await this.resolveSeason({ media: root || media, episode: parseInt(parseObj.episode_number), increment: !parseObj.anime_season ? null : true })
const result = await this.resolveSeason({ media: root || media, episode: parseInt(parseObj.episode_number[0]!), increment: !parseObj.anime_season[0] ? null : true })
// debug(`Found rootMedia for ${parseObj.anime_title}: ${result.rootMedia.id}:${result.rootMedia.title.userPreferred} from ${media.id}:${media.title.userPreferred}`)
media = result.rootMedia
episode = result.episode
@ -292,13 +292,13 @@ const AnimeResolver = new class AnimeResolver {
// if (failed) debug(`Failed to resolve ${parseObj.anime_title} ${parseObj.episode_number} ${media.title.userPreferred}`)
} else {
// cant find ep count or episode seems fine
episode = Number(parseObj.episode_number)
episode = Number(parseObj.episode_number[0])
}
}
}
// debug(`Resolved ${parseObj.anime_title} ${parseObj.episode_number} ${episode} ${media.id}:${media.title.userPreferred}`)
fileAnimes.push({
episode: episode ?? parseObj.episode_number,
episode: episode ?? parseObj.episode_number[0],
parseObject: parseObj,
media,
failed

View file

@ -142,9 +142,9 @@ export const extensions = new class Extensions {
for (const { hash, complete, downloaded, incomplete } of updated) {
const found = entries.find(mapped => mapped.hash === hash)
if (!found) continue
found.downloads = downloaded
found.leechers = incomplete
found.seeders = complete
found.downloads = Number(downloaded)
found.leechers = Number(incomplete)
found.seeders = Number(complete)
}
debug(`Found ${updated.length} entries: ${JSON.stringify(updated)}`)