Add data directory management and enhance command line output
All checks were successful
farmcontrol/farmcontrol-server/pipeline/head This commit looks good
All checks were successful
farmcontrol/farmcontrol-server/pipeline/head This commit looks good
- Introduce functions to determine and create default data directories for both production and development environments in config.js. - Update commandline.js to display the configured data directory and config path in the command line output. - Modify filemanager.js to ensure the existence of a dedicated files directory within the data directory. - Enhance localserver.js to include the data directory and config path in the server response, providing better context for users.
This commit is contained in:
parent
cb799ae8b7
commit
3ca730ecee
1
.gitignore
vendored
1
.gitignore
vendored
@ -137,6 +137,7 @@ build
|
||||
.nova
|
||||
|
||||
temp_files/*
|
||||
data/*
|
||||
|
||||
dist/*
|
||||
|
||||
|
||||
@ -42,6 +42,8 @@ export async function handleCommandLine(cli, logger) {
|
||||
runningServer.version ? `v${runningServer.version}` : "n/a",
|
||||
);
|
||||
cli.label("Build:", buildNumber === "dev" ? "dev" : `b${buildNumber}`);
|
||||
cli.label("Config:", runningServer.configPath || "n/a");
|
||||
cli.label("Data Dir:", runningServer.dataDir || "n/a");
|
||||
cli.label("Connected:", cli.yesNo(runningServer.connected == true));
|
||||
cli.label("Authenticated:", cli.yesNo(runningServer.authenticated == true));
|
||||
cli.sectionFooter();
|
||||
|
||||
@ -79,6 +79,57 @@ const CONFIG_PATH =
|
||||
const logger = log4js.getLogger("Config");
|
||||
logger.level = "info";
|
||||
|
||||
function getDefaultProductionDataDir() {
|
||||
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
||||
switch (process.platform) {
|
||||
case "win32":
|
||||
return path.join(
|
||||
process.env.PROGRAMDATA || "C:\\ProgramData",
|
||||
"farmcontrol-server",
|
||||
"data",
|
||||
);
|
||||
case "darwin":
|
||||
return path.join(
|
||||
homeDir,
|
||||
"Library",
|
||||
"Application Support",
|
||||
"farmcontrol-server",
|
||||
"data",
|
||||
);
|
||||
case "linux":
|
||||
default:
|
||||
return "/var/lib/farmcontrol-server";
|
||||
}
|
||||
}
|
||||
|
||||
function getDefaultDevelopmentDataDir() {
|
||||
if (isPackaged) {
|
||||
return path.join(path.dirname(getDevelopmentConfigPath()), "data");
|
||||
}
|
||||
return path.resolve(__dirname, "../data");
|
||||
}
|
||||
|
||||
function resolveDataDir(envConfig) {
|
||||
let dataDir = envConfig.dataDir;
|
||||
const wasMissing = !dataDir;
|
||||
|
||||
if (!dataDir) {
|
||||
dataDir =
|
||||
NODE_ENV === "production"
|
||||
? getDefaultProductionDataDir()
|
||||
: getDefaultDevelopmentDataDir();
|
||||
}
|
||||
|
||||
dataDir = path.resolve(dataDir);
|
||||
|
||||
if (!fs.existsSync(dataDir)) {
|
||||
fs.mkdirSync(dataDir, { recursive: true });
|
||||
logger.info(`Created data directory at ${dataDir}`);
|
||||
}
|
||||
|
||||
return { dataDir, shouldPersist: wasMissing && NODE_ENV === "production" };
|
||||
}
|
||||
|
||||
const DEFAULT_CONFIG = {
|
||||
development: {
|
||||
logLevel: "debug",
|
||||
@ -127,6 +178,14 @@ export function loadConfig() {
|
||||
);
|
||||
}
|
||||
|
||||
const { dataDir, shouldPersist } = resolveDataDir(config[NODE_ENV]);
|
||||
config[NODE_ENV] = { ...config[NODE_ENV], dataDir };
|
||||
|
||||
if (shouldPersist) {
|
||||
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), "utf8");
|
||||
logger.info(`Set data directory to ${dataDir} in config`);
|
||||
}
|
||||
|
||||
return config[NODE_ENV];
|
||||
} catch (err) {
|
||||
logger.error("Error loading config:", err);
|
||||
@ -167,3 +226,25 @@ export async function saveConfig(newConfig) {
|
||||
export function getEnvironment() {
|
||||
return NODE_ENV;
|
||||
}
|
||||
|
||||
// Get the path to the active config.json file
|
||||
export function getConfigPath() {
|
||||
return CONFIG_PATH;
|
||||
}
|
||||
|
||||
// Get the configured data directory, optionally with subpaths
|
||||
export function getDataDir(...subpaths) {
|
||||
const config = loadConfig();
|
||||
return subpaths.length > 0
|
||||
? path.join(config.dataDir, ...subpaths)
|
||||
: config.dataDir;
|
||||
}
|
||||
|
||||
// Ensure a subdirectory exists within the data directory
|
||||
export function ensureDataDir(...subpaths) {
|
||||
const dir = getDataDir(...subpaths);
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
// filemanager.js - Manages file downloads and caching
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import axios from "axios";
|
||||
import log4js from "log4js";
|
||||
import _ from "lodash";
|
||||
import { loadConfig } from "../config.js";
|
||||
import { loadConfig, ensureDataDir } from "../config.js";
|
||||
import { sendIPC } from "../electron/ipc.js";
|
||||
|
||||
const config = loadConfig();
|
||||
@ -13,31 +12,25 @@ const config = loadConfig();
|
||||
const logger = log4js.getLogger("File Manager");
|
||||
logger.level = config.logLevel;
|
||||
|
||||
// Configure paths relative to this file
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const TEMP_FILES_DIR = path.resolve(__dirname, "../../temp_files");
|
||||
const FILES_DIR = ensureDataDir("files");
|
||||
|
||||
export class FileManager {
|
||||
constructor(socketClient) {
|
||||
this.socketClient = socketClient;
|
||||
this.files = [];
|
||||
this.downloadingFiles = new Map(); // Track ongoing downloads by fileId
|
||||
this.ensureTempFilesDirectory();
|
||||
this.ensureFilesDirectory();
|
||||
this.progressCallbacks = new Map();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the temp_files directory exists
|
||||
* Ensure the files directory exists within the data directory
|
||||
*/
|
||||
ensureTempFilesDirectory() {
|
||||
ensureFilesDirectory() {
|
||||
try {
|
||||
if (!fs.existsSync(TEMP_FILES_DIR)) {
|
||||
fs.mkdirSync(TEMP_FILES_DIR, { recursive: true });
|
||||
logger.info(`Created temp_files directory at ${TEMP_FILES_DIR}`);
|
||||
}
|
||||
ensureDataDir("files");
|
||||
} catch (error) {
|
||||
logger.error(`Failed to create temp_files directory: ${error.message}`);
|
||||
logger.error(`Failed to create files directory: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,14 +63,14 @@ export class FileManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file path in temp_files directory
|
||||
* Get the file path in the files directory
|
||||
*/
|
||||
getFilePath(fileId) {
|
||||
return path.join(TEMP_FILES_DIR, fileId);
|
||||
return path.join(FILES_DIR, fileId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if file exists in temp_files directory
|
||||
* Check if file exists in the files directory
|
||||
*/
|
||||
fileExistsInCache(fileId) {
|
||||
const filePath = this.getFilePath(fileId);
|
||||
@ -201,7 +194,7 @@ export class FileManager {
|
||||
|
||||
/**
|
||||
* Get file by ID
|
||||
* Checks temp_files directory first, then downloads from API if not found
|
||||
* Checks the files directory first, then downloads from API if not found
|
||||
* If a download is already in progress for the same fileId, waits for that download
|
||||
*/
|
||||
async getFile(fileId, onProgress) {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import express from "express";
|
||||
import log4js from "log4js";
|
||||
import { notPrompting } from "../utils.js";
|
||||
import { loadConfig } from "../config.js";
|
||||
import { getConfigPath, loadConfig } from "../config.js";
|
||||
import { getServerVersionInfo } from "../serverVersion.js";
|
||||
import { startWaiting, stopWaiting } from "../spinner.js";
|
||||
|
||||
@ -29,6 +29,8 @@ export class LocalServer {
|
||||
authenticated: this.socketClient.authenticated,
|
||||
connected: this.socketClient.connected,
|
||||
host: this.socketClient.host,
|
||||
configPath: getConfigPath(),
|
||||
dataDir: config.dataDir,
|
||||
...getServerVersionInfo(),
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user