@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/prowlarr-api.ts
DELETED
|
@@ -1,488 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Prowlarr API Client
|
|
3
|
-
* Manages Indexer Proxies, Sync Profiles, and FlareSolverr integration
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { AutoSetupOptions, AutoSetupResult, IAutoSetupClient } from "./auto-setup-types"
|
|
7
|
-
import { debugLog } from "~/utils/debug"
|
|
8
|
-
import { BaseApiClient } from "./base-api"
|
|
9
|
-
|
|
10
|
-
export interface IndexerProxy {
|
|
11
|
-
id?: number
|
|
12
|
-
name: string
|
|
13
|
-
tags: number[]
|
|
14
|
-
implementation: string
|
|
15
|
-
configContract: string
|
|
16
|
-
fields: { name: string; value: unknown }[]
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface ProwlarrIndexerSchema {
|
|
20
|
-
id?: number
|
|
21
|
-
name: string
|
|
22
|
-
implementation: string
|
|
23
|
-
configContract: string
|
|
24
|
-
fields: { name: string; value?: unknown }[]
|
|
25
|
-
tags: number[]
|
|
26
|
-
enable: boolean
|
|
27
|
-
privacy: "public" | "private" | "semi-private"
|
|
28
|
-
protocol: "torrent" | "usenet"
|
|
29
|
-
priority: number
|
|
30
|
-
capabilities?: {
|
|
31
|
-
categories: { id: number; name: string; subCategories?: { id: number; name: string }[] }[]
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface ProwlarrIndexer {
|
|
36
|
-
id?: number
|
|
37
|
-
name: string
|
|
38
|
-
fields: { name: string; value?: unknown }[]
|
|
39
|
-
tags: number[]
|
|
40
|
-
enable: boolean
|
|
41
|
-
protocol: string
|
|
42
|
-
implementation: string
|
|
43
|
-
configContract: string
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export interface SyncProfile {
|
|
47
|
-
id?: number
|
|
48
|
-
name: string
|
|
49
|
-
enableRss: boolean
|
|
50
|
-
enableInteractiveSearch: boolean
|
|
51
|
-
enableAutomaticSearch: boolean
|
|
52
|
-
minimumSeeders: number
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface Tag {
|
|
56
|
-
id: number
|
|
57
|
-
label: string
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export interface Application {
|
|
61
|
-
id?: number
|
|
62
|
-
name: string
|
|
63
|
-
syncLevel: "disabled" | "addOnly" | "fullSync"
|
|
64
|
-
implementation: string
|
|
65
|
-
configContract: string
|
|
66
|
-
fields: { name: string; value: unknown }[]
|
|
67
|
-
tags: number[]
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export type ArrAppType = "Radarr" | "Sonarr" | "Lidarr" | "Readarr" | "Whisparr" | "Mylar"
|
|
71
|
-
|
|
72
|
-
export class ProwlarrClient extends BaseApiClient implements IAutoSetupClient {
|
|
73
|
-
protected readonly logPrefix = "Prowlarr"
|
|
74
|
-
private apiKey: string
|
|
75
|
-
|
|
76
|
-
constructor(host: string, port: number, apiKey: string) {
|
|
77
|
-
super(host, port)
|
|
78
|
-
this.apiKey = apiKey
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
private async request<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
|
82
|
-
const url = `${this.baseUrl}/api/v1${endpoint}`
|
|
83
|
-
const headers: Record<string, string> = {
|
|
84
|
-
"X-Api-Key": this.apiKey,
|
|
85
|
-
"Content-Type": "application/json",
|
|
86
|
-
...((options.headers as Record<string, string>) || {}),
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
debugLog("Prowlarr", `${options.method || "GET"} ${url}`)
|
|
90
|
-
|
|
91
|
-
const response = await fetch(url, { ...options, headers })
|
|
92
|
-
const text = await response.text()
|
|
93
|
-
|
|
94
|
-
if (!response.ok) {
|
|
95
|
-
throw new Error(`Prowlarr API request failed: ${response.status} ${response.statusText}`)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (!text) return {} as T
|
|
99
|
-
return JSON.parse(text) as T
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Health check
|
|
103
|
-
async isHealthy(): Promise<boolean> {
|
|
104
|
-
try {
|
|
105
|
-
await this.request("/health")
|
|
106
|
-
return true
|
|
107
|
-
} catch {
|
|
108
|
-
return false
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Tag management
|
|
113
|
-
async getTags(): Promise<Tag[]> {
|
|
114
|
-
return this.request<Tag[]>("/tag")
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
async createTag(label: string): Promise<Tag> {
|
|
118
|
-
return this.request<Tag>("/tag", {
|
|
119
|
-
method: "POST",
|
|
120
|
-
body: JSON.stringify({ label }),
|
|
121
|
-
})
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
async getOrCreateTag(label: string): Promise<Tag> {
|
|
125
|
-
const tags = await this.getTags()
|
|
126
|
-
const existing = tags.find((t) => t.label.toLowerCase() === label.toLowerCase())
|
|
127
|
-
if (existing) return existing
|
|
128
|
-
return this.createTag(label)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Indexer Proxy management
|
|
132
|
-
async getIndexerProxies(): Promise<IndexerProxy[]> {
|
|
133
|
-
return this.request<IndexerProxy[]>("/indexerproxy")
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
async addHttpProxy(
|
|
137
|
-
name: string,
|
|
138
|
-
host: string,
|
|
139
|
-
port: number,
|
|
140
|
-
tags: number[] = [],
|
|
141
|
-
username?: string,
|
|
142
|
-
password?: string
|
|
143
|
-
): Promise<IndexerProxy> {
|
|
144
|
-
const fields: { name: string; value: unknown }[] = [
|
|
145
|
-
{ name: "host", value: host },
|
|
146
|
-
{ name: "port", value: port },
|
|
147
|
-
{ name: "username", value: username || "" },
|
|
148
|
-
{ name: "password", value: password || "" },
|
|
149
|
-
]
|
|
150
|
-
|
|
151
|
-
return this.request<IndexerProxy>("/indexerproxy", {
|
|
152
|
-
method: "POST",
|
|
153
|
-
body: JSON.stringify({
|
|
154
|
-
name,
|
|
155
|
-
tags,
|
|
156
|
-
implementation: "Http",
|
|
157
|
-
configContract: "HttpSettings",
|
|
158
|
-
fields,
|
|
159
|
-
}),
|
|
160
|
-
})
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
async addSocks5Proxy(
|
|
164
|
-
name: string,
|
|
165
|
-
host: string,
|
|
166
|
-
port: number,
|
|
167
|
-
tags: number[] = [],
|
|
168
|
-
username?: string,
|
|
169
|
-
password?: string
|
|
170
|
-
): Promise<IndexerProxy> {
|
|
171
|
-
const fields: { name: string; value: unknown }[] = [
|
|
172
|
-
{ name: "host", value: host },
|
|
173
|
-
{ name: "port", value: port },
|
|
174
|
-
{ name: "username", value: username || "" },
|
|
175
|
-
{ name: "password", value: password || "" },
|
|
176
|
-
]
|
|
177
|
-
|
|
178
|
-
return this.request<IndexerProxy>("/indexerproxy", {
|
|
179
|
-
method: "POST",
|
|
180
|
-
body: JSON.stringify({
|
|
181
|
-
name,
|
|
182
|
-
tags,
|
|
183
|
-
implementation: "Socks5",
|
|
184
|
-
configContract: "Socks5Settings",
|
|
185
|
-
fields,
|
|
186
|
-
}),
|
|
187
|
-
})
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
async addFlareSolverr(
|
|
191
|
-
name: string,
|
|
192
|
-
host: string,
|
|
193
|
-
tags: number[] = [],
|
|
194
|
-
requestTimeout = 60
|
|
195
|
-
): Promise<IndexerProxy> {
|
|
196
|
-
const fields: { name: string; value: unknown }[] = [
|
|
197
|
-
{ name: "host", value: host },
|
|
198
|
-
{ name: "requestTimeout", value: requestTimeout },
|
|
199
|
-
]
|
|
200
|
-
|
|
201
|
-
return this.request<IndexerProxy>("/indexerproxy", {
|
|
202
|
-
method: "POST",
|
|
203
|
-
body: JSON.stringify({
|
|
204
|
-
name,
|
|
205
|
-
tags,
|
|
206
|
-
implementation: "FlareSolverr",
|
|
207
|
-
configContract: "FlareSolverrSettings",
|
|
208
|
-
fields,
|
|
209
|
-
}),
|
|
210
|
-
})
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
async deleteIndexerProxy(id: number): Promise<void> {
|
|
214
|
-
await this.request(`/indexerproxy/${id}`, { method: "DELETE" })
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// Indexer Management
|
|
218
|
-
async getIndexerSchemas(): Promise<ProwlarrIndexerSchema[]> {
|
|
219
|
-
return this.request<ProwlarrIndexerSchema[]>("/indexer/schema")
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
async getIndexers(): Promise<ProwlarrIndexer[]> {
|
|
223
|
-
return this.request<ProwlarrIndexer[]>("/indexer")
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
async createIndexer(indexer: ProwlarrIndexerSchema): Promise<ProwlarrIndexer> {
|
|
227
|
-
const payload = {
|
|
228
|
-
...indexer,
|
|
229
|
-
id: undefined,
|
|
230
|
-
appProfileId: 1,
|
|
231
|
-
}
|
|
232
|
-
return this.request<ProwlarrIndexer>("/indexer", {
|
|
233
|
-
method: "POST",
|
|
234
|
-
body: JSON.stringify(payload),
|
|
235
|
-
})
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// Sync Profile management
|
|
239
|
-
async getSyncProfiles(): Promise<SyncProfile[]> {
|
|
240
|
-
return this.request<SyncProfile[]>("/appprofile")
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
async createSyncProfile(profile: Omit<SyncProfile, "id">): Promise<SyncProfile> {
|
|
244
|
-
return this.request<SyncProfile>("/appprofile", {
|
|
245
|
-
method: "POST",
|
|
246
|
-
body: JSON.stringify(profile),
|
|
247
|
-
})
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
async createLimitedAPISyncProfiles(): Promise<{
|
|
251
|
-
automatic: SyncProfile
|
|
252
|
-
interactive: SyncProfile
|
|
253
|
-
}> {
|
|
254
|
-
const existingProfiles = await this.getSyncProfiles()
|
|
255
|
-
const findByName = (name: string) => existingProfiles.find((p) => p.name === name)
|
|
256
|
-
|
|
257
|
-
let automatic = findByName("Automatic Search")
|
|
258
|
-
if (!automatic) {
|
|
259
|
-
automatic = await this.createSyncProfile({
|
|
260
|
-
name: "Automatic Search",
|
|
261
|
-
enableRss: false,
|
|
262
|
-
enableInteractiveSearch: true,
|
|
263
|
-
enableAutomaticSearch: true,
|
|
264
|
-
minimumSeeders: 1,
|
|
265
|
-
})
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
let interactive = findByName("Interactive Search")
|
|
269
|
-
if (!interactive) {
|
|
270
|
-
interactive = await this.createSyncProfile({
|
|
271
|
-
name: "Interactive Search",
|
|
272
|
-
enableRss: false,
|
|
273
|
-
enableInteractiveSearch: true,
|
|
274
|
-
enableAutomaticSearch: false,
|
|
275
|
-
minimumSeeders: 1,
|
|
276
|
-
})
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
return { automatic, interactive }
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
async configureFlareSolverr(flareSolverrHost: string): Promise<void> {
|
|
283
|
-
const tag = await this.getOrCreateTag("flaresolverr")
|
|
284
|
-
const proxies = await this.getIndexerProxies()
|
|
285
|
-
const existingFS = proxies.find((p) => p.implementation === "FlareSolverr")
|
|
286
|
-
|
|
287
|
-
if (!existingFS) {
|
|
288
|
-
await this.addFlareSolverr("FlareSolverr", flareSolverrHost, [tag.id])
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// Application management
|
|
293
|
-
async getApplications(): Promise<Application[]> {
|
|
294
|
-
return this.request<Application[]>("/applications")
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
async addApplication(
|
|
298
|
-
appType: ArrAppType,
|
|
299
|
-
name: string,
|
|
300
|
-
prowlarrUrl: string,
|
|
301
|
-
appUrl: string,
|
|
302
|
-
appApiKey: string,
|
|
303
|
-
syncLevel: "disabled" | "addOnly" | "fullSync" = "fullSync",
|
|
304
|
-
syncCategories: number[] = []
|
|
305
|
-
): Promise<Application> {
|
|
306
|
-
const fields: { name: string; value: unknown }[] = [
|
|
307
|
-
{ name: "prowlarrUrl", value: prowlarrUrl },
|
|
308
|
-
{ name: "baseUrl", value: appUrl },
|
|
309
|
-
{ name: "apiKey", value: appApiKey },
|
|
310
|
-
{ name: "syncCategories", value: syncCategories },
|
|
311
|
-
]
|
|
312
|
-
|
|
313
|
-
return this.request<Application>("/applications", {
|
|
314
|
-
method: "POST",
|
|
315
|
-
body: JSON.stringify({
|
|
316
|
-
name,
|
|
317
|
-
syncLevel,
|
|
318
|
-
implementation: appType,
|
|
319
|
-
configContract: `${appType}Settings`,
|
|
320
|
-
fields,
|
|
321
|
-
tags: [],
|
|
322
|
-
}),
|
|
323
|
-
})
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
async deleteApplication(id: number): Promise<void> {
|
|
327
|
-
await this.request(`/applications/${id}`, { method: "DELETE" })
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
async updateApplication(
|
|
331
|
-
id: number,
|
|
332
|
-
appType: ArrAppType,
|
|
333
|
-
name: string,
|
|
334
|
-
prowlarrUrl: string,
|
|
335
|
-
appUrl: string,
|
|
336
|
-
appApiKey: string,
|
|
337
|
-
syncLevel: "disabled" | "addOnly" | "fullSync" = "fullSync",
|
|
338
|
-
syncCategories: number[] = [],
|
|
339
|
-
tags: number[] = []
|
|
340
|
-
): Promise<Application> {
|
|
341
|
-
const fields: { name: string; value: unknown }[] = [
|
|
342
|
-
{ name: "prowlarrUrl", value: prowlarrUrl },
|
|
343
|
-
{ name: "baseUrl", value: appUrl },
|
|
344
|
-
{ name: "apiKey", value: appApiKey },
|
|
345
|
-
{ name: "syncCategories", value: syncCategories },
|
|
346
|
-
{ name: "syncRejectBlocklistedTorrentHashesWhileGrabbing", value: false },
|
|
347
|
-
]
|
|
348
|
-
|
|
349
|
-
return this.request<Application>(`/applications/${id}`, {
|
|
350
|
-
method: "PUT",
|
|
351
|
-
body: JSON.stringify({
|
|
352
|
-
id,
|
|
353
|
-
name,
|
|
354
|
-
syncLevel,
|
|
355
|
-
enable: true,
|
|
356
|
-
implementation: appType,
|
|
357
|
-
implementationName: appType,
|
|
358
|
-
configContract: `${appType}Settings`,
|
|
359
|
-
infoLink: `https://wiki.servarr.com/prowlarr/supported#${appType.toLowerCase()}`,
|
|
360
|
-
fields,
|
|
361
|
-
tags,
|
|
362
|
-
}),
|
|
363
|
-
})
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
async syncApplications(): Promise<void> {
|
|
367
|
-
await this.request("/command", {
|
|
368
|
-
method: "POST",
|
|
369
|
-
body: JSON.stringify({
|
|
370
|
-
name: "ApplicationIndexerSync",
|
|
371
|
-
forceSync: true,
|
|
372
|
-
}),
|
|
373
|
-
})
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
async addArrApp(
|
|
377
|
-
appType: ArrAppType,
|
|
378
|
-
host: string,
|
|
379
|
-
port: number,
|
|
380
|
-
apiKey: string,
|
|
381
|
-
prowlarrHost: string,
|
|
382
|
-
prowlarrPort: number,
|
|
383
|
-
syncCategories?: number[]
|
|
384
|
-
): Promise<Application> {
|
|
385
|
-
const prowlarrUrl = `http://${prowlarrHost}:${prowlarrPort}`
|
|
386
|
-
const appUrl = `http://${host}:${port}`
|
|
387
|
-
|
|
388
|
-
const apps = await this.getApplications()
|
|
389
|
-
const existing = apps.find((a) => a.implementation === appType)
|
|
390
|
-
|
|
391
|
-
if (existing && existing.id) {
|
|
392
|
-
return this.updateApplication(
|
|
393
|
-
existing.id,
|
|
394
|
-
appType,
|
|
395
|
-
existing.name,
|
|
396
|
-
prowlarrUrl,
|
|
397
|
-
appUrl,
|
|
398
|
-
apiKey,
|
|
399
|
-
"fullSync",
|
|
400
|
-
syncCategories || [],
|
|
401
|
-
existing.tags || []
|
|
402
|
-
)
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
return this.addApplication(
|
|
406
|
-
appType,
|
|
407
|
-
appType,
|
|
408
|
-
prowlarrUrl,
|
|
409
|
-
appUrl,
|
|
410
|
-
apiKey,
|
|
411
|
-
"fullSync",
|
|
412
|
-
syncCategories
|
|
413
|
-
)
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
async isInitialized(): Promise<boolean> {
|
|
417
|
-
try {
|
|
418
|
-
const indexers = await this.getIndexers()
|
|
419
|
-
return indexers.length > 0
|
|
420
|
-
} catch {
|
|
421
|
-
return false
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
async setup(_options: AutoSetupOptions): Promise<AutoSetupResult> {
|
|
426
|
-
try {
|
|
427
|
-
const healthy = await this.isHealthy()
|
|
428
|
-
if (!healthy) {
|
|
429
|
-
return { success: false, message: "Prowlarr not reachable" }
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
const indexers = await this.getIndexers()
|
|
433
|
-
const apps = await this.getApplications()
|
|
434
|
-
const proxies = await this.getIndexerProxies()
|
|
435
|
-
|
|
436
|
-
return {
|
|
437
|
-
success: true,
|
|
438
|
-
message: indexers.length > 0 ? "Configured" : "Ready for indexer setup",
|
|
439
|
-
data: {
|
|
440
|
-
indexerCount: indexers.length,
|
|
441
|
-
appCount: apps.length,
|
|
442
|
-
proxyCount: proxies.length,
|
|
443
|
-
},
|
|
444
|
-
}
|
|
445
|
-
} catch (error) {
|
|
446
|
-
return { success: false, message: `${error}` }
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
export const PROWLARR_CATEGORIES = [
|
|
452
|
-
{ id: 1000, name: "Console", subCategories: [] as { id: number; name: string }[] },
|
|
453
|
-
{
|
|
454
|
-
id: 2000,
|
|
455
|
-
name: "Movies",
|
|
456
|
-
subCategories: [
|
|
457
|
-
{ id: 2010, name: "Movies/Foreign" },
|
|
458
|
-
{ id: 2020, name: "Movies/Other" },
|
|
459
|
-
{ id: 2030, name: "Movies/SD" },
|
|
460
|
-
{ id: 2040, name: "Movies/HD" },
|
|
461
|
-
{ id: 2045, name: "Movies/UHD" },
|
|
462
|
-
{ id: 2050, name: "Movies/BluRay" },
|
|
463
|
-
{ id: 2060, name: "Movies/3D" },
|
|
464
|
-
{ id: 2070, name: "Movies/DVD" },
|
|
465
|
-
{ id: 2080, name: "Movies/WEB-DL" },
|
|
466
|
-
],
|
|
467
|
-
},
|
|
468
|
-
{ id: 3000, name: "Audio", subCategories: [] as { id: number; name: string }[] },
|
|
469
|
-
{ id: 4000, name: "PC", subCategories: [] as { id: number; name: string }[] },
|
|
470
|
-
{
|
|
471
|
-
id: 5000,
|
|
472
|
-
name: "TV",
|
|
473
|
-
subCategories: [
|
|
474
|
-
{ id: 5010, name: "TV/WEB-DL" },
|
|
475
|
-
{ id: 5020, name: "TV/Foreign" },
|
|
476
|
-
{ id: 5030, name: "TV/SD" },
|
|
477
|
-
{ id: 5040, name: "TV/HD" },
|
|
478
|
-
{ id: 5045, name: "TV/UHD" },
|
|
479
|
-
{ id: 5050, name: "TV/Other" },
|
|
480
|
-
{ id: 5060, name: "TV/Sport" },
|
|
481
|
-
{ id: 5070, name: "TV/Anime" },
|
|
482
|
-
{ id: 5080, name: "TV/Documentary" },
|
|
483
|
-
],
|
|
484
|
-
},
|
|
485
|
-
{ id: 6000, name: "XXX", subCategories: [] as { id: number; name: string }[] },
|
|
486
|
-
{ id: 7000, name: "Books", subCategories: [] as { id: number; name: string }[] },
|
|
487
|
-
{ id: 8000, name: "Other", subCategories: [] as { id: number; name: string }[] },
|
|
488
|
-
]
|