@muhammedaksam/easiarr 1.3.5 → 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/README.md +8 -5
- package/dist/index.js +29837 -0
- package/package.json +18 -16
- package/src/VersionInfo.ts +0 -12
- package/src/api/arr-api.ts +0 -508
- package/src/api/auto-setup-types.ts +0 -64
- package/src/api/bazarr-api.ts +0 -356
- package/src/api/cloudflare-api.ts +0 -577
- package/src/api/custom-format-api.ts +0 -212
- package/src/api/grafana-api.ts +0 -314
- package/src/api/heimdall-api.ts +0 -209
- package/src/api/homarr-api.ts +0 -296
- package/src/api/huntarr-api.ts +0 -622
- package/src/api/index.ts +0 -1
- package/src/api/jellyfin-api.ts +0 -473
- package/src/api/jellyseerr-api.ts +0 -660
- package/src/api/maintainerr-api.ts +0 -731
- package/src/api/naming-config.ts +0 -93
- package/src/api/overseerr-api.ts +0 -513
- package/src/api/plex-api.ts +0 -358
- package/src/api/portainer-api.ts +0 -467
- package/src/api/profilarr-api.ts +0 -380
- package/src/api/prowlarr-api.ts +0 -859
- package/src/api/qbittorrent-api.ts +0 -339
- package/src/api/quality-profile-api.ts +0 -269
- package/src/api/tautulli-api.ts +0 -277
- package/src/api/uptime-kuma-api.ts +0 -342
- package/src/apps/categories.ts +0 -14
- package/src/apps/index.ts +0 -2
- package/src/apps/registry.ts +0 -1255
- package/src/compose/caddy-config.ts +0 -129
- package/src/compose/generator.ts +0 -262
- package/src/compose/index.ts +0 -3
- package/src/compose/templates.ts +0 -78
- package/src/compose/traefik-config.ts +0 -185
- package/src/config/bookmarks-generator.ts +0 -149
- package/src/config/defaults.ts +0 -37
- package/src/config/homepage-config.ts +0 -376
- package/src/config/index.ts +0 -3
- package/src/config/manager.ts +0 -149
- package/src/config/recyclarr-config.ts +0 -179
- package/src/config/schema.ts +0 -310
- package/src/config/slskd-config.ts +0 -85
- 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 -326
- package/src/docker/client.ts +0 -291
- package/src/docker/index.ts +0 -1
- package/src/index.ts +0 -77
- package/src/structure/manager.ts +0 -128
- package/src/ui/App.ts +0 -109
- package/src/ui/components/ApplicationSelector.ts +0 -272
- package/src/ui/components/FileEditor.ts +0 -91
- package/src/ui/components/FooterHint.ts +0 -119
- package/src/ui/components/PageLayout.ts +0 -152
- package/src/ui/components/UpdateNotification.ts +0 -101
- package/src/ui/index.ts +0 -1
- package/src/ui/screens/AdvancedSettings.ts +0 -181
- package/src/ui/screens/ApiKeyViewer.ts +0 -500
- package/src/ui/screens/AppConfigurator.ts +0 -731
- package/src/ui/screens/AppManager.ts +0 -276
- package/src/ui/screens/CloudflaredSetup.ts +0 -974
- package/src/ui/screens/ContainerControl.ts +0 -579
- package/src/ui/screens/FullAutoSetup.ts +0 -1719
- package/src/ui/screens/HomepageSetup.ts +0 -306
- package/src/ui/screens/JellyfinSetup.ts +0 -471
- package/src/ui/screens/JellyseerrSetup.ts +0 -612
- package/src/ui/screens/LogsViewer.ts +0 -468
- package/src/ui/screens/MainMenu.ts +0 -288
- package/src/ui/screens/MonitorDashboard.ts +0 -866
- package/src/ui/screens/ProwlarrSetup.ts +0 -623
- package/src/ui/screens/QBittorrentSetup.ts +0 -268
- package/src/ui/screens/QuickSetup.ts +0 -1161
- package/src/ui/screens/RecyclarrSetup.ts +0 -418
- package/src/ui/screens/SecretsEditor.ts +0 -214
- package/src/ui/screens/SettingsScreen.ts +0 -605
- package/src/ui/screens/TRaSHProfileSetup.ts +0 -395
- package/src/ui/screens/index.ts +0 -4
- package/src/util/arch.ts +0 -78
- package/src/utils/browser.ts +0 -26
- package/src/utils/categories.ts +0 -59
- package/src/utils/debug.ts +0 -91
- package/src/utils/env.ts +0 -137
- package/src/utils/logs.ts +0 -118
- package/src/utils/migrations/1765626338_rename_env_variables.ts +0 -101
- package/src/utils/migrations/1765707135_rename_easiarr_status.ts +0 -90
- package/src/utils/migrations/1765732722_remove_cloudflare_dns_api_token.ts +0 -44
- package/src/utils/migrations/1769515650_migrate_to_xdg.ts +0 -107
- package/src/utils/migrations.ts +0 -164
- package/src/utils/password.ts +0 -42
- package/src/utils/unraid.ts +0 -101
- package/src/utils/update-checker.ts +0 -210
- package/src/utils/url-utils.ts +0 -38
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* qBittorrent Setup Screen
|
|
3
|
-
* Configure qBittorrent for TRaSH Guide compliance
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { BoxRenderable, CliRenderer, TextRenderable, KeyEvent } from "@opentui/core"
|
|
7
|
-
import { createPageLayout } from "../components/PageLayout"
|
|
8
|
-
import type { EasiarrConfig } from "../../config/schema"
|
|
9
|
-
import { QBittorrentClient, type QBittorrentCategory } from "../../api/qbittorrent-api"
|
|
10
|
-
import { getCategoriesForApps } from "../../utils/categories"
|
|
11
|
-
import { debugLog } from "../../utils/debug"
|
|
12
|
-
|
|
13
|
-
type Step = "menu" | "host" | "port" | "user" | "pass" | "configuring" | "done"
|
|
14
|
-
|
|
15
|
-
export class QBittorrentSetup extends BoxRenderable {
|
|
16
|
-
private config: EasiarrConfig
|
|
17
|
-
private cliRenderer: CliRenderer
|
|
18
|
-
private onBack: () => void
|
|
19
|
-
private keyHandler!: (key: KeyEvent) => void
|
|
20
|
-
private contentBox!: BoxRenderable
|
|
21
|
-
private pageContainer!: BoxRenderable
|
|
22
|
-
|
|
23
|
-
private step: Step = "menu"
|
|
24
|
-
private menuIndex = 0
|
|
25
|
-
private host = "localhost"
|
|
26
|
-
private port = 8080
|
|
27
|
-
private user = "admin"
|
|
28
|
-
private pass = ""
|
|
29
|
-
private inputValue = ""
|
|
30
|
-
private statusMessage = ""
|
|
31
|
-
private statusColor = "#f1fa8c" // yellow
|
|
32
|
-
|
|
33
|
-
constructor(cliRenderer: CliRenderer, config: EasiarrConfig, onBack: () => void) {
|
|
34
|
-
const { container: pageContainer, content: contentBox } = createPageLayout(cliRenderer, {
|
|
35
|
-
title: "qBittorrent Setup",
|
|
36
|
-
stepInfo: "Configure TRaSH-compliant paths and categories",
|
|
37
|
-
footerHint: [
|
|
38
|
-
{ type: "key", key: "Enter", value: "Submit" },
|
|
39
|
-
{ type: "key", key: "Esc", value: "Back" },
|
|
40
|
-
],
|
|
41
|
-
})
|
|
42
|
-
super(cliRenderer, { width: "100%", height: "100%" })
|
|
43
|
-
this.add(pageContainer)
|
|
44
|
-
|
|
45
|
-
this.config = config
|
|
46
|
-
this.cliRenderer = cliRenderer
|
|
47
|
-
this.onBack = onBack
|
|
48
|
-
this.contentBox = contentBox
|
|
49
|
-
this.pageContainer = pageContainer
|
|
50
|
-
|
|
51
|
-
this.initKeyHandler()
|
|
52
|
-
this.refreshContent()
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
private initKeyHandler(): void {
|
|
56
|
-
this.keyHandler = (key: KeyEvent) => {
|
|
57
|
-
debugLog("qBittorrent", `Key: ${key.name}, step=${this.step}`)
|
|
58
|
-
|
|
59
|
-
if (key.name === "escape" || (key.name === "c" && key.ctrl)) {
|
|
60
|
-
if (this.step === "menu") {
|
|
61
|
-
this.cleanup()
|
|
62
|
-
} else {
|
|
63
|
-
this.step = "menu"
|
|
64
|
-
this.refreshContent()
|
|
65
|
-
}
|
|
66
|
-
return
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (this.step === "menu") {
|
|
70
|
-
this.handleMenuKeys(key)
|
|
71
|
-
} else if (this.step === "host" || this.step === "port" || this.step === "user" || this.step === "pass") {
|
|
72
|
-
this.handleInputKeys(key)
|
|
73
|
-
} else if (this.step === "done") {
|
|
74
|
-
if (key.name === "return") {
|
|
75
|
-
this.step = "menu"
|
|
76
|
-
this.refreshContent()
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
this.cliRenderer.keyInput.on("keypress", this.keyHandler)
|
|
81
|
-
debugLog("qBittorrent", "Key handler registered")
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
private handleMenuKeys(key: KeyEvent): void {
|
|
85
|
-
const menuItems = ["Configure qBittorrent", "Back"]
|
|
86
|
-
|
|
87
|
-
if (key.name === "up") {
|
|
88
|
-
this.menuIndex = Math.max(0, this.menuIndex - 1)
|
|
89
|
-
this.refreshContent()
|
|
90
|
-
} else if (key.name === "down") {
|
|
91
|
-
this.menuIndex = Math.min(menuItems.length - 1, this.menuIndex + 1)
|
|
92
|
-
this.refreshContent()
|
|
93
|
-
} else if (key.name === "return") {
|
|
94
|
-
if (this.menuIndex === 0) {
|
|
95
|
-
this.step = "host"
|
|
96
|
-
this.inputValue = this.host
|
|
97
|
-
this.refreshContent()
|
|
98
|
-
} else {
|
|
99
|
-
this.cleanup()
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
private handleInputKeys(key: KeyEvent): void {
|
|
105
|
-
if (key.name === "return") {
|
|
106
|
-
this.handleInputSubmit()
|
|
107
|
-
} else if (key.name === "backspace") {
|
|
108
|
-
this.inputValue = this.inputValue.slice(0, -1)
|
|
109
|
-
this.refreshContent()
|
|
110
|
-
} else if (key.sequence && key.sequence.length === 1 && !key.ctrl) {
|
|
111
|
-
this.inputValue += key.sequence
|
|
112
|
-
this.refreshContent()
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
private handleInputSubmit(): void {
|
|
117
|
-
if (this.step === "host") {
|
|
118
|
-
if (this.inputValue.trim()) this.host = this.inputValue.trim()
|
|
119
|
-
this.step = "port"
|
|
120
|
-
this.inputValue = String(this.port)
|
|
121
|
-
} else if (this.step === "port") {
|
|
122
|
-
const p = parseInt(this.inputValue)
|
|
123
|
-
if (!isNaN(p)) this.port = p
|
|
124
|
-
this.step = "user"
|
|
125
|
-
this.inputValue = this.user
|
|
126
|
-
} else if (this.step === "user") {
|
|
127
|
-
if (this.inputValue.trim()) this.user = this.inputValue.trim()
|
|
128
|
-
this.step = "pass"
|
|
129
|
-
this.inputValue = ""
|
|
130
|
-
} else if (this.step === "pass") {
|
|
131
|
-
this.pass = this.inputValue
|
|
132
|
-
this.step = "configuring"
|
|
133
|
-
this.configure()
|
|
134
|
-
return
|
|
135
|
-
}
|
|
136
|
-
this.refreshContent()
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
private async configure(): Promise<void> {
|
|
140
|
-
this.statusMessage = "⏳ Connecting to qBittorrent..."
|
|
141
|
-
this.statusColor = "#f1fa8c"
|
|
142
|
-
this.refreshContent()
|
|
143
|
-
|
|
144
|
-
try {
|
|
145
|
-
debugLog("qBittorrent", `Connecting to ${this.host}:${this.port}`)
|
|
146
|
-
const client = new QBittorrentClient(this.host, this.port, this.user, this.pass)
|
|
147
|
-
const loggedIn = await client.login()
|
|
148
|
-
|
|
149
|
-
if (!loggedIn) {
|
|
150
|
-
this.statusMessage = "❌ Login failed. Check credentials."
|
|
151
|
-
this.statusColor = "#ff5555"
|
|
152
|
-
this.step = "done"
|
|
153
|
-
this.refreshContent()
|
|
154
|
-
return
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
this.statusMessage = "✅ Logged in. Configuring..."
|
|
158
|
-
this.statusColor = "#50fa7b"
|
|
159
|
-
this.refreshContent()
|
|
160
|
-
|
|
161
|
-
// Get categories from enabled *arr apps
|
|
162
|
-
const enabledApps = this.config.apps.filter((a) => a.enabled).map((a) => a.id)
|
|
163
|
-
const categories: QBittorrentCategory[] = getCategoriesForApps(enabledApps).map((cat) => ({
|
|
164
|
-
name: cat.name,
|
|
165
|
-
savePath: `/data/torrents/${cat.name}`,
|
|
166
|
-
}))
|
|
167
|
-
|
|
168
|
-
await client.configureTRaSHCompliant(categories, { user: this.user, pass: this.pass })
|
|
169
|
-
|
|
170
|
-
const catNames = categories.map((c) => c.name).join(", ") || "none"
|
|
171
|
-
this.statusMessage = `✅ Done!\n\n save_path: /data/torrents\n Categories: ${catNames}\n\n Press Enter to continue.`
|
|
172
|
-
this.statusColor = "#50fa7b"
|
|
173
|
-
this.step = "done"
|
|
174
|
-
this.refreshContent()
|
|
175
|
-
} catch (e) {
|
|
176
|
-
debugLog("qBittorrent", `Error: ${e}`)
|
|
177
|
-
this.statusMessage = `❌ Error: ${e}`
|
|
178
|
-
this.statusColor = "#ff5555"
|
|
179
|
-
this.step = "done"
|
|
180
|
-
this.refreshContent()
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
private refreshContent(): void {
|
|
185
|
-
// Clear content box
|
|
186
|
-
this.contentBox.getChildren().forEach((child) => child.destroy())
|
|
187
|
-
|
|
188
|
-
if (this.step === "menu") {
|
|
189
|
-
this.renderMenu()
|
|
190
|
-
} else if (this.step === "host" || this.step === "port" || this.step === "user" || this.step === "pass") {
|
|
191
|
-
this.renderInput()
|
|
192
|
-
} else if (this.step === "configuring" || this.step === "done") {
|
|
193
|
-
this.renderStatus()
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
private renderMenu(): void {
|
|
198
|
-
this.contentBox.add(
|
|
199
|
-
new TextRenderable(this.cliRenderer, {
|
|
200
|
-
content: "Select an action:\n\n",
|
|
201
|
-
fg: "#aaaaaa",
|
|
202
|
-
})
|
|
203
|
-
)
|
|
204
|
-
|
|
205
|
-
const items = [
|
|
206
|
-
{ name: "🔧 Configure qBittorrent", desc: "Set save path and categories" },
|
|
207
|
-
{ name: "⬅️ Back", desc: "Return to main menu" },
|
|
208
|
-
]
|
|
209
|
-
|
|
210
|
-
items.forEach((item, idx) => {
|
|
211
|
-
const pointer = idx === this.menuIndex ? "→ " : " "
|
|
212
|
-
const fg = idx === this.menuIndex ? "#50fa7b" : "#8be9fd"
|
|
213
|
-
|
|
214
|
-
this.contentBox.add(
|
|
215
|
-
new TextRenderable(this.cliRenderer, {
|
|
216
|
-
content: `${pointer}${item.name}\n`,
|
|
217
|
-
fg,
|
|
218
|
-
})
|
|
219
|
-
)
|
|
220
|
-
this.contentBox.add(
|
|
221
|
-
new TextRenderable(this.cliRenderer, {
|
|
222
|
-
content: ` ${item.desc}\n\n`,
|
|
223
|
-
fg: "#6272a4",
|
|
224
|
-
})
|
|
225
|
-
)
|
|
226
|
-
})
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
private renderInput(): void {
|
|
230
|
-
const labels: Record<string, string> = {
|
|
231
|
-
host: "Enter qBittorrent host (e.g., localhost or qbittorrent):",
|
|
232
|
-
port: "Enter qBittorrent WebUI port:",
|
|
233
|
-
user: "Enter qBittorrent username:",
|
|
234
|
-
pass: "Enter qBittorrent password:",
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
this.contentBox.add(
|
|
238
|
-
new TextRenderable(this.cliRenderer, {
|
|
239
|
-
content: `${labels[this.step]}\n\n`,
|
|
240
|
-
fg: "#8be9fd",
|
|
241
|
-
})
|
|
242
|
-
)
|
|
243
|
-
|
|
244
|
-
const displayValue = this.step === "pass" ? "*".repeat(this.inputValue.length) : this.inputValue
|
|
245
|
-
this.contentBox.add(
|
|
246
|
-
new TextRenderable(this.cliRenderer, {
|
|
247
|
-
content: `> ${displayValue}_`,
|
|
248
|
-
fg: "#ffffff",
|
|
249
|
-
})
|
|
250
|
-
)
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
private renderStatus(): void {
|
|
254
|
-
this.contentBox.add(
|
|
255
|
-
new TextRenderable(this.cliRenderer, {
|
|
256
|
-
content: this.statusMessage,
|
|
257
|
-
fg: this.statusColor,
|
|
258
|
-
})
|
|
259
|
-
)
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
private cleanup(): void {
|
|
263
|
-
this.cliRenderer.keyInput.off("keypress", this.keyHandler)
|
|
264
|
-
debugLog("qBittorrent", "Key handler removed")
|
|
265
|
-
this.destroy()
|
|
266
|
-
this.onBack()
|
|
267
|
-
}
|
|
268
|
-
}
|