Skip to content

Commit

Permalink
feat: add support for cleaning up custom formats
Browse files Browse the repository at this point in the history
- fixes #191
  • Loading branch information
BlackDark committed Feb 10, 2025
1 parent 8b75779 commit c6f0152
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 2 deletions.
6 changes: 6 additions & 0 deletions docs/docs/configuration/_include/config-file-sample.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ sonarr:
# since v1.11.0. You can disable instances. Optional
# enabled: false

# since v1.12.0. Optional
# delete_unmanaged_custom_formats:
# enabled: true
# ignore: # optional
# - some-cf

quality_definition:
type: series # Quality definition type for Sonarr

Expand Down
23 changes: 23 additions & 0 deletions docs/docs/configuration/config-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,29 @@ Notes:
- clone order will be displayed in `DEBUG` log
- **experimental**, available since `v1.10.0`

## Cleanup / Deleting CustomFormats {#cleanup-custom-formats}

You can now enable the option to delete all custom formats which are not managed and used in the quality profiles.
Additionally you can provide exceptions which should be ignored from deletions.

```yml
# ...
sonarr:
instance1:
# ...
# since v1.12.0. Optional
delete_unmanaged_custom_formats:
enabled: true
ignore: # optional
- some-cf
```

Notes:

- **experimental**, available since `v1.12.0`

## Usage

1. Create both `config.yml` and `secrets.yml` files
Expand Down
6 changes: 6 additions & 0 deletions examples/full/config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ sonarr:
# since v1.11.0, optional, for disabling instances
enabled: false

# since v1.12.0. Optional
# delete_unmanaged_custom_formats:
# enabled: true
# ignore:
# - CustomFormatToKeep

quality_definition:
type: series

Expand Down
9 changes: 9 additions & 0 deletions src/__generated__/ky-client.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,10 @@ export const mergeConfigsAndTemplates = async (
mergedTemplates.custom_formats.push(...instanceConfig.custom_formats);
}

if (instanceConfig.delete_unmanaged_custom_formats) {
mergedTemplates.delete_unmanaged_custom_formats = instanceConfig.delete_unmanaged_custom_formats;
}

if (instanceConfig.quality_profiles) {
mergedTemplates.quality_profiles.push(...instanceConfig.quality_profiles);
}
Expand Down
7 changes: 7 additions & 0 deletions src/custom-formats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ export const deleteAllCustomFormats = async () => {
}
};

export const deleteCustomFormat = async (customFormat: MergedCustomFormatResource) => {
const api = getUnifiedClient();

await api.deleteCustomFormat(customFormat.id + "");
logger.info(`Deleted CF: '${customFormat.name}'`);
};

export const loadServerCustomFormats = async (): Promise<MergedCustomFormatResource[]> => {
if (getEnvs().LOAD_LOCAL_SAMPLES) {
return loadJsonFile<MergedCustomFormatResource[]>(path.resolve(__dirname, "../tests/samples/cfs.json"));
Expand Down
30 changes: 28 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { MergedCustomFormatResource } from "./__generated__/mergedTypes";
import { ServerCache } from "./cache";
import { configureApi, getUnifiedClient, unsetApi } from "./clients/unified-client";
import { getConfig, mergeConfigsAndTemplates } from "./config";
import { calculateCFsToManage, loadCustomFormatDefinitions, loadServerCustomFormats, manageCf } from "./custom-formats";
import { calculateCFsToManage, deleteCustomFormat, loadCustomFormatDefinitions, loadServerCustomFormats, manageCf } from "./custom-formats";
import { logHeading, logInstanceHeading, logger } from "./logger";
import { calculateMediamanagementDiff, calculateNamingDiff } from "./media-management";
import { calculateQualityDefinitionDiff, loadQualityDefinitionFromServer } from "./quality-definitions";
Expand All @@ -28,7 +28,7 @@ const pipeline = async (globalConfig: InputConfigSchema, instanceConfig: InputCo

const serverCache = new ServerCache(serverQD, [], serverCFs, languages);

logger.info(`Server objects: CustomFormats ${serverCFs.length}}`);
logger.info(`Server objects: CustomFormats ${serverCFs.length}`);

const { config } = await mergeConfigsAndTemplates(globalConfig, instanceConfig, arrType);

Expand All @@ -51,6 +51,32 @@ const pipeline = async (globalConfig: InputConfigSchema, instanceConfig: InputCo
serverCache.cf = await loadServerCustomFormats();
}

if (config.delete_unmanaged_custom_formats?.enabled) {
const idToCf = mergedCFs.carrIdMapping;

const mm = Array.from(idsToManage).reduce((p, c) => {
const cfName = idToCf.get(c)?.carrConfig.name;
if (cfName != null) {
p.set(cfName, true);
}
return p;
}, new Map<string, boolean>());

config.delete_unmanaged_custom_formats.ignore?.forEach((e) => {
mm.set(e, true);
});

const cfsToDelete = serverCache.cf.filter((e) => (e.name && mm.get(e.name)) !== true);

if (cfsToDelete.length > 0) {
logger.info(`Deleting ${cfsToDelete.length} CustomFormats ...`);

for (const element of cfsToDelete) {
await deleteCustomFormat(element);
}
}
}

logger.info(`CustomFormats synchronized`);

const qualityDefinition = config.quality_definition?.type;
Expand Down
1 change: 1 addition & 0 deletions src/types/common.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export type MappedTemplates = Partial<
| "media_management"
| "media_naming"
| "media_naming_api"
| "delete_unmanaged_custom_formats"
>
>;

Expand Down
11 changes: 11 additions & 0 deletions src/types/config.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ export type InputConfigArrInstance = {
* since v1.11.0
*/
enabled?: boolean;
/**
* since v1.12.0
* Deletes all CustomFormats which are not defined in any qualityprofile
*/
delete_unmanaged_custom_formats?: {
enabled: boolean;
/**
* Names of custom formats to ignore deleting
*/
ignore?: string[];
};
quality_definition?: {
type?: string;
preferred_ratio?: number; // 0.0 - 1.0
Expand Down

0 comments on commit c6f0152

Please sign in to comment.