@muhammedaksam/easiarr 1.4.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +29837 -0
- package/package.json +15 -15
- package/src/VersionInfo.ts +0 -12
- package/src/api/arr-api.ts +0 -521
- package/src/api/auto-setup-types.ts +0 -64
- package/src/api/base-api.ts +0 -216
- package/src/api/bazarr-api.ts +0 -297
- package/src/api/cloudflare-api.ts +0 -493
- package/src/api/custom-format-api.ts +0 -224
- package/src/api/grafana-api.ts +0 -230
- package/src/api/heimdall-api.ts +0 -141
- package/src/api/homarr-api.ts +0 -209
- package/src/api/huntarr-api.ts +0 -457
- package/src/api/index.ts +0 -9
- package/src/api/jellyfin-api.ts +0 -389
- package/src/api/jellyseerr-api.ts +0 -559
- package/src/api/maintainerr-api.ts +0 -461
- package/src/api/naming-config.ts +0 -101
- package/src/api/overseerr-api.ts +0 -392
- package/src/api/plex-api.ts +0 -308
- package/src/api/portainer-api.ts +0 -374
- package/src/api/profilarr-api.ts +0 -391
- package/src/api/prowlarr-api.ts +0 -488
- package/src/api/qbittorrent-api.ts +0 -300
- package/src/api/quality-profile-api.ts +0 -272
- package/src/api/tautulli-api.ts +0 -244
- package/src/api/uptime-kuma-api.ts +0 -343
- package/src/apps/categories.ts +0 -14
- package/src/apps/index.ts +0 -2
- package/src/apps/registry.ts +0 -1275
- package/src/compose/caddy-config.ts +0 -130
- package/src/compose/generator.ts +0 -287
- package/src/compose/index.ts +0 -7
- package/src/compose/templates.ts +0 -78
- package/src/compose/traefik-config.ts +0 -187
- package/src/config/bookmarks-generator.ts +0 -160
- package/src/config/defaults.ts +0 -37
- package/src/config/homepage-config.ts +0 -381
- package/src/config/index.ts +0 -6
- package/src/config/manager.ts +0 -150
- package/src/config/recyclarr-config.ts +0 -181
- package/src/config/schema.ts +0 -310
- package/src/config/slskd-config.ts +0 -86
- package/src/config/soularr-config.ts +0 -105
- package/src/config/trash-quality-definitions.ts +0 -213
- package/src/data/lidarr-custom-formats.ts +0 -127
- package/src/data/trash-profiles.ts +0 -333
- package/src/docker/client.ts +0 -312
- package/src/docker/index.ts +0 -18
- package/src/index.ts +0 -77
- package/src/setup/actions/arr-common.ts +0 -307
- package/src/setup/actions/dashboards.ts +0 -79
- package/src/setup/actions/download-clients.ts +0 -54
- package/src/setup/actions/jellyseerr.ts +0 -331
- package/src/setup/actions/media-servers.ts +0 -68
- package/src/setup/actions/monitoring.ts +0 -120
- package/src/setup/actions/prowlarr.ts +0 -137
- package/src/setup/actions/utilities.ts +0 -490
- package/src/setup/index.ts +0 -78
- package/src/setup/types.ts +0 -144
- package/src/structure/manager.ts +0 -129
- package/src/ui/App.ts +0 -111
- package/src/ui/components/ApplicationSelector.ts +0 -275
- package/src/ui/components/CredentialsForm.ts +0 -180
- package/src/ui/components/DownloadClientForm.ts +0 -114
- package/src/ui/components/FileEditor.ts +0 -91
- package/src/ui/components/FooterHint.ts +0 -119
- package/src/ui/components/PageLayout.ts +0 -160
- package/src/ui/components/UpdateNotification.ts +0 -102
- package/src/ui/index.ts +0 -7
- package/src/ui/screens/AdvancedSettings.ts +0 -188
- package/src/ui/screens/ApiKeyViewer.ts +0 -511
- package/src/ui/screens/AppConfigurator.ts +0 -543
- package/src/ui/screens/AppManager.ts +0 -284
- package/src/ui/screens/ContainerControl.ts +0 -581
- package/src/ui/screens/LogsViewer.ts +0 -478
- package/src/ui/screens/MainMenu.ts +0 -299
- package/src/ui/screens/MonitorDashboard.ts +0 -881
- package/src/ui/screens/SecretsEditor.ts +0 -216
- package/src/ui/screens/SettingsScreen.ts +0 -633
- package/src/ui/screens/index.ts +0 -22
- package/src/ui/screens/setup/BaseAppSetupScreen.ts +0 -375
- package/src/ui/screens/setup/CloudflaredSetup.ts +0 -460
- package/src/ui/screens/setup/FullAutoSetup.ts +0 -766
- package/src/ui/screens/setup/HomepageSetup.ts +0 -165
- package/src/ui/screens/setup/JellyfinSetup.ts +0 -328
- package/src/ui/screens/setup/JellyseerrSetup.ts +0 -242
- package/src/ui/screens/setup/ProwlarrSetup.ts +0 -500
- package/src/ui/screens/setup/QBittorrentSetup.ts +0 -221
- package/src/ui/screens/setup/QuickSetup.ts +0 -1169
- package/src/ui/screens/setup/RecyclarrSetup.ts +0 -270
- package/src/ui/screens/setup/TRaSHProfileSetup.ts +0 -381
- package/src/utils/arch.ts +0 -78
- package/src/utils/browser.ts +0 -27
- package/src/utils/categories.ts +0 -61
- package/src/utils/debug.ts +0 -84
- package/src/utils/env.ts +0 -138
- package/src/utils/index.ts +0 -8
- package/src/utils/logs.ts +0 -119
- package/src/utils/migrations/1765626338_rename_env_variables.ts +0 -102
- package/src/utils/migrations/1765707135_rename_easiarr_status.ts +0 -91
- package/src/utils/migrations/1765732722_remove_cloudflare_dns_api_token.ts +0 -45
- package/src/utils/migrations/1769515650_migrate_to_xdg.ts +0 -114
- package/src/utils/migrations.ts +0 -165
- package/src/utils/password.ts +0 -42
- package/src/utils/paths.ts +0 -33
- package/src/utils/unraid.ts +0 -103
- package/src/utils/update-checker.ts +0 -210
- package/src/utils/url-utils.ts +0 -38
package/src/api/huntarr-api.ts
DELETED
|
@@ -1,457 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Huntarr API Client
|
|
3
|
-
* Provides health check, version info, and auto-setup for Huntarr
|
|
4
|
-
* Configures Sonarr, Radarr, Lidarr, Readarr, Whisparr instances automatically
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { AutoSetupOptions, AutoSetupResult, IAutoSetupClient } from "./auto-setup-types"
|
|
8
|
-
import type { AppConfig } from "~/config/schema"
|
|
9
|
-
import { BaseApiClient } from "./base-api"
|
|
10
|
-
|
|
11
|
-
interface HuntarrVersion {
|
|
12
|
-
version: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
interface TestConnectionResult {
|
|
16
|
-
success: boolean
|
|
17
|
-
message?: string
|
|
18
|
-
version?: string
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface HuntarrInstance {
|
|
22
|
-
name: string
|
|
23
|
-
api_url: string
|
|
24
|
-
api_key: string
|
|
25
|
-
enabled?: boolean
|
|
26
|
-
[key: string]: unknown
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
interface HuntarrAppSettings {
|
|
30
|
-
instances?: HuntarrInstance[]
|
|
31
|
-
[key: string]: unknown
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const HUNTARR_APP_TYPES = ["sonarr", "radarr", "lidarr", "readarr", "whisparr"] as const
|
|
35
|
-
type HuntarrAppType = (typeof HUNTARR_APP_TYPES)[number]
|
|
36
|
-
|
|
37
|
-
export class HuntarrClient extends BaseApiClient implements IAutoSetupClient {
|
|
38
|
-
protected readonly logPrefix = "HuntarrApi"
|
|
39
|
-
private sessionCookie: string | null = null
|
|
40
|
-
|
|
41
|
-
constructor(host: string, port: number = 9705) {
|
|
42
|
-
super(host, port)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
private getHeaders(): Record<string, string> {
|
|
46
|
-
const headers: Record<string, string> = {
|
|
47
|
-
"Content-Type": "application/json",
|
|
48
|
-
Accept: "application/json",
|
|
49
|
-
}
|
|
50
|
-
if (this.sessionCookie) {
|
|
51
|
-
headers["Cookie"] = `huntarr_session=${this.sessionCookie}`
|
|
52
|
-
}
|
|
53
|
-
return headers
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async userExists(): Promise<boolean> {
|
|
57
|
-
try {
|
|
58
|
-
const response = await fetch(`${this.baseUrl}/api/setup/status`, {
|
|
59
|
-
method: "GET",
|
|
60
|
-
signal: AbortSignal.timeout(5000),
|
|
61
|
-
})
|
|
62
|
-
const data = await response.json()
|
|
63
|
-
return data.user_exists === true
|
|
64
|
-
} catch {
|
|
65
|
-
return false
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async createUser(username: string, password: string): Promise<boolean> {
|
|
70
|
-
try {
|
|
71
|
-
const response = await fetch(`${this.baseUrl}/setup`, {
|
|
72
|
-
method: "POST",
|
|
73
|
-
headers: { "Content-Type": "application/json" },
|
|
74
|
-
body: JSON.stringify({
|
|
75
|
-
username,
|
|
76
|
-
password,
|
|
77
|
-
confirm_password: password,
|
|
78
|
-
}),
|
|
79
|
-
signal: AbortSignal.timeout(10000),
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
if (response.ok) {
|
|
83
|
-
const setCookie = response.headers.get("set-cookie")
|
|
84
|
-
if (setCookie) {
|
|
85
|
-
const match = setCookie.match(/huntarr_session=([^;]+)/)
|
|
86
|
-
if (match) {
|
|
87
|
-
this.sessionCookie = match[1]
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
await this.completeSetup(username)
|
|
91
|
-
await this.enableLocalAccessBypass()
|
|
92
|
-
return true
|
|
93
|
-
}
|
|
94
|
-
} catch {
|
|
95
|
-
// Ignore
|
|
96
|
-
}
|
|
97
|
-
return false
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
async enableLocalAccessBypass(): Promise<boolean> {
|
|
101
|
-
try {
|
|
102
|
-
const response = await fetch(`${this.baseUrl}/api/settings/general`, {
|
|
103
|
-
method: "POST",
|
|
104
|
-
headers: this.getHeaders(),
|
|
105
|
-
body: JSON.stringify({ local_access_bypass: true }),
|
|
106
|
-
signal: AbortSignal.timeout(10000),
|
|
107
|
-
})
|
|
108
|
-
return response.ok
|
|
109
|
-
} catch {
|
|
110
|
-
return false
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
async completeSetup(username: string): Promise<boolean> {
|
|
115
|
-
try {
|
|
116
|
-
const progress = {
|
|
117
|
-
current_step: 6,
|
|
118
|
-
completed_steps: [1, 2, 3, 4, 5],
|
|
119
|
-
account_created: true,
|
|
120
|
-
two_factor_enabled: false,
|
|
121
|
-
plex_setup_done: false,
|
|
122
|
-
auth_mode_selected: false,
|
|
123
|
-
recovery_key_generated: true,
|
|
124
|
-
username,
|
|
125
|
-
timestamp: new Date().toISOString(),
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const saveResponse = await fetch(`${this.baseUrl}/api/setup/progress`, {
|
|
129
|
-
method: "POST",
|
|
130
|
-
headers: this.getHeaders(),
|
|
131
|
-
body: JSON.stringify({ progress }),
|
|
132
|
-
signal: AbortSignal.timeout(5000),
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
if (!saveResponse.ok) return false
|
|
136
|
-
|
|
137
|
-
const clearResponse = await fetch(`${this.baseUrl}/api/setup/clear`, {
|
|
138
|
-
method: "POST",
|
|
139
|
-
headers: this.getHeaders(),
|
|
140
|
-
signal: AbortSignal.timeout(5000),
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
return clearResponse.ok
|
|
144
|
-
} catch {
|
|
145
|
-
return false
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
async login(username: string, password: string): Promise<boolean> {
|
|
150
|
-
try {
|
|
151
|
-
const response = await fetch(`${this.baseUrl}/login`, {
|
|
152
|
-
method: "POST",
|
|
153
|
-
headers: { "Content-Type": "application/json" },
|
|
154
|
-
body: JSON.stringify({ username, password }),
|
|
155
|
-
signal: AbortSignal.timeout(10000),
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
if (response.ok) {
|
|
159
|
-
const setCookie = response.headers.get("set-cookie")
|
|
160
|
-
if (setCookie) {
|
|
161
|
-
const match = setCookie.match(/huntarr_session=([^;]+)/)
|
|
162
|
-
if (match) {
|
|
163
|
-
this.sessionCookie = match[1]
|
|
164
|
-
return true
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
const data = await response.json()
|
|
168
|
-
return data.success === true
|
|
169
|
-
}
|
|
170
|
-
} catch {
|
|
171
|
-
// Ignore
|
|
172
|
-
}
|
|
173
|
-
return false
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
async authenticate(username: string, password: string): Promise<boolean> {
|
|
177
|
-
const exists = await this.userExists()
|
|
178
|
-
|
|
179
|
-
if (!exists) {
|
|
180
|
-
return await this.createUser(username, password)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const loggedIn = await this.login(username, password)
|
|
184
|
-
if (loggedIn) {
|
|
185
|
-
await this.enableLocalAccessBypass()
|
|
186
|
-
}
|
|
187
|
-
return loggedIn
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
async isHealthy(): Promise<boolean> {
|
|
191
|
-
try {
|
|
192
|
-
const response = await fetch(`${this.baseUrl}/health`, {
|
|
193
|
-
method: "GET",
|
|
194
|
-
signal: AbortSignal.timeout(5000),
|
|
195
|
-
})
|
|
196
|
-
return response.ok
|
|
197
|
-
} catch {
|
|
198
|
-
return false
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
async isInitialized(): Promise<boolean> {
|
|
203
|
-
return this.isHealthy()
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
async getVersion(): Promise<string | null> {
|
|
207
|
-
try {
|
|
208
|
-
const response = await fetch(`${this.baseUrl}/api/version`, {
|
|
209
|
-
method: "GET",
|
|
210
|
-
signal: AbortSignal.timeout(5000),
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
if (response.ok) {
|
|
214
|
-
const data = (await response.json()) as HuntarrVersion
|
|
215
|
-
return data.version
|
|
216
|
-
}
|
|
217
|
-
} catch {
|
|
218
|
-
// Ignore
|
|
219
|
-
}
|
|
220
|
-
return null
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
async testConnection(
|
|
224
|
-
appType: HuntarrAppType,
|
|
225
|
-
apiUrl: string,
|
|
226
|
-
apiKey: string
|
|
227
|
-
): Promise<TestConnectionResult> {
|
|
228
|
-
try {
|
|
229
|
-
const response = await fetch(`${this.baseUrl}/api/${appType}/test-connection`, {
|
|
230
|
-
method: "POST",
|
|
231
|
-
headers: { "Content-Type": "application/json" },
|
|
232
|
-
body: JSON.stringify({
|
|
233
|
-
api_url: apiUrl,
|
|
234
|
-
api_key: apiKey,
|
|
235
|
-
api_timeout: 30,
|
|
236
|
-
}),
|
|
237
|
-
signal: AbortSignal.timeout(35000),
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
return (await response.json()) as TestConnectionResult
|
|
241
|
-
} catch (error) {
|
|
242
|
-
return { success: false, message: `${error}` }
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
async getSettings(appType: HuntarrAppType): Promise<HuntarrAppSettings | null> {
|
|
247
|
-
try {
|
|
248
|
-
const response = await fetch(`${this.baseUrl}/api/settings/${appType}`, {
|
|
249
|
-
method: "GET",
|
|
250
|
-
headers: this.getHeaders(),
|
|
251
|
-
signal: AbortSignal.timeout(10000),
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
if (response.ok) {
|
|
255
|
-
return (await response.json()) as HuntarrAppSettings
|
|
256
|
-
}
|
|
257
|
-
} catch {
|
|
258
|
-
// Ignore
|
|
259
|
-
}
|
|
260
|
-
return null
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
async saveSettings(appType: HuntarrAppType, settings: HuntarrAppSettings): Promise<boolean> {
|
|
264
|
-
try {
|
|
265
|
-
const response = await fetch(`${this.baseUrl}/api/settings/${appType}`, {
|
|
266
|
-
method: "POST",
|
|
267
|
-
headers: this.getHeaders(),
|
|
268
|
-
body: JSON.stringify(settings),
|
|
269
|
-
signal: AbortSignal.timeout(10000),
|
|
270
|
-
})
|
|
271
|
-
return response.ok
|
|
272
|
-
} catch {
|
|
273
|
-
return false
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
async addArrInstance(
|
|
278
|
-
appType: HuntarrAppType,
|
|
279
|
-
name: string,
|
|
280
|
-
apiUrl: string,
|
|
281
|
-
apiKey: string
|
|
282
|
-
): Promise<boolean> {
|
|
283
|
-
try {
|
|
284
|
-
const settings = await this.getSettings(appType)
|
|
285
|
-
|
|
286
|
-
if (!settings) {
|
|
287
|
-
return await this.saveSettings(appType, {
|
|
288
|
-
instances: [{ name, api_url: apiUrl, api_key: apiKey, enabled: true }],
|
|
289
|
-
})
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if (!settings.instances) settings.instances = []
|
|
293
|
-
|
|
294
|
-
const existingByUrl = settings.instances.find((i) => i.api_url === apiUrl && i.api_key)
|
|
295
|
-
if (existingByUrl) return true
|
|
296
|
-
|
|
297
|
-
const emptyInstance = settings.instances.find((i) => !i.api_url || !i.api_key)
|
|
298
|
-
if (emptyInstance) {
|
|
299
|
-
emptyInstance.name = name
|
|
300
|
-
emptyInstance.api_url = apiUrl
|
|
301
|
-
emptyInstance.api_key = apiKey
|
|
302
|
-
emptyInstance.enabled = true
|
|
303
|
-
} else {
|
|
304
|
-
settings.instances.push({
|
|
305
|
-
name,
|
|
306
|
-
api_url: apiUrl,
|
|
307
|
-
api_key: apiKey,
|
|
308
|
-
enabled: true,
|
|
309
|
-
})
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return await this.saveSettings(appType, settings)
|
|
313
|
-
} catch {
|
|
314
|
-
return false
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
async setup(options: AutoSetupOptions): Promise<AutoSetupResult> {
|
|
319
|
-
const { env } = options
|
|
320
|
-
const results: Array<{ app: string; success: boolean; message?: string }> = []
|
|
321
|
-
|
|
322
|
-
try {
|
|
323
|
-
const healthy = await this.isHealthy()
|
|
324
|
-
if (!healthy) {
|
|
325
|
-
return { success: false, message: "Huntarr not reachable" }
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
const version = await this.getVersion()
|
|
329
|
-
|
|
330
|
-
const { getApp } = await import("../apps/registry")
|
|
331
|
-
|
|
332
|
-
for (const appType of HUNTARR_APP_TYPES) {
|
|
333
|
-
const apiKeyEnvName = `API_KEY_${appType.toUpperCase()}`
|
|
334
|
-
const apiKey = env[apiKeyEnvName]
|
|
335
|
-
|
|
336
|
-
if (!apiKey) continue
|
|
337
|
-
|
|
338
|
-
const appDef = getApp(appType)
|
|
339
|
-
const port = appDef?.defaultPort ?? 8989
|
|
340
|
-
const apiUrl = `http://${appType}:${port}`
|
|
341
|
-
|
|
342
|
-
const result = await this.testConnection(appType, apiUrl, apiKey)
|
|
343
|
-
results.push({
|
|
344
|
-
app: appType,
|
|
345
|
-
success: result.success,
|
|
346
|
-
message: result.message,
|
|
347
|
-
})
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
const successCount = results.filter((r) => r.success).length
|
|
351
|
-
const failCount = results.filter((r) => !r.success).length
|
|
352
|
-
|
|
353
|
-
if (results.length === 0) {
|
|
354
|
-
return {
|
|
355
|
-
success: true,
|
|
356
|
-
message: "No *arr apps configured with API keys",
|
|
357
|
-
data: { version },
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
if (failCount === 0) {
|
|
362
|
-
return {
|
|
363
|
-
success: true,
|
|
364
|
-
message: `All ${successCount} *arr connections verified`,
|
|
365
|
-
data: { version, results },
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
return {
|
|
370
|
-
success: successCount > 0,
|
|
371
|
-
message: `${successCount} succeeded, ${failCount} failed.`,
|
|
372
|
-
data: { version, results },
|
|
373
|
-
}
|
|
374
|
-
} catch (error) {
|
|
375
|
-
return { success: false, message: `${error}` }
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
async setupEasiarrApps(
|
|
380
|
-
apps: AppConfig[],
|
|
381
|
-
env: Record<string, string>
|
|
382
|
-
): Promise<{
|
|
383
|
-
added: number
|
|
384
|
-
skipped: number
|
|
385
|
-
results: Array<{ app: string; success: boolean; message?: string }>
|
|
386
|
-
}> {
|
|
387
|
-
const results: Array<{ app: string; success: boolean; message?: string }> = []
|
|
388
|
-
const { getApp } = await import("../apps/registry")
|
|
389
|
-
|
|
390
|
-
for (const appConfig of apps) {
|
|
391
|
-
if (!appConfig.enabled) continue
|
|
392
|
-
if (!HUNTARR_APP_TYPES.includes(appConfig.id as HuntarrAppType)) continue
|
|
393
|
-
|
|
394
|
-
const appType = appConfig.id as HuntarrAppType
|
|
395
|
-
const apiKey = env[`API_KEY_${appType.toUpperCase()}`]
|
|
396
|
-
|
|
397
|
-
if (!apiKey) continue
|
|
398
|
-
|
|
399
|
-
const appDef = getApp(appType)
|
|
400
|
-
const port = appDef?.defaultPort ?? 8989
|
|
401
|
-
const apiUrl = `http://${appType}:${port}`
|
|
402
|
-
const instanceName = appDef?.name ?? appType
|
|
403
|
-
|
|
404
|
-
const added = await this.addArrInstance(appType, instanceName, apiUrl, apiKey)
|
|
405
|
-
results.push({
|
|
406
|
-
app: appType,
|
|
407
|
-
success: added,
|
|
408
|
-
message: added ? "Added to Huntarr" : "Failed to add",
|
|
409
|
-
})
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
const prowlarrConfig = apps.find((a) => a.id === "prowlarr" && a.enabled)
|
|
413
|
-
if (prowlarrConfig) {
|
|
414
|
-
const prowlarrApiKey = env["API_KEY_PROWLARR"]
|
|
415
|
-
if (prowlarrApiKey) {
|
|
416
|
-
const prowlarrDef = getApp("prowlarr")
|
|
417
|
-
const prowlarrPort = prowlarrConfig.port || prowlarrDef?.defaultPort || 9696
|
|
418
|
-
const prowlarrUrl = `http://prowlarr:${prowlarrPort}`
|
|
419
|
-
|
|
420
|
-
const configured = await this.configureProwlarr(prowlarrUrl, prowlarrApiKey)
|
|
421
|
-
results.push({
|
|
422
|
-
app: "prowlarr",
|
|
423
|
-
success: configured,
|
|
424
|
-
message: configured ? "Configured in Huntarr" : "Failed to configure",
|
|
425
|
-
})
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
return {
|
|
430
|
-
added: results.filter((r) => r.success).length,
|
|
431
|
-
skipped: results.filter((r) => !r.success).length,
|
|
432
|
-
results,
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
async configureProwlarr(apiUrl: string, apiKey: string): Promise<boolean> {
|
|
437
|
-
try {
|
|
438
|
-
const settings = {
|
|
439
|
-
api_url: apiUrl,
|
|
440
|
-
api_key: apiKey,
|
|
441
|
-
name: "Prowlarr",
|
|
442
|
-
enabled: true,
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
const response = await fetch(`${this.baseUrl}/api/settings/prowlarr`, {
|
|
446
|
-
method: "POST",
|
|
447
|
-
headers: this.getHeaders(),
|
|
448
|
-
body: JSON.stringify(settings),
|
|
449
|
-
signal: AbortSignal.timeout(10000),
|
|
450
|
-
})
|
|
451
|
-
|
|
452
|
-
return response.ok
|
|
453
|
-
} catch {
|
|
454
|
-
return false
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
package/src/api/index.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export * from "./arr-api"
|
|
2
|
-
export * from "./bazarr-api"
|
|
3
|
-
export * from "./cloudflare-api"
|
|
4
|
-
export * from "./custom-format-api"
|
|
5
|
-
export * from "./jellyfin-api"
|
|
6
|
-
export * from "./jellyseerr-api"
|
|
7
|
-
export * from "./prowlarr-api"
|
|
8
|
-
export * from "./qbittorrent-api"
|
|
9
|
-
export * from "./quality-profile-api"
|