diff --git a/config.ts b/config.ts index 82a9951..c34a160 100644 --- a/config.ts +++ b/config.ts @@ -13,6 +13,7 @@ export type ConfigType = { max_download_img_count: number; download_original_img: boolean; port: number; + export_zip_jpn_title: boolean; }; export class Config { @@ -89,6 +90,9 @@ export class Config { get port() { return this._return_number("port") || 8000; } + get export_zip_jpn_title() { + return this._return_bool("export_zip_jpn_title") || false; + } to_json(): ConfigType { return { cookies: typeof this.cookies === "string", @@ -102,6 +106,7 @@ export class Config { max_download_img_count: this.max_download_img_count, download_original_img: this.download_original_img, port: this.port, + export_zip_jpn_title: this.export_zip_jpn_title, }; } } diff --git a/islands/Settings.tsx b/islands/Settings.tsx index 85e9011..56f785c 100644 --- a/islands/Settings.tsx +++ b/islands/Settings.tsx @@ -112,6 +112,11 @@ export default class Settings extends Component { checked={settings.mpv} description={t("settings.mpv")} /> + = { } else if (d.type == "new_download_task") { t.add_download_task(d.gid, d.token); } else if (d.type == "new_export_zip_task") { - t.add_export_zip_task(d.gid, d.output); + t.add_export_zip_task(d.gid, { + output: d.output, + jpn_title: d.jpn_title, + }); } else if (d.type == "task_list") { t.get_task_list().then((tasks) => { sendMessage({ diff --git a/server/export_zip.ts b/server/export_zip.ts index 7925bf2..e8f900a 100644 --- a/server/export_zip.ts +++ b/server/export_zip.ts @@ -1,8 +1,13 @@ import { Uint8ArrayReader, ZipWriter } from "zipjs/index.js"; import { EhDb, PMeta } from "../db.ts"; +import { ExportZipConfig } from "../tasks/export_zip.ts"; import { addZero, configureZipJs } from "../utils.ts"; -export function get_export_zip_response(gid: number, db: EhDb) { +export function get_export_zip_response( + gid: number, + db: EhDb, + cfg: ExportZipConfig, +) { const gmeta = db.get_gmeta_by_gid(gid); if (!gmeta) return new Response("Gallery not found.", { status: 404 }); const pmetas = db.get_pmeta(gid).sort((a, b) => a.index - b.index); @@ -114,11 +119,14 @@ export function get_export_zip_response(gid: number, db: EhDb) { }, type: "bytes", }); + const title = (cfg.jpn_title && gmeta.title_jpn) + ? gmeta.title_jpn + : gmeta.title; return new Response(readable, { headers: { "content-type": "application/zip", "Content-Disposition": `attachment; filename="${ - encodeURIComponent(gmeta.title) + encodeURIComponent(title) }.zip"`, }, }); diff --git a/server/task.ts b/server/task.ts index 23e8217..7c0b473 100644 --- a/server/task.ts +++ b/server/task.ts @@ -1,5 +1,6 @@ import { Task } from "../task.ts"; import { TaskEventData } from "../task_manager.ts"; +import { ExportZipConfig } from "../tasks/export_zip.ts"; import { DiscriminatedUnion } from "../utils.ts"; export type TaskServerSocketData = TaskEventData | { type: "close" } | { @@ -8,9 +9,12 @@ export type TaskServerSocketData = TaskEventData | { type: "close" } | { running: number[]; }; +type Gid> = ({ gid: number } & T) extends + infer U ? { [Q in keyof U]: U[Q] } : never; + type EventMap = { new_download_task: { gid: number; token: string }; - new_export_zip_task: { gid: number; output?: string }; + new_export_zip_task: Gid; }; export type TaskClientSocketData = DiscriminatedUnion<"type", EventMap> | { diff --git a/task_manager.ts b/task_manager.ts index 91746fc..ffbe7f5 100644 --- a/task_manager.ts +++ b/task_manager.ts @@ -101,15 +101,14 @@ export class TaskManager extends EventTarget { }; return await this.#add_task(task); } - async add_export_zip_task(gid: number, output?: string) { - const cfg: ExportZipConfig = { output }; + async add_export_zip_task(gid: number, cfg?: ExportZipConfig) { const task: Task = { gid, token: "", id: 0, pid: Deno.pid, type: TaskType.ExportZip, - details: JSON.stringify(cfg), + details: JSON.stringify(cfg || DEFAULT_EXPORT_ZIP_CONFIG), }; return await this.#add_task(task); } diff --git a/tasks/export_zip.ts b/tasks/export_zip.ts index 3c7445c..08dbc27 100644 --- a/tasks/export_zip.ts +++ b/tasks/export_zip.ts @@ -13,6 +13,7 @@ import { TaskManager } from "../task_manager.ts"; export type ExportZipConfig = { output?: string; + jpn_title?: boolean; }; export const DEFAULT_EXPORT_ZIP_CONFIG: ExportZipConfig = {}; @@ -28,6 +29,9 @@ export async function export_zip( const gid = task.gid; const g = db.get_gmeta_by_gid(gid); if (!g) throw Error("Gallery not found in database."); + const jpn_title = ecfg.jpn_title !== undefined + ? ecfg.jpn_title + : cfg.export_zip_jpn_title; const progress: TaskExportZipProgress = { total_page: g.filecount, added_page: 0, @@ -39,8 +43,9 @@ export async function export_zip( }); }; sendEvent(); + const title = (jpn_title && g.title_jpn) ? g.title_jpn : g.title; const output = ecfg.output === undefined - ? join(cfg.base, filterFilename(g.title + ".zip")) + ? join(cfg.base, filterFilename(title + ".zip")) : ecfg.output; const f = await Deno.open(output, { create: true, diff --git a/translation/en/settings.jsonc b/translation/en/settings.jsonc index 018ab82..9b8ead7 100644 --- a/translation/en/settings.jsonc +++ b/translation/en/settings.jsonc @@ -18,5 +18,6 @@ "save_dlg": "Do you want to save settings?", "db_path": "The folder where the database is stored: ", "db_path_help": "If not set, the download location is used.", - "port": "Listening port: " + "port": "Listening port: ", + "export_zip_jpn_title": "Use japanese title first when exporting zip." } diff --git a/translation/zh-cn/settings.jsonc b/translation/zh-cn/settings.jsonc index 2633a56..c38faed 100644 --- a/translation/zh-cn/settings.jsonc +++ b/translation/zh-cn/settings.jsonc @@ -18,5 +18,6 @@ "save_dlg": "是否保存设置?", "db_path": "存放数据库的文件夹位置:", "db_path_help": "如果未设置,将使用下载位置。", - "port": "监听端口:" + "port": "监听端口:", + "export_zip_jpn_title": "导出Zip时优先使用日语标题。" }