diff --git a/db.ts b/db.ts index 55269ee..79b1110 100644 --- a/db.ts +++ b/db.ts @@ -63,6 +63,8 @@ export type PMeta = { type Tag = { id: number; tag: string; + translated: string | undefined; + intro: string | undefined; }; export type EhFile = { id: number; @@ -125,7 +127,9 @@ const PMETA_TABLE = `CREATE TABLE pmeta ( );`; const TAG_TABLE = `CREATE TABLE tag ( id INTEGER PRIMARY KEY AUTOINCREMENT, - tag TEXT + tag TEXT, + translated TEXT, + intro TEXT );`; const GTAG_TABLE = `CREATE TABLE gtag ( gid INT, @@ -151,7 +155,7 @@ export class EhDb { #lock_file: string | undefined; #dblock_file: string | undefined; #_tags: Map | undefined; - readonly version = new SemVer("1.0.0-0"); + readonly version = new SemVer("1.0.0-1"); constructor(base_path: string) { this.db = new DB(join(base_path, "data.db")); this.db.execute("PRAGMA main.locking_mode=EXCLUSIVE;"); @@ -190,6 +194,13 @@ export class EhDb { this.#updateExistsTable(); const v = this.#read_version(); if (!v) return false; + if (v.compare(this.version) === -1) { + if (v.compare("1.0.0-1") === -1) { + this.db.execute("ALTER TABLE tag ADD translated TEXT;"); + this.db.execute("ALTER TABLE tag ADD intro TEXT;"); + } + this.#write_version(); + } if ( ALL_TABLES.length !== this.#exist_table.size || !ALL_TABLES.every((x) => this.#exist_table.has(x)) @@ -511,4 +522,25 @@ export class EhDb { throw e; } } + update_tags(tag: string, translated: string, intro: string) { + const id = this.#tags.get(tag); + if (id === undefined) { + this.db.query( + "INSERT INTO tag (tag, translated, intro) VALUES (?, ?, ?);", + [tag, translated, intro], + ); + const r = this.db.queryEntries( + "SELECT * FROM tag WHERE tag = ?;", + [tag], + ); + this.#tags.set(tag, r[0].id); + } else { + this.db.query("INSERT OR REPLACE INTO tag VALUES (?, ?, ?, ?)", [ + id, + tag, + translated, + intro, + ]); + } + } } diff --git a/eh_translation.ts b/eh_translation.ts new file mode 100644 index 0000000..5a56512 --- /dev/null +++ b/eh_translation.ts @@ -0,0 +1,63 @@ +import { EhDb } from "./db.ts"; + +export type GHAuthor = { + name: string; + email: string; + when: string; +}; +export type EHTHeader = { + sha: string; + message: string; + author: GHAuthor; + committer: GHAuthor; +}; +export type EHTData = { + namespace: string; + frontMatters: { + name: string; + description: string; + key: string; + rules: string[]; + }; + count: number; + data: { + [x: string]: { + name: string; + intro: string; + links: string; + }; + }; +}; +export type EHTTextFile = { + version: number; + repo: string; + head: EHTHeader; + data: EHTData[]; +}; + +async function fetch_eht_file() { + const re = await fetch( + "https://github.com/EhTagTranslation/DatabaseReleases/raw/master/db.text.json", + ); + if (re.status != 200) throw Error("fetch failed"); + return re.text(); +} + +export async function load_eht_file( + location: string | undefined = undefined, +): Promise { + const s = location === undefined + ? await fetch_eht_file() + : await Deno.readTextFile(location); + return JSON.parse(s); +} + +export function update_database_tag(db: EhDb, f: EHTTextFile) { + for (const d of f.data) { + Object.getOwnPropertyNames(d.data).forEach((name) => { + const tag = `${d.namespace}:${name}`; + const t = d.data[name]; + db.update_tags(tag, t.name, t.intro); + }); + } +} diff --git a/main.ts b/main.ts index 5289409..ffb3a8a 100644 --- a/main.ts +++ b/main.ts @@ -5,6 +5,7 @@ import { AlreadyClosedError, TaskManager } from "./task_manager.ts"; import { ParsedUrl, parseUrl, UrlType } from "./url.ts"; import { sure_dir } from "./utils.ts"; import { EhDb } from "./db.ts"; +import { load_eht_file, update_database_tag } from "./eh_translation.ts"; function show_help() { console.log("Usage: main.ts [options]"); @@ -19,6 +20,7 @@ enum CMD { Download, Run, Optimize, + UpdateTagTranslation, } const args = parse(Deno.args, { @@ -38,6 +40,9 @@ let cmd = CMD.Unknown; if (rcmd == "d" || rcmd == "download") cmd = CMD.Download; if (rcmd == "r" || rcmd == "run") cmd = CMD.Run; if (rcmd == "optimize") cmd = CMD.Optimize; +if (rcmd == "utt" || rcmd == "update_tag_translation") { + cmd = CMD.UpdateTagTranslation; +} if (cmd == CMD.Unknown) { throw Error(`Unknown command: ${rcmd}`); } @@ -80,6 +85,13 @@ function optimize() { db.optimize(); db.close(); } +async function update_tag_translation() { + const db = new EhDb(settings.base); + const f = await load_eht_file( + args._.length > 1 ? args._[1].toString() : undefined, + ); + update_database_tag(db, f); +} async function main() { await sure_dir(settings.base); if (cmd == CMD.Download) { @@ -88,6 +100,8 @@ async function main() { await run(); } else if (cmd == CMD.Optimize) { optimize(); + } else if (cmd == CMD.UpdateTagTranslation) { + await update_tag_translation(); } }