anipy-cli 2.7.17__py3-none-any.whl → 3.8.2__py3-none-any.whl

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 (67) hide show
  1. anipy_cli/__init__.py +2 -20
  2. anipy_cli/anilist_proxy.py +229 -0
  3. anipy_cli/arg_parser.py +109 -21
  4. anipy_cli/cli.py +98 -0
  5. anipy_cli/clis/__init__.py +17 -0
  6. anipy_cli/clis/anilist_cli.py +62 -0
  7. anipy_cli/clis/base_cli.py +34 -0
  8. anipy_cli/clis/binge_cli.py +96 -0
  9. anipy_cli/clis/default_cli.py +115 -0
  10. anipy_cli/clis/download_cli.py +85 -0
  11. anipy_cli/clis/history_cli.py +96 -0
  12. anipy_cli/clis/mal_cli.py +71 -0
  13. anipy_cli/{cli/clis → clis}/seasonal_cli.py +9 -6
  14. anipy_cli/colors.py +14 -8
  15. anipy_cli/config.py +387 -90
  16. anipy_cli/discord.py +34 -0
  17. anipy_cli/download_component.py +194 -0
  18. anipy_cli/logger.py +200 -0
  19. anipy_cli/mal_proxy.py +228 -0
  20. anipy_cli/menus/__init__.py +6 -0
  21. anipy_cli/menus/anilist_menu.py +671 -0
  22. anipy_cli/{cli/menus → menus}/base_menu.py +9 -14
  23. anipy_cli/menus/mal_menu.py +657 -0
  24. anipy_cli/menus/menu.py +265 -0
  25. anipy_cli/menus/seasonal_menu.py +270 -0
  26. anipy_cli/prompts.py +387 -0
  27. anipy_cli/util.py +268 -0
  28. anipy_cli-3.8.2.dist-info/METADATA +71 -0
  29. anipy_cli-3.8.2.dist-info/RECORD +31 -0
  30. {anipy_cli-2.7.17.dist-info → anipy_cli-3.8.2.dist-info}/WHEEL +1 -2
  31. anipy_cli-3.8.2.dist-info/entry_points.txt +3 -0
  32. anipy_cli/cli/__init__.py +0 -1
  33. anipy_cli/cli/cli.py +0 -37
  34. anipy_cli/cli/clis/__init__.py +0 -6
  35. anipy_cli/cli/clis/base_cli.py +0 -43
  36. anipy_cli/cli/clis/binge_cli.py +0 -54
  37. anipy_cli/cli/clis/default_cli.py +0 -46
  38. anipy_cli/cli/clis/download_cli.py +0 -92
  39. anipy_cli/cli/clis/history_cli.py +0 -64
  40. anipy_cli/cli/clis/mal_cli.py +0 -27
  41. anipy_cli/cli/menus/__init__.py +0 -3
  42. anipy_cli/cli/menus/mal_menu.py +0 -411
  43. anipy_cli/cli/menus/menu.py +0 -102
  44. anipy_cli/cli/menus/seasonal_menu.py +0 -174
  45. anipy_cli/cli/util.py +0 -118
  46. anipy_cli/download.py +0 -454
  47. anipy_cli/history.py +0 -83
  48. anipy_cli/mal.py +0 -645
  49. anipy_cli/misc.py +0 -227
  50. anipy_cli/player/__init__.py +0 -1
  51. anipy_cli/player/player.py +0 -33
  52. anipy_cli/player/players/__init__.py +0 -3
  53. anipy_cli/player/players/base.py +0 -106
  54. anipy_cli/player/players/mpv.py +0 -19
  55. anipy_cli/player/players/mpv_contrl.py +0 -37
  56. anipy_cli/player/players/syncplay.py +0 -19
  57. anipy_cli/player/players/vlc.py +0 -18
  58. anipy_cli/query.py +0 -92
  59. anipy_cli/run_anipy_cli.py +0 -14
  60. anipy_cli/seasonal.py +0 -106
  61. anipy_cli/url_handler.py +0 -442
  62. anipy_cli/version.py +0 -1
  63. anipy_cli-2.7.17.dist-info/LICENSE +0 -674
  64. anipy_cli-2.7.17.dist-info/METADATA +0 -159
  65. anipy_cli-2.7.17.dist-info/RECORD +0 -43
  66. anipy_cli-2.7.17.dist-info/entry_points.txt +0 -2
  67. anipy_cli-2.7.17.dist-info/top_level.txt +0 -1
@@ -1,411 +0,0 @@
1
- from typing import List
2
-
3
- from anipy_cli.arg_parser import CliArgs
4
- from anipy_cli.colors import colors, cprint, cinput
5
- from anipy_cli.misc import Entry, print_names, error
6
- from anipy_cli.player import get_player
7
- from anipy_cli.url_handler import videourl
8
- from anipy_cli.query import query
9
- from anipy_cli.download import download
10
- from anipy_cli.config import Config
11
- from anipy_cli.mal import MAL
12
- from anipy_cli.cli.util import binge, get_season_searches
13
- from anipy_cli.cli.menus.base_menu import MenuBase, MenuOption
14
-
15
-
16
- class MALMenu(MenuBase):
17
- def __init__(self, options: CliArgs, rpc_client=None):
18
- self.entry = Entry()
19
- self.options = options
20
- self.rpc_client = rpc_client
21
-
22
- self.dl_path = Config().seasonals_dl_path
23
- if options.location:
24
- self.dl_path = options.location
25
-
26
- user = None
27
- if Config().mal_user and Config().mal_user != "":
28
- user = Config().mal_user
29
-
30
- if options.mal_password is not None and options.mal_password != "":
31
- password = options.mal_password
32
- else:
33
- password = Config().mal_password
34
- if not password or password == "":
35
- password = None
36
-
37
- if user is None or password is None:
38
- cprint(colors.ERROR, "Missing credentials!\n")
39
- cprint(
40
- colors.CYAN,
41
- "In order to use the MAL-Mode, you need to specify your username and password.\n",
42
- )
43
- cprint(
44
- colors.CYAN, "Those can be specified in the anipy-cli config file.\n"
45
- )
46
-
47
- if user is None:
48
- while not user:
49
- user_input = cinput(
50
- colors.CYAN,
51
- "Please enter your MyAnimeList ",
52
- colors.YELLOW,
53
- "Username ",
54
- colors.CYAN,
55
- ":\n",
56
- )
57
- if user_input and user_input != "":
58
- user = user_input
59
-
60
- if password is None:
61
- cprint(
62
- colors.MAGENTA,
63
- "The password can also be passed with the '--mal-password' parameter.",
64
- )
65
- while not password:
66
- pw_input = cinput(
67
- colors.CYAN,
68
- "Please enter your MyAnimeList ",
69
- colors.YELLOW,
70
- "Password ",
71
- colors.CYAN,
72
- ":\n",
73
- )
74
- if pw_input and pw_input != "":
75
- password = pw_input
76
-
77
- self.m_class = MAL(user, password)
78
-
79
- def print_header(self):
80
- pass
81
-
82
- @property
83
- def menu_options(self) -> List[MenuOption]:
84
- return [
85
- MenuOption("Add Anime", self.add_anime, "a"),
86
- MenuOption("Delete one anime from mal list", self.del_anime, "e"),
87
- MenuOption("List anime in mal list", self.list_animes, "l"),
88
- MenuOption("Map MAL anime to gogo Links", self.create_gogo_maps, "m"),
89
- MenuOption("Sync MAL list into seasonals", self.sync_mal_to_seasonals, "s"),
90
- MenuOption(
91
- "Sync seasonals into MAL list",
92
- self.m_class.sync_seasonals_with_mal,
93
- "b",
94
- ),
95
- MenuOption(
96
- "Download newest episodes", lambda: self.download(mode="latest"), "d"
97
- ),
98
- MenuOption("Download all episodes", lambda: self.download(mode="all"), "x"),
99
- MenuOption("Binge watch newest episodes", self.binge_latest, "w"),
100
- MenuOption("Quit", self.quit, "q"),
101
- ]
102
-
103
- def add_anime(self):
104
- searches = []
105
- if (
106
- not self.options.no_season_search
107
- and input("Search for anime in Season? (y|n): \n>> ") == "y"
108
- ):
109
- searches = get_season_searches(gogo=False)
110
-
111
- else:
112
- searches.append(input("Search: "))
113
-
114
- for search in searches:
115
- if isinstance(search, dict):
116
- mal_entry = search
117
-
118
- else:
119
- print("\nCurrent: ", search)
120
- temp_search = self.m_class.get_anime(search)
121
- names = [item["node"]["title"] for item in temp_search]
122
- print_names(names)
123
- selected = False
124
- skip = False
125
- while selected is False:
126
- try:
127
- sel_index = input("Select show (Number or c for cancel):\n")
128
- if sel_index == "c":
129
- skip = True
130
- break
131
- selected = int(sel_index) - 1
132
- except ValueError:
133
- print("Please enter a valid number.")
134
- if skip:
135
- continue
136
- mal_entry = temp_search[selected]
137
-
138
- self.m_class.update_anime_list(
139
- mal_entry["node"]["id"], {"status": "watching"}
140
- )
141
- self.create_gogo_maps()
142
-
143
- self.print_options()
144
-
145
- def del_anime(self):
146
- mal_list = self.m_class.get_anime_list()
147
- mal_list = [x for x in mal_list]
148
- mal_names = [n["node"]["title"] for n in mal_list]
149
- print_names(mal_names)
150
- while True:
151
- inp = cinput(colors.CYAN, "Enter Number: ")
152
- try:
153
- picked = mal_list[int(inp) - 1]["node"]["id"]
154
- break
155
- except:
156
- error("Invalid Input")
157
-
158
- self.m_class.del_show(picked)
159
- self.print_options()
160
-
161
- def list_animes(self):
162
- mal_list = self.m_class.get_anime_list()
163
- for i in mal_list:
164
- status = i["node"]["my_list_status"]["status"]
165
-
166
- if status == "completed":
167
- color = colors.MAGENTA
168
- elif status == "on_hold":
169
- color = colors.YELLOW
170
- elif status == "plan_to_watch":
171
- color = colors.BLUE
172
- elif status == "dropped":
173
- color = colors.ERROR
174
- else:
175
- color = colors.GREEN
176
-
177
- cprint(
178
- colors.CYAN,
179
- "==> Last watched EP: {}".format(
180
- i["node"]["my_list_status"]["num_episodes_watched"]
181
- ),
182
- color,
183
- " | ({}) | ".format(status),
184
- colors.CYAN,
185
- i["node"]["title"],
186
- )
187
- # List is empty
188
- if not mal_list:
189
- cprint(colors.YELLOW, "No anime found.\nAdd an anime to your list first.")
190
-
191
- input("Enter to continue")
192
- self.print_options()
193
-
194
- def list_possible(self, latest_urls):
195
- for i in latest_urls:
196
- cprint(colors.RED, f"{i}:")
197
- for j in latest_urls[i]["ep_list"]:
198
- cprint(colors.CYAN, f"==> EP: {j[0]}")
199
-
200
- def download(self, mode="all"):
201
- print("Preparing list of episodes...")
202
- if mode == "latest":
203
- urls = self.m_class.latest_eps()
204
-
205
- else:
206
- urls = self.m_class.latest_eps(all_eps=True)
207
-
208
- if not urls:
209
- error("Nothing to download")
210
- return
211
-
212
- cprint(colors.CYAN, "Stuff to be downloaded:")
213
- self.list_possible(urls)
214
- if not self.options.auto_update:
215
- cinput(colors.RED, "Enter to continue or CTRL+C to abort.")
216
-
217
- for i in urls:
218
- cprint(f"Downloading newest urls for {i}", colors.CYAN)
219
- show_entry = Entry()
220
- show_entry.show_name = i
221
- for j in urls[i]["ep_list"]:
222
- show_entry.embed_url = ""
223
- show_entry.ep = j[0]
224
- show_entry.ep_url = j[1]
225
- url_class = videourl(show_entry, self.options.quality)
226
- url_class.stream_url()
227
- show_entry = url_class.get_entry()
228
- download(
229
- show_entry, self.options.quality, self.options.ffmpeg, self.dl_path
230
- ).download()
231
-
232
- if not self.options.auto_update:
233
- self.print_options()
234
-
235
- def binge_latest(self):
236
- latest_eps = self.m_class.latest_eps()
237
- cprint(colors.CYAN, "Stuff to be watched:")
238
- self.list_possible(latest_eps)
239
- cinput(colors.RED, "Enter to continue or CTRL+C to abort.")
240
- ep_list = []
241
- ep_urls = []
242
- ep_dic = {}
243
- for i in latest_eps:
244
- for j in latest_eps[i]["ep_list"]:
245
- ep_list.append(j[0])
246
- ep_urls.append(j[1])
247
-
248
- ep_dic.update(
249
- {
250
- i: {
251
- "ep_urls": [x for x in ep_urls],
252
- "eps": [x for x in ep_list],
253
- "category_url": latest_eps[i]["category_url"],
254
- }
255
- }
256
- )
257
- ep_list.clear()
258
- ep_urls.clear()
259
-
260
- player = get_player(self.rpc_client, self.options.optional_player)
261
- binge(
262
- ep_dic,
263
- self.options.quality,
264
- player=player,
265
- mode="mal",
266
- mal_class=self.m_class,
267
- )
268
- player.kill_player()
269
- self.print_options()
270
-
271
- def sync_mal_to_seasonals(self):
272
- self.create_gogo_maps()
273
-
274
- self.m_class.sync_mal_with_seasonal()
275
-
276
- def manual_gogomap(self):
277
- self.create_gogo_maps()
278
-
279
- def create_gogo_maps(self):
280
- if not self.options.auto_update and input(
281
- "Try auto mapping MAL to gogo format? (y/n):\n"
282
- ).lower() in ["y", "yes"]:
283
- self.m_class.auto_map_all_without_map()
284
- failed_to_map = list(self.m_class.get_all_without_gogo_map())
285
- failed_to_map.sort(key=len, reverse=True)
286
- if not self.options.auto_update and len(failed_to_map) > 0:
287
- cprint(colors.YELLOW, "Some Anime failed auto-mapping...")
288
- cprint(colors.GREEN, "Select Anime for manual mapping:\n")
289
- selected = []
290
- searches = []
291
-
292
- print_names(failed_to_map)
293
- print("Selection: (e.g. 1, 1 3, 1-3 or * [for all]) \n")
294
- cprint(colors.YELLOW, "Enter or n to skip...")
295
- selection = cinput(colors.GREEN, ">>")
296
- if selection.__contains__("-"):
297
- selection_range = selection.strip(" ").split("-")
298
- for i in range(
299
- int(selection_range[0]) - 1, int(selection_range[1]) - 1, 1
300
- ):
301
- selected.append(i)
302
-
303
- elif selection in ["all", "*"]:
304
- selected = range(0, len(failed_to_map) - 1)
305
- elif selection in ["", "n", "N"]:
306
- selected = []
307
-
308
- else:
309
- for i in selection.strip(" ").split(" "):
310
- selected.append(int(i) - 1)
311
-
312
- for value in selected:
313
- show_entries = []
314
- done = False
315
- search_name = failed_to_map[value]
316
- while not done:
317
- cprint(
318
- colors.GREEN,
319
- "Current: ",
320
- colors.CYAN,
321
- f"{failed_to_map[value]}\n",
322
- )
323
- show_entry = Entry()
324
- query_class = query(search_name, show_entry)
325
- links_query = query_class.get_links()
326
-
327
- if not links_query:
328
- skip = False
329
- while not links_query and not skip:
330
- cprint(
331
- colors.ERROR,
332
- "No search results for ",
333
- colors.YELLOW,
334
- failed_to_map[value],
335
- )
336
- cprint(
337
- colors.GREEN,
338
- "Sometimes the names on GoGo are too different from the ones on MAL.\n",
339
- )
340
- cprint(colors.CYAN, "Try custom name for mapping? (Y/N):\n")
341
- if input().lower() == "y":
342
- query_class = query(
343
- cinput(
344
- colors.GREEN,
345
- "Enter Search String to search on GoGo:\n",
346
- ),
347
- show_entry,
348
- )
349
- links_query = query_class.get_links()
350
- if links_query:
351
- show = query_class.pick_show(cancelable=True)
352
- if show:
353
- show_entries.append(show_entry)
354
- mapped = self.m_class.manual_map_gogo_mal(
355
- failed_to_map[value],
356
- {
357
- "link": show_entry.category_url,
358
- "name": show_entry.show_name,
359
- },
360
- )
361
- if mapped:
362
- del failed_to_map[value]
363
- del selected[value]
364
- else:
365
- print("Skipping show")
366
- skip = True
367
- done = True
368
- elif links_query[0] != 0:
369
- links, names = links_query
370
- search_another = True
371
- while search_another and len(links) > 0:
372
- show = query_class.pick_show(cancelable=True)
373
- if show:
374
- show_entries.append(show_entry)
375
- self.m_class.manual_map_gogo_mal(
376
- failed_to_map[value],
377
- {
378
- "link": show_entry.category_url,
379
- "name": show_entry.show_name,
380
- },
381
- )
382
-
383
- links.remove(
384
- "/category/"
385
- + show_entry.category_url.split("/category/")[1]
386
- )
387
- names.remove(show_entry.show_name)
388
- print(
389
- f"{colors.GREEN} Added {show_entry.show_name} ...{colors.END}"
390
- )
391
- if input(
392
- f"Add another show map to {failed_to_map[value]}? (y/n):\n"
393
- ).lower() not in ["y", "yes"]:
394
- search_another = False
395
- done = True
396
- else:
397
- search_name_parts = search_name.split(" ")
398
- if len(search_name_parts) <= 1:
399
- print(
400
- f"{colors.YELLOW}Could not find {failed_to_map[value]} on gogo.{colors.END}"
401
- )
402
- done = True
403
- else:
404
- print(
405
- f"{colors.YELLOW} Nothing found. Trying to shorten name...{colors.END}"
406
- )
407
-
408
- search_name_parts.pop()
409
- search_name = " ".join(search_name_parts)
410
- self.m_class.write_save_data()
411
- self.m_class.write_mal_list()
@@ -1,102 +0,0 @@
1
- import sys
2
- from typing import List
3
-
4
- from anipy_cli.arg_parser import CliArgs
5
- from anipy_cli.colors import colors, cprint
6
- from anipy_cli.misc import Entry, error
7
- from anipy_cli.player import PlayerBaseType
8
- from anipy_cli.url_handler import videourl, epHandler
9
- from anipy_cli.query import query
10
- from anipy_cli.download import download
11
- from anipy_cli.config import Config
12
- from anipy_cli.cli.menus.base_menu import MenuBase, MenuOption
13
-
14
-
15
- class Menu(MenuBase):
16
- def __init__(
17
- self, options: CliArgs, entry: Entry, player: PlayerBaseType, rpc_client=None
18
- ):
19
- self.rpc_client = rpc_client
20
- self.options = options
21
- self.entry = entry
22
- self.player = player
23
-
24
- @property
25
- def menu_options(self) -> List[MenuOption]:
26
- return [
27
- MenuOption("Next Episode", self.next_ep, "n"),
28
- MenuOption("Previous Episode", self.prev_ep, "p"),
29
- MenuOption("Replay Episode", self.repl_ep, "r"),
30
- MenuOption("Select episode", self.selec_ep, "s"),
31
- MenuOption("Search for Anime", self.search, "a"),
32
- MenuOption("Print Video Info", self.video_info, "i"),
33
- MenuOption("Download Episode", self.download_video, "d"),
34
- MenuOption("Quit", self.quit, "q"),
35
- ]
36
-
37
- def print_header(self):
38
- cprint(
39
- colors.GREEN,
40
- f"Playing: {self.entry.show_name} {self.entry.quality} | ",
41
- colors.RED,
42
- f"{self.entry.ep}/{self.entry.latest_ep}",
43
- )
44
-
45
- def start_ep(self):
46
- self.entry.embed_url = ""
47
- url_class = videourl(self.entry, self.options.quality)
48
- url_class.stream_url()
49
- self.entry = url_class.get_entry()
50
- self.player.play_title(self.entry)
51
-
52
- def next_ep(self):
53
- ep_class = epHandler(self.entry)
54
- self.entry = ep_class.next_ep()
55
- self.start_ep()
56
- self.print_options()
57
-
58
- def prev_ep(self):
59
- ep_class = epHandler(self.entry)
60
- self.entry = ep_class.prev_ep()
61
- self.start_ep()
62
- self.print_options()
63
-
64
- def repl_ep(self):
65
- self.start_ep()
66
-
67
- def selec_ep(self):
68
- ep_class = epHandler(self.entry)
69
- self.entry = ep_class.pick_ep()
70
- self.start_ep()
71
- self.print_options()
72
-
73
- def search(self):
74
- query_class = query(input("Search: "), self.entry)
75
- if query_class.get_links() == 0:
76
- error("no search results")
77
- return
78
- else:
79
- self.entry = query_class.pick_show()
80
- ep_class = epHandler(self.entry)
81
- self.entry = ep_class.pick_ep()
82
- self.start_ep()
83
- self.print_options()
84
-
85
- def video_info(self):
86
- print(f"Show Name: {self.entry.show_name}")
87
- print(f"Category Url: {self.entry.category_url}")
88
- print(f"Episode Url: {self.entry.ep_url}")
89
- print(f"Episode: {self.entry.ep}")
90
- print(f"Embed Url: {self.entry.embed_url}")
91
- print(f"Stream Url: {self.entry.stream_url}")
92
- print(f"Quality: {self.entry.quality}")
93
-
94
- def download_video(self):
95
- path = download(self.entry, self.options.quality).download()
96
- if Config().auto_open_dl_defaultcli:
97
- self.player.play_file(str(path))
98
- self.print_options()
99
-
100
- def quit(self):
101
- self.player.kill_player()
102
- sys.exit(0)
@@ -1,174 +0,0 @@
1
- import sys
2
- from typing import List
3
-
4
- from anipy_cli.arg_parser import CliArgs
5
- from anipy_cli.colors import colors, cprint, cinput
6
- from anipy_cli.misc import Entry, print_names, error
7
- from anipy_cli.player import get_player
8
- from anipy_cli.url_handler import videourl, epHandler
9
- from anipy_cli.query import query
10
- from anipy_cli.download import download
11
- from anipy_cli.config import Config
12
- from anipy_cli.seasonal import Seasonal
13
- from anipy_cli.cli.util import get_season_searches, binge
14
- from anipy_cli.cli.menus.base_menu import MenuBase, MenuOption
15
-
16
-
17
- class SeasonalMenu(MenuBase, Seasonal):
18
- def __init__(self, options: CliArgs, rpc_client=None):
19
- super().__init__()
20
-
21
- self.rpc_client = rpc_client
22
- self.options = options
23
- self.entry = Entry()
24
- self.dl_path = Config().seasonals_dl_path
25
- if options.location:
26
- self.dl_path = options.location
27
-
28
- @property
29
- def menu_options(self) -> List[MenuOption]:
30
- return [
31
- MenuOption("Add Anime", self.add_anime, "a"),
32
- MenuOption("Delete one anime from seasonals", self.del_anime, "e"),
33
- MenuOption("List anime in seasonals file", self.list_animes, "l"),
34
- MenuOption("Download newest episodes", self.download_latest, "d"),
35
- MenuOption("Binge watch newest episodes", self.binge_latest, "w"),
36
- MenuOption("Quit", self.quit, "q"),
37
- ]
38
-
39
- def print_header(self):
40
- pass
41
-
42
- def add_anime(self):
43
- show_entry = Entry()
44
- is_season_search = False
45
- searches = []
46
- if (
47
- not self.options.no_season_search
48
- and input("Search for anime in Season? (y|n): \n>> ") == "y"
49
- ):
50
- searches = get_season_searches()
51
-
52
- else:
53
- searches.append(input("Search: "))
54
-
55
- for search in searches:
56
- query_class = None
57
- if isinstance(search, dict):
58
- is_season_search = True
59
- links = [search["category_url"]]
60
-
61
- else:
62
- print("\nCurrent: ", search)
63
- query_class = query(search, show_entry)
64
- query_class.get_pages()
65
- links = query_class.get_links()
66
-
67
- if links == 0:
68
- error("no search results")
69
- input("Enter to continue")
70
- self.print_options()
71
-
72
- if is_season_search:
73
- show_entry = Entry()
74
- show_entry.show_name = search["name"]
75
- show_entry.category_url = search["category_url"]
76
-
77
- else:
78
- show_entry = query_class.pick_show()
79
-
80
- picked_ep = epHandler(show_entry).pick_ep_seasonal().ep
81
- self.add_show(show_entry.show_name, show_entry.category_url, picked_ep)
82
- self.print_options()
83
-
84
- def del_anime(self):
85
- seasonals = self.list_seasonals()
86
- seasonals = [x[0] for x in seasonals]
87
- print_names(seasonals)
88
- while True:
89
- inp = cinput(colors.CYAN, "Enter Number: ")
90
- try:
91
- picked = seasonals[int(inp) - 1]
92
- break
93
- except:
94
- error("Invalid Input")
95
-
96
- self.del_show(picked)
97
-
98
- self.print_options()
99
-
100
- def list_animes(self):
101
- for i in self.list_seasonals():
102
- print(f"==> EP: {i[1]} | {i[0]}")
103
-
104
- def list_possible(self, latest_urls):
105
- for i in latest_urls:
106
- cprint(colors.RED, f"{i}:")
107
- for j in latest_urls[i]["ep_list"]:
108
- cprint(colors.CYAN, f"==> EP: {j[0]}")
109
-
110
- def download_latest(self):
111
- latest_urls = self.latest_eps()
112
-
113
- if not latest_urls:
114
- error("Nothing to download")
115
- return
116
-
117
- print("Stuff to be downloaded:")
118
- self.list_possible(latest_urls)
119
- if not self.options.auto_update:
120
- cinput(colors.RED, "Enter to continue or CTRL+C to abort.")
121
-
122
- for i in latest_urls:
123
- print(f"Downloading newest urls for {i}")
124
- show_entry = Entry()
125
- show_entry.show_name = i
126
- for j in latest_urls[i]["ep_list"]:
127
- show_entry.embed_url = ""
128
- show_entry.ep = j[0]
129
- show_entry.ep_url = j[1]
130
- url_class = videourl(show_entry, self.options.quality)
131
- url_class.stream_url()
132
- show_entry = url_class.get_entry()
133
- download(
134
- show_entry, self.options.quality, self.options.ffmpeg, self.dl_path
135
- ).download()
136
-
137
- if not self.options.auto_update:
138
- self.print_options()
139
-
140
- for i in latest_urls:
141
- self.update_show(i, latest_urls[i]["category_url"])
142
-
143
- def binge_latest(self):
144
- latest_eps = self.latest_eps()
145
- print("Stuff to be watched:")
146
- self.list_possible(latest_eps)
147
- cinput(colors.RED, "Enter to continue or CTRL+C to abort.")
148
- ep_list = []
149
- ep_urls = []
150
- ep_dic = {}
151
- for i in latest_eps:
152
- for j in latest_eps[i]["ep_list"]:
153
- ep_list.append(j[0])
154
- ep_urls.append(j[1])
155
-
156
- ep_dic.update(
157
- {
158
- i: {
159
- "ep_urls": [x for x in ep_urls],
160
- "eps": [x for x in ep_list],
161
- "category_url": latest_eps[i]["category_url"],
162
- }
163
- }
164
- )
165
- ep_list.clear()
166
- ep_urls.clear()
167
-
168
- player = get_player(self.rpc_client, self.options.optional_player)
169
- binge(ep_dic, self.options.quality, player, mode="seasonal")
170
- player.kill_player()
171
- for i in latest_eps:
172
- self.update_show(i, latest_eps[i]["category_url"])
173
-
174
- self.print_options()