weeb-cli 2.0.0__tar.gz → 2.1.0__tar.gz
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.
- {weeb_cli-2.0.0/weeb_cli.egg-info → weeb_cli-2.1.0}/PKG-INFO +3 -3
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/README.md +2 -2
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/pyproject.toml +1 -1
- weeb_cli-2.1.0/weeb_cli/__init__.py +1 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/commands/downloads.py +12 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/commands/search.py +12 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/commands/settings.py +207 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/commands/watchlist.py +30 -8
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/locales/en.json +31 -1
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/locales/tr.json +31 -1
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/main.py +18 -0
- weeb_cli-2.1.0/weeb_cli/services/tracker.py +737 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0/weeb_cli.egg-info}/PKG-INFO +3 -3
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli.egg-info/SOURCES.txt +1 -0
- weeb_cli-2.0.0/weeb_cli/__init__.py +0 -1
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/LICENSE +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/setup.cfg +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/__main__.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/commands/setup.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/config.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/i18n.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/providers/__init__.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/providers/allanime.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/providers/animecix.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/providers/anizle.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/providers/base.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/providers/extractors/__init__.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/providers/extractors/megacloud.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/providers/hianime.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/providers/registry.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/providers/turkanime.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/services/__init__.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/services/database.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/services/dependency_manager.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/services/details.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/services/downloader.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/services/local_library.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/services/logger.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/services/notifier.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/services/player.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/services/progress.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/services/scraper.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/services/search.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/services/updater.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/services/watch.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/ui/__init__.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/ui/header.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/ui/menu.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli/ui/prompt.py +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli.egg-info/dependency_links.txt +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli.egg-info/entry_points.txt +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli.egg-info/requires.txt +0 -0
- {weeb_cli-2.0.0 → weeb_cli-2.1.0}/weeb_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: weeb-cli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: Tarayıcı yok, reklam yok, dikkat dağıtıcı unsur yok. Sadece siz ve eşsiz bir anime izleme deneyimi.
|
|
5
5
|
Author-email: ewgsta <ewgst@proton.me>
|
|
6
6
|
License-Expression: CC-BY-NC-ND-4.0
|
|
@@ -25,7 +25,7 @@ Requires-Dist: appdirs
|
|
|
25
25
|
Dynamic: license-file
|
|
26
26
|
|
|
27
27
|
<p align="center">
|
|
28
|
-
<img src="weeb_landing/logo/
|
|
28
|
+
<img src="weeb_landing/logo/512x512.webp" alt="Weeb CLI Logo" width="120">
|
|
29
29
|
</p>
|
|
30
30
|
|
|
31
31
|
<h1 align="center">Weeb CLI</h1>
|
|
@@ -124,7 +124,7 @@ pip install -e .
|
|
|
124
124
|
## Kullanım
|
|
125
125
|
|
|
126
126
|
```bash
|
|
127
|
-
weeb
|
|
127
|
+
weeb-cli
|
|
128
128
|
```
|
|
129
129
|
|
|
130
130
|
### Klavye Kontrolleri
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="weeb_landing/logo/
|
|
2
|
+
<img src="weeb_landing/logo/512x512.webp" alt="Weeb CLI Logo" width="120">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<h1 align="center">Weeb CLI</h1>
|
|
@@ -98,7 +98,7 @@ pip install -e .
|
|
|
98
98
|
## Kullanım
|
|
99
99
|
|
|
100
100
|
```bash
|
|
101
|
-
weeb
|
|
101
|
+
weeb-cli
|
|
102
102
|
```
|
|
103
103
|
|
|
104
104
|
### Klavye Kontrolleri
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "weeb-cli"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.1.0"
|
|
8
8
|
description = "Tarayıcı yok, reklam yok, dikkat dağıtıcı unsur yok. Sadece siz ve eşsiz bir anime izleme deneyimi."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "ewgsta", email = "ewgst@proton.me" }]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.1.0"
|
|
@@ -348,6 +348,18 @@ def play_local_episode(anime, episode):
|
|
|
348
348
|
episode["number"],
|
|
349
349
|
anime["episode_count"]
|
|
350
350
|
)
|
|
351
|
+
|
|
352
|
+
from weeb_cli.services.tracker import anilist_tracker, mal_tracker
|
|
353
|
+
anilist_tracker.update_progress(
|
|
354
|
+
anime["title"],
|
|
355
|
+
episode["number"],
|
|
356
|
+
anime["episode_count"]
|
|
357
|
+
)
|
|
358
|
+
mal_tracker.update_progress(
|
|
359
|
+
anime["title"],
|
|
360
|
+
episode["number"],
|
|
361
|
+
anime["episode_count"]
|
|
362
|
+
)
|
|
351
363
|
except:
|
|
352
364
|
pass
|
|
353
365
|
|
|
@@ -327,6 +327,18 @@ def handle_watch_flow(slug, details):
|
|
|
327
327
|
total_episodes=total_eps
|
|
328
328
|
)
|
|
329
329
|
|
|
330
|
+
from weeb_cli.services.tracker import anilist_tracker, mal_tracker
|
|
331
|
+
anilist_tracker.update_progress(
|
|
332
|
+
details.get("title"),
|
|
333
|
+
n,
|
|
334
|
+
total_eps
|
|
335
|
+
)
|
|
336
|
+
mal_tracker.update_progress(
|
|
337
|
+
details.get("title"),
|
|
338
|
+
n,
|
|
339
|
+
total_eps
|
|
340
|
+
)
|
|
341
|
+
|
|
330
342
|
completed_ids.add(n)
|
|
331
343
|
if n >= next_ep_num:
|
|
332
344
|
next_ep_num = n + 1
|
|
@@ -65,6 +65,9 @@ def open_settings():
|
|
|
65
65
|
if config.get("ytdlp_enabled"):
|
|
66
66
|
choices.append(opt_ytdlp_conf)
|
|
67
67
|
|
|
68
|
+
opt_trackers = i18n.get("settings.trackers")
|
|
69
|
+
choices.append(opt_trackers)
|
|
70
|
+
|
|
68
71
|
try:
|
|
69
72
|
answer = questionary.select(
|
|
70
73
|
i18n.get("settings.title"),
|
|
@@ -98,6 +101,8 @@ def open_settings():
|
|
|
98
101
|
toggle_config("ytdlp_enabled", "yt-dlp")
|
|
99
102
|
elif answer == opt_ytdlp_conf:
|
|
100
103
|
ytdlp_settings_menu()
|
|
104
|
+
elif answer == opt_trackers:
|
|
105
|
+
trackers_menu()
|
|
101
106
|
elif answer is None:
|
|
102
107
|
return
|
|
103
108
|
|
|
@@ -378,3 +383,205 @@ def manage_drive(drive):
|
|
|
378
383
|
|
|
379
384
|
except KeyboardInterrupt:
|
|
380
385
|
return
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
def trackers_menu():
|
|
389
|
+
while True:
|
|
390
|
+
console.clear()
|
|
391
|
+
show_header(i18n.get("settings.trackers"))
|
|
392
|
+
|
|
393
|
+
opt_anilist = "AniList"
|
|
394
|
+
opt_mal = "MyAnimeList"
|
|
395
|
+
|
|
396
|
+
try:
|
|
397
|
+
sel = questionary.select(
|
|
398
|
+
i18n.get("downloads.action_prompt"),
|
|
399
|
+
choices=[opt_anilist, opt_mal],
|
|
400
|
+
pointer=">",
|
|
401
|
+
use_shortcuts=False
|
|
402
|
+
).ask()
|
|
403
|
+
|
|
404
|
+
if sel is None:
|
|
405
|
+
return
|
|
406
|
+
|
|
407
|
+
if sel == opt_anilist:
|
|
408
|
+
anilist_settings_menu()
|
|
409
|
+
elif sel == opt_mal:
|
|
410
|
+
mal_settings_menu()
|
|
411
|
+
|
|
412
|
+
except KeyboardInterrupt:
|
|
413
|
+
return
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def anilist_settings_menu():
|
|
417
|
+
from weeb_cli.services.tracker import anilist_tracker
|
|
418
|
+
|
|
419
|
+
while True:
|
|
420
|
+
console.clear()
|
|
421
|
+
show_header("AniList")
|
|
422
|
+
|
|
423
|
+
if anilist_tracker.is_authenticated():
|
|
424
|
+
username = anilist_tracker.get_username()
|
|
425
|
+
console.print(f"[green]{i18n.t('settings.anilist_connected', user=username)}[/green]\n")
|
|
426
|
+
|
|
427
|
+
pending = anilist_tracker.get_pending_count()
|
|
428
|
+
if pending > 0:
|
|
429
|
+
console.print(f"[yellow]{i18n.t('settings.anilist_pending', count=pending)}[/yellow]\n")
|
|
430
|
+
|
|
431
|
+
opt_sync = i18n.get("settings.anilist_sync")
|
|
432
|
+
opt_logout = i18n.get("settings.anilist_logout")
|
|
433
|
+
|
|
434
|
+
choices = []
|
|
435
|
+
if pending > 0:
|
|
436
|
+
choices.append(opt_sync)
|
|
437
|
+
choices.append(opt_logout)
|
|
438
|
+
|
|
439
|
+
try:
|
|
440
|
+
sel = questionary.select(
|
|
441
|
+
i18n.get("downloads.action_prompt"),
|
|
442
|
+
choices=choices,
|
|
443
|
+
pointer=">",
|
|
444
|
+
use_shortcuts=False
|
|
445
|
+
).ask()
|
|
446
|
+
|
|
447
|
+
if sel is None:
|
|
448
|
+
return
|
|
449
|
+
|
|
450
|
+
if sel == opt_sync:
|
|
451
|
+
with console.status(i18n.get("common.processing"), spinner="dots"):
|
|
452
|
+
synced = anilist_tracker.sync_pending()
|
|
453
|
+
console.print(f"[green]{i18n.t('settings.anilist_synced', count=synced)}[/green]")
|
|
454
|
+
time.sleep(1)
|
|
455
|
+
elif sel == opt_logout:
|
|
456
|
+
confirm = questionary.confirm(
|
|
457
|
+
i18n.get("settings.confirm_logout"),
|
|
458
|
+
default=False
|
|
459
|
+
).ask()
|
|
460
|
+
if confirm:
|
|
461
|
+
anilist_tracker.logout()
|
|
462
|
+
console.print(f"[green]{i18n.get('settings.anilist_logged_out')}[/green]")
|
|
463
|
+
time.sleep(1)
|
|
464
|
+
return
|
|
465
|
+
|
|
466
|
+
except KeyboardInterrupt:
|
|
467
|
+
return
|
|
468
|
+
else:
|
|
469
|
+
console.print(f"[dim]{i18n.get('settings.anilist_not_connected')}[/dim]\n")
|
|
470
|
+
|
|
471
|
+
opt_login = i18n.get("settings.anilist_login")
|
|
472
|
+
|
|
473
|
+
try:
|
|
474
|
+
sel = questionary.select(
|
|
475
|
+
i18n.get("downloads.action_prompt"),
|
|
476
|
+
choices=[opt_login],
|
|
477
|
+
pointer=">",
|
|
478
|
+
use_shortcuts=False
|
|
479
|
+
).ask()
|
|
480
|
+
|
|
481
|
+
if sel is None:
|
|
482
|
+
return
|
|
483
|
+
|
|
484
|
+
if sel == opt_login:
|
|
485
|
+
console.print(f"\n[cyan]{i18n.get('settings.anilist_opening_browser')}[/cyan]")
|
|
486
|
+
console.print(f"[dim]{i18n.get('settings.anilist_waiting')}[/dim]\n")
|
|
487
|
+
|
|
488
|
+
with console.status(i18n.get("common.processing"), spinner="dots"):
|
|
489
|
+
token = anilist_tracker.start_auth_server(timeout=120)
|
|
490
|
+
|
|
491
|
+
if token:
|
|
492
|
+
success = anilist_tracker.authenticate(token)
|
|
493
|
+
if success:
|
|
494
|
+
console.print(f"[green]{i18n.get('settings.anilist_login_success')}[/green]")
|
|
495
|
+
else:
|
|
496
|
+
console.print(f"[red]{i18n.get('settings.anilist_login_failed')}[/red]")
|
|
497
|
+
else:
|
|
498
|
+
console.print(f"[yellow]{i18n.get('settings.anilist_timeout')}[/yellow]")
|
|
499
|
+
time.sleep(1)
|
|
500
|
+
|
|
501
|
+
except KeyboardInterrupt:
|
|
502
|
+
return
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
def mal_settings_menu():
|
|
506
|
+
from weeb_cli.services.tracker import mal_tracker
|
|
507
|
+
|
|
508
|
+
while True:
|
|
509
|
+
console.clear()
|
|
510
|
+
show_header("MyAnimeList")
|
|
511
|
+
|
|
512
|
+
if mal_tracker.is_authenticated():
|
|
513
|
+
username = mal_tracker.get_username()
|
|
514
|
+
console.print(f"[green]{i18n.t('settings.mal_connected', user=username)}[/green]\n")
|
|
515
|
+
|
|
516
|
+
pending = mal_tracker.get_pending_count()
|
|
517
|
+
if pending > 0:
|
|
518
|
+
console.print(f"[yellow]{i18n.t('settings.mal_pending', count=pending)}[/yellow]\n")
|
|
519
|
+
|
|
520
|
+
opt_sync = i18n.get("settings.mal_sync")
|
|
521
|
+
opt_logout = i18n.get("settings.mal_logout")
|
|
522
|
+
|
|
523
|
+
choices = []
|
|
524
|
+
if pending > 0:
|
|
525
|
+
choices.append(opt_sync)
|
|
526
|
+
choices.append(opt_logout)
|
|
527
|
+
|
|
528
|
+
try:
|
|
529
|
+
sel = questionary.select(
|
|
530
|
+
i18n.get("downloads.action_prompt"),
|
|
531
|
+
choices=choices,
|
|
532
|
+
pointer=">",
|
|
533
|
+
use_shortcuts=False
|
|
534
|
+
).ask()
|
|
535
|
+
|
|
536
|
+
if sel is None:
|
|
537
|
+
return
|
|
538
|
+
|
|
539
|
+
if sel == opt_sync:
|
|
540
|
+
with console.status(i18n.get("common.processing"), spinner="dots"):
|
|
541
|
+
synced = mal_tracker.sync_pending()
|
|
542
|
+
console.print(f"[green]{i18n.t('settings.mal_synced', count=synced)}[/green]")
|
|
543
|
+
time.sleep(1)
|
|
544
|
+
elif sel == opt_logout:
|
|
545
|
+
confirm = questionary.confirm(
|
|
546
|
+
i18n.get("settings.confirm_logout"),
|
|
547
|
+
default=False
|
|
548
|
+
).ask()
|
|
549
|
+
if confirm:
|
|
550
|
+
mal_tracker.logout()
|
|
551
|
+
console.print(f"[green]{i18n.get('settings.mal_logged_out')}[/green]")
|
|
552
|
+
time.sleep(1)
|
|
553
|
+
return
|
|
554
|
+
|
|
555
|
+
except KeyboardInterrupt:
|
|
556
|
+
return
|
|
557
|
+
else:
|
|
558
|
+
console.print(f"[dim]{i18n.get('settings.mal_not_connected')}[/dim]\n")
|
|
559
|
+
|
|
560
|
+
opt_login = i18n.get("settings.mal_login")
|
|
561
|
+
|
|
562
|
+
try:
|
|
563
|
+
sel = questionary.select(
|
|
564
|
+
i18n.get("downloads.action_prompt"),
|
|
565
|
+
choices=[opt_login],
|
|
566
|
+
pointer=">",
|
|
567
|
+
use_shortcuts=False
|
|
568
|
+
).ask()
|
|
569
|
+
|
|
570
|
+
if sel is None:
|
|
571
|
+
return
|
|
572
|
+
|
|
573
|
+
if sel == opt_login:
|
|
574
|
+
console.print(f"\n[cyan]{i18n.get('settings.mal_opening_browser')}[/cyan]")
|
|
575
|
+
console.print(f"[dim]{i18n.get('settings.mal_waiting')}[/dim]\n")
|
|
576
|
+
|
|
577
|
+
with console.status(i18n.get("common.processing"), spinner="dots"):
|
|
578
|
+
user = mal_tracker.start_auth_flow(timeout=120)
|
|
579
|
+
|
|
580
|
+
if user:
|
|
581
|
+
console.print(f"[green]{i18n.get('settings.mal_login_success')}[/green]")
|
|
582
|
+
else:
|
|
583
|
+
console.print(f"[red]{i18n.get('settings.mal_login_failed')}[/red]")
|
|
584
|
+
time.sleep(1)
|
|
585
|
+
|
|
586
|
+
except KeyboardInterrupt:
|
|
587
|
+
return
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import questionary
|
|
2
|
+
from pathlib import Path
|
|
2
3
|
from rich.console import Console
|
|
3
4
|
from rich.table import Table
|
|
4
5
|
from weeb_cli.i18n import i18n
|
|
@@ -83,6 +84,8 @@ def show_completed_list():
|
|
|
83
84
|
|
|
84
85
|
def show_in_progress_list():
|
|
85
86
|
from weeb_cli.commands.search import show_anime_details
|
|
87
|
+
from weeb_cli.commands.downloads import show_anime_episodes
|
|
88
|
+
from weeb_cli.services.local_library import local_library
|
|
86
89
|
|
|
87
90
|
console.clear()
|
|
88
91
|
show_header(i18n.get("watchlist.in_progress"))
|
|
@@ -97,6 +100,8 @@ def show_in_progress_list():
|
|
|
97
100
|
pass
|
|
98
101
|
return
|
|
99
102
|
|
|
103
|
+
indexed_anime = {a["title"].lower(): a for a in local_library.get_indexed_anime()}
|
|
104
|
+
|
|
100
105
|
choices = []
|
|
101
106
|
for anime in in_progress:
|
|
102
107
|
watched = len(anime.get("completed", []))
|
|
@@ -104,9 +109,13 @@ def show_in_progress_list():
|
|
|
104
109
|
total_str = str(total) if total > 0 else "?"
|
|
105
110
|
title = anime.get("title", anime["slug"])
|
|
106
111
|
next_ep = anime.get("last_watched", 0) + 1
|
|
112
|
+
|
|
113
|
+
is_local = title.lower() in indexed_anime
|
|
114
|
+
prefix = "[dim]●[/dim] " if is_local else ""
|
|
115
|
+
|
|
107
116
|
choices.append(questionary.Choice(
|
|
108
117
|
title=f"{title} [{watched}/{total_str}] - {i18n.get('watchlist.next')}: {next_ep}",
|
|
109
|
-
value=anime
|
|
118
|
+
value={"anime": anime, "is_local": is_local, "local_data": indexed_anime.get(title.lower())}
|
|
110
119
|
))
|
|
111
120
|
|
|
112
121
|
try:
|
|
@@ -118,13 +127,26 @@ def show_in_progress_list():
|
|
|
118
127
|
).ask()
|
|
119
128
|
|
|
120
129
|
if selected:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
130
|
+
if selected["is_local"] and selected["local_data"]:
|
|
131
|
+
local_data = selected["local_data"]
|
|
132
|
+
anime_path = local_data["folder_path"]
|
|
133
|
+
anime_info = {
|
|
134
|
+
"title": local_data["title"],
|
|
135
|
+
"path": anime_path,
|
|
136
|
+
"episodes": local_library._scan_anime_folder(Path(anime_path)),
|
|
137
|
+
"episode_count": local_data["episode_count"],
|
|
138
|
+
"source": local_data["source_name"]
|
|
139
|
+
}
|
|
140
|
+
show_anime_episodes(anime_info)
|
|
141
|
+
else:
|
|
142
|
+
anime = selected["anime"]
|
|
143
|
+
anime_data = {
|
|
144
|
+
"id": anime["slug"],
|
|
145
|
+
"slug": anime["slug"],
|
|
146
|
+
"title": anime.get("title", anime["slug"]),
|
|
147
|
+
"name": anime.get("title", anime["slug"])
|
|
148
|
+
}
|
|
149
|
+
show_anime_details(anime_data)
|
|
128
150
|
|
|
129
151
|
except KeyboardInterrupt:
|
|
130
152
|
pass
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"settings": {
|
|
28
28
|
"title": "Settings",
|
|
29
|
+
"trackers": "MyAnimeList & AniList",
|
|
29
30
|
"language": "Change Language",
|
|
30
31
|
"source": "Select Scraping Source",
|
|
31
32
|
"aria2": "Aria2 Downloader",
|
|
@@ -59,7 +60,36 @@
|
|
|
59
60
|
"remove_drive": "Remove Drive",
|
|
60
61
|
"confirm_remove": "Are you sure you want to remove this drive?",
|
|
61
62
|
"drive_renamed": "Drive renamed.",
|
|
62
|
-
"drive_removed": "Drive removed."
|
|
63
|
+
"drive_removed": "Drive removed.",
|
|
64
|
+
"anilist": "AniList",
|
|
65
|
+
"anilist_connected": "Connected: {user}",
|
|
66
|
+
"anilist_not_connected": "Connect your AniList account to sync your watch history.",
|
|
67
|
+
"anilist_login": "Connect to AniList",
|
|
68
|
+
"anilist_logout": "Disconnect",
|
|
69
|
+
"anilist_sync": "Sync Pending Updates",
|
|
70
|
+
"anilist_pending": "{count} updates pending",
|
|
71
|
+
"anilist_synced": "{count} updates synced",
|
|
72
|
+
"anilist_opening_browser": "Opening browser...",
|
|
73
|
+
"anilist_waiting": "Log in via browser, it will be detected automatically...",
|
|
74
|
+
"anilist_timeout": "Timeout. Please try again.",
|
|
75
|
+
"anilist_paste_token": "After logging in, paste the token from the URL here:",
|
|
76
|
+
"anilist_login_success": "Successfully connected to AniList!",
|
|
77
|
+
"anilist_login_failed": "Connection failed. Token may be invalid.",
|
|
78
|
+
"anilist_logged_out": "Disconnected from AniList.",
|
|
79
|
+
"confirm_logout": "Are you sure you want to disconnect?",
|
|
80
|
+
"mal": "MyAnimeList",
|
|
81
|
+
"mal_connected": "Connected: {user}",
|
|
82
|
+
"mal_not_connected": "Connect your MAL account to sync your watch history.",
|
|
83
|
+
"mal_login": "Connect to MAL",
|
|
84
|
+
"mal_logout": "Disconnect",
|
|
85
|
+
"mal_sync": "Sync Pending Updates",
|
|
86
|
+
"mal_pending": "{count} updates pending",
|
|
87
|
+
"mal_synced": "{count} updates synced",
|
|
88
|
+
"mal_opening_browser": "Opening browser...",
|
|
89
|
+
"mal_waiting": "Log in via browser, it will be detected automatically...",
|
|
90
|
+
"mal_login_success": "Successfully connected to MAL!",
|
|
91
|
+
"mal_login_failed": "Connection failed. Please try again.",
|
|
92
|
+
"mal_logged_out": "Disconnected from MAL."
|
|
63
93
|
},
|
|
64
94
|
"setup": {
|
|
65
95
|
"welcome": "Welcome to Weeb CLI!",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"settings": {
|
|
28
28
|
"title": "Ayarlar",
|
|
29
|
+
"trackers": "MyAnimeList & AniList",
|
|
29
30
|
"language": "Dil Değiştir",
|
|
30
31
|
"source": "Kaynak Seçimi",
|
|
31
32
|
"aria2": "Aria2 İndirici",
|
|
@@ -59,7 +60,36 @@
|
|
|
59
60
|
"remove_drive": "Diski Kaldır",
|
|
60
61
|
"confirm_remove": "Bu diski kaldırmak istediğinize emin misiniz?",
|
|
61
62
|
"drive_renamed": "Disk ismi değiştirildi.",
|
|
62
|
-
"drive_removed": "Disk kaldırıldı."
|
|
63
|
+
"drive_removed": "Disk kaldırıldı.",
|
|
64
|
+
"anilist": "AniList",
|
|
65
|
+
"anilist_connected": "Bağlı: {user}",
|
|
66
|
+
"anilist_not_connected": "AniList hesabınıza bağlanarak izleme geçmişinizi senkronize edebilirsiniz.",
|
|
67
|
+
"anilist_login": "AniList'e Bağlan",
|
|
68
|
+
"anilist_logout": "Bağlantıyı Kes",
|
|
69
|
+
"anilist_sync": "Bekleyenleri Senkronize Et",
|
|
70
|
+
"anilist_pending": "{count} güncelleme bekliyor",
|
|
71
|
+
"anilist_synced": "{count} güncelleme senkronize edildi",
|
|
72
|
+
"anilist_opening_browser": "Tarayıcı açılıyor...",
|
|
73
|
+
"anilist_waiting": "Tarayıcıda giriş yapın, otomatik olarak algılanacak...",
|
|
74
|
+
"anilist_timeout": "Zaman aşımı. Lütfen tekrar deneyin.",
|
|
75
|
+
"anilist_paste_token": "Tarayıcıda giriş yaptıktan sonra URL'deki token'ı buraya yapıştırın:",
|
|
76
|
+
"anilist_login_success": "AniList'e başarıyla bağlandı!",
|
|
77
|
+
"anilist_login_failed": "Bağlantı başarısız. Token geçersiz olabilir.",
|
|
78
|
+
"anilist_logged_out": "AniList bağlantısı kesildi.",
|
|
79
|
+
"confirm_logout": "Bağlantıyı kesmek istediğinize emin misiniz?",
|
|
80
|
+
"mal": "MyAnimeList",
|
|
81
|
+
"mal_connected": "Bağlı: {user}",
|
|
82
|
+
"mal_not_connected": "MAL hesabınıza bağlanarak izleme geçmişinizi senkronize edebilirsiniz.",
|
|
83
|
+
"mal_login": "MAL'a Bağlan",
|
|
84
|
+
"mal_logout": "Bağlantıyı Kes",
|
|
85
|
+
"mal_sync": "Bekleyenleri Senkronize Et",
|
|
86
|
+
"mal_pending": "{count} güncelleme bekliyor",
|
|
87
|
+
"mal_synced": "{count} güncelleme senkronize edildi",
|
|
88
|
+
"mal_opening_browser": "Tarayıcı açılıyor...",
|
|
89
|
+
"mal_waiting": "Tarayıcıda giriş yapın, otomatik olarak algılanacak...",
|
|
90
|
+
"mal_login_success": "MAL'a başarıyla bağlandı!",
|
|
91
|
+
"mal_login_failed": "Bağlantı başarısız. Lütfen tekrar deneyin.",
|
|
92
|
+
"mal_logged_out": "MAL bağlantısı kesildi."
|
|
63
93
|
},
|
|
64
94
|
"setup": {
|
|
65
95
|
"welcome": "Weeb CLI'a Hoş Geldiniz!",
|
|
@@ -54,6 +54,7 @@ def start():
|
|
|
54
54
|
|
|
55
55
|
check_network()
|
|
56
56
|
check_ffmpeg_silent()
|
|
57
|
+
sync_anilist_pending()
|
|
57
58
|
|
|
58
59
|
show_main_menu()
|
|
59
60
|
|
|
@@ -76,6 +77,23 @@ def check_incomplete_downloads():
|
|
|
76
77
|
except KeyboardInterrupt:
|
|
77
78
|
queue_manager.cancel_incomplete()
|
|
78
79
|
|
|
80
|
+
def sync_anilist_pending():
|
|
81
|
+
from weeb_cli.services.tracker import anilist_tracker, mal_tracker
|
|
82
|
+
|
|
83
|
+
if anilist_tracker.is_authenticated():
|
|
84
|
+
pending = anilist_tracker.get_pending_count()
|
|
85
|
+
if pending > 0:
|
|
86
|
+
synced = anilist_tracker.sync_pending()
|
|
87
|
+
if synced > 0:
|
|
88
|
+
console.print(f"[dim]AniList: {synced} {i18n.get('settings.anilist_synced').split()[1]}[/dim]")
|
|
89
|
+
|
|
90
|
+
if mal_tracker.is_authenticated():
|
|
91
|
+
pending = mal_tracker.get_pending_count()
|
|
92
|
+
if pending > 0:
|
|
93
|
+
synced = mal_tracker.sync_pending()
|
|
94
|
+
if synced > 0:
|
|
95
|
+
console.print(f"[dim]MAL: {synced} {i18n.get('settings.mal_synced').split()[1]}[/dim]")
|
|
96
|
+
|
|
79
97
|
@app.callback(invoke_without_command=True)
|
|
80
98
|
def main(ctx: typer.Context):
|
|
81
99
|
if ctx.invoked_subcommand is None:
|