Skip to content

Commit c58812e

Browse files
authored
Merge pull request #3 from raydak-labs/feat/local-templates
2 parents 330bfac + 9cb5293 commit c58812e

18 files changed

+354
-68
lines changed

.env.template

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#CONFIG_LOCATION=/app/config/config.yml
22
#SECRETS_LOCATION=/app/config/secrets.yml
3-
DRY_RUN=true
3+
DRY_RUN=true # not fully supported yet
44
LOAD_LOCAL_SAMPLES=false
55
DEBUG_CREATE_FILES=false
6+
LOG_LEVEL=info

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ Possible ideas:
6363
- [ ] Plain docker
6464
- [ ] Kubernetes
6565
- [ ] Simple Config validation
66-
- [ ] Custom recyclarr templates?
67-
- [ ] Lets say you want the same template but with a different name
66+
- [x] Local recyclarr templates to include
67+
- [ ] Clone existing templates: Lets say you want the same template but with a different name?
6868
6969
## Development
7070
@@ -110,6 +110,7 @@ services:
110110
- ./config:/app/config # Contains the config.yml and secrets.yml
111111
- ./dockerrepos:/app/repos # Cache repositories
112112
- ./custom/cfs:/app/cfs # Optional if custom formats locally provided
113+
- ./custom/templates:/app/templates # Optional if custom templates
113114
```
114115

115116
### Kubernetes

config.yml.template

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ recyclarrConfigUrl: https://github.com/recyclarr/config-templates
55

66
# Optional if you want to add custom formats locally
77
#localCustomFormatsPath: ./custom/cfs
8+
#localConfigTemplatesPath: /app/templates
89

910
sonarr:
1011
series:

docker-compose.yml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ services:
1010
- ./config:/app/config
1111
- ./dockerrepos:/app/repos
1212
- ./custom/cfs:/app/cfs
13+
- ./custom/templates:/app/templates
1314

1415
sonarr:
1516
image: lscr.io/linuxserver/sonarr:4.0.2

index.ts

+32-22
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { CustomFormatResource } from "./src/__generated__/generated-sonarr-api";
55
import { configureRadarrApi, configureSonarrApi, getArrApi, unsetApi } from "./src/api";
66
import { getConfig } from "./src/config";
77
import { calculateCFsToManage, loadLocalCfs, loadServerCustomFormats, manageCf, mergeCfSources } from "./src/custom-formats";
8+
import { logHeading, logger } from "./src/logger";
89
import { calculateQualityDefinitionDiff, loadQualityDefinitionFromServer } from "./src/quality-definitions";
910
import {
1011
calculateQualityProfilesDiff,
@@ -27,12 +28,17 @@ const pipeline = async (value: YamlConfigInstance, arrType: ArrType) => {
2728
};
2829

2930
if (value.include) {
30-
console.log(`Recyclarr Includes:\n${value.include.map((e) => e.template).join("\n")}`);
31+
logger.info(`Recyclarr includes ${value.include.length} templates`);
32+
logger.debug(
33+
value.include.map((e) => e.template),
34+
"Included templates",
35+
);
36+
3137
value.include.forEach((e) => {
3238
const template = recyclarrTemplateMap.get(e.template);
3339

3440
if (!template) {
35-
console.log(`Unknown recyclarr template requested: ${e.template}`);
41+
logger.info(`Unknown recyclarr template requested: ${e.template}`);
3642
return;
3743
}
3844

@@ -72,18 +78,18 @@ const pipeline = async (value: YamlConfigInstance, arrType: ArrType) => {
7278

7379
const idsToManage = calculateCFsToManage(recylarrMergedTemplates);
7480

75-
console.log(`Stuff to manage: ${Array.from(idsToManage)}`);
81+
logger.debug(Array.from(idsToManage), `CustomFormats to manage`);
7682

7783
const serverCFs = await loadServerCustomFormats();
78-
console.log(`CFs on server: ${serverCFs.length}`);
84+
logger.info(`CustomFormats on server: ${serverCFs.length}`);
7985

8086
const serverCFMapping = serverCFs.reduce((p, c) => {
8187
p.set(c.name!, c);
8288
return p;
8389
}, new Map<string, CustomFormatResource>());
8490

8591
await manageCf(mergedCFs, serverCFMapping, idsToManage);
86-
console.log(`CustomFormats should be in sync`);
92+
logger.info(`CustomFormats synchronized`);
8793

8894
const qualityDefinition = recylarrMergedTemplates.quality_definition?.type;
8995

@@ -109,18 +115,18 @@ const pipeline = async (value: YamlConfigInstance, arrType: ArrType) => {
109115

110116
if (changeMap.size > 0) {
111117
if (IS_DRY_RUN) {
112-
console.log("DryRun: Would update QualityDefinitions.");
118+
logger.info("DryRun: Would update QualityDefinitions.");
113119
} else {
114-
console.log(`Diffs in quality definitions found`, changeMap.values());
120+
logger.info(`Diffs in quality definitions found`, changeMap.values());
115121
await api.v3QualitydefinitionUpdateUpdate(restData as any); // Ignore types
116-
console.log(`Updated QualityDefinitions`);
122+
logger.info(`Updated QualityDefinitions`);
117123
}
118124
} else {
119-
console.log(`QualityDefinitions do not need update!`);
125+
logger.info(`QualityDefinitions do not need update!`);
120126
}
121127

122128
if (create.length > 0) {
123-
console.log(`Currently not implemented this case for quality definitions.`);
129+
logger.info(`Currently not implemented this case for quality definitions.`);
124130
}
125131
}
126132

@@ -169,29 +175,29 @@ const pipeline = async (value: YamlConfigInstance, arrType: ArrType) => {
169175
});
170176
}
171177

172-
console.log(`QPs: Create: ${create.length}, Update: ${changedQPs.length}, Unchanged: ${noChanges.length}`);
178+
logger.info(`QualityProfiles: Create: ${create.length}, Update: ${changedQPs.length}, Unchanged: ${noChanges.length}`);
173179

174180
if (!IS_DRY_RUN) {
175181
for (const element of create) {
176182
try {
177183
const newProfile = await api.v3QualityprofileCreate(element as any); // Ignore types
178-
console.log(`Created QualityProfile: ${newProfile.data.name}`);
184+
logger.info(`Created QualityProfile: ${newProfile.data.name}`);
179185
} catch (error: any) {
180186
let message;
181187

182188
if (error.response) {
183-
console.log(error.response);
189+
logger.info(error.response);
184190
// The request was made and the server responded with a status code
185191
// that falls out of the range of 2xx
186192
message = `Failed creating QualityProfile (${element.name}): Data ${JSON.stringify(error.response.data)}`;
187193
} else if (error.request) {
188194
// The request was made but no response was received
189195
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
190196
// http.ClientRequest in node.js
191-
console.log(error.request);
197+
logger.info(error.request);
192198
} else {
193199
// Something happened in setting up the request that triggered an Error
194-
console.log("Error", error.message);
200+
logger.info("Error", error.message);
195201
}
196202

197203
throw new Error(message);
@@ -201,7 +207,7 @@ const pipeline = async (value: YamlConfigInstance, arrType: ArrType) => {
201207
for (const element of changedQPs) {
202208
try {
203209
const newProfile = await api.v3QualityprofileUpdate("" + element.id, element as any); // Ignore types
204-
console.log(`Updated QualityProfile: ${newProfile.data.name}`);
210+
logger.info(`Updated QualityProfile: ${newProfile.data.name}`);
205211
} catch (error: any) {
206212
let message;
207213

@@ -213,10 +219,10 @@ const pipeline = async (value: YamlConfigInstance, arrType: ArrType) => {
213219
// The request was made but no response was received
214220
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
215221
// http.ClientRequest in node.js
216-
console.log(error.request);
222+
logger.info(error.request);
217223
} else {
218224
// Something happened in setting up the request that triggered an Error
219-
console.log("Error", error.message);
225+
logger.info("Error", error.message);
220226
}
221227

222228
throw new Error(message);
@@ -242,9 +248,11 @@ const run = async () => {
242248

243249
// TODO currently this has to be run sequentially because of the centrally configured api
244250

251+
logHeading(`Processing Sonarr ...`);
252+
245253
for (const instanceName in applicationConfig.sonarr) {
246254
const instance = applicationConfig.sonarr[instanceName];
247-
console.log(`Processing Sonarr Instance: ${instanceName}`);
255+
logger.info(`Processing Sonarr Instance: ${instanceName}`);
248256
await configureSonarrApi(instance.base_url, instance.api_key);
249257
await pipeline(instance, "SONARR");
250258
unsetApi();
@@ -256,11 +264,13 @@ const run = async () => {
256264
applicationConfig.sonarr !== null &&
257265
Object.keys(applicationConfig.sonarr).length <= 0
258266
) {
259-
console.log(`No sonarr instances defined.`);
267+
logger.info(`No sonarr instances defined.`);
260268
}
261269

270+
logHeading(`Processing Radarr ...`);
271+
262272
for (const instanceName in applicationConfig.radarr) {
263-
console.log(`Processing Radarr instance: ${instanceName}`);
273+
logger.info(`Processing Radarr instance: ${instanceName}`);
264274
const instance = applicationConfig.radarr[instanceName];
265275
await configureRadarrApi(instance.base_url, instance.api_key);
266276
await pipeline(instance, "RADARR");
@@ -273,7 +283,7 @@ const run = async () => {
273283
applicationConfig.radarr !== null &&
274284
Object.keys(applicationConfig.radarr).length <= 0
275285
) {
276-
console.log(`No radarr instances defined.`);
286+
logger.info(`No radarr instances defined.`);
277287
}
278288
};
279289

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
"axios": "^1.6.8",
1919
"dotenv": "^16.4.5",
2020
"node-ts": "^6.0.1",
21+
"pino": "^8.19.0",
22+
"pino-pretty": "^11.0.0",
2123
"simple-git": "^3.23.0",
2224
"swagger-typescript-api": "^13.0.3",
2325
"tsx": "^4.7.1",

0 commit comments

Comments
 (0)