weeb-cli 2.12.0__tar.gz → 2.13.2__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.
Files changed (129) hide show
  1. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/PKG-INFO +17 -6
  2. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/README.md +15 -4
  3. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/pyproject.toml +2 -2
  4. weeb_cli-2.13.2/weeb_cli/__init__.py +25 -0
  5. weeb_cli-2.13.2/weeb_cli/commands/__init__.py +44 -0
  6. weeb_cli-2.13.2/weeb_cli/commands/search/__init__.py +28 -0
  7. weeb_cli-2.13.2/weeb_cli/commands/settings/__init__.py +32 -0
  8. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/settings/settings_config.py +11 -0
  9. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/settings/settings_menu.py +5 -1
  10. weeb_cli-2.13.2/weeb_cli/config.py +169 -0
  11. weeb_cli-2.13.2/weeb_cli/exceptions.py +112 -0
  12. weeb_cli-2.13.2/weeb_cli/i18n.py +148 -0
  13. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/locales/de.json +1 -0
  14. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/locales/en.json +1 -0
  15. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/locales/pl.json +1 -0
  16. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/locales/tr.json +1 -0
  17. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/main.py +5 -0
  18. weeb_cli-2.13.2/weeb_cli/providers/__init__.py +52 -0
  19. weeb_cli-2.13.2/weeb_cli/providers/base.py +285 -0
  20. weeb_cli-2.13.2/weeb_cli/providers/de/__init__.py +12 -0
  21. weeb_cli-2.13.2/weeb_cli/providers/en/__init__.py +13 -0
  22. weeb_cli-2.13.2/weeb_cli/providers/extractors/__init__.py +25 -0
  23. weeb_cli-2.13.2/weeb_cli/providers/pl/__init__.py +12 -0
  24. weeb_cli-2.13.2/weeb_cli/providers/registry.py +207 -0
  25. weeb_cli-2.13.2/weeb_cli/providers/tr/__init__.py +15 -0
  26. weeb_cli-2.13.2/weeb_cli/services/__init__.py +57 -0
  27. weeb_cli-2.13.2/weeb_cli/services/aniskip.py +169 -0
  28. weeb_cli-2.13.2/weeb_cli/services/cache.py +375 -0
  29. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/player.py +36 -0
  30. weeb_cli-2.13.2/weeb_cli/ui/__init__.py +15 -0
  31. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli.egg-info/PKG-INFO +17 -6
  32. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli.egg-info/SOURCES.txt +2 -0
  33. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli.egg-info/requires.txt +1 -1
  34. weeb_cli-2.12.0/weeb_cli/__init__.py +0 -1
  35. weeb_cli-2.12.0/weeb_cli/commands/search/__init__.py +0 -3
  36. weeb_cli-2.12.0/weeb_cli/commands/settings/__init__.py +0 -3
  37. weeb_cli-2.12.0/weeb_cli/config.py +0 -71
  38. weeb_cli-2.12.0/weeb_cli/exceptions.py +0 -33
  39. weeb_cli-2.12.0/weeb_cli/i18n.py +0 -67
  40. weeb_cli-2.12.0/weeb_cli/providers/__init__.py +0 -15
  41. weeb_cli-2.12.0/weeb_cli/providers/base.py +0 -107
  42. weeb_cli-2.12.0/weeb_cli/providers/de/__init__.py +0 -0
  43. weeb_cli-2.12.0/weeb_cli/providers/en/__init__.py +0 -0
  44. weeb_cli-2.12.0/weeb_cli/providers/extractors/__init__.py +0 -0
  45. weeb_cli-2.12.0/weeb_cli/providers/pl/__init__.py +0 -0
  46. weeb_cli-2.12.0/weeb_cli/providers/registry.py +0 -70
  47. weeb_cli-2.12.0/weeb_cli/providers/tr/__init__.py +0 -0
  48. weeb_cli-2.12.0/weeb_cli/services/__init__.py +0 -0
  49. weeb_cli-2.12.0/weeb_cli/services/cache.py +0 -175
  50. weeb_cli-2.12.0/weeb_cli/ui/__init__.py +0 -1
  51. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/LICENSE +0 -0
  52. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/setup.cfg +0 -0
  53. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/tests/test_anilist_tracker.py +0 -0
  54. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/tests/test_aniworld_provider.py +0 -0
  55. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/tests/test_api.py +0 -0
  56. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/tests/test_cache.py +0 -0
  57. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/tests/test_exceptions.py +0 -0
  58. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/tests/test_kitsu_tracker.py +0 -0
  59. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/tests/test_mal_tracker.py +0 -0
  60. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/tests/test_providers.py +0 -0
  61. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/tests/test_sanitizer.py +0 -0
  62. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/tests/test_sanitizer_security.py +0 -0
  63. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/__main__.py +0 -0
  64. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/api.py +0 -0
  65. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/downloads.py +0 -0
  66. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/library.py +0 -0
  67. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/search/anime_details.py +0 -0
  68. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/search/download_flow.py +0 -0
  69. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/search/episode_utils.py +0 -0
  70. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/search/search_handlers.py +0 -0
  71. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/search/stream_utils.py +0 -0
  72. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/search/watch_flow.py +0 -0
  73. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/search.py +0 -0
  74. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/serve.py +0 -0
  75. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/settings/settings_backup.py +0 -0
  76. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/settings/settings_cache.py +0 -0
  77. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/settings/settings_download.py +0 -0
  78. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/settings/settings_drives.py +0 -0
  79. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/settings/settings_shortcuts.py +0 -0
  80. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/settings/settings_trackers.py +0 -0
  81. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/settings.py +0 -0
  82. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/setup.py +0 -0
  83. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/commands/watchlist.py +0 -0
  84. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/providers/de/aniworld.py +0 -0
  85. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/providers/en/allanime.py +0 -0
  86. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/providers/en/hianime.py +0 -0
  87. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/providers/extractors/doodstream.py +0 -0
  88. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/providers/extractors/filemoon.py +0 -0
  89. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/providers/extractors/megacloud.py +0 -0
  90. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/providers/extractors/streamtape.py +0 -0
  91. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/providers/extractors/vidoza.py +0 -0
  92. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/providers/extractors/voe.py +0 -0
  93. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/providers/pl/docchi.py +0 -0
  94. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/providers/tr/animecix.py +0 -0
  95. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/providers/tr/anizle.py +0 -0
  96. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/providers/tr/turkanime.py +0 -0
  97. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/providers/tr/weeb.py +0 -0
  98. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/_base.py +0 -0
  99. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/_tracker_base.py +0 -0
  100. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/database.py +0 -0
  101. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/dependency_manager.py +0 -0
  102. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/details.py +0 -0
  103. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/discord_rpc.py +0 -0
  104. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/downloader.py +0 -0
  105. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/error_handler.py +0 -0
  106. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/headless_downloader.py +0 -0
  107. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/local_library.py +0 -0
  108. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/logger.py +0 -0
  109. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/notifier.py +0 -0
  110. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/progress.py +0 -0
  111. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/scraper.py +0 -0
  112. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/search.py +0 -0
  113. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/shortcuts.py +0 -0
  114. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/stream_validator.py +0 -0
  115. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/tracker.py +0 -0
  116. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/updater.py +0 -0
  117. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/services/watch.py +0 -0
  118. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/templates/anilist_error.html +0 -0
  119. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/templates/anilist_success.html +0 -0
  120. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/templates/mal_error.html +0 -0
  121. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/templates/mal_success.html +0 -0
  122. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/ui/header.py +0 -0
  123. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/ui/menu.py +0 -0
  124. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/ui/prompt.py +0 -0
  125. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/utils/__init__.py +0 -0
  126. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli/utils/sanitizer.py +0 -0
  127. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli.egg-info/dependency_links.txt +0 -0
  128. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/weeb_cli.egg-info/entry_points.txt +0 -0
  129. {weeb_cli-2.12.0 → weeb_cli-2.13.2}/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.12.0
3
+ Version: 2.13.2
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: GPL-3.0-only
@@ -24,7 +24,7 @@ Requires-Dist: lxml
24
24
  Requires-Dist: pycryptodome
25
25
  Requires-Dist: curl_cffi
26
26
  Requires-Dist: appdirs
27
- Requires-Dist: prompt_toolkit<3.0.50,>=3.0.36
27
+ Requires-Dist: prompt_toolkit<3.0.53,>=3.0.36
28
28
  Requires-Dist: pyfiglet
29
29
  Requires-Dist: py7zr
30
30
  Requires-Dist: pypresence
@@ -51,6 +51,11 @@ Dynamic: license-file
51
51
  <strong>No browser, no ads, no distractions. Just you and an unparalleled anime viewing experience.</strong>
52
52
  </p>
53
53
 
54
+ <div align="center">
55
+ <a href="README.md">English</a> | <a href="md/tr/README.md">Türkçe</a> | <a href="md/de/README.md">Deutsch</a> | <a href="md/pl/README.md">Polski</a>
56
+ </div>
57
+ <br>
58
+
54
59
  <p align="center">
55
60
  <a href="https://github.com/ewgsta/weeb-cli/releases"><img src="https://img.shields.io/github/v/release/ewgsta/weeb-cli?style=flat-square" alt="Release"></a>
56
61
  <a href="https://github.com/ewgsta/weeb-cli/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-GPL--3.0-blue?style=flat-square" alt="License"></a>
@@ -63,7 +68,7 @@ Dynamic: license-file
63
68
  <a href="#features">Features</a> •
64
69
  <a href="#usage">Usage</a> •
65
70
  <a href="#sources">Sources</a> •
66
- <a href="README-TR.md">Türkçe</a>
71
+ <a href="https://ewgsta.github.io/weeb-cli/">Documentation</a>
67
72
  </p>
68
73
 
69
74
  ---
@@ -71,8 +76,10 @@ Dynamic: license-file
71
76
  ## Features
72
77
 
73
78
  ### Multiple Sources
74
- - **Turkish**: Animecix, Turkanime, Anizle
79
+ - **Turkish**: Animecix, Turkanime, Anizle, Weeb
75
80
  - **English**: HiAnime, AllAnime
81
+ - **German**: AniWorld
82
+ - **Polish**: Docchi
76
83
 
77
84
  ### Smart Streaming
78
85
  - High-quality HLS/MP4 playback with MPV
@@ -224,6 +231,8 @@ CMD ["weeb-cli", "serve", "--port", "9876", "--watch-dir", "/downloads/watch", "
224
231
  | Weeb | Turkish |
225
232
  | HiAnime | English |
226
233
  | AllAnime | English |
234
+ | AniWorld | German |
235
+ | Docchi | Polish |
227
236
 
228
237
  ---
229
238
 
@@ -235,7 +244,7 @@ Config location: `~/.weeb-cli/weeb.db` (SQLite)
235
244
 
236
245
  | Setting | Description | Default | Type |
237
246
  |---------|-------------|---------|------|
238
- | `language` | Interface language (tr/en) | `null` (asks on first run) | string |
247
+ | `language` | Interface language (tr/en/de/pl) | `null` (asks on first run) | string |
239
248
  | `scraping_source` | Active anime source | `animecix` | string |
240
249
  | `aria2_enabled` | Use Aria2 for downloads | `true` | boolean |
241
250
  | `aria2_max_connections` | Max connections per download | `16` | integer |
@@ -270,7 +279,7 @@ All settings can be modified through the interactive Settings menu.
270
279
  ## Roadmap
271
280
 
272
281
  ### Completed
273
- - [x] Multiple source support (TR/EN)
282
+ - [x] Multiple source support (TR/EN/DE/PL)
274
283
  - [x] MPV streaming
275
284
  - [x] Watch history and progress tracking
276
285
  - [x] Aria2/yt-dlp download integration
@@ -353,7 +362,9 @@ weeb-cli/
353
362
  │ │ └── sanitizer.py # Filename/path sanitization
354
363
  │ │
355
364
  │ ├── locales/ # Internationalization
365
+ │ │ ├── de.json # German translations
356
366
  │ │ ├── en.json # English translations
367
+ │ │ ├── pl.json # Polish translations
357
368
  │ │ └── tr.json # Turkish translations
358
369
  │ │
359
370
  │ ├── templates/ # HTML templates
@@ -8,6 +8,11 @@
8
8
  <strong>No browser, no ads, no distractions. Just you and an unparalleled anime viewing experience.</strong>
9
9
  </p>
10
10
 
11
+ <div align="center">
12
+ <a href="README.md">English</a> | <a href="md/tr/README.md">Türkçe</a> | <a href="md/de/README.md">Deutsch</a> | <a href="md/pl/README.md">Polski</a>
13
+ </div>
14
+ <br>
15
+
11
16
  <p align="center">
12
17
  <a href="https://github.com/ewgsta/weeb-cli/releases"><img src="https://img.shields.io/github/v/release/ewgsta/weeb-cli?style=flat-square" alt="Release"></a>
13
18
  <a href="https://github.com/ewgsta/weeb-cli/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-GPL--3.0-blue?style=flat-square" alt="License"></a>
@@ -20,7 +25,7 @@
20
25
  <a href="#features">Features</a> •
21
26
  <a href="#usage">Usage</a> •
22
27
  <a href="#sources">Sources</a> •
23
- <a href="README-TR.md">Türkçe</a>
28
+ <a href="https://ewgsta.github.io/weeb-cli/">Documentation</a>
24
29
  </p>
25
30
 
26
31
  ---
@@ -28,8 +33,10 @@
28
33
  ## Features
29
34
 
30
35
  ### Multiple Sources
31
- - **Turkish**: Animecix, Turkanime, Anizle
36
+ - **Turkish**: Animecix, Turkanime, Anizle, Weeb
32
37
  - **English**: HiAnime, AllAnime
38
+ - **German**: AniWorld
39
+ - **Polish**: Docchi
33
40
 
34
41
  ### Smart Streaming
35
42
  - High-quality HLS/MP4 playback with MPV
@@ -181,6 +188,8 @@ CMD ["weeb-cli", "serve", "--port", "9876", "--watch-dir", "/downloads/watch", "
181
188
  | Weeb | Turkish |
182
189
  | HiAnime | English |
183
190
  | AllAnime | English |
191
+ | AniWorld | German |
192
+ | Docchi | Polish |
184
193
 
185
194
  ---
186
195
 
@@ -192,7 +201,7 @@ Config location: `~/.weeb-cli/weeb.db` (SQLite)
192
201
 
193
202
  | Setting | Description | Default | Type |
194
203
  |---------|-------------|---------|------|
195
- | `language` | Interface language (tr/en) | `null` (asks on first run) | string |
204
+ | `language` | Interface language (tr/en/de/pl) | `null` (asks on first run) | string |
196
205
  | `scraping_source` | Active anime source | `animecix` | string |
197
206
  | `aria2_enabled` | Use Aria2 for downloads | `true` | boolean |
198
207
  | `aria2_max_connections` | Max connections per download | `16` | integer |
@@ -227,7 +236,7 @@ All settings can be modified through the interactive Settings menu.
227
236
  ## Roadmap
228
237
 
229
238
  ### Completed
230
- - [x] Multiple source support (TR/EN)
239
+ - [x] Multiple source support (TR/EN/DE/PL)
231
240
  - [x] MPV streaming
232
241
  - [x] Watch history and progress tracking
233
242
  - [x] Aria2/yt-dlp download integration
@@ -310,7 +319,9 @@ weeb-cli/
310
319
  │ │ └── sanitizer.py # Filename/path sanitization
311
320
  │ │
312
321
  │ ├── locales/ # Internationalization
322
+ │ │ ├── de.json # German translations
313
323
  │ │ ├── en.json # English translations
324
+ │ │ ├── pl.json # Polish translations
314
325
  │ │ └── tr.json # Turkish translations
315
326
  │ │
316
327
  │ ├── templates/ # HTML templates
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "weeb-cli"
7
- version = "2.12.0"
7
+ version = "2.13.2"
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" }]
@@ -27,7 +27,7 @@ dependencies = [
27
27
  "pycryptodome",
28
28
  "curl_cffi",
29
29
  "appdirs",
30
- "prompt_toolkit>=3.0.36,<3.0.50",
30
+ "prompt_toolkit>=3.0.36,<3.0.53",
31
31
  "pyfiglet",
32
32
  "py7zr",
33
33
  "pypresence",
@@ -0,0 +1,25 @@
1
+ """Weeb CLI - Terminal-based anime streaming and downloading application.
2
+
3
+ Weeb CLI provides a browser-free, ad-free anime viewing experience with support
4
+ for multiple anime sources across different languages (Turkish, English, German, Polish).
5
+
6
+ Features:
7
+ - Multi-source anime streaming and downloading
8
+ - Integration with tracking services (AniList, MyAnimeList, Kitsu)
9
+ - Local library management with external drive support
10
+ - Advanced download queue with Aria2 and yt-dlp
11
+ - Discord Rich Presence integration
12
+ - Multi-language support (TR, EN, DE, PL)
13
+
14
+ Example:
15
+ Basic usage::
16
+
17
+ $ weeb-cli start
18
+ $ weeb-cli api search "anime name"
19
+ $ weeb-cli serve --port 8080
20
+
21
+ Attributes:
22
+ __version__ (str): Current version of Weeb CLI.
23
+ """
24
+
25
+ __version__ = "2.13.2"
@@ -0,0 +1,44 @@
1
+ """Command handlers for Weeb CLI.
2
+
3
+ This package contains all CLI command implementations using Typer framework.
4
+ Commands provide both interactive (TUI) and non-interactive (API) interfaces.
5
+
6
+ Command Modules:
7
+ api: Non-interactive JSON API for scripts and automation
8
+ search: Anime search with history and filtering
9
+ downloads: Download queue management and monitoring
10
+ watchlist: Watch history and progress tracking
11
+ library: Local and virtual library management
12
+ settings: Configuration and user preferences
13
+ setup: Initial setup wizard
14
+ serve: Torznab server for *arr integration
15
+
16
+ Interactive Commands:
17
+ Most commands provide rich terminal UI with menus, prompts, and
18
+ progress indicators using Rich and Questionary libraries.
19
+
20
+ API Commands:
21
+ The api subcommand provides JSON output for headless operation
22
+ and integration with external tools.
23
+
24
+ Example:
25
+ Interactive mode::
26
+
27
+ $ weeb-cli start
28
+
29
+ API mode::
30
+
31
+ $ weeb-cli api search "anime name" --provider animecix
32
+ $ weeb-cli api episodes <anime-id> --provider animecix
33
+ """
34
+
35
+ __all__ = [
36
+ "api",
37
+ "search",
38
+ "downloads",
39
+ "watchlist",
40
+ "library",
41
+ "settings",
42
+ "setup",
43
+ "serve",
44
+ ]
@@ -0,0 +1,28 @@
1
+ """Search command submodules.
2
+
3
+ This package contains the implementation of the search command,
4
+ split into logical components for better maintainability.
5
+
6
+ Modules:
7
+ anime_details: Anime details display and selection
8
+ download_flow: Download workflow and queue management
9
+ episode_utils: Episode selection and filtering utilities
10
+ search_handlers: Search query handling and results display
11
+ stream_utils: Stream quality selection and validation
12
+ watch_flow: Watch workflow with player integration
13
+
14
+ The search command is the primary entry point for discovering and
15
+ accessing anime content across all providers.
16
+ """
17
+
18
+ from .search_handlers import search_anime
19
+
20
+ __all__ = [
21
+ "search_anime",
22
+ "anime_details",
23
+ "download_flow",
24
+ "episode_utils",
25
+ "search_handlers",
26
+ "stream_utils",
27
+ "watch_flow",
28
+ ]
@@ -0,0 +1,32 @@
1
+ """Settings command submodules.
2
+
3
+ This package contains the implementation of the settings command,
4
+ organized by configuration category.
5
+
6
+ Modules:
7
+ settings_menu: Main settings menu and navigation
8
+ settings_config: General configuration options
9
+ settings_download: Download-related settings
10
+ settings_cache: Cache management settings
11
+ settings_trackers: Tracker authentication and configuration
12
+ settings_drives: External drive management
13
+ settings_shortcuts: Keyboard shortcuts configuration
14
+ settings_backup: Backup and restore functionality
15
+
16
+ Each module handles a specific category of settings with dedicated
17
+ UI and validation logic.
18
+ """
19
+
20
+ from .settings_menu import open_settings
21
+
22
+ __all__ = [
23
+ "open_settings",
24
+ "settings_menu",
25
+ "settings_config",
26
+ "settings_download",
27
+ "settings_cache",
28
+ "settings_trackers",
29
+ "settings_drives",
30
+ "settings_shortcuts",
31
+ "settings_backup",
32
+ ]
@@ -3,6 +3,7 @@ import questionary
3
3
  from rich.console import Console
4
4
  from weeb_cli.i18n import i18n
5
5
  from weeb_cli.config import config
6
+ from weeb_cli.services.aniskip import aniskip_service
6
7
 
7
8
  console = Console()
8
9
 
@@ -38,6 +39,16 @@ def toggle_shortcuts():
38
39
  console.print(f"[green]{i18n.t(msg_key, tool=i18n.t('settings.shortcuts'))}[/green]")
39
40
  time.sleep(0.5)
40
41
 
42
+ def toggle_aniskip():
43
+ current = config.get("aniskip_enabled", False)
44
+ new_val = not current
45
+ config.set("aniskip_enabled", new_val)
46
+ aniskip_service.set_enabled(new_val)
47
+
48
+ msg_key = "settings.toggle_on" if new_val else "settings.toggle_off"
49
+ console.print(f"[green]{i18n.t(msg_key, tool=i18n.t('settings.aniskip'))}[/green]")
50
+ time.sleep(0.5)
51
+
41
52
  def change_language():
42
53
  from weeb_cli.services.scraper import scraper
43
54
 
@@ -3,7 +3,7 @@ from rich.console import Console
3
3
  from weeb_cli.i18n import i18n
4
4
  from weeb_cli.ui.header import show_header
5
5
  from weeb_cli.config import config
6
- from .settings_config import change_language, change_source, toggle_description, toggle_discord_rpc, toggle_shortcuts
6
+ from .settings_config import change_language, change_source, toggle_description, toggle_discord_rpc, toggle_shortcuts, toggle_aniskip
7
7
  from .settings_download import download_settings_menu, aria2_settings_menu, ytdlp_settings_menu, toggle_config
8
8
  from .settings_drives import external_drives_menu
9
9
  from .settings_trackers import trackers_menu
@@ -55,6 +55,7 @@ def _build_settings_menu():
55
55
  desc_state = i18n.t("common.enabled") if config.get("show_description", True) else i18n.t("common.disabled")
56
56
  discord_rpc_state = i18n.t("common.enabled") if config.get("discord_rpc_enabled", False) else i18n.t("common.disabled")
57
57
  shortcuts_state = i18n.t("common.enabled") if config.get("shortcuts_enabled", True) else i18n.t("common.disabled")
58
+ aniskip_state = i18n.t("common.enabled") if config.get("aniskip_enabled", False) else i18n.t("common.disabled")
58
59
 
59
60
  choices = [
60
61
  i18n.t("settings.language"),
@@ -63,6 +64,7 @@ def _build_settings_menu():
63
64
  i18n.t("settings.external_drives"),
64
65
  f"{i18n.t('settings.show_description')} [{desc_state}]",
65
66
  f"{i18n.t('settings.discord_rpc')} [{discord_rpc_state}]",
67
+ f"{i18n.t('settings.aniskip')} [{aniskip_state}]",
66
68
  f"{i18n.t('settings.shortcuts')} [{shortcuts_state}]",
67
69
  ]
68
70
 
@@ -103,6 +105,8 @@ def _handle_settings_action(answer):
103
105
  toggle_description()
104
106
  elif answer.startswith(i18n.t('settings.discord_rpc')):
105
107
  toggle_discord_rpc()
108
+ elif answer.startswith(i18n.t('settings.aniskip')):
109
+ toggle_aniskip()
106
110
  elif answer.startswith(i18n.t('settings.shortcuts')) and not answer.startswith(" ↳"):
107
111
  toggle_shortcuts()
108
112
  elif answer == f" ↳ {i18n.t('settings.shortcuts_config')}":
@@ -0,0 +1,169 @@
1
+ """Configuration management for Weeb CLI.
2
+
3
+ This module provides a centralized configuration system that stores settings
4
+ in a SQLite database with fallback to default values. Supports both interactive
5
+ and headless (API) modes.
6
+
7
+ Configuration is stored persistently in the database and can be accessed
8
+ throughout the application using the global `config` instance.
9
+
10
+ Example:
11
+ Basic usage::
12
+
13
+ from weeb_cli.config import config
14
+
15
+ # Get configuration value
16
+ download_dir = config.get("download_dir")
17
+ aria2_enabled = config.get("aria2_enabled", True)
18
+
19
+ # Set configuration value
20
+ config.set("language", "tr")
21
+
22
+ # Enable headless mode (no database access)
23
+ config.set_headless(True)
24
+
25
+ Attributes:
26
+ APP_NAME (str): Application name for directory naming.
27
+ CONFIG_DIR (Path): User configuration directory (~/.weeb-cli).
28
+ DEFAULT_CONFIG (dict): Default configuration values.
29
+ config (Config): Global configuration instance.
30
+ """
31
+
32
+ import os
33
+ from pathlib import Path
34
+ from typing import Any, Optional, TYPE_CHECKING
35
+
36
+ if TYPE_CHECKING:
37
+ from weeb_cli.services.database import Database
38
+
39
+ APP_NAME = "weeb-cli"
40
+ CONFIG_DIR = Path.home() / f".{APP_NAME}"
41
+
42
+
43
+ def get_default_download_dir() -> str:
44
+ """Get the default download directory path.
45
+
46
+ Uses localized folder name from i18n translations.
47
+
48
+ Returns:
49
+ Absolute path to default download directory in current working directory.
50
+ """
51
+ from weeb_cli.i18n import i18n
52
+
53
+ folder_name = i18n.t("downloads.default_folder_name", "weeb-downloads")
54
+ return os.path.join(os.getcwd(), folder_name)
55
+
56
+
57
+ DEFAULT_CONFIG = {
58
+ "language": None,
59
+ "aria2_enabled": True,
60
+ "ytdlp_enabled": True,
61
+ "aria2_max_connections": 16,
62
+ "max_concurrent_downloads": 3,
63
+ "download_dir": None,
64
+ "ytdlp_format": "bestvideo+bestaudio/best",
65
+ "scraping_source": None,
66
+ "show_description": True,
67
+ "debug_mode": False,
68
+ "download_max_retries": 3,
69
+ "download_retry_delay": 10,
70
+ "discord_rpc_enabled": True,
71
+ "shortcuts_enabled": False,
72
+ "aniskip_enabled": False,
73
+ }
74
+
75
+
76
+ class Config:
77
+ """Configuration manager with database persistence.
78
+
79
+ Provides a simple key-value interface for application settings with
80
+ automatic persistence to SQLite database. Supports headless mode for
81
+ API usage without database access.
82
+
83
+ Attributes:
84
+ _db (Optional[Database]): Lazy-loaded database instance.
85
+ _headless (bool): Whether running in headless mode (no database).
86
+ """
87
+
88
+ def __init__(self) -> None:
89
+ """Initialize configuration manager."""
90
+ self._db: Optional['Database'] = None
91
+ self._headless: bool = False
92
+
93
+ @property
94
+ def db(self) -> 'Database':
95
+ """Get database instance with lazy loading.
96
+
97
+ Returns:
98
+ Database instance for configuration storage.
99
+ """
100
+ if self._db is None:
101
+ from weeb_cli.services.database import db
102
+ self._db = db
103
+ return self._db
104
+
105
+ def get(self, key: str, default: Optional[Any] = None) -> Any:
106
+ """Get configuration value by key.
107
+
108
+ Attempts to retrieve value from database first, then falls back to
109
+ provided default or DEFAULT_CONFIG. Special handling for download_dir
110
+ to generate localized default path.
111
+
112
+ Args:
113
+ key: Configuration key name.
114
+ default: Default value if key not found in database.
115
+
116
+ Returns:
117
+ Configuration value, default, or None.
118
+
119
+ Example:
120
+ >>> config.get("language", "en")
121
+ "tr"
122
+ >>> config.get("aria2_max_connections")
123
+ 16
124
+ """
125
+ if not self._headless:
126
+ try:
127
+ val = self.db.get_config(key)
128
+ if val is not None:
129
+ return val
130
+ except Exception:
131
+ pass
132
+
133
+ # Special handling for download_dir
134
+ if key == "download_dir":
135
+ return default if default is not None else get_default_download_dir()
136
+
137
+ # Use provided default, fallback to DEFAULT_CONFIG, then None
138
+ if default is not None:
139
+ return DEFAULT_CONFIG.get(key, default)
140
+ return DEFAULT_CONFIG.get(key)
141
+
142
+ def set(self, key: str, value: Any) -> None:
143
+ """Set configuration value.
144
+
145
+ Persists the value to database for future retrieval.
146
+
147
+ Args:
148
+ key: Configuration key name.
149
+ value: Value to store (must be JSON-serializable).
150
+
151
+ Example:
152
+ >>> config.set("language", "tr")
153
+ >>> config.set("aria2_max_connections", 32)
154
+ """
155
+ self.db.set_config(key, value)
156
+
157
+ def set_headless(self, headless: bool = True) -> None:
158
+ """Enable or disable headless mode.
159
+
160
+ In headless mode, configuration is read from DEFAULT_CONFIG only,
161
+ without database access. Useful for API commands and testing.
162
+
163
+ Args:
164
+ headless: Whether to enable headless mode.
165
+ """
166
+ self._headless = headless
167
+
168
+
169
+ config = Config()
@@ -0,0 +1,112 @@
1
+ """Custom exceptions for Weeb CLI.
2
+
3
+ This module defines the exception hierarchy for error handling throughout
4
+ the application. All exceptions inherit from WeebCLIError base class.
5
+
6
+ Exception Hierarchy:
7
+ WeebCLIError (base)
8
+ ├── ProviderError: Anime provider-related errors
9
+ ├── DownloadError: Download operation failures
10
+ ├── NetworkError: Network connectivity issues
11
+ ├── AuthenticationError: Tracker authentication failures
12
+ ├── DatabaseError: Database operation errors
13
+ ├── ValidationError: Input validation failures
14
+ └── DependencyError: External dependency issues
15
+
16
+ Example:
17
+ Raising exceptions::
18
+
19
+ from weeb_cli.exceptions import ProviderError, DownloadError
20
+
21
+ raise ProviderError("Failed to fetch anime", code="PROVIDER_001")
22
+ raise DownloadError("Insufficient disk space", code="DISK_FULL")
23
+
24
+ Catching exceptions::
25
+
26
+ try:
27
+ provider.search("anime")
28
+ except ProviderError as e:
29
+ print(f"Provider error: {e.message} ({e.code})")
30
+ except WeebCLIError as e:
31
+ print(f"General error: {e}")
32
+ """
33
+
34
+
35
+ class WeebCLIError(Exception):
36
+ """Base exception for all Weeb CLI errors.
37
+
38
+ Provides structured error handling with optional error codes for
39
+ better error tracking and debugging.
40
+
41
+ Attributes:
42
+ message (str): Human-readable error message.
43
+ code (str): Optional error code for categorization.
44
+ """
45
+
46
+ def __init__(self, message: str = "", code: str = "") -> None:
47
+ """Initialize exception with message and optional code.
48
+
49
+ Args:
50
+ message: Descriptive error message.
51
+ code: Optional error code (e.g., 'PROVIDER_001').
52
+ """
53
+ self.message = message
54
+ self.code = code
55
+ super().__init__(f"{code}: {message}" if code else message)
56
+
57
+
58
+ class ProviderError(WeebCLIError):
59
+ """Exception raised for anime provider-related errors.
60
+
61
+ Used when providers fail to search, fetch details, or extract streams.
62
+ """
63
+ pass
64
+
65
+
66
+ class DownloadError(WeebCLIError):
67
+ """Exception raised for download operation failures.
68
+
69
+ Used when downloads fail due to network issues, disk space, or
70
+ invalid stream URLs.
71
+ """
72
+ pass
73
+
74
+
75
+ class NetworkError(WeebCLIError):
76
+ """Exception raised for network connectivity issues.
77
+
78
+ Used when HTTP requests fail or network is unavailable.
79
+ """
80
+ pass
81
+
82
+
83
+ class AuthenticationError(WeebCLIError):
84
+ """Exception raised for tracker authentication failures.
85
+
86
+ Used when OAuth flows fail or credentials are invalid.
87
+ """
88
+ pass
89
+
90
+
91
+ class DatabaseError(WeebCLIError):
92
+ """Exception raised for database operation errors.
93
+
94
+ Used when SQLite operations fail or database is corrupted.
95
+ """
96
+ pass
97
+
98
+
99
+ class ValidationError(WeebCLIError):
100
+ """Exception raised for input validation failures.
101
+
102
+ Used when user input or configuration values are invalid.
103
+ """
104
+ pass
105
+
106
+
107
+ class DependencyError(WeebCLIError):
108
+ """Exception raised for external dependency issues.
109
+
110
+ Used when required tools (FFmpeg, MPV, Aria2) are missing or fail.
111
+ """
112
+ pass