Add bots files handling logic

This commit is contained in:
2026-10-21 17:56:09 +01:00
parent b0af4db1bf
commit d17a4a7bdd
97 changed files with 5843 additions and 41 deletions
@@ -0,0 +1,12 @@
import grabAppSettings from "./grab-app-settings";
type Params = {
key: string;
};
/**
* One install-wide setting, or undefined when it was never saved.
*/
export default async function grabAppSetting({ key }: Params) {
return (await grabAppSettings()).get(key);
}
@@ -0,0 +1,34 @@
import BunSQLite from "@moduletrace/bun-sqlite";
import type { BUN_SQLITE_COBBLE_APP_SETTINGS } from "@/db/types/db";
let cache: Map<string, string> | null = null;
/**
* Every install-wide setting, cached per process (like `grabAllEnvs`).
* `saveAppSetting` and `deleteAppSetting` clear it.
*/
export default async function grabAppSettings() {
if (cache) return cache;
const res = await BunSQLite.sql<BUN_SQLITE_COBBLE_APP_SETTINGS>({
sql: `SELECT key, value FROM app_settings`,
values: [],
});
const map = new Map<string, string>();
for (const row of res.payload || []) {
if (row.key) map.set(row.key, row.value || "");
}
cache = map;
return map;
}
/**
* Drops the cache, so the next read sees the database.
*/
export function clearAppSettingsCache() {
cache = null;
}
@@ -0,0 +1,25 @@
import { BotFileQuotaSettingKey } from "@/src/dict/bot-file-dict";
import { grabBotFileQuotaMb } from "../bot-files/grab-bot-file-quota-bytes";
import { grabStorageUsageByOwner, grabTotalStorageUsage } from "../bot-files/grab-storage-usage";
/**
* The General settings' bot file storage: the quota each folder gets, and
* what is used right now.
*/
export default async function grabStorageQuotaOverview() {
const [quota_mb, total, by_owner] = await Promise.all([
grabBotFileQuotaMb(),
grabTotalStorageUsage(),
grabStorageUsageByOwner(),
]);
return {
setting_key: BotFileQuotaSettingKey,
quota_mb,
total_bytes: total.bytes,
total_files: total.files,
folders: by_owner.length,
};
}
export type StorageQuotaOverview = Awaited<ReturnType<typeof grabStorageQuotaOverview>>;
@@ -0,0 +1,47 @@
import BunSQLite from "@moduletrace/bun-sqlite";
import type { BUN_SQLITE_COBBLE_APP_SETTINGS, BunSQLiteTables } from "@/db/types/db";
import { clearAppSettingsCache } from "./grab-app-settings";
type Params = {
key: string;
/**
* Null or empty removes it, so the code's default applies again.
*/
value?: string | null;
};
/**
* Saves (or removes) one install-wide setting and clears the cache, so the
* next read sees it.
*/
export default async function saveAppSetting({ key, value }: Params) {
const existing = await BunSQLite.sql<BUN_SQLITE_COBBLE_APP_SETTINGS>({
sql: `SELECT id FROM app_settings WHERE key = ? LIMIT 1`,
values: [key],
}).then((res) => res.payload?.[0]);
if (!value) {
await BunSQLite.sql({
sql: `DELETE FROM app_settings WHERE key = ?`,
values: [key],
});
clearAppSettingsCache();
return null;
}
if (existing?.id) {
await BunSQLite.sql({
sql: `UPDATE app_settings SET value = ?, updated_at = ? WHERE id = ?`,
values: [value, Date.now(), existing.id],
});
} else {
await BunSQLite.insert<BUN_SQLITE_COBBLE_APP_SETTINGS, (typeof BunSQLiteTables)[number]>({
table: "app_settings",
data: [{ key, value }],
});
}
clearAppSettingsCache();
return value;
}