Use config instead of constants, other review commetns

This commit is contained in:
Danielv123 committed 2025-04-13 18:00:52 +02:00
1 parent c6f10e2195
commit 25099c03ba
4 files changed
+35 -35

No files matched your search

+4 -7
View File
@@ -524,7 +524,8 @@ export default class ControlConnection extends BaseConnection {
const cacheKey = `${request.factorioVersion}-${request.hide_deprecated}`;
const cachedData = this._controller.modPortalCache.get(cacheKey);
if (cachedData && Date.now() - cachedData.timestamp < Controller.MOD_PORTAL_CACHE_DURATION) {
const cacheDuration = this._controller.config.get("controller.mod_portal_cache_duration_minutes") * 60 * 1000;
if (cachedData && Date.now() - cachedData.timestamp < cacheDuration) {
return new lib.ModPortalGetAllRequest.Response(cachedData.data);
}
@@ -532,6 +533,7 @@ export default class ControlConnection extends BaseConnection {
logger.info(`Fetching mod portal data for ${cacheKey}`);
const mods = await lib.ModStore.fetchAllModsFromPortal(
request.factorioVersion,
this._controller.config.get("controller.mod_portal_page_size"),
request.hide_deprecated
);
this._controller.modPortalCache.set(cacheKey, { timestamp: Date.now(), data: mods });
@@ -555,7 +557,6 @@ export default class ControlConnection extends BaseConnection {
// Check if mod already exists
if (this._controller.modStore.files.has(filename)) {
logger.verbose(`Mod ${filename} already exists, skipping download.`);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return this._controller.modStore.files.get(filename)!;
}
@@ -564,11 +565,7 @@ export default class ControlConnection extends BaseConnection {
const token = this._controller.config.get("controller.factorio_token");
if (!username || !token) {
// Attempt download without credentials - might fail for some mods
logger.warn(`Factorio username or token not configured. Attempting anonymous download for ${filename}.`);
// Note: The Factorio Mod Portal API might reject downloads without credentials.
// Consider throwing an error here if credentials are required by your setup.
// throw new lib.RequestError("Factorio credentials (username, token) not configured on the controller.");
throw new lib.RequestError("Factorio credentials (username, token) not configured on the controller.");
}
try {
-4
View File
@@ -97,12 +97,8 @@ export default class Controller {
clusterLogBuildInterval: ReturnType<typeof setInterval> | null = null;
// Cache for mod portal requests
static MOD_PORTAL_CACHE_DURATION = 30 * 60 * 1000; // 30 minutes
modPortalCache = new Map<string, { timestamp: number, data: any[] }>();
/** @type {?module:lib.ProcessConnector} */
process = null;
static async bootstrap(config: lib.ControllerConfig) {
let databaseDirectory = config.get("controller.database_directory");
await fs.ensureDir(databaseDirectory);
+17 -24
View File
@@ -64,9 +64,6 @@ interface ModPortalResponse {
results: ModDetails[];
}
const MOD_PORTAL_API_URL = "https://mods.factorio.com/api/mods";
const MOD_PORTAL_MAX_PAGE_SIZE = 1000; // Or largest allowed by API
export default class ModStore extends TypedEventEmitter<keyof ModStoreEvents, ModStoreEvents> {
constructor(
public modsDirectory: string,
@@ -188,35 +185,33 @@ export default class ModStore extends TypedEventEmitter<keyof ModStoreEvents, Mo
private async downloadModFromReleases(releases: Array<ModRelease>, version: string,
username: string, token: string
) {
if (releases.length === 0) { return; }
const selectedRelease = releases.find(release => release.version === version);
const latestRelease = releases.find(release => release.version === version);
if (latestRelease === undefined) {
if (selectedRelease === undefined) {
logger.warn(`Mod release matching version ${version} not found.`);
return;
}
try {
const url = new URL(`https://mods.factorio.com/${latestRelease.download_url}`);
const url = new URL(`https://mods.factorio.com/${selectedRelease.download_url}`);
url.searchParams.set("username", username);
url.searchParams.set("token", token);
const tempFileName = `${this.modsDirectory}/${latestRelease.file_name}.tmp`;
const finalFileName = `${this.modsDirectory}/${latestRelease.file_name}`;
const tempFileName = `${this.modsDirectory}/${selectedRelease.file_name}.tmp`;
const finalFileName = `${this.modsDirectory}/${selectedRelease.file_name}`;
await ModStore.downloadFile(url, tempFileName);
await fs.rename(tempFileName, finalFileName);
await this.loadFile(latestRelease.file_name);
await this.loadFile(selectedRelease.file_name);
} catch (err: any) {
logger.error(`Failed to download or load mod ${latestRelease.file_name} (${version}): ${err.message}`);
logger.error(`Failed to download or load mod ${selectedRelease.file_name} (${version}): ${err.message}`);
// Attempt to clean up temp file if it exists
try {
const tempFileName = `${this.modsDirectory}/${latestRelease.file_name}.tmp`;
const tempFileName = `${this.modsDirectory}/${selectedRelease.file_name}.tmp`;
await fs.unlink(tempFileName);
} catch (unlinkErr: any) {
if (unlinkErr.code !== "ENOENT") { // Ignore if file doesn't exist
logger.warn(`Failed to clean up temp file ${latestRelease.file_name}.tmp: ${unlinkErr.message}`);
logger.warn(`Failed to clean up temp file ${selectedRelease.file_name}.tmp: ${unlinkErr.message}`);
}
}
}
@@ -322,11 +317,13 @@ export default class ModStore extends TypedEventEmitter<keyof ModStoreEvents, Mo
* Handles pagination automatically to retrieve the complete list.
*
* @param factorioVersion - The Factorio version to fetch mods for (e.g., "1.1").
* @param pageSize - The page size for fetching mods.
* @param hide_deprecated - Whether to exclude deprecated mods.
* @returns An array of mod details.
*/
static async fetchAllModsFromPortal(
factorioVersion: string,
pageSize: number,
hide_deprecated: boolean = false
): Promise<ModDetails[]> {
logger.info(`Fetching all mods for Factorio version ${factorioVersion}...`);
@@ -335,8 +332,8 @@ export default class ModStore extends TypedEventEmitter<keyof ModStoreEvents, Mo
let hasMorePages = true;
while (hasMorePages) {
const url = new URL(MOD_PORTAL_API_URL);
url.searchParams.set("page_size", String(MOD_PORTAL_MAX_PAGE_SIZE));
const url = new URL("https://mods.factorio.com/api/mods");
url.searchParams.set("page_size", String(pageSize));
url.searchParams.set("version", factorioVersion);
url.searchParams.set("page", String(currentPage));
url.searchParams.set("hide_deprecated", String(hide_deprecated));
@@ -345,16 +342,12 @@ export default class ModStore extends TypedEventEmitter<keyof ModStoreEvents, Mo
const response = await fetch(url.toString());
if (!response.ok) {
let errorDetail = "";
try {
errorDetail = await response.text();
} catch (bodyError) {
logger.warn("Failed to read response body for failed portal request");
}
let errorMessage = `Mod portal fetch page ${currentPage} failed: `;
errorMessage += `${response.status} ${response.statusText}`;
if (errorDetail) {
errorMessage += ` - ${errorDetail}`;
try {
errorMessage += ` - ${await response.text()}`;
} catch (bodyError) {
logger.warn("Failed to read response body for failed portal request");
}
throw new Error(errorMessage);
}
+14
View File
@@ -26,6 +26,8 @@ export interface ControllerConfigFields {
"controller.default_mod_pack_id": number | null;
"controller.default_role_id": number | null;
"controller.autosave_interval": number;
"controller.mod_portal_cache_duration_minutes": number;
"controller.mod_portal_page_size": number;
}
/**
@@ -197,6 +199,18 @@ export class ControllerConfig extends classes.Config<ControllerConfigFields> {
optional: true,
initialValue: 1,
},
"controller.mod_portal_cache_duration_minutes": {
title: "Mod Portal Cache Duration",
description: "Duration in minutes to cache mod portal API responses.",
type: "number",
initialValue: 30,
},
"controller.mod_portal_page_size": {
title: "Mod Portal Page Size",
description: "Maximum number of results per page when querying the Factorio mod portal API.",
type: "number",
initialValue: 1000,
},
};
}