anipy-cli 3.4.5__tar.gz → 3.4.7__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.

Potentially problematic release.


This version of anipy-cli might be problematic. Click here for more details.

Files changed (26) hide show
  1. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/PKG-INFO +2 -2
  2. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/pyproject.toml +2 -2
  3. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/__init__.py +1 -1
  4. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/arg_parser.py +9 -0
  5. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/cli.py +10 -1
  6. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/menus/seasonal_menu.py +2 -48
  7. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/prompts.py +53 -0
  8. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/README.md +0 -0
  9. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/clis/__init__.py +0 -0
  10. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/clis/base_cli.py +0 -0
  11. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/clis/binge_cli.py +0 -0
  12. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/clis/default_cli.py +0 -0
  13. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/clis/download_cli.py +0 -0
  14. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/clis/history_cli.py +0 -0
  15. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/clis/mal_cli.py +0 -0
  16. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/clis/seasonal_cli.py +0 -0
  17. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/colors.py +0 -0
  18. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/config.py +0 -0
  19. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/discord.py +0 -0
  20. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/download_component.py +0 -0
  21. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/mal_proxy.py +0 -0
  22. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/menus/__init__.py +0 -0
  23. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/menus/base_menu.py +0 -0
  24. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/menus/mal_menu.py +0 -0
  25. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/menus/menu.py +0 -0
  26. {anipy_cli-3.4.5 → anipy_cli-3.4.7}/src/anipy_cli/util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: anipy-cli
3
- Version: 3.4.5
3
+ Version: 3.4.7
4
4
  Summary: Watch and Download anime from the comfort of your Terminal
5
5
  License: GPL-3.0
6
6
  Keywords: anime,cli
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Programming Language :: Python :: 3.13
17
- Requires-Dist: anipy-api (>=3.4.5,<4.0.0)
17
+ Requires-Dist: anipy-api (>=3.4.7,<4.0.0)
18
18
  Requires-Dist: appdirs (>=1.4.4,<2.0.0)
19
19
  Requires-Dist: inquirerpy (>=0.3.4,<0.4.0)
20
20
  Requires-Dist: pypresence (>=4.3.0,<5.0.0)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "anipy-cli"
3
- version = "3.4.5"
3
+ version = "3.4.7"
4
4
  description = "Watch and Download anime from the comfort of your Terminal"
5
5
  authors = ["sdaqo <sdaqo.dev@protonmail.com>"]
6
6
  license = "GPL-3.0"
@@ -20,7 +20,7 @@ yaspin = "^3.0.2"
20
20
  inquirerpy = "^0.3.4"
21
21
  appdirs = "^1.4.4"
22
22
  pypresence = "^4.3.0"
23
- anipy-api = "^3.4.5"
23
+ anipy-api = "^3.4.7"
24
24
 
25
25
  [tool.poetry.scripts]
26
26
  anipy-cli = "anipy_cli.cli:run_cli"
@@ -1,2 +1,2 @@
1
1
  __appname__ = "anipy-cli"
2
- __version__ = "3.4.5"
2
+ __version__ = "3.4.7"
@@ -14,6 +14,7 @@ class CliArgs:
14
14
  seasonal: bool
15
15
  mal: bool
16
16
  delete: bool
17
+ migrate_hist: bool
17
18
  quality: Optional[Union[str, int]]
18
19
  ffmpeg: bool
19
20
  auto_update: bool
@@ -99,6 +100,14 @@ def parse_args(override_args: Optional[list[str]] = None) -> CliArgs:
99
100
  help="Delete your History.",
100
101
  )
101
102
 
103
+ actions_group.add_argument(
104
+ "--migrate-history",
105
+ required=False,
106
+ dest="migrate_hist",
107
+ action="store_true",
108
+ help="Migrate your history to the current provider.",
109
+ )
110
+
102
111
  options_group.add_argument(
103
112
  "-s",
104
113
  "--search",
@@ -2,10 +2,13 @@ from typing import Optional
2
2
 
3
3
  from pypresence.exceptions import DiscordNotFound
4
4
 
5
+ from anipy_api.locallist import LocalList
6
+ from anipy_cli.prompts import migrate_provider
7
+
5
8
  from anipy_cli.arg_parser import parse_args
6
9
  from anipy_cli.clis import *
7
10
  from anipy_cli.colors import colors, cprint
8
- from anipy_cli.util import error, DotSpinner
11
+ from anipy_cli.util import error, DotSpinner, migrate_locallist
9
12
  from anipy_cli.config import Config
10
13
  from anipy_cli.discord import DiscordPresence
11
14
 
@@ -45,6 +48,12 @@ def run_cli(override_args: Optional[list[str]] = None):
45
48
  except FileNotFoundError:
46
49
  error("no history file found")
47
50
  return
51
+ elif args.migrate_hist:
52
+ history_list = LocalList(
53
+ Config()._history_file_path, migrate_cb=migrate_locallist
54
+ )
55
+ migrate_provider("default", history_list)
56
+ return
48
57
 
49
58
  clis_dict = {
50
59
  args.download: DownloadCli,
@@ -25,7 +25,7 @@ from anipy_cli.util import (
25
25
  get_prefered_providers,
26
26
  migrate_locallist,
27
27
  )
28
- from anipy_cli.prompts import pick_episode_prompt, search_show_prompt, lang_prompt
28
+ from anipy_cli.prompts import pick_episode_prompt, search_show_prompt, lang_prompt, migrate_provider
29
29
 
30
30
 
31
31
  if TYPE_CHECKING:
@@ -209,53 +209,7 @@ class SeasonalMenu(MenuBase):
209
209
  print(i)
210
210
 
211
211
  def migrate_provider(self):
212
- config = Config()
213
- all_seasonals = self.seasonal_list.get_all()
214
- current_providers = list(get_prefered_providers("seasonal"))
215
- print(
216
- "Migrating to configured providers:",
217
- ", ".join([p.NAME for p in current_providers]),
218
- )
219
- for s in all_seasonals:
220
- if s.provider in [p.NAME for p in current_providers]:
221
- continue
222
-
223
- print(f"Mapping: {s.name}")
224
-
225
- search_results: List[Anime] = []
226
- for p in current_providers:
227
- search_results.extend(
228
- [Anime.from_search_result(p, r) for r in p.get_search(s.name)]
229
- )
230
-
231
- best_anime = None
232
- best_ratio = 0
233
- for r in search_results:
234
- titles = {r.name}
235
- titles |= set(r.get_info().alternative_names or [])
236
- ratio = MyAnimeListAdapter._find_best_ratio(titles, {s.name})
237
-
238
- if ratio > best_ratio:
239
- best_ratio = ratio
240
- best_anime = r
241
-
242
- if best_ratio == 1:
243
- break
244
-
245
- if best_anime is None:
246
- continue
247
-
248
- if best_ratio >= config.mal_mapping_min_similarity:
249
- self.seasonal_list.delete(s)
250
- else:
251
- print(f"Could not autmatically map {s.name}, you can map it manually.")
252
- best_anime = search_show_prompt("seasonal", skip_season_search=True)
253
- if best_anime is None:
254
- continue
255
-
256
- episode = find_closest(best_anime.get_episodes(s.language), s.episode)
257
- self.seasonal_list.update(best_anime, language=s.language, episode=episode)
258
-
212
+ migrate_provider("seasonal", self.seasonal_list)
259
213
  self.print_options(clear_screen=True)
260
214
 
261
215
  def download_latest(self):
@@ -2,6 +2,7 @@ import time
2
2
  from typing import TYPE_CHECKING, Optional, List, Tuple
3
3
  from InquirerPy import inquirer
4
4
  from InquirerPy.base.control import Choice
5
+ from anipy_api.mal import MyAnimeListAdapter
5
6
  from anipy_api.provider import (
6
7
  BaseProvider,
7
8
  FilterCapabilities,
@@ -13,6 +14,7 @@ from anipy_api.anime import Anime
13
14
 
14
15
  from anipy_cli.util import (
15
16
  DotSpinner,
17
+ find_closest,
16
18
  get_anime_season,
17
19
  get_prefered_providers,
18
20
  error,
@@ -25,6 +27,7 @@ from anipy_cli.config import Config
25
27
 
26
28
  if TYPE_CHECKING:
27
29
  from anipy_api.provider import Episode
30
+ from anipy_api.locallist import LocalList
28
31
 
29
32
 
30
33
  def search_show_prompt(
@@ -332,3 +335,53 @@ def parse_auto_search(
332
335
  error("could not determine any epiosdes from search parameter", fatal=True)
333
336
 
334
337
  return result, lang, chosen
338
+
339
+ def migrate_provider(mode: str, local_list: "LocalList"):
340
+ config = Config()
341
+ all_entries = local_list.get_all()
342
+ current_providers = list(get_prefered_providers(mode))
343
+ print(
344
+ f"Migrating to configured providers ({mode}):",
345
+ ", ".join([p.NAME for p in current_providers]),
346
+ )
347
+ for s in all_entries:
348
+ if s.provider in [p.NAME for p in current_providers]:
349
+ continue
350
+
351
+ print(f"Mapping: {s.name}")
352
+
353
+ search_results: List[Anime] = []
354
+ for p in current_providers:
355
+ search_results.extend(
356
+ [Anime.from_search_result(p, r) for r in p.get_search(s.name)]
357
+ )
358
+
359
+ best_anime = None
360
+ best_ratio = 0
361
+ for r in search_results:
362
+ titles = {r.name}
363
+ titles |= set(r.get_info().alternative_names or [])
364
+ ratio = MyAnimeListAdapter._find_best_ratio(titles, {s.name})
365
+
366
+ if ratio > best_ratio:
367
+ best_ratio = ratio
368
+ best_anime = r
369
+
370
+ if best_ratio == 1:
371
+ break
372
+
373
+ if best_anime is None:
374
+ continue
375
+
376
+ if best_ratio >= config.mal_mapping_min_similarity:
377
+ local_list.delete(s)
378
+ else:
379
+ print(f"Could not autmatically map {s.name}, you can map it manually.")
380
+ best_anime = search_show_prompt("seasonal", skip_season_search=True)
381
+ if best_anime is None:
382
+ continue
383
+ local_list.delete(s)
384
+
385
+ episode = find_closest(best_anime.get_episodes(s.language), s.episode)
386
+ local_list.update(best_anime, language=s.language, episode=episode)
387
+
File without changes