def _parse_info(self, item): info = utils.show() showid = item['id'] info.update({ 'id': showid, 'title': item['title']['userPreferred'], 'status': self.status_translate[item['status']], 'image': item['coverImage']['large'], 'url': item['siteUrl'], 'start_date': self._dict2date(item.get('startDate')), 'end_date': self._dict2date(item.get('endDate')), 'extra': [ ('English', item['title'].get('english')), ('Romaji', item['title'].get('romaji')), ('Japanese', item['title'].get('native')), ('Synonyms', item['title'].get('synonyms')), #('Classification', item.get('classification')), ('Genres', item.get('genres')), ('Synopsis', item.get('description')), ('Type', item.get('format')), ('Average score', item.get('averageScore')), ('Status', self.status_translate[item['status']]), #('Start Date', item.get('start_date')), #('End Date', item.get('end_date')), ] }) return info
def search(self, criteria): self.check_credentials() criteria = str(criteria) self.msg.info(self.name, "Searching for {}...".format(criteria)) param = {'access_token': self._get_userconfig('access_token')} data = self._request("GET", "{0}/search/{1}".format(self.mediatype, criteria), get=param) showlist = [] for item in data: show = utils.show() showid = item['id'] show.update({ 'id': showid, 'title': item['title_romaji'], 'aliases': [item['title_english']], 'type': item['type'], 'status': item[self.airing_str], 'my_status': self.media_info()['status_start'], 'total': item[self.total_str], 'image': item['image_url_lge'], 'image_thumb': item['image_url_med'], }) showlist.append(show) return showlist
def _parse_anime(self, root): """Converts an XML anime list to a dictionary""" showlist = dict() for child in root.iter('anime'): show_id = int(child.find('series_animedb_id').text) if child.find('series_synonyms').text: aliases = child.find('series_synonyms').text.lstrip('; ').split('; ') else: aliases = [] show = utils.show() show.update({ 'id': show_id, 'title': child.find('series_title').text, 'aliases': aliases, 'my_progress': int(child.find('my_watched_episodes').text), 'my_status': int(child.find('my_status').text), 'my_score': int(child.find('my_score').text), 'my_start_date': self._str2date( child.find('my_start_date').text ), 'my_finish_date': self._str2date( child.find('my_finish_date').text ), 'total': int(child.find('series_episodes').text), 'status': int(child.find('series_status').text), 'start_date': self._str2date( child.find('series_start').text ), 'end_date': self._str2date( child.find('series_end').text ), 'image': child.find('series_image').text, 'url': "http://myanimelist.net/anime/%d" % show_id, }) showlist[show_id] = show return showlist
def _parse_manga(self, root): """Converts an XML manga list to a dictionary""" mangalist = dict() for child in root.iter('manga'): manga_id = int(child.find('series_mangadb_id').text) if child.find('series_synonyms').text: aliases = child.find('series_synonyms').text.lstrip('; ').split('; ') else: aliases = [] show = utils.show() show.update({ 'id': manga_id, 'title': child.find('series_title').text, 'aliases': aliases, 'my_progress': int(child.find('my_read_chapters').text), 'my_status': int(child.find('my_status').text), 'my_score': int(child.find('my_score').text), 'my_start_date': self._str2date( child.find('my_start_date').text ), 'my_finish_date': self._str2date( child.find('my_finish_date').text ), 'total': int(child.find('series_chapters').text), 'status': int(child.find('series_status').text), 'start_date': self._str2date( child.find('series_start').text ), 'end_date': self._str2date( child.find('series_end').text ), 'image': child.find('series_image').text, 'url': "http://myanimelist.net/manga/%d" % manga_id, }) mangalist[manga_id] = show return mangalist
def _parse_info(self, item): info = utils.show() info.update({ 'id': item['id'], 'title': item['name'], 'type': self.type_translate[item['kind']], 'status': self.status_translate[item['status']], 'image': self.url + item['image']['original'], 'url': self.url + item['url'], 'extra': [ ('Description', self._lc(item.get('description'))), #('Genres', item.get('genres')), ('Type', self._lc(item.get('kind').capitalize())), ('Average score', self._lc(item.get('score'))), ('Russian title', self._lc(item.get('russian'))), ('Japanese title', self._lc(item.get('japanese')[0])), ('English title', self._lc(item.get('english'))), ] }) return info
def _parse_info(self, item): start_date = self._str2date(item['released']) info = utils.show() info.update({ 'id': item['id'], 'title': item['title'], 'image': item['image'], 'url': self._get_url(item['id']), 'start_date': self._str2date(item['released']), 'extra': [ ('Original Name', item['original']), ('Released', item['released']), ('Languages', ','.join(item['languages'])), ('Original Language', ','.join(item['orig_lang'])), ('Platforms', ','.join(item['platforms'])), ('Aliases', item['aliases']), ('Length', item['length']), ('Description', item['description']), ('Links', item['links']), ] }) return info
def _parse_info(self, item): info = utils.show() showid = item['id'] aliases = [a for a in (item['title']['romaji'], item['title']['english'], item['title']['native']) if a] info.update({ 'id': showid, 'title': item['title']['userPreferred'], 'total': self._c(item[self.total_str]), 'aliases': aliases, 'type': self.type_translate[item['format']], 'status': self.status_translate[item['status']], 'image': item['coverImage']['large'], 'image_thumb': item['coverImage']['medium'], 'url': item['siteUrl'], 'start_date': self._dict2date(item.get('startDate')), 'end_date': self._dict2date(item.get('endDate')), 'extra': [ ('English', item['title'].get('english')), ('Romaji', item['title'].get('romaji')), ('Japanese', item['title'].get('native')), ('Synonyms', item['title'].get('synonyms')), ('Genres', item.get('genres')), ('Studios', [s['name'] for s in item['studios']['nodes']]), ('Synopsis', item.get('description')), ('Type', item.get('format')), ('Average score', item.get('averageScore')), ('Status', self.status_translate[item['status']]), ] }) return info
def fetch_list(self): self.check_credentials() self.msg.info(self.name, 'Downloading list...') param = {'access_token': self._get_userconfig('access_token')} data = self._request("GET", "user/{0}/{1}list".format(self.userid, self.mediatype), get=param) showlist = {} airinglist = [] #with open('list', 'w') as f: # json.dump(data, f, indent=2) if not data["lists"]: # No lists returned so no need to continue return showlist for remotelist in data["lists"].itervalues(): for item in remotelist: if item['list_status'] not in self.media_info()['statuses']: continue show = utils.show() showid = item[self.mediatype]['id'] show.update({ 'id': showid, 'title': item[self.mediatype]['title_romaji'], 'aliases': [item[self.mediatype]['title_english']], 'type': item[self.mediatype]['type'], 'status': self.status_translate[item[self.mediatype][self.airing_str]], 'my_progress': self._c(item[self.watched_str]), 'my_status': item['list_status'], 'my_score': self._c(item['score']), 'total': self._c(item[self.mediatype][self.total_str]), 'image': item[self.mediatype]['image_url_lge'], 'image_thumb': item[self.mediatype]['image_url_med'], 'url': str("http://anilist.co/%s/%d" % (self.mediatype, showid)), }) if show['status'] == 1: airinglist.append(showid) showlist[showid] = show if self.mediatype == 'anime': # Airing data unavailable for manga if len(airinglist) > 0: browseparam = {'access_token': self._get_userconfig('access_token'), 'status': 'Currently Airing', 'airing_data': 'true', 'full_page': 'true'} data = self._request("GET", "browse/anime", get=browseparam) for item in data: id = item['id'] if id in showlist and 'airing' in item: if item['airing']: showlist[id].update({ 'next_ep_number': item['airing']['next_episode'], 'next_ep_time': item['airing']['time'], }) return showlist
def _parse_info(self, show): info = utils.show() alt_titles = [] if show['alternate_title'] is not None: alt_titles.append(show['alternate_title']) info.update({ 'id': show['id'], 'title': show['title'] or show['alternate_title'] or "", 'status': self.status_translate[show['status']], 'image': show['cover_image'], 'url': show['url'], 'aliases': alt_titles, 'extra': [ ('Alternate title', show['alternate_title']), ('Show type', show['show_type']), ('Synopsis', show['synopsis']), ('Status', show['status']), ] }) return info
def search(self, criteria): self.check_credentials() self.msg.info(self.name, "Searching for {}...".format(criteria)) param = {'q': criteria} try: data = self._request("GET", "/api/{}s/search".format(self.mediatype), get=param) except ValueError: # An empty document, without any JSON, is returned # when there are no results. return [] showlist = [] for item in data: show = utils.show() showid = item['id'] show.update({ 'id': showid, 'title': item['name'], 'aliases': [item['russian']], 'type': item.get('kind', ''), #'status': item[self.airing_str], 'status': 0, 'my_status': self.media_info()['status_start'], 'total': item[self.total_str], 'image': self.url + item['image']['original'], 'image_thumb': self.url + item['image']['preview'], }) showlist.append( show ) return showlist
def _parse_info(self, item): info = utils.show() showid = item['id'] info.update({ 'id': showid, 'title': item['title_romaji'], 'status': self.status_translate[item[self.airing_str]], 'image': item['image_url_lge'], 'url': str("http://anilist.co/%s/%d" % (self.mediatype, showid)), 'start_date': self._str2date(item.get('start_date')), 'end_date': self._str2date(item.get('end_date')), 'extra': [ ('English', item.get('title_english')), ('Japanese', item.get('title_japanese')), ('Classification', item.get('classification')), ('Genres', item.get('genres')), ('Synopsis', item.get('description')), ('Type', item.get('type')), ('Average score', item.get('average_score')), ('Status', item.get(self.airing_str)), ('Start Date', item.get('start_date')), ('End Date', item.get('end_date')), ] }) return info
def _parse_anime(self, root): """Converts an XML anime list to a dictionary""" showlist = dict() for child in root.iter('anime'): show_id = int(child.find('series_animedb_id').text) if child.find('series_synonyms').text: aliases = child.find('series_synonyms').text.lstrip('; ').split('; ') else: aliases = [] show = utils.show() show.update({ 'id': show_id, 'title': child.find('series_title').text, 'aliases': aliases, 'my_progress': int(child.find('my_watched_episodes').text), 'my_status': int(child.find('my_status').text), 'my_score': int(child.find('my_score').text), 'my_start_date': self._str2date( child.find('my_start_date').text ), 'my_finish_date': self._str2date( child.find('my_finish_date').text ), 'my_tags': child.find('my_tags').text, 'total': int(child.find('series_episodes').text), 'status': int(child.find('series_status').text), 'start_date': self._str2date( child.find('series_start').text ), 'end_date': self._str2date( child.find('series_end').text ), 'image': child.find('series_image').text, 'url': "http://myanimelist.net/anime/%d" % show_id, }) showlist[show_id] = show return showlist
def _parse_info(self, item): info = utils.show() showid = item['id'] info.update({ 'id': showid, 'title': item['title']['userPreferred'], 'total': self._c(item[self.total_str]), 'aliases': self._get_aliases(item), 'type': self.type_translate[item['format']], 'status': self.status_translate[item['status']], 'image': item['coverImage']['large'], 'image_thumb': item['coverImage']['medium'], 'url': item['siteUrl'], 'start_date': self._dict2date(item.get('startDate')), 'end_date': self._dict2date(item.get('endDate')), 'extra': [ ('English', item['title'].get('english')), ('Romaji', item['title'].get('romaji')), ('Japanese', item['title'].get('native')), ('Synonyms', item.get('synonyms')), ('Genres', item.get('genres')), ('Studios', [s['name'] for s in item['studios']['nodes']]), ('Synopsis', item.get('description')), ('Type', item.get('format')), ('Average score', item.get('averageScore')), ('Status', self.status_translate[item['status']]), ] }) return info
def _parse_info(self, item): info = utils.show() showid = item['id'] info.update({ 'id': showid, 'title': item['title_romaji'], 'status': self.status_translate[item[self.airing_str]], 'image': item['image_url_lge'], 'url': str("https://anilist.co/%s/%d" % (self.mediatype, showid)), 'start_date': self._str2date(item.get('start_date')), 'end_date': self._str2date(item.get('end_date')), 'extra': [ ('English', item.get('title_english')), ('Japanese', item.get('title_japanese')), ('Classification', item.get('classification')), ('Genres', item.get('genres')), ('Synopsis', item.get('description')), ('Type', item.get('type')), ('Average score', item.get('average_score')), ('Status', item.get(self.airing_str)), ('Start Date', item.get('start_date')), ('End Date', item.get('end_date')), ] }) return info
def search(self, criteria, method): self.check_credentials() self.msg.info(self.name, "Searching for {}...".format(criteria)) param = {'q': criteria} try: data = self._request("GET", self.api_url + "/{}s/search".format(self.mediatype), get=param) except ValueError: # An empty document, without any JSON, is returned # when there are no results. return [] showlist = [] for item in data: show = utils.show() showid = item['id'] show.update({ 'id': showid, 'title': item['name'], 'aliases': [item['russian']], 'type': self.type_translate[item['kind']], 'status': self.status_translate[item['status']], 'my_status': self.media_info()['statuses_start'][0], 'total': item[self.total_str], 'image': self.url + item['image']['original'], 'image_thumb': self.url + item['image']['preview'], }) showlist.append(show) return showlist
def search(self, criteria): self.check_credentials() self.msg.info(self.name, "Searching for {}...".format(criteria)) param = {'access_token': self._get_userconfig('access_token')} try: data = self._request("GET", "{0}/search/{1}".format(self.mediatype, criteria), get=param) except ValueError: # An empty document, without any JSON, is returned # when there are no results. return [] showlist = [] for item in data: show = utils.show() showid = item['id'] show.update({ 'id': showid, 'title': item['title_romaji'], 'aliases': [item['title_english']], 'type': item['type'], 'status': item[self.airing_str], 'my_status': self.media_info()['status_start'], 'total': item[self.total_str], 'image': item['image_url_lge'], 'image_thumb': item['image_url_med'], 'url': str("http://anilist.co/%s/%d" % (self.mediatype, showid)), }) showlist.append( show ) return showlist
def search(self, criteria): self.check_credentials() self.msg.info(self.name, "Searching for {}...".format(criteria)) param = {"q": criteria} try: data = self._request("GET", "/api/{}s/search".format(self.mediatype), get=param) except ValueError: # An empty document, without any JSON, is returned # when there are no results. return [] showlist = [] for item in data: show = utils.show() showid = item["id"] show.update( { "id": showid, "title": item["name"], "aliases": [item["russian"]], "type": item.get("kind", ""), #'status': item[self.airing_str], "status": 0, "my_status": self.media_info()["status_start"], "total": item[self.total_str], "image": self.url + item["image"]["original"], "image_thumb": self.url + item["image"]["preview"], } ) showlist.append(show) return showlist
def fetch_list(self): self.check_credentials() self.msg.info(self.name, 'Downloading list...') data = self._request("GET", "/api/users/{}/{}_rates".format(self.userid, self.mediatype)) showlist = {} #with open('list', 'w') as f: # json.dump(data, f, indent=2) for item in data: show = utils.show() showid = item[self.mediatype]['id'] show.update({ 'id': showid, 'my_id': item['id'], 'title': item[self.mediatype]['name'], 'aliases': [item[self.mediatype]['russian']], #'type': item[self.mediatype]['type'], #'status': self.status_translate[item[self.mediatype][self.airing_str]], 'my_id': item['id'], 'my_progress': item[self.watched_str], 'my_status': item['status'], 'my_score': item['score'], 'total': item[self.mediatype][self.total_str], 'url': self.url + item[self.mediatype]['url'], 'image': self.url + item[self.mediatype]['image']['original'], 'image_thumb': self.url + item[self.mediatype]['image']['preview'], }) showlist[showid] = show return showlist
def fetch_list(self): """Queries the full list from the remote server. Returns the list if successful, False otherwise.""" self.check_credentials() self.msg.info(self.name, 'Downloading list...') try: data = self._request("/users/%s/library" % self.username, get={'auth_token': self.auth}) shows = json.load(data) showlist = dict() infolist = list() for show in shows: showid = show['anime']['id'] status = show['anime']['status'] rating = show['rating']['value'] epCount = show['anime']['episode_count'] alt_titles = [] if show['anime']['alternate_title'] is not None: alt_titles.append(show['anime']['alternate_title']) showlist[showid] = utils.show() showlist[showid].update({ 'id': showid, 'title': show['anime']['title'] or show['anime']['alternate_title'] or "", 'status': self.status_translate[status], 'start_date': self._str2date(show['anime']['started_airing']), 'end_date': self._str2date(show['anime']['finished_airing']), 'my_progress': show['episodes_watched'], 'my_score': float(rating) if rating is not None else 0.0, 'aliases': alt_titles, 'my_status': show['status'], 'total': int(epCount) if epCount is not None else 0, 'image': show['anime']['cover_image'], }) info = self._parse_info(show['anime']) infolist.append(info) self._emit_signal('show_info_changed', infolist) return showlist except urllib2.HTTPError, e: raise utils.APIError("Error getting list.")
def fetch_list(self): self.check_credentials() self.msg.info(self.name, 'Downloading list...') param = {'access_token': self._get_userconfig('access_token')} data = self._request("GET", "user/{0}/{1}list".format(self.userid, self.mediatype), get=param) showlist = {} #with open('list', 'w') as f: # json.dump(data, f, indent=2) if not data["lists"]: # No lists returned so no need to continue return showlist for remotelist in data["lists"].itervalues(): for item in remotelist: if item['list_status'] not in self.media_info()['statuses']: continue show = utils.show() showid = item[self.mediatype]['id'] show.update({ 'id': showid, 'title': item[self.mediatype]['title_romaji'], 'aliases': [item[self.mediatype]['title_english']], 'type': item[self.mediatype]['type'], 'status': self.status_translate[item[self.mediatype][ self.airing_str]], 'my_progress': self._c(item[self.watched_str]), 'my_status': item['list_status'], 'my_score': self._c(item['score']), 'total': self._c(item[self.mediatype][self.total_str]), 'image': item[self.mediatype]['image_url_lge'], 'image_thumb': item[self.mediatype]['image_url_med'], }) showlist[showid] = show return showlist
def fetch_list(self): self.check_credentials() shows = {} fields = 'id,alternative_titles,title,main_picture,' + self.total_str + ',status' listfields = self.watched_str + ',score,status,start_date,finish_date' params = { 'fields': '%s,list_status{%s}' % (fields, listfields), 'limit': self.library_page_limit } url = "{}/users/@me/{}list?{}".format(self.query_url, self.mediatype, urllib.parse.urlencode(params)) i = 1 while url: self.msg.info(self.name, 'Downloading list (page %d)...' % i) data = self._request('GET', url, auth=True) for item in data['data']: showid = item['node']['id'] shows[showid] = utils.show() shows[showid].update({ 'id': showid, 'title': item['node']['title'], 'url': "https://myanimelist.net/%s/%d" % (self.mediatype, showid), 'aliases': self._get_aliases(item['node']), 'image': item['node']['main_picture']['large'], 'image_thumb': item['node']['main_picture']['medium'], 'total': item['node'][self.total_str], 'status': self._translate_status(item['node']['status']), 'my_progress': item['list_status'][self.watched_str], 'my_score': item['list_status']['score'], 'my_status': item['list_status']['status'], 'my_start_date': self._str2date(item['list_status'].get('start_date')), 'my_finish_date': self._str2date(item['list_status'].get('finish_date')), }) url = data['paging'].get('next') i += 1 return shows
def _parse_info(self, media): info = utils.show() attr = media['attributes'] #print(json.dumps(media, indent=2)) #raise NotImplementedError if media['type'] == 'anime': total = attr['episodeCount'] elif media['type'] == 'manga': total = attr['chapterCount'] elif media['type'] == 'drama': total = attr['episodeCount'] # TODO Unconfirmed info.update({ 'id': int(media['id']), # TODO : Some shows actually don't have a canonicalTitle; this should be fixed in the future. # For now I'm just picking the romaji title in these cases. 'title': attr['titles'].get('en_jp') or attr.get('canonicalTitle') or attr['titles'].get('en'), 'total': total or 0, 'image': attr['posterImage'] and attr['posterImage']['small'], 'image_thumb': attr['posterImage'] and attr['posterImage']['tiny'], 'start_date': self._str2date(attr['startDate']), 'end_date': self._str2date(attr['endDate']), 'url': "https://kitsu.io/{}/{}".format(self.mediatype, attr['slug']), 'aliases': list(filter(None, attr['titles'].values())), 'extra': [ ('Synopsis', attr['synopsis']), ('Type', attr['subtype']), ] }) # WORKAROUND: Shows with 1 episode (TVs, SPs, OVAs) end the same day they start if total == 1: info['end_date'] = info['start_date'] # WORKAROUND: Since there's no way to get the formal status, # use the helper function to guess it. info['status'] = self._guess_status(info['start_date'], info['end_date']) return info
def search(self, criteria): self.check_credentials() self.msg.info(self.name, "Searching for {}...".format(criteria)) query = '''query ($query: String, $type: MediaType) { Page { media(search: $query, type: $type) { id title { userPreferred romaji english native } coverImage { medium large } format averageScore popularity chapters episodes status isAdult startDate { year month day } endDate { year month day } siteUrl mediaListEntry { status progress score } } } }''' variables = {'query': urllib.parse.quote_plus(criteria), 'type': self.mediatype.upper()} data = self._request(query, variables)['data']['Page']['media'] showlist = [] for media in data: show = utils.show() showid = media['id'] aliases = [a for a in (media['title']['romaji'], media['title']['english'], media['title']['native']) if a] showdata = { 'id': showid, 'title': media['title']['userPreferred'], 'aliases': aliases, 'type': media['format'], # Need to reformat output 'status': self.status_translate[media['status']], 'total': self._c(media[self.total_str]), 'image': media['coverImage']['large'], 'image_thumb': media['coverImage']['medium'], 'url': media['siteUrl'], } if media['mediaListEntry']: showdata['my_progress'] = self._c(media['mediaListEntry']['progress']) showdata['my_status'] = media['mediaListEntry']['status'] showdata['my_score'] = self._c(media['mediaListEntry']['score']) show.update({k:v for k,v in showdata.items() if v}) showlist.append(show) return showlist
def _parse_info(self, media): info = utils.show() attr = media['attributes'] #print(json.dumps(media, indent=2)) #raise NotImplementedError if media['type'] == 'anime': total = attr['episodeCount'] elif media['type'] == 'manga': total = attr['chapterCount'] elif media['type'] == 'drama': total = attr['episodeCount'] # TODO Unconfirmed info.update({ 'id': int(media['id']), # TODO : Some shows actually don't have a canonicalTitle; this should be fixed in the future. # For now I'm just picking the romaji title in these cases. 'title': attr['titles'].get('en_jp') or attr.get('canonicalTitle') or attr['titles'].get('en'), 'total': total or 0, 'image': attr['posterImage'] and attr['posterImage']['small'], 'image_thumb': attr['posterImage'] and attr['posterImage']['tiny'], 'start_date': self._str2date(attr['startDate']), 'end_date': self._str2date(attr['endDate']), 'type': self.type_translate.get(attr['subtype'],utils.TYPE_UNKNOWN), 'status': self.status_translate.get(attr['status'],utils.STATUS_UNKNOWN), 'url': "https://kitsu.io/{}/{}".format(self.mediatype, attr['slug']), 'aliases': list(filter(None, attr['titles'].values())), 'extra': [ ('Synopsis', attr['description']), ('Type', attr['subtype']), ('Titles', list(filter(None, attr['titles'].values())) ), ('Average Rating', attr['averageRating'] or '?'), ('Popularity Rank', attr['popularityRank']), ('Rating Rank', attr['ratingRank']), ('Age Rating', attr['ageRating']), ] }) # WORKAROUND: Shows with 1 episode (TVs, SPs, OVAs) end the same day they start if total == 1: info['end_date'] = info['start_date'] if attr['status'] in ['upcoming', 'unreleased']: info['extra'].append(('Expected Release', attr['tba'] or '?')) if attr['nsfw']: info['extra'].append(('Not Safe for Work', None)) return info
def fetch_list(self): self.check_credentials() self.msg.info(self.name, "Downloading list...") # Get a JSON list from API response = self.opener.open( "http://melative.com/api/library.json?user={0}&context_type={1}".format(self.username, self.mediatype) ) data = json.load(response) # Load data from the JSON stream into a parsed dictionary statuses = self.media_info()["statuses_dict"] itemlist = dict() for record in data["library"]: entity = record["entity"] segment = record["segment"] itemid = int(entity["id"]) # use appropiate number for the show state _status = 0 for k, v in statuses.items(): if v.lower() == record["state"]: _status = k # use show length if available try: _total = int(entity["length"]) except TypeError: _total = 0 # use show progress if needed if self.mediatypes[self.mediatype]["has_progress"]: _progress = int(segment["name"]) else: _progress = 0 show = utils.show() show["id"] = itemid show["title"] = entity["aliases"][0].encode("utf-8") show["my_status"] = _status show["my_score"] = int(record["rating"] or 0) show["my_progress"] = _progress show["total"] = _total show["image"] = entity["image_url"] show["status"] = 0 # placeholder itemlist[itemid] = show return itemlist
def fetch_list(self): self.check_credentials() self.msg.info(self.name, 'Downloading list...') # Get a JSON list from API response = self.opener.open( "http://melative.com/api/library.json?user={0}&context_type={1}". format(self.username, self.mediatype)) data = json.load(response) # Load data from the JSON stream into a parsed dictionary statuses = self.media_info()['statuses_dict'] itemlist = dict() for record in data['library']: entity = record['entity'] segment = record['segment'] itemid = int(entity['id']) # use appropiate number for the show state _status = 0 for k, v in statuses.items(): if v.lower() == record['state']: _status = k # use show length if available try: _total = int(entity['length']) except TypeError: _total = 0 # use show progress if needed if self.mediatypes[self.mediatype]['has_progress']: _progress = int(segment['name']) else: _progress = 0 show = utils.show() show['id'] = itemid show['title'] = entity['aliases'][0].encode('utf-8') show['my_status'] = _status show['my_score'] = int(record['rating'] or 0) show['my_progress'] = _progress show['total'] = _total show['image'] = entity['image_url'] show['status'] = 0 #placeholder itemlist[itemid] = show return itemlist
def fetch_list(self): self.check_credentials() self.msg.info(self.name, 'Downloading list...') params = {'limit': 5000} data = self._request( "GET", self.api_url + "/users/{}/{}_rates".format(self.userid, self.mediatype), get=params) showlist = {} for item in data: show = utils.show() showid = item[self.mediatype]['id'] show.update({ 'id': showid, 'my_id': item['id'], 'title': item[self.mediatype]['name'], 'aliases': [item[self.mediatype]['russian']], 'type': self.type_translate[item[self.mediatype]['kind']], 'status': self.status_translate[item[self.mediatype]['status']], 'my_id': item['id'], 'my_progress': item[self.watched_str], 'my_status': item['status'], 'my_score': item['score'], 'total': item[self.mediatype][self.total_str], 'url': self.url + item[self.mediatype]['url'], 'image': self.url + item[self.mediatype]['image']['original'], 'image_thumb': self.url + item[self.mediatype]['image']['preview'], }) showlist[showid] = show return showlist
def fetch_list(self): self.check_credentials() self.msg.info(self.name, 'Downloading list...') # Get a JSON list from API response = self.opener.open("http://melative.com/api/library.json?user={0}&context_type={1}".format(self.username, self.mediatype)) data = json.loads(response.read().decode('utf-8')) # Load data from the JSON stream into a parsed dictionary statuses = self.media_info()['statuses_dict'] itemlist = dict() for record in data['library']: entity = record['entity'] segment = record['segment'] itemid = int(entity['id']) # use appropiate number for the show state _status = 0 for k, v in statuses.items(): if v.lower() == record['state']: _status = k # use show length if available try: _total = int(entity['length']) except TypeError: _total = 0 # use show progress if needed if self.mediatypes[self.mediatype]['has_progress']: _progress = int(segment['name']) else: _progress = 0 show = utils.show() show['id'] = itemid show['title'] = entity['aliases'][0] show['my_status'] = _status show['my_score'] = int(record['rating'] or 0) show['my_progress'] =_progress show['total'] = _total show['image'] = entity['image_url'] show['status'] = 0 #placeholder itemlist[itemid] = show return itemlist
def search(self, criteria): self.check_credentials() self.msg.info(self.name, "Searching for {}...".format(criteria)) param = {'access_token': self._get_userconfig('access_token')} try: data = self._request("GET", "{0}/search/{1}".format( self.mediatype, criteria), get=param) except ValueError: # An empty document, without any JSON, is returned # when there are no results. return [] showlist = [] for item in data: show = utils.show() showid = item['id'] show.update({ 'id': showid, 'title': item['title_romaji'], 'aliases': [item['title_english']], 'type': item['type'], 'status': item[self.airing_str], 'my_status': self.media_info()['status_start'], 'total': item[self.total_str], 'image': item['image_url_lge'], 'image_thumb': item['image_url_med'], 'url': str("http://anilist.co/%s/%d" % (self.mediatype, showid)), }) showlist.append(show) return showlist
def _parse_info(self, item): info = utils.show() info.update({ 'id': item['id'], 'title': item['title_romaji'], 'status': self.status_translate[item[self.airing_str]], 'image': item['image_url_lge'], 'extra': [ ('Description', item.get('description')), ('Genres', item.get('genres')), ('Classification', item.get('classification')), ('Status', item.get('airing_status')), ('Average score', item.get('average_score')), ('Japanese title', item.get('title_japanese')), ('English title', item.get('title_english')), ] }) return info
def fetch_list(self): """Queries the full list from the remote server. Returns the list if successful, False otherwise.""" self.check_credentials() self.msg.info(self.name, 'Downloading list...') try: data = self._request( "/users/%s/library" % self.username, get={'auth_token': self.auth} ) shows = json.loads(data.read().decode('utf-8')) showlist = dict() infolist = list() for show in shows: showid = show['anime']['id'] status = show['anime']['status'] rating = show['rating']['value'] epCount = show['anime']['episode_count'] alt_titles = [] if show['anime']['alternate_title'] is not None: alt_titles.append(show['anime']['alternate_title']) showlist[showid] = utils.show() showlist[showid].update({ 'id': showid, 'title': show['anime']['title'] or show['anime']['alternate_title'] or "", 'status': self.status_translate[status], 'start_date': self._str2date( show['anime']['started_airing'] ), 'end_date': self._str2date( show['anime']['finished_airing'] ), 'my_progress': show['episodes_watched'], 'my_score': float(rating) if rating is not None else 0.0, 'aliases': alt_titles, 'my_status': show['status'], 'total': int(epCount) if epCount is not None else 0, 'image': show['anime']['cover_image'], 'url': str("https://hummingbird.me/%s/%d" % (self.mediatype, showid)), }) info = self._parse_info(show['anime']) infolist.append(info) self._emit_signal('show_info_changed', infolist) return showlist except urllib.request.HTTPError as e: raise utils.APIError("Error getting list.")
def _parse_info(self, item): info = utils.show() info.update({ 'id': item['id'], 'title': item['name'], 'status': 0, 'image': self.url + item['image']['original'], 'url': self.url + item['url'], 'extra': [ ('Description', item.get('description')), #('Genres', item.get('genres')), ('Type', item.get('kind').capitalize()), ('Average score', item.get('score')), ('Russian title', item.get('russian')), ('Japanese title', item.get('japanese')[0]), ('English title', item.get('english')), ] }) return info
def _parse_info(self, item): info = utils.show() info.update( { "id": item["id"], "title": item["name"], "status": 0, "image": self.url + item["image"]["original"], "url": self.url + item["url"], "extra": [ ("Description", item.get("description")), # ('Genres', item.get('genres')), ("Type", item.get("kind").capitalize()), ("Average score", item.get("score")), ("Russian title", item.get("russian")), ("Japanese title", item.get("japanese")[0]), ("English title", item.get("english")), ], } ) return info
def fetch_list(self): self.check_credentials() self.msg.info(self.name, 'Downloading list...') param = {'access_token': self._get_userconfig('access_token')} data = self._request("GET", "user/{0}/{1}list".format(self.userid, self.mediatype), get=param) showlist = {} #with open('list', 'w') as f: # json.dump(data, f, indent=2) if not data["lists"]: # No lists returned so no need to continue return showlist for remotelist in data["lists"].itervalues(): for item in remotelist: if item['list_status'] not in self.media_info()['statuses']: continue show = utils.show() showid = item[self.mediatype]['id'] show.update({ 'id': showid, 'title': item[self.mediatype]['title_romaji'], 'aliases': [item[self.mediatype]['title_english']], 'type': item[self.mediatype]['type'], 'status': self.status_translate[item[self.mediatype][self.airing_str]], 'my_progress': self._c(item[self.watched_str]), 'my_status': item['list_status'], 'my_score': self._c(item['score']), 'total': self._c(item[self.mediatype][self.total_str]), 'image': item[self.mediatype]['image_url_lge'], 'image_thumb': item[self.mediatype]['image_url_med'], }) showlist[showid] = show return showlist
def _parse_info(self, item): start_date = self._str2date(item['released']) info = utils.show() info.update({'id': item['id'], 'title': item['title'], 'image': item['image'], 'url': self._get_url(item['id']), 'start_date': self._str2date(item['released']), 'extra': [ ('Original Name', item['original']), ('Released', item['released']), ('Languages', ','.join(item['languages'])), ('Original Language', ','.join(item['orig_lang'])), ('Platforms', ','.join(item['platforms'])), ('Aliases', item['aliases']), ('Length', item['length']), ('Description', item['description']), ('Links', item['links']), ] }) return info
def search(self, criteria): self.check_credentials() self.msg.info(self.name, "Searching for {}...".format(criteria)) param = {'access_token': self._get_userconfig('access_token')} data = self._request("GET", "{0}/search/{1}".format(self.mediatype, criteria), get=param) if type(data) == dict: # In case of error API returns a small JSON payload # which translates into a dict with the key 'error' # instead of a list. if data['error']['messages'][0] == 'No Results.': data = [] else: raise utils.APIError("Error while searching for \ {0}: {1}".format(criteria, str(data))) showlist = [] for item in data: show = utils.show() showid = item['id'] showdata = { 'id': showid, 'title': item['title_romaji'], 'aliases': [item['title_english']], 'type': item['type'], 'status': item[self.airing_str], 'my_status': self.media_info()['status_start'], 'total': item[self.total_str], 'image': item['image_url_lge'], 'image_thumb': item['image_url_med'], 'url': str("https://anilist.co/%s/%d" % (self.mediatype, showid)), } show.update({k:v for k,v in showdata.items() if v}) showlist.append( show ) return showlist
def search(self, criteria): self.check_credentials() self.msg.info(self.name, "Searching for {}...".format(criteria)) param = {'access_token': self._get_userconfig('access_token')} data = self._request("GET", "{0}/search/{1}".format(self.mediatype, urllib.parse.quote_plus(criteria)), get=param) if type(data) == dict: # In case of error API returns a small JSON payload # which translates into a dict with the key 'error' # instead of a list. if data['error']['messages'][0] == 'No Results.': data = [] else: raise utils.APIError("Error while searching for \ {0}: {1}".format(criteria, str(data))) showlist = [] for item in data: show = utils.show() showid = item['id'] showdata = { 'id': showid, 'title': item['title_romaji'], 'aliases': [item['title_english']], 'type': item['type'], 'status': item[self.airing_str], 'my_status': self.media_info()['status_start'], 'total': item[self.total_str], 'image': item['image_url_lge'], 'image_thumb': item['image_url_med'], 'url': str("https://anilist.co/%s/%d" % (self.mediatype, showid)), } show.update({k:v for k,v in showdata.items() if v}) showlist.append( show ) return showlist
def _parse_info(self, item): info = utils.show() showid = item['id'] info.update({ 'id': showid, 'title': item['title'], 'url': "https://myanimelist.net/%s/%d" % (self.mediatype, showid), 'aliases': self._get_aliases(item), 'type': self.type_translate[item['media_type']], 'total': item[self.total_str], 'status': self._translate_status(item['status']), 'image': item['main_picture']['large'], 'start_date': self._str2date(item.get('start_date')), 'end_date': self._str2date(item.get('end_date')), 'extra': [ ('English', item['alternative_titles'].get('en')), ('Japanese', item['alternative_titles'].get('ja')), ('Synonyms', item['alternative_titles'].get('synonyms')), ('Synopsis', item.get('synopsis')), ('Type', item.get('media_type')), ('Mean score', item.get('mean')), ('Status', self._translate_status(item['status'])), ] }) return info
def fetch_list(self): self.check_credentials() self.msg.info(self.name, "Downloading list...") data = self._request("GET", "/api/users/{}/{}_rates".format(self.userid, self.mediatype)) showlist = {} # with open('list', 'w') as f: # json.dump(data, f, indent=2) for item in data: show = utils.show() showid = item[self.mediatype]["id"] show.update( { "id": showid, "my_id": item["id"], "title": item[self.mediatype]["name"], "aliases": [item[self.mediatype]["russian"]], #'type': item[self.mediatype]['type'], #'status': self.status_translate[item[self.mediatype][self.airing_str]], "my_id": item["id"], "my_progress": item[self.watched_str], "my_status": item["status"], "my_score": item["score"], "total": item[self.mediatype][self.total_str], "url": self.url + item[self.mediatype]["url"], "image": self.url + item[self.mediatype]["image"]["original"], "image_thumb": self.url + item[self.mediatype]["image"]["preview"], } ) showlist[showid] = show return showlist
def fetch_list(self): """Queries the full list from the remote server. Returns the list if successful, False otherwise.""" self.check_credentials() self.msg.info(self.name, 'Downloading list...') try: showlist = dict() infolist = list() # Get first page and continue from there params = { "filter[user_id]": self._get_userconfig('userid'), "filter[kind]": self.mediatype, #"include": self.mediatype, # TODO : This returns a 500 for some reason. "include": "media", # TODO : List for manga should be different "fields[anime]": "id,slug,canonicalTitle,titles,episodeCount,synopsis,subtype,posterImage,startDate,endDate", "page[limit]": "250", } url = "{}/library-entries?{}".format(self.prefix, urllib.parse.urlencode(params)) i = 1 while url: self.msg.info(self.name, 'Getting page {}...'.format(i)) data = self._request('GET', url) data_json = json.loads(data) #print(json.dumps(data_json, sort_keys=True, indent=2)) #return [] entries = data_json['data'] links = data_json['links'] for entry in entries: # TODO : Including the mediatype returns a 500 for some reason. #showid = int(entry['relationships'][self.mediatype]['data']['id']) showid = int(entry['relationships']['media']['data']['id']) status = entry['attributes']['status'] rating = entry['attributes']['rating'] showlist[showid] = utils.show() showlist[showid].update({ 'id': showid, 'my_id': entry['id'], 'my_progress': entry['attributes']['progress'], 'my_score': float(rating) if rating is not None else 0.0, 'my_status': entry['attributes']['status'], 'my_start_date': self._iso2date(entry['attributes']['startedAt']), 'my_finish_date': self._iso2date(entry['attributes']['finishedAt']), }) if 'included' in data_json: medias = data_json['included'] for media in medias: info = self._parse_info(media) infolist.append(info) self._emit_signal('show_info_changed', infolist) url = links.get('next') i += 1 return showlist except urllib.request.HTTPError as e: raise utils.APIError("Error getting list.")
def search(self, criteria): """Searches MyAnimeList database for the queried show""" self.msg.info(self.name, "Searching for %s..." % criteria) # Send the urlencoded query to the search API query = urllib.parse.urlencode({'q': criteria}) data = self._request(self.url + self.mediatype + "/search.xml?" + query) # Load the results into XML try: root = self._parse_xml(data) except ET.ParseError as e: if e.code == 3: # Empty document; no results return [] else: raise utils.APIError("Parser error: %r" % e) except IOError: raise utils.APIError("IO error: %r" % e) # Use the correct tag name for episodes if self.mediatype == 'manga': episodes_str = 'chapters' else: episodes_str = 'episodes' # Since the MAL API returns the status as a string, and # we handle statuses as integers, we need to convert them if self.mediatype == 'anime': status_translate = { 'Currently Airing': utils.STATUS_AIRING, 'Finished Airing': utils.STATUS_FINISHED, 'Not yet aired': utils.STATUS_NOTYET } elif self.mediatype == 'manga': status_translate = { 'Publishing': utils.STATUS_AIRING, 'Finished': utils.STATUS_AIRING } entries = list() for child in root.iter('entry'): show = utils.show() showid = int(child.find('id').text) show.update({ 'id': showid, 'title': child.find('title').text, 'type': child.find('type').text, 'status': status_translate[child.find( 'status').text], # TODO : This should return an int! 'total': int(child.find(episodes_str).text), 'image': child.find('image').text, 'url': "https://myanimelist.net/anime/%d" % showid, 'start_date': self._str2date(child.find('start_date').text), 'end_date': self._str2date(child.find('end_date').text), 'extra': [ ('English', child.find('english').text), ('Synonyms', child.find('synonyms').text), ('Synopsis', self._translate_synopsis(child.find('synopsis').text)), (episodes_str.title(), child.find(episodes_str).text), ('Type', child.find('type').text), ('Score', child.find('score').text), ('Status', child.find('status').text), ('Start date', child.find('start_date').text), ('End date', child.find('end_date').text), ] }) entries.append(show) self._emit_signal('show_info_changed', entries) return entries
# Use the correct tag name for episodes if self.mediatype == 'manga': episodes_str = 'chapters' else: episodes_str = 'episodes' # Since the MAL API returns the status as a string, and # we handle statuses as integers, we need to convert them if self.mediatype == 'anime': status_translate = {'Currently Airing': 1, 'Finished Airing': 2, 'Not yet aired': 3} elif self.mediatype == 'manga': status_translate = {'Publishing': 1, 'Finished': 2} entries = list() for child in root.iter('entry'): show = utils.show() showid = int(child.find('id').text) show.update({ 'id': showid, 'title': child.find('title').text, 'type': child.find('type').text, 'status': status_translate[child.find('status').text], # TODO : This should return an int! 'total': int(child.find(episodes_str).text), 'image': child.find('image').text, 'url': "http://myanimelist.net/anime/%d" % showid, 'start_date': self._str2date( child.find('start_date').text ), 'end_date': self._str2date( child.find('end_date').text ), 'extra': [ ('English', child.find('english').text), ('Synonyms', child.find('synonyms').text), ('Synopsis', self._translate_synopsis(child.find('synopsis').text)),
def fetch_list(self): """Queries the full list from the remote server. Returns the list if successful, False otherwise.""" self.check_credentials() # Retrieve VNs per pages page = 1 vns = dict() while True: self.msg.info(self.name, 'Downloading list... (%d)' % page) (name, data) = self._sendcmd('get %s basic (uid = 0)' % self.mediatype, { 'page': page, 'results': self.pagesize_list }) # Something is wrong if we don't get a results response. if name != 'results': raise utils.APIFatal("Invalid response (%s)" % name) # Process list for item in data['items']: vnid = item['vn'] vns[vnid] = utils.show() vns[vnid]['id'] = vnid vns[vnid]['url'] = self._get_url(vnid) vns[vnid]['my_status'] = item.get('status', item.get('priority')) if not data['more']: # No more VNs, finish break page += 1 # Retrieve scores per pages page = 1 while True: self.msg.info(self.name, 'Downloading votes... (%d)' % page) (name, data) = self._sendcmd('get votelist basic (uid = 0)', { 'page': page, 'results': self.pagesize_list }) # Something is wrong if we don't get a results response. if name != 'results': raise utils.APIFatal("Invalid response (%s)" % name) for item in data['items']: vnid = item['vn'] if vnid not in vns: # Ghost vote; create entry for it. vns[vnid] = utils.show() vns[vnid]['id'] = vnid vns[vnid]['url'] = self._get_url(vnid) vns[vnid]['my_status'] = 0 vns[vnid]['my_score'] = (item['vote'] / 10.0) vns[vnid]['my_finish_date'] = datetime.datetime.fromtimestamp( item['added']) if not data['more']: # No more VNs, finish break page += 1 return vns
def fetch_list(self): self.check_credentials() self.msg.info(self.name, 'Downloading list...') query = '''query ($id: Int!, $listType: MediaType) { MediaListCollection (userId: $id, type: $listType) { lists { name isCustomList status entries { ... mediaListEntry } } user { mediaListOptions { scoreFormat } } } } fragment mediaListEntry on MediaList { id score progress startedAt { year month day } completedAt { year month day } media { id title { userPreferred romaji english native } synonyms coverImage { large medium } format status chapters episodes nextAiringEpisode { airingAt episode } startDate { year month day } endDate { year month day } siteUrl } }''' variables = {'id': self.userid, 'listType': self.mediatype.upper()} data = self._request(query, variables)['data']['MediaListCollection'] showlist = {} if not data['lists']: # No lists returned so no need to continue return showlist # Handle different score formats provided by Anilist self.scoreformat = data['user']['mediaListOptions']['scoreFormat'] self._apply_scoreformat(self.scoreformat) self._set_userconfig('scoreformat_' + self.mediatype, self.scoreformat) self._emit_signal('userconfig_changed') for remotelist in data['lists']: my_status = remotelist['status'] if my_status not in self.media_info()['statuses']: continue if remotelist['isCustomList']: continue # Maybe do something with this later for item in remotelist['entries']: show = utils.show() media = item['media'] showid = media['id'] showdata = { 'my_id': item['id'], 'id': showid, 'title': media['title']['userPreferred'], 'aliases': self._get_aliases(media), 'type': self.type_translate[media['format']], 'status': self.status_translate[media['status']], 'my_progress': self._c(item['progress']), 'my_status': my_status, 'my_score': self._c(item['score']), 'total': self._c(media[self.total_str]), 'image': media['coverImage']['large'], 'image_thumb': media['coverImage']['medium'], 'url': media['siteUrl'], 'start_date': self._dict2date(media['startDate']), 'end_date': self._dict2date(media['endDate']), 'my_start_date': self._dict2date(item['startedAt']), 'my_finish_date': self._dict2date(item['completedAt']), } if media['nextAiringEpisode']: showdata['next_ep_number'] = media['nextAiringEpisode']['episode'] showdata['next_ep_time'] = self._int2date(media['nextAiringEpisode']['airingAt']) show.update({k:v for k,v in showdata.items() if v}) showlist[showid] = show return showlist
def search(self, criteria): """Searches MyAnimeList database for the queried show""" self.msg.info(self.name, "Searching for %s..." % criteria) # Send the urlencoded query to the search API query = urllib.parse.urlencode({'q': criteria}) data = self._request(self.url + self.mediatype + "/search.xml?" + query) # Load the results into XML try: root = self._parse_xml(data) except ET.ParseError as e: if e.code == 3: # Empty document; no results return [] else: raise utils.APIError("Parser error: %r" % e) except IOError: raise utils.APIError("IO error: %r" % e) # Use the correct tag name for episodes if self.mediatype == 'manga': episodes_str = 'chapters' else: episodes_str = 'episodes' # Since the MAL API returns the status as a string, and # we handle statuses as integers, we need to convert them if self.mediatype == 'anime': status_translate = {'Currently Airing': utils.STATUS_AIRING, 'Finished Airing': utils.STATUS_FINISHED, 'Not yet aired': utils.STATUS_NOTYET} elif self.mediatype == 'manga': status_translate = {'Publishing': utils.STATUS_AIRING, 'Finished': utils.STATUS_AIRING} entries = list() for child in root.iter('entry'): show = utils.show() showid = int(child.find('id').text) show.update({ 'id': showid, 'title': child.find('title').text, 'type': child.find('type').text, 'status': status_translate[child.find('status').text], # TODO : This should return an int! 'total': int(child.find(episodes_str).text), 'image': child.find('image').text, 'url': "https://myanimelist.net/anime/%d" % showid, 'start_date': self._str2date( child.find('start_date').text ), 'end_date': self._str2date( child.find('end_date').text ), 'extra': [ ('English', child.find('english').text), ('Synonyms', child.find('synonyms').text), ('Synopsis', self._translate_synopsis(child.find('synopsis').text)), (episodes_str.title(), child.find(episodes_str).text), ('Type', child.find('type').text), ('Score', child.find('score').text), ('Status', child.find('status').text), ('Start date', child.find('start_date').text), ('End date', child.find('end_date').text), ] }) entries.append(show) self._emit_signal('show_info_changed', entries) return entries
else: episodes_str = 'episodes' # Since the MAL API returns the status as a string, and # we handle statuses as integers, we need to convert them if self.mediatype == 'anime': status_translate = {'Currently Airing': utils.STATUS_AIRING, 'Finished Airing': utils.STATUS_FINISHED, 'Not yet aired': utils.STATUS_NOTYET} elif self.mediatype == 'manga': status_translate = {'Publishing': utils.STATUS_AIRING, 'Finished': utils.STATUS_AIRING} entries = list() for child in root.iter('entry'): show = utils.show() showid = int(child.find('id').text) show.update({ 'id': showid, 'title': child.find('title').text, 'type': child.find('type').text, 'status': status_translate[child.find('status').text], # TODO : This should return an int! 'total': int(child.find(episodes_str).text), 'image': child.find('image').text, 'url': "http://myanimelist.net/anime/%d" % showid, 'start_date': self._str2date( child.find('start_date').text ), 'end_date': self._str2date( child.find('end_date').text ), 'extra': [ ('English', child.find('english').text), ('Synonyms', child.find('synonyms').text), ('Synopsis', self._translate_synopsis(child.find('synopsis').text)),
def fetch_list(self): self.check_credentials() self.msg.info(self.name, 'Downloading list...') query = '''query ($id: Int!, $listType: MediaType) { MediaListCollection (userId: $id, type: $listType) { lists { name isCustomList status entries { ... mediaListEntry } } user { mediaListOptions { scoreFormat } } } } fragment mediaListEntry on MediaList { id score progress startedAt { year month day } completedAt { year month day } media { id title { userPreferred romaji english native } synonyms coverImage { large medium } format status chapters episodes nextAiringEpisode { airingAt episode } startDate { year month day } endDate { year month day } siteUrl } }''' variables = {'id': self.userid, 'listType': self.mediatype.upper()} data = self._request(query, variables)['data']['MediaListCollection'] showlist = {} if not data['lists']: # No lists returned so no need to continue return showlist # Handle different score formats provided by Anilist self.scoreformat = data['user']['mediaListOptions']['scoreFormat'] self._apply_scoreformat(self.scoreformat) self._set_userconfig('scoreformat_' + self.mediatype, self.scoreformat) self._emit_signal('userconfig_changed') for remotelist in data['lists']: my_status = remotelist['status'] if my_status not in self.media_info()['statuses']: continue if remotelist['isCustomList']: continue # Maybe do something with this later for item in remotelist['entries']: show = utils.show() media = item['media'] showid = media['id'] showdata = { 'my_id': item['id'], 'id': showid, 'title': media['title']['userPreferred'], 'aliases': self._get_aliases(media), 'type': self._translate_type(media['format']), 'status': self._translate_status(media['status']), 'my_progress': self._c(item['progress']), 'my_status': my_status, 'my_score': self._c(item['score']), 'total': self._c(media[self.total_str]), 'image': media['coverImage']['large'], 'image_thumb': media['coverImage']['medium'], 'url': media['siteUrl'], 'start_date': self._dict2date(media['startDate']), 'end_date': self._dict2date(media['endDate']), 'my_start_date': self._dict2date(item['startedAt']), 'my_finish_date': self._dict2date(item['completedAt']), } if media['nextAiringEpisode']: showdata['next_ep_number'] = media['nextAiringEpisode'][ 'episode'] showdata['next_ep_time'] = self._int2date( media['nextAiringEpisode']['airingAt']) show.update({k: v for k, v in showdata.items() if v}) showlist[showid] = show return showlist
def fetch_list(self): self.check_credentials() self.msg.info(self.name, 'Downloading list...') param = {'access_token': self._get_userconfig('access_token')} data = self._request("GET", "user/{0}/{1}list".format(self.userid, self.mediatype), get=param) showlist = {} airinglist = [] #with open('list', 'w') as f: # json.dump(data, f, indent=2) if not data["lists"]: # No lists returned so no need to continue return showlist for remotelist in data["lists"].values(): for item in remotelist: if item['list_status'] not in self.media_info()['statuses']: continue show = utils.show() showid = item[self.mediatype]['id'] showdata = { 'id': showid, 'title': item[self.mediatype]['title_romaji'], 'aliases': [item[self.mediatype]['title_english']], 'type': item[self.mediatype]['type'], 'status': self.status_translate[item[self.mediatype][self.airing_str]], 'my_progress': self._c(item[self.watched_str]), 'my_status': item['list_status'], 'my_score': self._c(item['score']), 'total': self._c(item[self.mediatype][self.total_str]), 'image': item[self.mediatype]['image_url_lge'], 'image_thumb': item[self.mediatype]['image_url_med'], 'url': str("https://anilist.co/%s/%d" % (self.mediatype, showid)), } show.update({k:v for k,v in showdata.items() if v}) if show['status'] == 1: airinglist.append(showid) showlist[showid] = show if self.mediatype == 'anime': # Airing data unavailable for manga if len(airinglist) > 0: browseparam = {'access_token': self._get_userconfig('access_token'), 'status': 'Currently Airing', 'airing_data': 'true', 'full_page': 'true'} data = self._request("GET", "browse/anime", get=browseparam) for item in data: id = item['id'] if id in showlist and 'airing' in item: if item['airing']: showlist[id].update({ 'next_ep_number': item['airing']['next_episode'], 'next_ep_time': item['airing']['time'], }) return showlist
def fetch_list(self): """Queries the full list from the remote server. Returns the list if successful, False otherwise.""" self.check_credentials() self.msg.info(self.name, 'Downloading list...') try: showlist = dict() infolist = list() # Get first page and continue from there params = { "filter[user_id]": self._get_userconfig('userid'), "filter[kind]": self.mediatype, # "include": self.mediatype, # TODO : This returns a 500 for some reason. "include": "media", # TODO : List for manga should be different f"fields[{self.mediatype}]": ','.join([ 'id', 'slug', 'canonicalTitle', 'titles', 'episodeCount' if self.mediatype in ['anime', 'drama'] else 'chapterCount', 'description', 'status', 'tba', 'subtype', 'posterImage', 'startDate', 'endDate', 'abbreviatedTitles', 'averageRating', 'popularityRank', 'ratingRank', 'ageRating', 'ageRatingGuide', 'userCount', 'favoritesCount' ]), "page[limit]": "250", } if self.mediatype == 'anime': params['fields[anime]'] += ',nsfw' if self.mediatype == 'manga': params['fields[manga]'] += ',serialization' url = "{}/library-entries?{}".format( self.prefix, urllib.parse.urlencode(params)) i = 1 while url: self.msg.info(self.name, 'Getting page {}...'.format(i)) data = self._request('GET', url) data_json = json.loads(data) #print(json.dumps(data_json, sort_keys=True, indent=2)) # return [] entries = data_json['data'] links = data_json['links'] for entry in entries: # TODO : Including the mediatype returns a 500 for some reason. #showid = int(entry['relationships'][self.mediatype]['data']['id']) showid = int(entry['relationships']['media']['data']['id']) status = entry['attributes']['status'] rating = entry['attributes']['ratingTwenty'] showlist[showid] = utils.show() showlist[showid].update({ 'id': showid, 'my_id': entry['id'], 'my_progress': entry['attributes']['progress'], 'my_score': float(rating) / 4.00 if rating is not None else 0.0, 'my_status': entry['attributes']['status'], 'my_start_date': self._iso2date(entry['attributes']['startedAt']), 'my_finish_date': self._iso2date(entry['attributes']['finishedAt']), }) if 'included' in data_json: medias = data_json['included'] for media in medias: info = self._parse_info(media) infolist.append(info) self._emit_signal('show_info_changed', infolist) url = links.get('next') i += 1 return showlist except urllib.request.HTTPError as e: raise utils.APIError("Error getting list (HTTPError): %s" % e.read()) except urllib.error.URLError as e: raise utils.APIError("Error getting list (URLError): %s" % e.reason)
def fetch_list(self): """Queries the full list from the remote server. Returns the list if successful, False otherwise.""" self.check_credentials() # Retrieve VNs per pages page = 1 vns = dict() while True: self.msg.info(self.name, 'Downloading list... (%d)' % page) (name, data) = self._sendcmd('get %s basic (uid = 0)' % self.mediatype, {'page': page, 'results': 25 }) # Something is wrong if we don't get a results response. if name != 'results': raise utils.APIFatal("Invalid response (%s)" % name) # Process list for item in data['items']: vnid = item['vn'] vns[vnid] = utils.show() vns[vnid]['id'] = vnid vns[vnid]['url'] = self._get_url(vnid) vns[vnid]['my_status'] = item.get('status', item.get('priority')) if not data['more']: # No more VNs, finish break page += 1 # Retrieve scores per pages page = 1 while True: self.msg.info(self.name, 'Downloading votes... (%d)' % page) (name, data) = self._sendcmd('get votelist basic (uid = 0)', {'page': page, 'results': 25 }) # Something is wrong if we don't get a results response. if name != 'results': raise utils.APIFatal("Invalid response (%s)" % name) for item in data['items']: vnid = item['vn'] try: vns[vnid]['my_score'] = (item['vote'] / 10.0) except KeyError: # Ghost vote; ignore it pass if not data['more']: # No more VNs, finish break page += 1 return vns