Add the media MCP tools and live-verified slopbot path
This commit is contained in:
@@ -135,6 +135,8 @@ CREATE TABLE IF NOT EXISTS media (
|
||||
preview_url TEXT,
|
||||
file_hash TEXT,
|
||||
preview_hash TEXT,
|
||||
file_bytes INTEGER,
|
||||
preview_bytes INTEGER,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
@@ -155,6 +157,16 @@ export class ScrapeStore {
|
||||
constructor(readonly dir: string) {
|
||||
this.db = new DatabaseSync(join(dir, "index.db"));
|
||||
this.db.exec(SCHEMA);
|
||||
this.migrate();
|
||||
}
|
||||
|
||||
/** Add columns introduced after a scrape was created. */
|
||||
private migrate(): void {
|
||||
const columns = this.db.prepare("PRAGMA table_info(media)").all() as unknown as Array<{ name: string }>;
|
||||
const names = new Set(columns.map(column => column.name));
|
||||
|
||||
if (!names.has("file_bytes")) this.db.exec("ALTER TABLE media ADD COLUMN file_bytes INTEGER");
|
||||
if (!names.has("preview_bytes")) this.db.exec("ALTER TABLE media ADD COLUMN preview_bytes INTEGER");
|
||||
}
|
||||
|
||||
close(): void {
|
||||
@@ -216,10 +228,12 @@ export class ScrapeStore {
|
||||
return added;
|
||||
}
|
||||
|
||||
/** Sum of the recorded source sizes per kind. Used by the storage bar. */
|
||||
sumBytesByKind(): Record<MediaKind, number> {
|
||||
/** Bytes actually on disk per kind (downloaded files and cached previews). */
|
||||
storedBytesByKind(): Record<MediaKind, number> {
|
||||
const rows = this.db
|
||||
.prepare("SELECT kind, COALESCE(SUM(size), 0) AS bytes FROM media GROUP BY kind")
|
||||
.prepare(
|
||||
"SELECT kind, COALESCE(SUM(COALESCE(file_bytes, 0) + COALESCE(preview_bytes, 0)), 0) AS bytes FROM media GROUP BY kind"
|
||||
)
|
||||
.all() as unknown as Array<{ kind: string; bytes: number }>;
|
||||
|
||||
const result = emptyMediaCounts();
|
||||
@@ -241,6 +255,13 @@ export class ScrapeStore {
|
||||
return result;
|
||||
}
|
||||
|
||||
getMedia(id: number): MediaRow | null {
|
||||
const row = this.db.prepare("SELECT * FROM media WHERE id = ?").get(id) as unknown as
|
||||
| MediaRow
|
||||
| undefined;
|
||||
return row ?? null;
|
||||
}
|
||||
|
||||
queryMedia(options: { kind?: MediaKind; limit?: number; offset?: number } = {}): MediaRow[] {
|
||||
const limit = Math.max(1, Math.min(options.limit ?? 50, 500));
|
||||
const offset = Math.max(0, options.offset ?? 0);
|
||||
|
||||
Reference in New Issue
Block a user