From 69f5722f17aa9a012c9ab57f9edf7c7e251940ec Mon Sep 17 00:00:00 2001 From: Michael Johnson <44432163+MichaelDavidJohnson@users.noreply.github.com> Date: Wed, 5 Aug 2020 23:58:19 +0100 Subject: [PATCH] MAL importing into watch (#465) * Update watch.py * Update README.md Co-authored-by: Blatzar <46196380+Blatzar@users.noreply.github.com> --- README.md | 1 + anime_downloader/commands/watch.py | 24 +++++++++++++++++-- anime_downloader/watch.py | 38 ++++++++++++++++++++++++++++-- docs/usage/watch.rst | 21 +++++++++++++---- 4 files changed, 76 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4d0421c..5b74f56 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ Yeah. Me too! That's why this tool exists. - Download or stream any episode or episode range of any anime. - Have a locally stored anime list to track your progress and stream anime using the watch command. +- Import your MAL anime list to the local anime list. - Specify the quality you want to stream or download. - Search and download. - Save yourselves from those malicious ads. diff --git a/anime_downloader/commands/watch.py b/anime_downloader/commands/watch.py index 4380679..d5bdb6e 100644 --- a/anime_downloader/commands/watch.py +++ b/anime_downloader/commands/watch.py @@ -38,9 +38,15 @@ sitenames = [v[1] for v in ALL_ANIME_SITES] help='The anime provider (website) for search.', type=click.Choice(sitenames) ) +@click.option( + '--mal_import', + help='Import xml file from MAL export.', + type = bool, + is_flag = True + ) def command(anime_name, new, update_all, _list, quality, remove, - download_dir, provider): + download_dir,mal_import, provider): """ With watch you can keep track of any anime you watch. Available Commands after selection of an anime:\n @@ -83,6 +89,20 @@ def command(anime_name, new, update_all, _list, quality, remove, for anime in animes: watcher.update_anime(anime) + if mal_import: + PATH = anime_name # Hack, but needed to prompt the user. Uses the anime name as parameter. + if PATH: + query = PATH + else: + query = click.prompt('Enter the file path for the MAL .xml file', type=str) + + if PATH.endswith('.xml'): + watcher._import_from_MAL(query) + sys.exit(0) + else: + logging.error("Either the file selected was not an .xml or no file was selected.") + sys.exit(1) + # Defaults the command to anime watch -l all. # It's a bit of a hack to use sys.argv, but doesn't break # if new commands are added (provided you used a bunch of and statements) @@ -106,7 +126,7 @@ def command(anime_name, new, update_all, _list, quality, remove, watch_anime(watcher, anime,quality,download_dir) def command_parser(command): - # Returns a list of the commands + # Returns a list of the commands # new "no neverland" --provider vidstream > ['new', '--provider', 'no neverland', 'vidstream'] # Better than split(' ') because it accounts for quoutes. diff --git a/anime_downloader/watch.py b/anime_downloader/watch.py index bc737bf..3f90bb2 100644 --- a/anime_downloader/watch.py +++ b/anime_downloader/watch.py @@ -122,11 +122,45 @@ class Watcher: self._write_to_watch_file(data) - def _write_to_watch_file(self, animes): - animes = [anime.__dict__ for anime in animes] + def _write_to_watch_file(self, animes, MAL_import = False): + if not MAL_import: + animes = [anime.__dict__ for anime in animes] + with open(self.WATCH_FILE, 'w') as watch_file: json.dump(animes, watch_file) + def _import_from_MAL(self,PATH): + import xml.etree.ElementTree as ET #Standard Library import, conditional as it only needs to be imported for this line + root = ET.parse(PATH).getroot() + list_to_dict = [] + values = { 'Plan to Watch' : { 'planned' : 'yellow' }, + 'Completed' : { 'completed' : 'green' }, + 'Watching' : { 'watching' : 'blue' }, + 'Dropped' : { 'dropped' : 'red' } + } + for type_tag in root.findall('anime'): + mal_watched_episodes = type_tag.find('my_watched_episodes').text + mal_score = type_tag.find('my_score').text + mal_watch_status = type_tag.find('my_status').text + colour = str(list(values[mal_watch_status].values())[0]) + mal_watch_status = str(list(values[mal_watch_status].keys())[0]) + mal_title = type_tag.find('series_title').text + mal_episodes = type_tag.find('series_episodes').text + list_to_dict.append( { + "episodes_done": int(mal_watched_episodes), + "_timestamp": time(), + "score": int(mal_score), + "watch_status": mal_watch_status, + "colours": colour, + "url": "https://twist.moe/", + "_fallback_qualities": ["720p", "480p", "360p"], + "quality": "720p", + "title": mal_title, + "_episode_urls": [[1, "https://twist.moe/anime/"]], + "_len": int(mal_episodes) + }) + self._write_to_watch_file(list_to_dict, MAL_import = True) + def _read_from_watch_file(self): if not os.path.exists(self.WATCH_FILE): logger.error('Add something to watch list first.') diff --git a/docs/usage/watch.rst b/docs/usage/watch.rst index 2122db7..2d9b740 100644 --- a/docs/usage/watch.rst +++ b/docs/usage/watch.rst @@ -10,8 +10,12 @@ ``anime watch`` can be a all in one solution for your anime needs. Anime watch contains exactly the same providers used in anime dl so you will not be missing anything! -``watch`` will locally track your progress with an anime list making your time with anime watch easy and enjoyable (Work is being done to try and format the locally stored list in a way that importing / exporting to MAL could be possible) +``watch`` will locally track your progress with an anime list making your time with anime watch easy and enjoyable. Anime lists from MyAnimeList can also be imported into your list, so you need not worry about losing a complete tracker! +.. figure:: https://media.giphy.com/media/RKNArLOzM2jUjkXNJu/giphy.gif + :alt: mp4 + + Revamped watch command with an imported MyAnimeList list!! :: CONTROLS IN MPV: @@ -25,9 +29,16 @@ Usage: anime watch [OPTIONS] [ANIME_NAME] With watch you can keep track of any anime you watch. - + + Using anime watch without any options: + Using anime watch without any options will return the complete tracking list. Allowing for quick access to the list. + + Available Commands inside a list: + swap : Swap the list + add : Add new anime + Available Commands after selection of an anime: - set : Set episodes_done, provider and title. Ex: set episodes_done=3 + set : Set episodes_done, provider,title, anime_status and stars. Ex: set episodes_done=3 remove : Remove selected anime from watch list. update : Update the episodes of the currrent anime, brilliant for currently airing series. watch : Watch selected anime. @@ -36,8 +47,10 @@ Options: -n, --new Add a new entry to the list. - -l, --list List all animes in watch list. + -l, --list [all,completed,watching,dropped,planned] + Return a list of the anime from the tracker, sorted by anime_status. -r, --remove Remove a specified anime from the list. + --mal_import [FILEPATH] Give a .xml MAL file to populate the list with MAL. -q, --quality [360p|480p|720p|1080p] Specify the quality of episodes. -ll, --log-level [DEBUG|INFO|WARNING|ERROR]