- offer to create tag when none is found while adding a link from cli - fix tag display in search
207 lines
5.4 KiB
JavaScript
207 lines
5.4 KiB
JavaScript
import fs from "fs-extra";
|
|
import path from "path";
|
|
import inquirer from "inquirer";
|
|
import { fileURLToPath } from "url";
|
|
import dotenv from "dotenv";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const rootDir = path.resolve(__dirname, "..");
|
|
const CACHE_DIR = path.join(rootDir, ".cache");
|
|
const CONFIG_PATH = path.join(CACHE_DIR, "config.json");
|
|
|
|
export const MEDIA_TYPES = [
|
|
{ key: "movie", label: "movie", folder: "movies" },
|
|
{ key: "show", label: "tv show", folder: "shows" }
|
|
];
|
|
|
|
const ASSET_TYPES = ["poster", "backdrop"];
|
|
|
|
dotenv.config({ path: path.resolve(__dirname, "..", "..", ".env") });
|
|
|
|
export const initConfig = async () => {
|
|
const existingConfig = (await fs.pathExists(CONFIG_PATH)) ? await fs.readJson(CONFIG_PATH) : {};
|
|
const config = { ...existingConfig };
|
|
|
|
if (config.storageDir) {
|
|
const { updateStorage } = await inquirer.prompt([
|
|
{
|
|
type: "confirm",
|
|
name: "updateStorage",
|
|
message: `Storage directory is already set to "${config.storageDir}". Do you want to update it?`,
|
|
default: false
|
|
}
|
|
]);
|
|
|
|
if (updateStorage) {
|
|
const { storageDir } = await inquirer.prompt([
|
|
{
|
|
name: "storageDir",
|
|
message: "Where is your storage root directory?",
|
|
validate: fs.pathExists
|
|
}
|
|
]);
|
|
|
|
config.storageDir = storageDir;
|
|
}
|
|
} else {
|
|
const { storageDir } = await inquirer.prompt([
|
|
{
|
|
name: "storageDir",
|
|
message: "Where is your storage root directory?",
|
|
validate: fs.pathExists
|
|
}
|
|
]);
|
|
|
|
config.storageDir = storageDir;
|
|
}
|
|
|
|
const { customize } = await inquirer.prompt([
|
|
{
|
|
type: "confirm",
|
|
name: "customize",
|
|
message: "Do you want to customize default media paths?",
|
|
default: false
|
|
}
|
|
]);
|
|
|
|
config.mediaPaths = {};
|
|
|
|
for (const { key, label, folder } of MEDIA_TYPES) {
|
|
config.mediaPaths[key] = {};
|
|
|
|
for (const assetType of ASSET_TYPES) {
|
|
const assetFolder = assetType === "poster" ? "" : `/${assetType}s`;
|
|
const defaultPath = `Media assets/${folder}${assetFolder}`.replace(/\/$/, "");
|
|
let subpath = defaultPath;
|
|
|
|
if (customize) {
|
|
const response = await inquirer.prompt([
|
|
{
|
|
name: "subpath",
|
|
message: `Subpath for ${label}/${assetType} (relative to storage root):`,
|
|
default: defaultPath
|
|
}
|
|
]);
|
|
|
|
subpath = response.subpath;
|
|
}
|
|
|
|
config.mediaPaths[key][assetType] = subpath;
|
|
}
|
|
}
|
|
|
|
config.artistPath = customize
|
|
? (
|
|
await inquirer.prompt([
|
|
{
|
|
name: "artistPath",
|
|
message: "Subpath for artist images (relative to storage root):",
|
|
default: "Media assets/artists"
|
|
}
|
|
])
|
|
).artistPath
|
|
: "Media assets/artists";
|
|
|
|
config.albumPath = customize
|
|
? (
|
|
await inquirer.prompt([
|
|
{
|
|
name: "albumPath",
|
|
message: "Subpath for album images (relative to storage root):",
|
|
default: "Media assets/albums"
|
|
}
|
|
])
|
|
).albumPath
|
|
: "Media assets/albums";
|
|
|
|
config.bookPath = customize
|
|
? (
|
|
await inquirer.prompt([
|
|
{
|
|
name: "bookPath",
|
|
message: "Subpath for book images (relative to storage root):",
|
|
default: "Media assets/books"
|
|
}
|
|
])
|
|
).bookPath
|
|
: "Media assets/books";
|
|
|
|
if (config.directus?.apiUrl) {
|
|
const { updateApiUrl } = await inquirer.prompt([
|
|
{
|
|
type: "confirm",
|
|
name: "updateApiUrl",
|
|
message: `Directus API URL is already set to "${config.directus.apiUrl}". Do you want to update it?`,
|
|
default: false
|
|
}
|
|
]);
|
|
|
|
if (updateApiUrl) {
|
|
const { apiUrl } = await inquirer.prompt([
|
|
{
|
|
name: "apiUrl",
|
|
message: "Enter your Directus instance URL:",
|
|
validate: (input) => input.startsWith("http") || "Must be a valid URL"
|
|
}
|
|
]);
|
|
|
|
config.directus.apiUrl = apiUrl;
|
|
}
|
|
} else {
|
|
const { apiUrl } = await inquirer.prompt([
|
|
{
|
|
name: "apiUrl",
|
|
message: "Enter your Directus URL:",
|
|
validate: (input) => input.startsWith("http") || "Must be a valid URL"
|
|
}
|
|
]);
|
|
|
|
config.directus = { ...(config.directus || {}), apiUrl };
|
|
}
|
|
|
|
const globals = await fetchGlobals();
|
|
|
|
config.url = globals.url;
|
|
|
|
await fs.ensureDir(CACHE_DIR);
|
|
await fs.writeJson(CONFIG_PATH, config, { spaces: 2 });
|
|
|
|
console.log(`✅ Config saved to ${CONFIG_PATH}`);
|
|
};
|
|
|
|
export const loadConfig = async () => {
|
|
if (!(await fs.pathExists(CONFIG_PATH))) {
|
|
console.error("❌ Config not found. Run \`coryd init\` first.");
|
|
process.exit(1);
|
|
}
|
|
|
|
return await fs.readJson(CONFIG_PATH);
|
|
};
|
|
|
|
const fetchGlobals = async () => {
|
|
const POSTGREST_URL = process.env.POSTGREST_URL;
|
|
const POSTGREST_API_KEY = process.env.POSTGREST_API_KEY;
|
|
|
|
if (!POSTGREST_URL || !POSTGREST_API_KEY) {
|
|
console.warn("⚠️ Missing POSTGREST_URL or POSTGREST_API_KEY in env, skipping globals fetch.");
|
|
return {};
|
|
}
|
|
|
|
try {
|
|
const res = await fetch(`${POSTGREST_URL}/optimized_globals?select=*`, {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${POSTGREST_API_KEY}`
|
|
}
|
|
});
|
|
|
|
if (!res.ok) throw new Error(await res.text());
|
|
|
|
const data = await res.json();
|
|
return data[0] || {};
|
|
} catch (err) {
|
|
console.error("❌ Error fetching globals:", err.message);
|
|
return {};
|
|
}
|
|
};
|