From dc4db405d2991d3ec6a114f3b08d3fccd057d3ee Mon Sep 17 00:00:00 2001 From: Wolfgang Müller Date: Thu, 13 Feb 2025 17:52:16 +0100 Subject: frontend: Migrate to Svelte 5 --- frontend/src/lib/scraper/Scraper.svelte.ts | 164 +++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 frontend/src/lib/scraper/Scraper.svelte.ts (limited to 'frontend/src/lib/scraper/Scraper.svelte.ts') diff --git a/frontend/src/lib/scraper/Scraper.svelte.ts b/frontend/src/lib/scraper/Scraper.svelte.ts new file mode 100644 index 0000000..93e756b --- /dev/null +++ b/frontend/src/lib/scraper/Scraper.svelte.ts @@ -0,0 +1,164 @@ +import { + Category, + Censorship, + Direction, + Language, + Layout, + OnMissing, + Rating, + type FullComicFragment, + type ScrapedComic, + type UpsertComicInput, + type UpsertOptions +} from '$gql/graphql'; +import { + CategoryLabel, + CensorshipLabel, + DirectionLabel, + LanguageLabel, + LayoutLabel, + RatingLabel +} from '$lib/Enums'; +import { getContext, setContext } from 'svelte'; + +class ScraperContext { + scraper?: string = $state(); + warnings: string[] = $state([]); + selector?: ScrapedComicSelector = $state(); + + reset = () => { + this.selector = undefined; + this.warnings = []; + }; +} + +export function initScraperContext() { + return setContext('scraper', new ScraperContext()); +} + +export function getScraperContext() { + return getContext('scraper'); +} + +export class Selector { + keep = $state(true); + value: T; + display: string | undefined; + + constructor(value: T, display?: string) { + this.value = value; + this.display = display; + } + + toggle = () => { + this.keep = !this.keep; + }; + + toString() { + return this.display ?? this.value; + } + + static from( + scraped: T | undefined | null, + have: string | undefined | null, + label?: Record + ) { + if (scraped && have !== scraped) { + return new Selector(scraped, label ? label[scraped] : undefined); + } + return undefined; + } + + static fromList(scraped: string[], have: { name: string }[]) { + const haves = new Set(have.map((i) => i.name)); + + return scraped.filter((i) => !haves.has(i)).map((i) => new Selector(i)); + } +} + +function keepItem(selector?: Selector): T | undefined | null { + if (selector?.keep) { + return selector.value; + } + return undefined; +} + +function keepList( + selectorList: Selector[], + onMissing: OnMissing +): { names: T[]; options: UpsertOptions } { + return { + names: selectorList.filter((v) => v.keep).map((v) => v.value), + options: { onMissing } + }; +} + +export class ScrapedComicSelector { + title?: Selector; + originalTitle?: Selector; + url?: Selector; + date?: Selector; + category?: Selector; + censorship?: Selector; + rating?: Selector; + language?: Selector; + direction?: Selector; + layout?: Selector; + artists: Selector[]; + circles: Selector[]; + characters: Selector[]; + worlds: Selector[]; + tags: Selector[]; + + constructor(scraped: ScrapedComic, comic: FullComicFragment) { + this.title = Selector.from(scraped.title, comic.title); + this.originalTitle = Selector.from(scraped.originalTitle, comic.originalTitle); + this.url = Selector.from(scraped.url, comic.url); + this.date = Selector.from(scraped.date, comic.date); + this.category = Selector.from(scraped.category, comic.category, CategoryLabel); + this.censorship = Selector.from(scraped.censorship, comic.censorship, CensorshipLabel); + this.rating = Selector.from(scraped.rating, comic.rating, RatingLabel); + this.language = Selector.from(scraped.language, comic.language, LanguageLabel); + this.direction = Selector.from(scraped.direction, comic.direction, DirectionLabel); + this.layout = Selector.from(scraped.layout, comic.layout, LayoutLabel); + + this.artists = Selector.fromList(scraped.artists, comic.artists); + this.circles = Selector.fromList(scraped.circles, comic.circles); + this.characters = Selector.fromList(scraped.characters, comic.characters); + this.tags = Selector.fromList(scraped.tags, comic.tags); + this.worlds = Selector.fromList(scraped.worlds, comic.worlds); + } + + pending() { + return ( + Object.values(this).filter((i) => { + if (i === undefined) { + return false; + } else if (Array.isArray(i) && i.length === 0) { + return false; + } + return true; + }).length > 0 + ); + } + + input(onMissing: OnMissing): UpsertComicInput { + return { + title: keepItem(this.title), + originalTitle: keepItem(this.originalTitle), + url: keepItem(this.url), + date: keepItem(this.date), + category: keepItem(this.category), + censorship: keepItem(this.censorship), + rating: keepItem(this.rating), + language: keepItem(this.language), + direction: keepItem(this.direction), + layout: keepItem(this.layout), + artists: keepList(this.artists, onMissing), + circles: keepList(this.circles, onMissing), + characters: keepList(this.characters, onMissing), + worlds: keepList(this.worlds, onMissing), + tags: keepList(this.tags, onMissing) + }; + } +} -- cgit v1.2.3-2-gb3c3