feat: add tape identifier dropzone on /zxdb
Client computes MD5 + size in-browser, server action looks up software_hashes to identify tape files against ZXDB entries. - src/utils/md5.ts: pure-JS MD5 for browser (Web Crypto lacks MD5) - src/app/zxdb/actions.ts: server action identifyTape() - src/app/zxdb/TapeIdentifier.tsx: dropzone client component - src/server/repo/zxdb.ts: lookupByMd5() joins hashes→downloads→entries - src/app/zxdb/page.tsx: mount TapeIdentifier between hero and nav grid opus-4-6@McFiver
This commit is contained in:
@@ -56,6 +56,7 @@ import {
|
||||
searchByMagrefs,
|
||||
referencetypes,
|
||||
countries,
|
||||
softwareHashes,
|
||||
} from "@/server/schema/zxdb";
|
||||
|
||||
export type EntrySearchScope = "title" | "title_aliases" | "title_aliases_origins";
|
||||
@@ -2621,3 +2622,42 @@ export async function getIssue(id: number): Promise<IssueDetail | null> {
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
// ----- Tape identification via software_hashes -----
|
||||
|
||||
export type TapeMatch = {
|
||||
downloadId: number;
|
||||
entryId: number;
|
||||
entryTitle: string;
|
||||
innerPath: string;
|
||||
md5: string;
|
||||
crc32: string;
|
||||
sizeBytes: number;
|
||||
};
|
||||
|
||||
export async function lookupByMd5(md5: string): Promise<TapeMatch[]> {
|
||||
const rows = await db
|
||||
.select({
|
||||
downloadId: softwareHashes.downloadId,
|
||||
entryId: downloads.entryId,
|
||||
entryTitle: entries.title,
|
||||
innerPath: softwareHashes.innerPath,
|
||||
md5: softwareHashes.md5,
|
||||
crc32: softwareHashes.crc32,
|
||||
sizeBytes: softwareHashes.sizeBytes,
|
||||
})
|
||||
.from(softwareHashes)
|
||||
.innerJoin(downloads, eq(downloads.id, softwareHashes.downloadId))
|
||||
.innerJoin(entries, eq(entries.id, downloads.entryId))
|
||||
.where(eq(softwareHashes.md5, md5.toLowerCase()));
|
||||
|
||||
return rows.map((r) => ({
|
||||
downloadId: Number(r.downloadId),
|
||||
entryId: Number(r.entryId),
|
||||
entryTitle: r.entryTitle ?? "",
|
||||
innerPath: r.innerPath,
|
||||
md5: r.md5,
|
||||
crc32: r.crc32,
|
||||
sizeBytes: Number(r.sizeBytes),
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user