From 274c4c6489104a11f00e2051e3c671de3472cd73 Mon Sep 17 00:00:00 2001
From: schroda <50052685+schroda@users.noreply.github.com>
Date: Sun, 1 Sep 2024 03:04:34 +0200
Subject: [PATCH] Add server log file rotation settings
---
public/locales/en.json | 14 ++++++++
.../settings/text/TextSettingDialog.tsx | 14 ++++++--
.../graphql/fragments/SettingsFragments.ts | 3 ++
src/lib/graphql/generated/apollo-helpers.ts | 15 ++++++--
src/lib/graphql/generated/graphql.ts | 20 ++++++++---
src/screens/settings/ServerSettings.tsx | 36 +++++++++++++++++++
versionToServerVersionMapping.json | 2 +-
7 files changed, 94 insertions(+), 10 deletions(-)
diff --git a/public/locales/en.json b/public/locales/en.json
index 8d2e6b0d..efaa5011 100644
--- a/public/locales/en.json
+++ b/public/locales/en.json
@@ -997,6 +997,20 @@
}
},
"misc": {
+ "log_files": {
+ "file_cleanup": {
+ "title": "Log file cleanup",
+ "value": "Delete backups that are older than $t(global.date.value.label.day)"
+ },
+ "file_size": {
+ "description": "Example for possible values: 1 (bytes), 1KB (kilobytes), 1MB (megabytes), 1GB (gigabytes)",
+ "title": "Maximum log file size"
+ },
+ "total_size": {
+ "description": "$t(settings.server.misc.log_files.file_size.description)",
+ "title": "Maximum size of all log files"
+ }
+ },
"log_level": {
"graphql": {
"label": {
diff --git a/src/components/settings/text/TextSettingDialog.tsx b/src/components/settings/text/TextSettingDialog.tsx
index 810369e8..a727a9df 100644
--- a/src/components/settings/text/TextSettingDialog.tsx
+++ b/src/components/settings/text/TextSettingDialog.tsx
@@ -27,6 +27,7 @@ export type TextSettingDialogProps = {
placeholder?: string;
isDialogOpen: boolean;
setIsDialogOpen: (open: boolean) => void;
+ validate?: (value: string) => boolean;
};
export const TextSettingDialog = ({
@@ -39,10 +40,12 @@ export const TextSettingDialog = ({
placeholder = '',
isDialogOpen,
setIsDialogOpen,
+ validate = () => true,
}: TextSettingDialogProps) => {
const { t } = useTranslation();
const [dialogValue, setDialogValue] = useState(value ?? '');
+ const [isValidValue, setIsValidValue] = useState(true);
const TextFieldComponent = useMemo(() => (isPassword ? PasswordTextField : TextField), [isPassword]);
@@ -82,14 +85,21 @@ export const TextSettingDialog = ({
autoFocus
placeholder={placeholder}
value={dialogValue}
- onChange={(e) => setDialogValue(e.target.value)}
+ error={!isValidValue}
+ helperText={!isValidValue ? t('global.error.label.invalid_input') : ''}
+ onChange={(e) => {
+ const newValue = e.target.value;
+
+ setIsValidValue(validate(newValue));
+ setDialogValue(newValue);
+ }}
/>
-
diff --git a/src/lib/graphql/fragments/SettingsFragments.ts b/src/lib/graphql/fragments/SettingsFragments.ts
index cdda5e08..385b6510 100644
--- a/src/lib/graphql/fragments/SettingsFragments.ts
+++ b/src/lib/graphql/fragments/SettingsFragments.ts
@@ -60,6 +60,9 @@ export const SERVER_SETTINGS = gql`
debugLogsEnabled
gqlDebugLogsEnabled
systemTrayEnabled
+ maxLogFileSize
+ maxLogFiles
+ maxLogFolderSize
# backup
backupPath
diff --git a/src/lib/graphql/generated/apollo-helpers.ts b/src/lib/graphql/generated/apollo-helpers.ts
index 9b2cc242..8e731230 100644
--- a/src/lib/graphql/generated/apollo-helpers.ts
+++ b/src/lib/graphql/generated/apollo-helpers.ts
@@ -522,7 +522,7 @@ export type PageInfoFieldPolicy = {
hasPreviousPage?: FieldPolicy | FieldReadFunction,
startCursor?: FieldPolicy | FieldReadFunction
};
-export type PartialSettingsTypeKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadIgnoreReUploads' | 'autoDownloadNewChapters' | 'autoDownloadNewChaptersLimit' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'flareSolverrAsResponseFallback' | 'flareSolverrEnabled' | 'flareSolverrSessionName' | 'flareSolverrSessionTtl' | 'flareSolverrTimeout' | 'flareSolverrUrl' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPassword' | 'socksProxyPort' | 'socksProxyUsername' | 'socksProxyVersion' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | PartialSettingsTypeKeySpecifier)[];
+export type PartialSettingsTypeKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadIgnoreReUploads' | 'autoDownloadNewChapters' | 'autoDownloadNewChaptersLimit' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'flareSolverrAsResponseFallback' | 'flareSolverrEnabled' | 'flareSolverrSessionName' | 'flareSolverrSessionTtl' | 'flareSolverrTimeout' | 'flareSolverrUrl' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxLogFileSize' | 'maxLogFiles' | 'maxLogFolderSize' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPassword' | 'socksProxyPort' | 'socksProxyUsername' | 'socksProxyVersion' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | PartialSettingsTypeKeySpecifier)[];
export type PartialSettingsTypeFieldPolicy = {
autoDownloadAheadLimit?: FieldPolicy | FieldReadFunction,
autoDownloadIgnoreReUploads?: FieldPolicy | FieldReadFunction,
@@ -555,6 +555,9 @@ export type PartialSettingsTypeFieldPolicy = {
initialOpenInBrowserEnabled?: FieldPolicy | FieldReadFunction,
ip?: FieldPolicy | FieldReadFunction,
localSourcePath?: FieldPolicy | FieldReadFunction,
+ maxLogFileSize?: FieldPolicy | FieldReadFunction,
+ maxLogFiles?: FieldPolicy | FieldReadFunction,
+ maxLogFolderSize?: FieldPolicy | FieldReadFunction,
maxSourcesInParallel?: FieldPolicy | FieldReadFunction,
port?: FieldPolicy | FieldReadFunction,
socksProxyEnabled?: FieldPolicy | FieldReadFunction,
@@ -661,7 +664,7 @@ export type SetSourceMetaPayloadFieldPolicy = {
clientMutationId?: FieldPolicy | FieldReadFunction,
meta?: FieldPolicy | FieldReadFunction
};
-export type SettingsKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadIgnoreReUploads' | 'autoDownloadNewChapters' | 'autoDownloadNewChaptersLimit' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'flareSolverrAsResponseFallback' | 'flareSolverrEnabled' | 'flareSolverrSessionName' | 'flareSolverrSessionTtl' | 'flareSolverrTimeout' | 'flareSolverrUrl' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPassword' | 'socksProxyPort' | 'socksProxyUsername' | 'socksProxyVersion' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | SettingsKeySpecifier)[];
+export type SettingsKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadIgnoreReUploads' | 'autoDownloadNewChapters' | 'autoDownloadNewChaptersLimit' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'flareSolverrAsResponseFallback' | 'flareSolverrEnabled' | 'flareSolverrSessionName' | 'flareSolverrSessionTtl' | 'flareSolverrTimeout' | 'flareSolverrUrl' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxLogFileSize' | 'maxLogFiles' | 'maxLogFolderSize' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPassword' | 'socksProxyPort' | 'socksProxyUsername' | 'socksProxyVersion' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | SettingsKeySpecifier)[];
export type SettingsFieldPolicy = {
autoDownloadAheadLimit?: FieldPolicy | FieldReadFunction,
autoDownloadIgnoreReUploads?: FieldPolicy | FieldReadFunction,
@@ -694,6 +697,9 @@ export type SettingsFieldPolicy = {
initialOpenInBrowserEnabled?: FieldPolicy | FieldReadFunction,
ip?: FieldPolicy | FieldReadFunction,
localSourcePath?: FieldPolicy | FieldReadFunction,
+ maxLogFileSize?: FieldPolicy | FieldReadFunction,
+ maxLogFiles?: FieldPolicy | FieldReadFunction,
+ maxLogFolderSize?: FieldPolicy | FieldReadFunction,
maxSourcesInParallel?: FieldPolicy | FieldReadFunction,
port?: FieldPolicy | FieldReadFunction,
socksProxyEnabled?: FieldPolicy | FieldReadFunction,
@@ -709,7 +715,7 @@ export type SettingsFieldPolicy = {
webUIInterface?: FieldPolicy | FieldReadFunction,
webUIUpdateCheckInterval?: FieldPolicy | FieldReadFunction
};
-export type SettingsTypeKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadIgnoreReUploads' | 'autoDownloadNewChapters' | 'autoDownloadNewChaptersLimit' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'flareSolverrAsResponseFallback' | 'flareSolverrEnabled' | 'flareSolverrSessionName' | 'flareSolverrSessionTtl' | 'flareSolverrTimeout' | 'flareSolverrUrl' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPassword' | 'socksProxyPort' | 'socksProxyUsername' | 'socksProxyVersion' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | SettingsTypeKeySpecifier)[];
+export type SettingsTypeKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadIgnoreReUploads' | 'autoDownloadNewChapters' | 'autoDownloadNewChaptersLimit' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'flareSolverrAsResponseFallback' | 'flareSolverrEnabled' | 'flareSolverrSessionName' | 'flareSolverrSessionTtl' | 'flareSolverrTimeout' | 'flareSolverrUrl' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxLogFileSize' | 'maxLogFiles' | 'maxLogFolderSize' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPassword' | 'socksProxyPort' | 'socksProxyUsername' | 'socksProxyVersion' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | SettingsTypeKeySpecifier)[];
export type SettingsTypeFieldPolicy = {
autoDownloadAheadLimit?: FieldPolicy | FieldReadFunction,
autoDownloadIgnoreReUploads?: FieldPolicy | FieldReadFunction,
@@ -742,6 +748,9 @@ export type SettingsTypeFieldPolicy = {
initialOpenInBrowserEnabled?: FieldPolicy | FieldReadFunction,
ip?: FieldPolicy | FieldReadFunction,
localSourcePath?: FieldPolicy | FieldReadFunction,
+ maxLogFileSize?: FieldPolicy | FieldReadFunction,
+ maxLogFiles?: FieldPolicy | FieldReadFunction,
+ maxLogFolderSize?: FieldPolicy | FieldReadFunction,
maxSourcesInParallel?: FieldPolicy | FieldReadFunction,
port?: FieldPolicy | FieldReadFunction,
socksProxyEnabled?: FieldPolicy | FieldReadFunction,
diff --git a/src/lib/graphql/generated/graphql.ts b/src/lib/graphql/generated/graphql.ts
index da581c94..e9a60dd7 100644
--- a/src/lib/graphql/generated/graphql.ts
+++ b/src/lib/graphql/generated/graphql.ts
@@ -1474,6 +1474,9 @@ export type PartialSettingsType = Settings & {
initialOpenInBrowserEnabled?: Maybe;
ip?: Maybe;
localSourcePath?: Maybe;
+ maxLogFileSize?: Maybe;
+ maxLogFiles?: Maybe;
+ maxLogFolderSize?: Maybe;
maxSourcesInParallel?: Maybe;
port?: Maybe;
socksProxyEnabled?: Maybe;
@@ -1521,6 +1524,9 @@ export type PartialSettingsTypeInput = {
initialOpenInBrowserEnabled?: InputMaybe;
ip?: InputMaybe;
localSourcePath?: InputMaybe;
+ maxLogFileSize?: InputMaybe;
+ maxLogFiles?: InputMaybe;
+ maxLogFolderSize?: InputMaybe;
maxSourcesInParallel?: InputMaybe;
port?: InputMaybe;
socksProxyEnabled?: InputMaybe;
@@ -1892,6 +1898,9 @@ export type Settings = {
initialOpenInBrowserEnabled?: Maybe;
ip?: Maybe;
localSourcePath?: Maybe;
+ maxLogFileSize?: Maybe;
+ maxLogFiles?: Maybe;
+ maxLogFolderSize?: Maybe;
maxSourcesInParallel?: Maybe;
port?: Maybe;
socksProxyEnabled?: Maybe;
@@ -1942,6 +1951,9 @@ export type SettingsType = Settings & {
initialOpenInBrowserEnabled: Scalars['Boolean']['output'];
ip: Scalars['String']['output'];
localSourcePath: Scalars['String']['output'];
+ maxLogFileSize: Scalars['String']['output'];
+ maxLogFiles: Scalars['Int']['output'];
+ maxLogFolderSize: Scalars['String']['output'];
maxSourcesInParallel: Scalars['Int']['output'];
port: Scalars['Int']['output'];
socksProxyEnabled: Scalars['Boolean']['output'];
@@ -2745,7 +2757,7 @@ export type MangaScreenFieldsFragment = { __typename?: 'MangaType', artist?: str
export type MangaLibraryDuplicateScreenFieldsFragment = { __typename?: 'MangaType', description?: string | null, id: number, title: string, thumbnailUrl?: string | null, thumbnailUrlLastFetched?: string | null, inLibrary: boolean, initialized: boolean, sourceId: string, unreadCount: number, downloadCount: number, bookmarkCount: number, hasDuplicateChapters: boolean, chapters: { __typename?: 'ChapterNodeList', totalCount: number } };
-export type ServerSettingsFragment = { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean };
+export type ServerSettingsFragment = { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, maxLogFileSize: string, maxLogFiles: number, maxLogFolderSize: string, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean };
export type SourceBaseFieldsFragment = { __typename?: 'SourceType', id: string, name: string, displayName: string };
@@ -3099,14 +3111,14 @@ export type ResetServerSettingsMutationVariables = Exact<{
}>;
-export type ResetServerSettingsMutation = { __typename?: 'Mutation', resetSettings: { __typename?: 'ResetSettingsPayload', settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean } } };
+export type ResetServerSettingsMutation = { __typename?: 'Mutation', resetSettings: { __typename?: 'ResetSettingsPayload', settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, maxLogFileSize: string, maxLogFiles: number, maxLogFolderSize: string, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean } } };
export type UpdateServerSettingsMutationVariables = Exact<{
input: SetSettingsInput;
}>;
-export type UpdateServerSettingsMutation = { __typename?: 'Mutation', setSettings: { __typename?: 'SetSettingsPayload', settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean } } };
+export type UpdateServerSettingsMutation = { __typename?: 'Mutation', setSettings: { __typename?: 'SetSettingsPayload', settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, maxLogFileSize: string, maxLogFiles: number, maxLogFolderSize: string, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean } } };
export type GetSourceMangasFetchMutationVariables = Exact<{
input: FetchSourceMangaInput;
@@ -3466,7 +3478,7 @@ export type GetWebuiUpdateStatusQuery = { __typename?: 'Query', getWebUIUpdateSt
export type GetServerSettingsQueryVariables = Exact<{ [key: string]: never; }>;
-export type GetServerSettingsQuery = { __typename?: 'Query', settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean } };
+export type GetServerSettingsQuery = { __typename?: 'Query', settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, maxLogFileSize: string, maxLogFiles: number, maxLogFolderSize: string, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean } };
export type GetSourceBrowseQueryVariables = Exact<{
id: Scalars['LongString']['input'];
diff --git a/src/screens/settings/ServerSettings.tsx b/src/screens/settings/ServerSettings.tsx
index 0d5c1867..793fe77f 100644
--- a/src/screens/settings/ServerSettings.tsx
+++ b/src/screens/settings/ServerSettings.tsx
@@ -14,6 +14,7 @@ import ListItem from '@mui/material/ListItem';
import ListItemText from '@mui/material/ListItemText';
import Switch from '@mui/material/Switch';
import ListSubheader from '@mui/material/ListSubheader';
+import { t as translate } from 'i18next';
import { NavBarContext } from '@/components/context/NavbarContext.tsx';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import { useLocalStorage } from '@/util/useStorage.tsx';
@@ -43,6 +44,9 @@ type ServerSettingsType = Pick<
| 'debugLogsEnabled'
| 'gqlDebugLogsEnabled'
| 'systemTrayEnabled'
+ | 'maxLogFiles'
+ | 'maxLogFileSize'
+ | 'maxLogFolderSize'
| 'basicAuthEnabled'
| 'basicAuthUsername'
| 'basicAuthPassword'
@@ -66,6 +70,9 @@ const extractServerSettings = (settings: GqlServerSettings): ServerSettingsType
debugLogsEnabled: settings.debugLogsEnabled,
gqlDebugLogsEnabled: settings.gqlDebugLogsEnabled,
systemTrayEnabled: settings.systemTrayEnabled,
+ maxLogFiles: settings.maxLogFiles,
+ maxLogFileSize: settings.maxLogFileSize,
+ maxLogFolderSize: settings.maxLogFolderSize,
basicAuthEnabled: settings.basicAuthEnabled,
basicAuthUsername: settings.basicAuthUsername,
basicAuthPassword: settings.basicAuthPassword,
@@ -77,6 +84,14 @@ const extractServerSettings = (settings: GqlServerSettings): ServerSettingsType
flareSolverrAsResponseFallback: settings.flareSolverrAsResponseFallback,
});
+const getLogFilesCleanupDisplayValue = (ttl: number): string => {
+ if (ttl === 0) {
+ return translate('global.label.never');
+ }
+
+ return translate('settings.server.misc.log_files.file_cleanup.value', { days: ttl, count: ttl });
+};
+
export const ServerSettings = () => {
const { t } = useTranslation();
const { setTitle, setAction } = useContext(NavBarContext);
@@ -408,6 +423,27 @@ export const ServerSettings = () => {
onChange={(e) => updateSetting('systemTrayEnabled', e.target.checked)}
/>
+ updateSetting('maxLogFiles', maxFiles)}
+ />
+ !!value.match(/^[0-9]+(|kb|KB|mb|MB|gb|GB)$/g)}
+ handleChange={(maxLogFileSize) => updateSetting('maxLogFileSize', maxLogFileSize)}
+ />
+ !!value.match(/^[0-9]+(|kb|KB|mb|MB|gb|GB)$/g)}
+ handleChange={(maxLogFolderSize) => updateSetting('maxLogFolderSize', maxLogFolderSize)}
+ />
);
diff --git a/versionToServerVersionMapping.json b/versionToServerVersionMapping.json
index 5e9fdd0d..9b30321c 100644
--- a/versionToServerVersionMapping.json
+++ b/versionToServerVersionMapping.json
@@ -1,7 +1,7 @@
[
{
"uiVersion": "PREVIEW",
- "serverVersion": "r1548"
+ "serverVersion": "r1566"
},
{
"tag": "v1.1.0",