@@ -3,7 +3,7 @@ import "dotenv/config";
3
3
import fs from "node:fs" ;
4
4
import { MergedCustomFormatResource } from "./src/__generated__/mergedTypes" ;
5
5
import { configureRadarrApi , configureSonarrApi , getArrApi , unsetApi } from "./src/api" ;
6
- import { getConfig } from "./src/config" ;
6
+ import { getConfig , validateConfig } from "./src/config" ;
7
7
import {
8
8
calculateCFsToManage ,
9
9
loadCFFromConfig ,
@@ -29,13 +29,21 @@ import {
29
29
transformTrashQPCFs ,
30
30
transformTrashQPToTemplate ,
31
31
} from "./src/trash-guide" ;
32
- import { ArrType , MappedMergedTemplates } from "./src/types/common.types" ;
33
- import { ConfigArrInstance , ConfigQualityProfile , YamlConfigIncludeItem } from "./src/types/config.types" ;
32
+ import { ArrType , CFProcessing , MappedMergedTemplates } from "./src/types/common.types" ;
33
+ import { ConfigQualityProfile , InputConfigArrInstance , InputConfigIncludeItem , MergedConfigInstance } from "./src/types/config.types" ;
34
34
import { TrashQualityDefintion } from "./src/types/trashguide.types" ;
35
35
import { DEBUG_CREATE_FILES , IS_DRY_RUN } from "./src/util" ;
36
36
37
- const pipeline = async ( value : ConfigArrInstance , arrType : ArrType ) => {
38
- const api = getArrApi ( ) ;
37
+ /**
38
+ * Load data from trash, recyclarr, custom configs and merge.
39
+ * Afterwards do sanitize and check against required configuration.
40
+ * @param value
41
+ * @param arrType
42
+ */
43
+ const mergeConfigsAndTemplates = async (
44
+ value : InputConfigArrInstance ,
45
+ arrType : ArrType ,
46
+ ) : Promise < { mergedCFs : CFProcessing ; config : MergedConfigInstance } > => {
39
47
const recyclarrTemplateMap = loadRecyclarrTemplates ( arrType ) ;
40
48
const trashTemplates = await loadQPFromTrash ( arrType ) ;
41
49
@@ -45,9 +53,7 @@ const pipeline = async (value: ConfigArrInstance, arrType: ArrType) => {
45
53
} ;
46
54
47
55
if ( value . include ) {
48
- logger . info ( `Found ${ value . include . length } templates to include ...` ) ;
49
-
50
- const mappedIncludes = value . include . reduce < { recyclarr : YamlConfigIncludeItem [ ] ; trash : YamlConfigIncludeItem [ ] } > (
56
+ const mappedIncludes = value . include . reduce < { recyclarr : InputConfigIncludeItem [ ] ; trash : InputConfigIncludeItem [ ] } > (
51
57
( previous , current ) => {
52
58
switch ( current . source ) {
53
59
case "TRASH" :
@@ -65,14 +71,15 @@ const pipeline = async (value: ConfigArrInstance, arrType: ArrType) => {
65
71
{ recyclarr : [ ] , trash : [ ] } ,
66
72
) ;
67
73
68
- logger . debug ( mappedIncludes . recyclarr , `Included ${ mappedIncludes . recyclarr . length } templates [recyclarr]` ) ;
69
- logger . debug ( mappedIncludes . trash , `Included ${ mappedIncludes . trash . length } templates [trash]` ) ;
74
+ logger . info (
75
+ `Found ${ value . include . length } templates to include: [recyclarr]=${ mappedIncludes . recyclarr . length } , [trash]=${ mappedIncludes . trash . length } ...` ,
76
+ ) ;
70
77
71
78
mappedIncludes . recyclarr . forEach ( ( e ) => {
72
79
const template = recyclarrTemplateMap . get ( e . template ) ;
73
80
74
81
if ( ! template ) {
75
- logger . info ( `Unknown recyclarr template requested: ${ e . template } ` ) ;
82
+ logger . warn ( `Unknown recyclarr template requested: ${ e . template } ` ) ;
76
83
return ;
77
84
}
78
85
@@ -97,7 +104,7 @@ const pipeline = async (value: ConfigArrInstance, arrType: ArrType) => {
97
104
const template = trashTemplates . get ( e . template ) ;
98
105
99
106
if ( ! template ) {
100
- logger . info ( `Unknown trash template requested: ${ e . template } ` ) ;
107
+ logger . warn ( `Unknown trash template requested: ${ e . template } ` ) ;
101
108
return ;
102
109
}
103
110
@@ -147,10 +154,21 @@ const pipeline = async (value: ConfigArrInstance, arrType: ArrType) => {
147
154
const configCFDefinition = loadCFFromConfig ( ) ;
148
155
const mergedCFs = mergeCfSources ( [ trashCFs , localFileCFs , configCFDefinition ] ) ;
149
156
150
- const idsToManage = calculateCFsToManage ( recylarrMergedTemplates ) ;
157
+ const validatedConfig = validateConfig ( recylarrMergedTemplates ) ;
158
+ return { mergedCFs : mergedCFs , config : validatedConfig } ;
159
+ } ;
160
+
161
+ const pipeline = async ( value : InputConfigArrInstance , arrType : ArrType ) => {
162
+ const api = getArrApi ( ) ;
163
+
164
+ const { config, mergedCFs } = await mergeConfigsAndTemplates ( value , arrType ) ;
165
+
166
+ const idsToManage = calculateCFsToManage ( config ) ;
151
167
152
168
logger . debug ( Array . from ( idsToManage ) , `CustomFormats to manage` ) ;
153
169
170
+ // TODO here the configs should be merged -> sanitize + check
171
+
154
172
const serverCFs = await loadServerCustomFormats ( ) ;
155
173
logger . info ( `CustomFormats on server: ${ serverCFs . length } ` ) ;
156
174
@@ -162,7 +180,7 @@ const pipeline = async (value: ConfigArrInstance, arrType: ArrType) => {
162
180
await manageCf ( mergedCFs , serverCFMapping , idsToManage ) ;
163
181
logger . info ( `CustomFormats synchronized` ) ;
164
182
165
- const qualityDefinition = recylarrMergedTemplates . quality_definition ?. type ;
183
+ const qualityDefinition = config . quality_definition ?. type ;
166
184
167
185
if ( qualityDefinition ) {
168
186
const qdSonarr = await loadQualityDefinitionFromServer ( ) ;
@@ -203,10 +221,11 @@ const pipeline = async (value: ConfigArrInstance, arrType: ArrType) => {
203
221
204
222
// merge CFs of templates and custom CFs into one mapping of QualityProfile -> CFs + Score
205
223
// TODO traversing the merged templates probably to often once should be enough. Loop once and extract a couple of different maps, arrays as needed. Future optimization.
206
- const cfToQualityProfiles = mapQualityProfiles ( mergedCFs , recylarrMergedTemplates . custom_formats , recylarrMergedTemplates ) ;
224
+ // TODO double config
225
+ const cfToQualityProfiles = mapQualityProfiles ( mergedCFs , config . custom_formats , config ) ;
207
226
208
227
// merge profiles from recyclarr templates into one
209
- const qualityProfilesMerged = recylarrMergedTemplates . quality_profiles . reduce ( ( p , c ) => {
228
+ const qualityProfilesMerged = config . quality_profiles . reduce ( ( p , c ) => {
210
229
let existingQp = p . get ( c . name ) ;
211
230
212
231
if ( ! existingQp ) {
@@ -289,42 +308,34 @@ const run = async () => {
289
308
290
309
// TODO currently this has to be run sequentially because of the centrally configured api
291
310
292
- logHeading ( `Processing Sonarr ...` ) ;
311
+ const sonarrConfig = applicationConfig . sonarr ;
293
312
294
- for ( const instanceName in applicationConfig . sonarr ) {
295
- const instance = applicationConfig . sonarr [ instanceName ] ;
296
- logger . info ( `Processing Sonarr Instance: ${ instanceName } ` ) ;
297
- await configureSonarrApi ( instance . base_url , instance . api_key ) ;
298
- await pipeline ( instance , "SONARR" ) ;
299
- unsetApi ( ) ;
300
- }
313
+ if ( sonarrConfig == null || Array . isArray ( sonarrConfig ) || typeof sonarrConfig !== "object" || Object . keys ( sonarrConfig ) . length <= 0 ) {
314
+ logHeading ( `No Sonarr instances defined.` ) ;
315
+ } else {
316
+ logHeading ( `Processing Sonarr ...` ) ;
301
317
302
- if (
303
- typeof applicationConfig . sonarr === "object" &&
304
- ! Array . isArray ( applicationConfig . sonarr ) &&
305
- applicationConfig . sonarr !== null &&
306
- Object . keys ( applicationConfig . sonarr ) . length <= 0
307
- ) {
308
- logger . info ( `No sonarr instances defined.` ) ;
318
+ for ( const [ instanceName , instance ] of Object . entries ( sonarrConfig ) ) {
319
+ logger . info ( `Processing Sonarr Instance: ${ instanceName } ` ) ;
320
+ await configureSonarrApi ( instance . base_url , instance . api_key ) ;
321
+ await pipeline ( instance , "SONARR" ) ;
322
+ unsetApi ( ) ;
323
+ }
309
324
}
310
325
311
- logHeading ( `Processing Radarr ...` ) ;
326
+ const radarrConfig = applicationConfig . radarr ;
312
327
313
- for ( const instanceName in applicationConfig . radarr ) {
314
- logger . info ( `Processing Radarr instance: ${ instanceName } ` ) ;
315
- const instance = applicationConfig . radarr [ instanceName ] ;
316
- await configureRadarrApi ( instance . base_url , instance . api_key ) ;
317
- await pipeline ( instance , "RADARR" ) ;
318
- unsetApi ( ) ;
319
- }
328
+ if ( radarrConfig == null || Array . isArray ( radarrConfig ) || typeof radarrConfig !== "object" || Object . keys ( radarrConfig ) . length <= 0 ) {
329
+ logHeading ( `No Radarr instances defined.` ) ;
330
+ } else {
331
+ logHeading ( `Processing Radarr ...` ) ;
320
332
321
- if (
322
- typeof applicationConfig . radarr === "object" &&
323
- ! Array . isArray ( applicationConfig . radarr ) &&
324
- applicationConfig . radarr !== null &&
325
- Object . keys ( applicationConfig . radarr ) . length <= 0
326
- ) {
327
- logger . info ( `No radarr instances defined.` ) ;
333
+ for ( const [ instanceName , instance ] of Object . entries ( radarrConfig ) ) {
334
+ logger . info ( `Processing Radarr Instance: ${ instanceName } ` ) ;
335
+ await configureRadarrApi ( instance . base_url , instance . api_key ) ;
336
+ await pipeline ( instance , "RADARR" ) ;
337
+ unsetApi ( ) ;
338
+ }
328
339
}
329
340
} ;
330
341
0 commit comments