@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
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Main Menu Screen
|
|
3
|
-
* Central navigation hub for easiarr
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { CliRenderer, RenderContext } from "@opentui/core"
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
BoxRenderable,
|
|
10
|
-
SelectRenderable,
|
|
11
|
-
SelectRenderableEvents,
|
|
12
|
-
TextRenderable,
|
|
13
|
-
} from "@opentui/core"
|
|
14
|
-
|
|
15
|
-
import type { EasiarrConfig } from "~/config/schema"
|
|
16
|
-
import type { App } from "~/ui/App"
|
|
17
|
-
import { saveCompose } from "~/compose"
|
|
18
|
-
import { saveBookmarks } from "~/config/bookmarks-generator"
|
|
19
|
-
import { createPageLayout } from "~/ui/components/PageLayout"
|
|
20
|
-
import { ApiKeyViewer } from "~/ui/screens/ApiKeyViewer"
|
|
21
|
-
import { AppConfigurator } from "~/ui/screens/AppConfigurator"
|
|
22
|
-
import { LogsViewer } from "~/ui/screens/LogsViewer"
|
|
23
|
-
import { MonitorDashboard } from "~/ui/screens/MonitorDashboard"
|
|
24
|
-
import { SettingsScreen } from "~/ui/screens/SettingsScreen"
|
|
25
|
-
import { CloudflaredSetup } from "~/ui/screens/setup/CloudflaredSetup"
|
|
26
|
-
import { FullAutoSetup } from "~/ui/screens/setup/FullAutoSetup"
|
|
27
|
-
import { HomepageSetup } from "~/ui/screens/setup/HomepageSetup"
|
|
28
|
-
import { JellyfinSetup } from "~/ui/screens/setup/JellyfinSetup"
|
|
29
|
-
import { JellyseerrSetup } from "~/ui/screens/setup/JellyseerrSetup"
|
|
30
|
-
import { ProwlarrSetup } from "~/ui/screens/setup/ProwlarrSetup"
|
|
31
|
-
import { QBittorrentSetup } from "~/ui/screens/setup/QBittorrentSetup"
|
|
32
|
-
import { RecyclarrSetup } from "~/ui/screens/setup/RecyclarrSetup"
|
|
33
|
-
import { TRaSHProfileSetup } from "~/ui/screens/setup/TRaSHProfileSetup"
|
|
34
|
-
import { openUrl } from "~/utils/browser"
|
|
35
|
-
|
|
36
|
-
type MenuItem = { name: string; description: string; action: () => void | Promise<void> }
|
|
37
|
-
|
|
38
|
-
type ScreenConstructor = new (
|
|
39
|
-
renderer: CliRenderer,
|
|
40
|
-
config: EasiarrConfig,
|
|
41
|
-
onBack: () => void
|
|
42
|
-
) => BoxRenderable
|
|
43
|
-
|
|
44
|
-
export class MainMenu {
|
|
45
|
-
private renderer: RenderContext
|
|
46
|
-
private container: BoxRenderable
|
|
47
|
-
private app: App
|
|
48
|
-
private config: EasiarrConfig
|
|
49
|
-
private menu!: SelectRenderable
|
|
50
|
-
private page!: BoxRenderable
|
|
51
|
-
private menuItems: MenuItem[] = []
|
|
52
|
-
|
|
53
|
-
constructor(renderer: RenderContext, container: BoxRenderable, app: App, config: EasiarrConfig) {
|
|
54
|
-
this.renderer = renderer
|
|
55
|
-
this.container = container
|
|
56
|
-
this.app = app
|
|
57
|
-
this.config = config
|
|
58
|
-
|
|
59
|
-
this.render()
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
private isAppEnabled(id: string): boolean {
|
|
63
|
-
return this.config.apps.some((a) => a.id === id && a.enabled)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
private buildMenuItems(): MenuItem[] {
|
|
67
|
-
const items: MenuItem[] = []
|
|
68
|
-
|
|
69
|
-
// Core items (always shown)
|
|
70
|
-
items.push({
|
|
71
|
-
name: "📦 Manage Apps",
|
|
72
|
-
description: "Add, remove, or configure apps",
|
|
73
|
-
action: () => this.app.navigateTo("appManager"),
|
|
74
|
-
})
|
|
75
|
-
items.push({
|
|
76
|
-
name: "⚙️ Settings",
|
|
77
|
-
description: "Edit Traefik, VPN, and system configuration",
|
|
78
|
-
action: () => this.showScreen(SettingsScreen),
|
|
79
|
-
})
|
|
80
|
-
items.push({
|
|
81
|
-
name: "🐳 Container Control",
|
|
82
|
-
description: "Start, stop, restart containers",
|
|
83
|
-
action: () => this.app.navigateTo("containerControl"),
|
|
84
|
-
})
|
|
85
|
-
items.push({
|
|
86
|
-
name: "📋 View Container Logs",
|
|
87
|
-
description: "Stream and save container logs",
|
|
88
|
-
action: () => this.showScreen(LogsViewer),
|
|
89
|
-
})
|
|
90
|
-
items.push({
|
|
91
|
-
name: "⚙️ Advanced Settings",
|
|
92
|
-
description: "Customize ports, volumes, env",
|
|
93
|
-
action: () => this.app.navigateTo("advancedSettings"),
|
|
94
|
-
})
|
|
95
|
-
items.push({
|
|
96
|
-
name: "🔑 Extract API Keys",
|
|
97
|
-
description: "Find API keys from running containers",
|
|
98
|
-
action: () => this.showScreen(ApiKeyViewer),
|
|
99
|
-
})
|
|
100
|
-
items.push({
|
|
101
|
-
name: "⚙️ Configure Apps",
|
|
102
|
-
description: "Set root folders and download clients via API",
|
|
103
|
-
action: () => this.showScreen(AppConfigurator),
|
|
104
|
-
})
|
|
105
|
-
items.push({
|
|
106
|
-
name: "🎯 TRaSH Guide Setup",
|
|
107
|
-
description: "Apply TRaSH quality profiles and custom formats",
|
|
108
|
-
action: () => this.showScreen(TRaSHProfileSetup),
|
|
109
|
-
})
|
|
110
|
-
items.push({
|
|
111
|
-
name: "🔄 Regenerate Compose",
|
|
112
|
-
description: "Rebuild docker-compose.yml",
|
|
113
|
-
action: async () => {
|
|
114
|
-
await saveCompose(this.config)
|
|
115
|
-
},
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
// Conditional items based on enabled apps
|
|
119
|
-
if (this.isAppEnabled("prowlarr")) {
|
|
120
|
-
items.push({
|
|
121
|
-
name: "🔗 Prowlarr Setup",
|
|
122
|
-
description: "Sync indexers to *arr apps, FlareSolverr",
|
|
123
|
-
action: () => this.showScreen(ProwlarrSetup),
|
|
124
|
-
})
|
|
125
|
-
}
|
|
126
|
-
if (this.isAppEnabled("qbittorrent")) {
|
|
127
|
-
items.push({
|
|
128
|
-
name: "⚡ qBittorrent Setup",
|
|
129
|
-
description: "Configure TRaSH-compliant paths and categories",
|
|
130
|
-
action: () => this.showScreen(QBittorrentSetup),
|
|
131
|
-
})
|
|
132
|
-
}
|
|
133
|
-
if (this.isAppEnabled("recyclarr")) {
|
|
134
|
-
items.push({
|
|
135
|
-
name: "♻️ Recyclarr Setup",
|
|
136
|
-
description: "Configure TRaSH Guide profiles and run sync",
|
|
137
|
-
action: () => this.showScreen(RecyclarrSetup),
|
|
138
|
-
})
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Full Auto Setup (always shown)
|
|
142
|
-
items.push({
|
|
143
|
-
name: "🚀 Full Auto Setup",
|
|
144
|
-
description: "Run all configurations (Auth, Root Folders, Prowlarr, etc.)",
|
|
145
|
-
action: () => this.showScreen(FullAutoSetup),
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
items.push({
|
|
149
|
-
name: "📊 Monitor Dashboard",
|
|
150
|
-
description: "Configure app health monitoring",
|
|
151
|
-
action: () => this.showScreen(MonitorDashboard),
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
if (this.isAppEnabled("homepage")) {
|
|
155
|
-
items.push({
|
|
156
|
-
name: "🏠 Homepage Setup",
|
|
157
|
-
description: "Generate Homepage dashboard config",
|
|
158
|
-
action: () => this.showScreen(HomepageSetup),
|
|
159
|
-
})
|
|
160
|
-
}
|
|
161
|
-
if (this.isAppEnabled("jellyfin")) {
|
|
162
|
-
items.push({
|
|
163
|
-
name: "🎬 Jellyfin Setup",
|
|
164
|
-
description: "Run Jellyfin setup wizard via API",
|
|
165
|
-
action: () => this.showScreen(JellyfinSetup),
|
|
166
|
-
})
|
|
167
|
-
}
|
|
168
|
-
if (this.isAppEnabled("jellyseerr")) {
|
|
169
|
-
items.push({
|
|
170
|
-
name: "🎥 Jellyseerr Setup",
|
|
171
|
-
description: "Configure Jellyseerr with media server",
|
|
172
|
-
action: () => this.showScreen(JellyseerrSetup),
|
|
173
|
-
})
|
|
174
|
-
}
|
|
175
|
-
if (this.isAppEnabled("cloudflared") || this.isAppEnabled("traefik")) {
|
|
176
|
-
items.push({
|
|
177
|
-
name: "☁️ Cloudflare Tunnel",
|
|
178
|
-
description: "Setup or configure Cloudflare Tunnel via API",
|
|
179
|
-
action: () => this.showScreen(CloudflaredSetup),
|
|
180
|
-
})
|
|
181
|
-
}
|
|
182
|
-
// Bookmark generation options
|
|
183
|
-
const generateAndOpenBookmarks = async (type: "local" | "remote") => {
|
|
184
|
-
await saveBookmarks(this.config, type)
|
|
185
|
-
// Open in browser if easiarr service is enabled
|
|
186
|
-
if (this.isAppEnabled("easiarr")) {
|
|
187
|
-
const port = this.config.apps.find((a) => a.id === "easiarr")?.port ?? 3010
|
|
188
|
-
const filename = type === "remote" ? "bookmarks-remote.html" : "bookmarks-local.html"
|
|
189
|
-
await openUrl(`http://localhost:${port}/${filename}`)
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (this.config.traefik?.enabled) {
|
|
194
|
-
items.push({
|
|
195
|
-
name: "📑 Bookmarks (Local URLs)",
|
|
196
|
-
description: "Generate bookmarks using localhost addresses",
|
|
197
|
-
action: async () => generateAndOpenBookmarks("local"),
|
|
198
|
-
})
|
|
199
|
-
items.push({
|
|
200
|
-
name: "📑 Bookmarks (Traefik URLs)",
|
|
201
|
-
description: `Generate bookmarks using ${this.config.traefik.domain} addresses`,
|
|
202
|
-
action: async () => generateAndOpenBookmarks("remote"),
|
|
203
|
-
})
|
|
204
|
-
} else {
|
|
205
|
-
items.push({
|
|
206
|
-
name: "📑 Generate Bookmarks",
|
|
207
|
-
description: "Create browser-importable bookmarks file",
|
|
208
|
-
action: async () => generateAndOpenBookmarks("local"),
|
|
209
|
-
})
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
items.push({
|
|
213
|
-
name: "❌ Exit",
|
|
214
|
-
description: "Close easiarr",
|
|
215
|
-
action: () => process.exit(0),
|
|
216
|
-
})
|
|
217
|
-
|
|
218
|
-
return items
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
private showScreen(ScreenClass: ScreenConstructor): void {
|
|
222
|
-
this.menu.blur()
|
|
223
|
-
this.page.visible = false
|
|
224
|
-
const screen = new ScreenClass(this.renderer as CliRenderer, this.config, () => {
|
|
225
|
-
this.page.visible = true
|
|
226
|
-
this.menu.focus()
|
|
227
|
-
})
|
|
228
|
-
this.container.add(screen)
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
private render(): void {
|
|
232
|
-
const { container: page, content } = createPageLayout(this.renderer as CliRenderer, {
|
|
233
|
-
title: "Main Menu",
|
|
234
|
-
stepInfo: "Docker Compose Generator for *arr Ecosystem",
|
|
235
|
-
footerHint: [{ type: "key", key: "Enter", value: "Select" }],
|
|
236
|
-
})
|
|
237
|
-
this.page = page
|
|
238
|
-
|
|
239
|
-
// Config info
|
|
240
|
-
const configBox = new BoxRenderable(this.renderer, {
|
|
241
|
-
width: "100%",
|
|
242
|
-
flexDirection: "column",
|
|
243
|
-
marginBottom: 1,
|
|
244
|
-
})
|
|
245
|
-
|
|
246
|
-
configBox.add(
|
|
247
|
-
new TextRenderable(this.renderer, {
|
|
248
|
-
id: "config-info-header",
|
|
249
|
-
content: "Configuration Overview:",
|
|
250
|
-
fg: "#4a9eff",
|
|
251
|
-
})
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
configBox.add(new BoxRenderable(this.renderer, { width: 1, height: 1 })) // Spacer
|
|
255
|
-
|
|
256
|
-
configBox.add(
|
|
257
|
-
new TextRenderable(this.renderer, {
|
|
258
|
-
id: "config-info",
|
|
259
|
-
content: ` 📁 Root: ${this.config.rootDir}`,
|
|
260
|
-
fg: "#aaaaaa",
|
|
261
|
-
})
|
|
262
|
-
)
|
|
263
|
-
|
|
264
|
-
configBox.add(
|
|
265
|
-
new TextRenderable(this.renderer, {
|
|
266
|
-
id: "apps-info",
|
|
267
|
-
content: ` Apps: ${this.config.apps.filter((a) => a.enabled).length} configured`,
|
|
268
|
-
fg: "#aaaaaa",
|
|
269
|
-
})
|
|
270
|
-
)
|
|
271
|
-
|
|
272
|
-
content.add(configBox)
|
|
273
|
-
|
|
274
|
-
content.add(new TextRenderable(this.renderer, { id: "spacer2", content: " " }))
|
|
275
|
-
|
|
276
|
-
// Build menu items dynamically based on enabled apps
|
|
277
|
-
this.menuItems = this.buildMenuItems()
|
|
278
|
-
|
|
279
|
-
// Menu
|
|
280
|
-
this.menu = new SelectRenderable(this.renderer, {
|
|
281
|
-
id: "main-menu-select",
|
|
282
|
-
width: "100%",
|
|
283
|
-
flexGrow: 1,
|
|
284
|
-
options: this.menuItems.map((item) => ({ name: item.name, description: item.description })),
|
|
285
|
-
})
|
|
286
|
-
|
|
287
|
-
this.menu.on(SelectRenderableEvents.ITEM_SELECTED, async (index) => {
|
|
288
|
-
const item = this.menuItems[index]
|
|
289
|
-
if (item) {
|
|
290
|
-
await item.action()
|
|
291
|
-
}
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
content.add(this.menu)
|
|
295
|
-
this.menu.focus()
|
|
296
|
-
|
|
297
|
-
this.container.add(page)
|
|
298
|
-
}
|
|
299
|
-
}
|