def bangumi_calendar(self, force_update=False, save=True, cover=None): if force_update and not test_connection(): force_update = False print_warning('Network is unreachable') if force_update: print_info('Fetching bangumi info ...') Bangumi.delete_all() weekly_list = self.fetch(save=save) else: weekly_list = Bangumi.get_updating_bangumi() if not weekly_list: print_warning('Warning: no bangumi schedule, fetching ...') weekly_list = self.fetch(save=save) if cover is not None: # download cover to local cover_to_be_download = cover for daily_bangumi in weekly_list.values(): for bangumi in daily_bangumi: _, file_path = convert_cover_to_path(bangumi['cover']) if not glob.glob(file_path): cover_to_be_download.append(bangumi['cover']) if cover_to_be_download: print_info('Updating cover ...') download_cover(cover_to_be_download) return weekly_list
def get(self, bangumi_name): data = Followed(bangumi_name=bangumi_name) data.select_obj() bangumi_obj = Bangumi(name=bangumi_name) bangumi_obj.select_obj() if not data: return self.write_error(404) episode_list = {} bangumi_path = os.path.join(BGMI_SAVE_PATH, bangumi_name) for root, _, files in os.walk(bangumi_path): if not _ and files: _ = root.replace(bangumi_path, '').split('/') base_path = root.replace(BGMI_SAVE_PATH, '') if len(_) >= 2: episode_path = root.replace(os.path.join(BGMI_SAVE_PATH, bangumi_name), '') episode = int(episode_path.split('/')[1]) else: episode = -1 for bangumi in files: if bangumi.lower().endswith('.mp4'): episode_list[episode] = {'path': os.path.join(base_path, bangumi)} break if not episode_list: self.write('_(:3 There are nothing to play, please try again later.') self.finish() else: self.render('templates/dplayer.html', bangumi=episode_list, bangumi_name=bangumi_name, bangumi_cover='{}/{}'.format(COVER_URL, bangumi_obj['cover']), DANMAKU_URL=DANMAKU_API_URL)
def add(ret): # action add # add bangumi by a list of bangumi name if not Bangumi.get_all_bangumi(): print_warning('No bangumi data in database, fetching...') update(ret) for bangumi in ret.action.add.name: bangumi_obj = Bangumi(name=bangumi) data = bangumi_obj.select(one=True, fields=['id', 'name', 'keyword']) if data: followed_obj = Followed(bangumi_name=data['name'], status=STATUS_FOLLOWED) followed_obj.select_obj() if not followed_obj or followed_obj.status == STATUS_NORMAL: if not followed_obj: ret, _ = get_maximum_episode(bangumi_obj, subtitle=False) followed_obj.episode = ret['episode'] followed_obj.save() else: followed_obj.status = STATUS_FOLLOWED followed_obj.save() print_success('{0} has followed'.format(bangumi_obj)) else: print_warning('{0} already followed'.format(bangumi_obj)) else: print_error('{0} not found, please check the name'.format(bangumi))
def update(ret): print_info('marking bangumi status ...') now = int(time.time()) for i in Followed.get_all_followed(): if i['updated_time'] and int(i['updated_time'] + 86400) < now: followed_obj = Followed(bangumi_name=i['bangumi_name']) followed_obj.status = STATUS_FOLLOWED followed_obj.save() print_info('updating bangumi data ...') fetch(save=True, group_by_weekday=False) print_info('updating subscriptions ...') download_queue = [] if ret.action.update.name is None: updated_bangumi_obj = Followed.get_all_followed() else: updated_bangumi_obj = [] for i in ret.action.update.name: f = Followed(bangumi_name=i) f.select_obj() updated_bangumi_obj.append(f) for subscribe in updated_bangumi_obj: print_info('fetching %s ...' % subscribe['bangumi_name']) bangumi_obj = Bangumi(name=subscribe['bangumi_name']) bangumi_obj.select_obj() # filter by subtitle group if not bangumi_obj: print_error( 'The bangumi {0} you subscribed does not exists ..'.format( subscribe['bangumi_name']), exit_=False) continue episode, all_episode_data = get_maximum_episode(bangumi=bangumi_obj) if episode.get('episode') > subscribe['episode']: episode_range = range(subscribe['episode'] + 1, episode.get('episode')) print_success('%s updated, episode: %d' % (subscribe['bangumi_name'], episode['episode'])) _ = Followed(bangumi_name=subscribe['bangumi_name']) _.episode = episode['episode'] _.status = STATUS_UPDATED _.updated_time = int(time.time()) _.save() download_queue.append(episode) for i in episode_range: for epi in all_episode_data: if epi['episode'] == i: download_queue.append(epi) break if ret.action.update and ret.action.update.download: download_prepare(download_queue) print_info('Re-downloading ...') download_prepare( Download.get_all_downloads(status=STATUS_NOT_DOWNLOAD))
def save_data(self, data): b, obj_created = Bangumi.get_or_create(name=data['name'], defaults=data) if not obj_created: b.status = STATUS_UPDATING b.subtitle_group = Bangumi(**data).subtitle_group b.cover = data['cover'] # if not b.cover.startswith(self.cover_url): # b.cover = self.cover_url + data['cover'] b.save()
def filter_(ret): bangumi_obj = Bangumi(name=ret.name) bangumi_obj.select_obj() if not bangumi_obj: print_error('Bangumi {0} does not exist.'.format(bangumi_obj.name)) followed_obj = Followed(bangumi_name=bangumi_obj.name) followed_obj.select_obj() if not followed_obj: print_error( 'Bangumi {0} has not subscribed, try \'bgmi add "{1}"\'.'.format( bangumi_obj.name, bangumi_obj.name)) subtitle = ret.subtitle include = ret.include exclude = ret.exclude regex = ret.regex followed_filter_obj = Filter(bangumi_name=ret.name) followed_filter_obj.select_obj() if not followed_filter_obj: followed_filter_obj.save() if subtitle is not None: subtitle = map(lambda s: s.strip(), subtitle.split(',')) subtitle = map(lambda s: s['id'], Subtitle.get_subtitle_by_name(subtitle)) subtitle_list = [ s.split('.')[0] for s in bangumi_obj.subtitle_group.split(', ') if '.' in s ] subtitle_list.extend(bangumi_obj.subtitle_group.split(', ')) subtitle = filter(lambda s: True if s in subtitle_list else False, subtitle) subtitle = ', '.join(subtitle) followed_filter_obj.subtitle = subtitle if include is not None: followed_filter_obj.include = include if exclude is not None: followed_filter_obj.exclude = exclude if regex is not None: followed_filter_obj.regex = regex followed_filter_obj.save() print_info('Usable subtitle group: {0}'.format(', '.join( map(lambda s: s['name'], Subtitle.get_subtitle(bangumi_obj.subtitle_group.split(', '))) )) if bangumi_obj.subtitle_group else 'None') print_filter(followed_filter_obj)
def followed_bangumi(): weekly_list_followed = Bangumi.get_updating_bangumi(status=STATUS_FOLLOWED) weekly_list_updated = Bangumi.get_updating_bangumi(status=STATUS_UPDATED) weekly_list = defaultdict(list) for k, v in chain(weekly_list_followed.items(), weekly_list_updated.items()): weekly_list[k].extend(v) for bangumi_list in weekly_list.values(): for bangumi in bangumi_list: bangumi['subtitle_group'] = [{'name': x['name'], 'id': x['id']} for x in Subtitle.get_subtitle_by_id(bangumi['subtitle_group'].split(', '))] return weekly_list
def get(self): is_json = self.get_argument('json', False) is_old = self.get_argument('old', False) if not os.path.exists(DB_PATH): self.write('BGmi db file not found.') self.finish() return data = Followed.get_all_followed(STATUS_NORMAL, STATUS_UPDATING, order='followed.updated_time', desc=True) followed = map(lambda b: b['bangumi_name'], data) data = Followed.get_all_followed(STATUS_NORMAL, STATUS_UPDATING if not is_old else STATUS_END, order='followed.updated_time', desc=True) calendar = Bangumi.get_all_bangumi() def shift(seq, n): n %= len(seq) return seq[n:] + seq[:n] weekday_order = shift(WEEK, datetime.datetime.today().weekday()) cal_ordered = OrderedDict() for week in weekday_order: cal_ordered[week] = calendar[week.lower()] if is_json: self.write(json.dumps(cal_ordered)) self.finish() else: self.render('templates/bangumi.html', data=data, cal=cal_ordered, followed=list(followed), version=__version__)
def add(name, episode=None): """ ret.name :str """ # action add # add bangumi by a list of bangumi name # result = {} if not Bangumi.get_updating_bangumi(): website.fetch(save=True, group_by_weekday=False) try: bangumi_obj = Bangumi.get(name=name) except Bangumi.DoesNotExist: return { 'status': 'error', 'message': '{0} not found, please check the name'.format(name) } followed_obj, this_obj_created = Followed.get_or_create( bangumi_name=bangumi_obj.name, defaults={'status': STATUS_FOLLOWED}) if not this_obj_created: if followed_obj.status == STATUS_FOLLOWED: return { 'status': 'warning', 'message': '{0} already followed'.format(bangumi_obj.name) } else: followed_obj.status = STATUS_FOLLOWED followed_obj.save() Filter.get_or_create(bangumi_name=name) bangumi_data, _ = website.get_maximum_episode(bangumi_obj, subtitle=False, max_page=1) followed_obj.episode = bangumi_data[ 'episode'] if episode is None else episode followed_obj.save() result = { 'status': 'success', 'message': '{0} has been followed'.format(bangumi_obj.name) } return result
def add(name, episode=None): """ ret.name :str """ # action add # add bangumi by a list of bangumi name # result = {} if not Bangumi.get_all_bangumi(): website.fetch(save=True, group_by_weekday=False) bangumi_obj = Bangumi(name=name) data = bangumi_obj.select(one=True, fields=['id', 'name', 'keyword']) if data: followed_obj = Followed(bangumi_name=data['name'], status=STATUS_FOLLOWED) followed_obj.select_obj() if not followed_obj or followed_obj.status == STATUS_NORMAL: if not followed_obj: bangumi_data, _ = website.get_maximum_episode(bangumi_obj, subtitle=False, max_page=1) followed_obj.episode = bangumi_data[ 'episode'] if episode is None else episode followed_obj.save() else: followed_obj.status = STATUS_FOLLOWED followed_obj.save() result = { 'status': 'success', 'message': '{0} has been followed'.format(bangumi_obj) } else: result = { 'status': 'warning', 'message': '{0} already followed'.format(bangumi_obj) } else: result = { 'status': 'error', 'message': '{0} not found, please check the name'.format(name) } return result
def filter_(ret): bangumi_obj = Bangumi(name=ret.action.filter.name) bangumi_obj.select_obj() if not bangumi_obj: print_error('Bangumi {0} does not exist.'.format(bangumi_obj.name)) followed_obj = Followed(bangumi_name=bangumi_obj.name) followed_obj.select_obj() if not followed_obj: print_error( 'Bangumi {0} has not subscribed, try \'bgmi add "{1}"\'.'.format( bangumi_obj.name, bangumi_obj.name)) subtitle = ret.action.filter.subtitle_group if subtitle: if not ret.action.filter.remove and not ret.action.filter.remove_all: if not followed_obj.subtitle_group: followed_obj.subtitle_group = subtitle else: group = followed_obj.subtitle_group.split(',') for i in subtitle.split(','): if i not in group: group.append(i) followed_obj.subtitle_group = ','.join(group) elif ret.action.filter.remove: if followed_obj.subtitle_group: group = followed_obj.subtitle_group.split(',') new_group = [] while group: _ = group.pop() if _ not in subtitle: new_group.append(_) followed_obj.subtitle_group = ','.join(new_group) if ret.action.filter.remove_all: followed_obj.subtitle_group = '' followed_obj.save() print_info('Usable subtitle group: {0}'.format(bangumi_obj.subtitle_group)) print_info('Added subtitle group: {0}'.format(followed_obj.subtitle_group))
def fetch_(ret): bangumi_obj = Bangumi(name=ret.name) bangumi_obj.select_obj() followed_obj = Followed(bangumi_name=bangumi_obj.name) followed_obj.select_obj() followed_filter_obj = Filter(bangumi_name=ret.name) followed_filter_obj.select_obj() print_filter(followed_filter_obj) if bangumi_obj: print_info('Fetch bangumi {0} ...'.format(bangumi_obj.name)) _, data = website.get_maximum_episode( bangumi_obj, ignore_old_row=False if ret.not_ignore else True) if not data: print_warning('Nothing.') for i in data: print_success(i['title']) else: print_error('Bangumi {0} not exist'.format(ret.name))
def bangumi_calendar(self, force_update=False, save=True, cover=False): if force_update and not test_connection(): force_update = False print_warning('network is unreachable') if force_update: print_info('fetching bangumi info ...') Bangumi.delete_all() weekly_list = self.fetch(save=save) else: weekly_list = Bangumi.get_all_bangumi() if not weekly_list: print_warning('warning: no bangumi schedule, fetching ...') weekly_list = self.fetch(save=save) runner = ScriptRunner() patch_list = runner.get_models_dict() for i in patch_list: weekly_list[i['update_time'].lower()].append(i) if cover: # download cover to local cover_to_be_download = [] for daily_bangumi in weekly_list.values(): for bangumi in daily_bangumi: followed_obj = Followed(bangumi_name=bangumi['name']) if followed_obj: bangumi['status'] = followed_obj.status _, file_path, _ = self.convert_cover_to_path( bangumi['cover']) if not glob.glob(file_path): cover_to_be_download.append(bangumi['cover']) if cover_to_be_download: print_info('updating cover') for cover in tqdm.tqdm(cover_to_be_download): self.download_cover(cover) return weekly_list
def test_select_and_save(self): b2 = Bangumi(name='test_select_and_save', update_time='Sun') d = b2.select() self.assertEqual(d, []) b2.save() ret = b2.select(one=True) self.assertIsInstance(ret, dict)
def complete(ret): # coding=utf-8 """eval "$(bgmi complete)" to complete bgmi in bash""" updating_bangumi_names = [ x['name'] for x in Bangumi.get_updating_bangumi(order=False) ] all_config = [x for x in bgmi.config.__all__ if not x == 'DATA_SOURCE'] actions_and_opts = {} helper = {} for action in actions_and_arguments: actions_and_opts[action['action']] = [ x for x in action.get('arguments', []) if x['dest'].startswith('-') ] helper[action['action']] = action.get('help', '') if 'bash' in os.getenv('SHELL').lower(): # bash template_file_path = os.path.join(os.path.dirname(__file__), 'others', '_bgmi_completion_bash.sh') elif 'zsh' in os.getenv('SHELL').lower(): # zsh template_file_path = os.path.join(os.path.dirname(__file__), 'others', '_bgmi_completion_zsh.sh') else: import sys print('unsupported shell {}'.format(os.getenv('SHELL').lower()), file=sys.stderr) return with open(template_file_path, 'r') as template_file: shell_template = template.Template(template_file.read(), autoescape='') template_with_content = shell_template.generate( actions=ACTIONS, bangumi=updating_bangumi_names, config=all_config, actions_and_opts=actions_and_opts, source=[x['id'] for x in SUPPORT_WEBSITE], helper=helper) # type: bytes if os.environ.get('DEBUG', False): # pragma: no cover with open('./_bgmi', 'wb+') as template_file: template_file.write(template_with_content) import sys template_with_content = template_with_content.decode() # type:str # print(template_with_content.rstrip()) # sys.stdout.write(template_with_content) print(template_with_content.replace('\r', '\n'), file=sys.stdout, flush=True)
def test_add_and_remove_followed(self): f = Followed(bangumi_name='test_add_and_remove_followed', status=STATUS_FOLLOWED, episode=6) f.save() b = Bangumi(name='test_add_and_remove_followed') b.save() bangumi_data = b.select( one=True, join='LEFT JOIN %s ON %s.bangumi_name=%s.name' % (Followed.table, Followed.table, Bangumi.table)) self.assertEqual(bangumi_data['status'], STATUS_FOLLOWED) f.delete() bangumi_data = b.select( one=True, join='LEFT JOIN %s ON %s.bangumi_name=%s.name' % (Followed.table, Followed.table, Bangumi.table)) self.assertEqual(bangumi_data['status'], STATUS_NORMAL)
def fetch_(ret): try: bangumi_obj = Bangumi.get(name=ret.name) except Bangumi.DoesNotExist: print_error('Bangumi {0} not exist'.format(ret.name)) return try: Followed.get(bangumi_name=bangumi_obj.name) except Bangumi.DoesNotExist: print_error('Bangumi {0} is not followed'.format(ret.name)) return followed_filter_obj = Filter.get(bangumi_name=ret.name) print_filter(followed_filter_obj) print_info('Fetch bangumi {0} ...'.format(bangumi_obj.name)) _, data = website.get_maximum_episode( bangumi_obj, ignore_old_row=False if ret.not_ignore else True) if not data: print_warning('Nothing.') for i in data: print_success(i['title'])
def filter_(name, subtitle=None, include=None, exclude=None, regex=None): result = {'status': 'success', 'message': ''} try: bangumi_obj = Bangumi.get(name=name) except Bangumi.DoesNotExist: result['status'] = 'error' result['message'] = 'Bangumi {0} does not exist.'.format(name) return result try: Followed.get(bangumi_name=bangumi_obj.name) except Followed.DoesNotExist as exc: result['status'] = 'error' result['message'] = 'Bangumi {name} has not subscribed, try \'bgmi add "{name}"\'.' \ .format(name=bangumi_obj.name) return result followed_filter_obj, is_this_obj_created = Filter.get_or_create( bangumi_name=name) if is_this_obj_created: followed_filter_obj.save() if subtitle is not None: subtitle = [s.strip() for s in subtitle.split(',')] subtitle = [s['id'] for s in Subtitle.get_subtitle_by_name(subtitle)] subtitle_list = [ s.split('.')[0] for s in bangumi_obj.subtitle_group.split(', ') if '.' in s ] subtitle_list.extend(bangumi_obj.subtitle_group.split(', ')) subtitle = filter(lambda s: s in subtitle_list, subtitle) subtitle = ', '.join(subtitle) followed_filter_obj.subtitle = subtitle if include is not None: followed_filter_obj.include = include if exclude is not None: followed_filter_obj.exclude = exclude if regex is not None: followed_filter_obj.regex = regex followed_filter_obj.save() subtitle_list = list( map( lambda s: s['name'], Subtitle.get_subtitle_by_id( bangumi_obj.subtitle_group.split(', ')))) result['data'] = { 'name': name, 'subtitle_group': subtitle_list, 'followed': list( map( lambda s: s['name'], Subtitle. get_subtitle_by_id(followed_filter_obj.subtitle.split(', ') )) if followed_filter_obj.subtitle else []), 'include': followed_filter_obj.include, 'exclude': followed_filter_obj.exclude, 'regex': followed_filter_obj.regex, } return result
def test_delete(self): b1 = Bangumi(name='test_delete', update_time='Sun') b1.save() self.assertEqual(b1.select(one=True)['name'], 'test_delete') b1.delete() self.assertEqual(b1.select(one=True), None)
def filter_(name, subtitle=None, include=None, exclude=None, regex=None): result = {'status': 'success', 'message': ''} bangumi_obj = Bangumi(name=name) bangumi_obj.select_obj() if not bangumi_obj: result['status'] = 'error' result['message'] = 'Bangumi {0} does not exist.'.format( bangumi_obj.name) return result followed_obj = Followed(bangumi_name=bangumi_obj.name) followed_obj.select_obj() if not followed_obj: result['status'] = 'error' result['message'] = 'Bangumi {name} has not subscribed, try \'bgmi add "{name}"\'.' \ .format(name=bangumi_obj.name) return result followed_filter_obj = Filter(bangumi_name=name) followed_filter_obj.select_obj() if not followed_filter_obj: followed_filter_obj.save() if subtitle is not None: subtitle = map(lambda s: s.strip(), subtitle.split(',')) subtitle = map(lambda s: s['id'], Subtitle.get_subtitle_by_name(subtitle)) subtitle_list = [ s.split('.')[0] for s in bangumi_obj.subtitle_group.split(', ') if '.' in s ] subtitle_list.extend(bangumi_obj.subtitle_group.split(', ')) subtitle = filter(lambda s: s in subtitle_list, subtitle) subtitle = ', '.join(subtitle) followed_filter_obj.subtitle = subtitle if include is not None: followed_filter_obj.include = include if exclude is not None: followed_filter_obj.exclude = exclude if regex is not None: followed_filter_obj.regex = regex followed_filter_obj.save() subtitle_list = list( map(lambda s: s['name'], Subtitle.get_subtitle(bangumi_obj.subtitle_group.split(', ')))) print_info('Usable subtitle group: {0}'.format( ', '.join(subtitle_list) if subtitle_list else 'None')) print_filter(followed_filter_obj) result['data'] = { 'name': name, 'subtitle_group': list( map(lambda s: s['name'], Subtitle.get_subtitle( bangumi_obj.subtitle_group.split(', ')))), 'followed': list( map( lambda s: s['name'], Subtitle.get_subtitle(followed_filter_obj.subtitle.split(', ')) ) if followed_filter_obj.subtitle else []), 'include': followed_filter_obj.include, 'exclude': followed_filter_obj.exclude, 'regex': followed_filter_obj.regex, } return result
def test_update(self): b1 = Bangumi(name='test_update', update_time='Sun') b1.save() b1.update_time = 'Mon' b1.update() ret = b1.select(one=True) self.assertEqual(ret['update_time'], 'Mon') b1.update(data={'name': 'test666', 'update_time': 'Sat'}) ret = b1.select(one=True) self.assertIsInstance(ret, dict)
def test_get_all_bangumi(self): from collections import defaultdict self.assertIsInstance(Bangumi.get_all_bangumi(), defaultdict)
def update(name, download=None, not_ignore=False): result = { 'status': 'info', 'message': '', 'data': { 'updated': [], 'downloaded': [] } } ignore = not bool(not_ignore) print_info('marking bangumi status ...') now = int(time.time()) for i in Followed.get_all_followed(): if i['updated_time'] and int(i['updated_time'] + 86400) < now: followed_obj = Followed.get(bangumi_name=i['bangumi_name']) followed_obj.status = STATUS_FOLLOWED followed_obj.save() for script in ScriptRunner().scripts: obj = script.Model().obj if obj.updated_time and int(obj.updated_time + 86400) < now: obj.status = STATUS_FOLLOWED obj.save() print_info('updating bangumi data ...') website.fetch(save=True, group_by_weekday=False) print_info('updating subscriptions ...') download_queue = [] if download: if not name: print_warning('No specified bangumi, ignore `--download` option') if len(name) > 1: print_warning( 'Multiple specified bangumi, ignore `--download` option') if not name: updated_bangumi_obj = Followed.get_all_followed() else: updated_bangumi_obj = [] for i in name: try: f = Followed.get(bangumi_name=i).__dict__['_data'] updated_bangumi_obj.append(f) except DoesNotExist: pass runner = ScriptRunner() script_download_queue = runner.run() for subscribe in updated_bangumi_obj: print_info('fetching %s ...' % subscribe['bangumi_name']) try: bangumi_obj = Bangumi.get(name=subscribe['bangumi_name']) except Bangumi.DoesNotExist: print_error('Bangumi<{0}> does not exists.'.format( subscribe['bangumi_name']), exit_=False) continue try: followed_obj = Followed.get(bangumi_name=subscribe['bangumi_name']) except Followed.DoesNotExist: print_error('Bangumi<{0}> is not followed.'.format( subscribe['bangumi_name']), exit_=False) continue episode, all_episode_data = website.get_maximum_episode( bangumi=bangumi_obj, ignore_old_row=ignore, max_page=1) if (episode.get('episode') > subscribe['episode']) or (len(name) == 1 and download): if len(name) == 1 and download: episode_range = download else: episode_range = range(subscribe['episode'] + 1, episode.get('episode', 0) + 1) print_success('%s updated, episode: %d' % (subscribe['bangumi_name'], episode['episode'])) followed_obj.episode = episode['episode'] followed_obj.status = STATUS_UPDATED followed_obj.updated_time = int(time.time()) followed_obj.save() result['data']['updated'].append({ 'bangumi': subscribe['bangumi_name'], 'episode': episode['episode'] }) for i in episode_range: for epi in all_episode_data: if epi['episode'] == i: download_queue.append(epi) break if download is not None: result['data']['downloaded'] = download_queue download_prepare(download_queue) download_prepare(script_download_queue) print_info('Re-downloading ...') download_prepare( Download.get_all_downloads(status=STATUS_NOT_DOWNLOAD)) return result
def update(ret): ignore = False if ret.not_ignore else True print_info('marking bangumi status ...') now = int(time.time()) for i in Followed.get_all_followed(): if i['updated_time'] and int(i['updated_time'] + 86400) < now: followed_obj = Followed(bangumi_name=i['bangumi_name']) followed_obj.status = STATUS_FOLLOWED followed_obj.save() print_info('updating bangumi data ...') fetch(save=True, group_by_weekday=False) print_info('updating subscriptions ...') download_queue = [] if ret.download: if not ret.name: print_warning('No specified bangumi, ignore `--download` option') if len(ret.name) > 1: print_warning( 'Multiple specified bangumi, ignore `--download` option') if not ret.name: updated_bangumi_obj = Followed.get_all_followed() else: updated_bangumi_obj = [] for i in ret.name: f = Followed(bangumi_name=i) f.select_obj() updated_bangumi_obj.append(f) for subscribe in updated_bangumi_obj: print_info('fetching %s ...' % subscribe['bangumi_name']) bangumi_obj = Bangumi(name=subscribe['bangumi_name']) bangumi_obj.select_obj() followed_obj = Followed(bangumi_name=subscribe['bangumi_name']) followed_obj.select_obj() # filter by subtitle group if not bangumi_obj or not followed_obj: print_error( 'Bangumi<{0}> does not exist or not been followed.'.format( subscribe['bangumi_name']), exit_=False) continue episode, all_episode_data = get_maximum_episode(bangumi=bangumi_obj, ignore_old_row=ignore, max_page=1) if (episode.get('episode') > subscribe['episode']) or (len( ret.name) == 1 and ret.download): if len(ret.name) == 1 and ret.download: episode_range = ret.download else: episode_range = range(subscribe['episode'] + 1, episode.get('episode', 0) + 1) print_success('%s updated, episode: %d' % (subscribe['bangumi_name'], episode['episode'])) followed_obj.episode = episode['episode'] followed_obj.status = STATUS_UPDATED followed_obj.updated_time = int(time.time()) followed_obj.save() for i in episode_range: for epi in all_episode_data: if epi['episode'] == i: download_queue.append(epi) break if ret.download is not None: download_prepare(download_queue) print_info('Re-downloading ...') download_prepare( Download.get_all_downloads(status=STATUS_NOT_DOWNLOAD))
def save_data(data): b = Bangumi(**data) b.save()
def get_maximum_episode(bangumi, subtitle=True): subtitle_group = bangumi.subtitle_group if subtitle: followed_obj = Followed(bangumi_name=bangumi.name) followed_obj.select_obj() if followed_obj: subtitle_group = followed_obj.subtitle_group data = [ i for i in fetch_episode( keyword=bangumi.keyword, name=bangumi.name, subtitle_group=subtitle_group if subtitle else None) if i['episode'] is not None ] if data: bangumi = max(data, key=lambda i: i['episode']) return bangumi, data else: return {'episode': 0}, [] if __name__ == '__main__': # fetch(save=True, group_by_weekday=False) b = Bangumi(name='槍彈辯駁3未來篇') b.select_obj() a, _ = get_maximum_episode(b) print(a['episode'])
def bangumi_calendar(force_update=False, today=False, followed=False, save=True): env_columns = get_terminal_col() if env_columns < 36: print_error('terminal window is too small.') row = int(env_columns / 36 if env_columns / 36 <= 3 else 3) if force_update and not test_connection(): force_update = False print_warning('network is unreachable') if force_update: print_info('fetching bangumi info ...') Bangumi.delete_all() weekly_list = fetch(save=save, status=True) else: if followed: weekly_list_followed = Bangumi.get_all_bangumi( status=STATUS_FOLLOWED) weekly_list_updated = Bangumi.get_all_bangumi( status=STATUS_UPDATED) weekly_list = defaultdict(list) for k, v in chain(weekly_list_followed.items(), weekly_list_updated.items()): weekly_list[k].extend(v) else: weekly_list = Bangumi.get_all_bangumi() if not weekly_list: if not followed: print_warning('warning: no bangumi schedule, fetching ...') weekly_list = fetch(save=save) else: print_warning('you have not subscribed any bangumi') def shift(seq, n): n = n % len(seq) return seq[n:] + seq[:n] def print_line(): num = 33 # print('+', '-' * num, '+', '-' * num, '+', '-' * num, '+') split = '-' * num + ' ' print(split * row) if today: weekday_order = (Bangumi.week[datetime.datetime.today().weekday()], ) else: weekday_order = shift(Bangumi.week, datetime.datetime.today().weekday()) spacial_append_chars = ['Ⅱ', 'Ⅲ', '♪', 'Δ', '×', '☆'] spacial_remove_chars = [] for index, weekday in enumerate(weekday_order): if weekly_list[weekday.lower()]: print( '\033[1;32m%s. \033[0m' % (weekday if not today else 'Bangumi Schedule for Today (%s)' % weekday), end='') if not followed: print() print_line() for i, bangumi in enumerate(weekly_list[weekday.lower()]): if isinstance(bangumi['name'], _unicode): # bangumi['name'] = bangumi['name'] pass if bangumi['status'] in (STATUS_UPDATED, STATUS_FOLLOWED ) and 'episode' in bangumi: bangumi['name'] = '%s(%d)' % (bangumi['name'], bangumi['episode']) half = len( re.findall('[%s]' % string.printable, bangumi['name'])) full = (len(bangumi['name']) - half) space_count = 34 - (full * 2 + half) for s in spacial_append_chars: if s in bangumi['name']: space_count += 1 for s in spacial_remove_chars: if s in bangumi['name']: space_count -= 1 if bangumi['status'] == STATUS_FOLLOWED: bangumi['name'] = '\033[1;33m%s\033[0m' % bangumi['name'] if bangumi['status'] == STATUS_UPDATED: bangumi['name'] = '\033[1;32m%s\033[0m' % bangumi['name'] if followed: if i > 0: print(' ' * 5, end='') print(bangumi['name'], bangumi['subtitle_group']) else: print(' ' + bangumi['name'], ' ' * space_count, end='') if (i + 1) % row == 0 or i + 1 == len( weekly_list[weekday.lower()]): print() if not followed: print()
def main(): c = CommandParser() action = c.add_arg_group('action') sub_parser_add = action.add_sub_parser(ACTION_ADD, help='Subscribe bangumi.') sub_parser_add.add_argument('name', arg_type='+', required=True, help='Bangumi name to subscribe.') sub_parser_filter = action.add_sub_parser(ACTION_FILTER, help='Set bangumi fetch filter.') sub_parser_filter.add_argument('name', required=True, help='Bangumi name to set the filter.') sub_parser_filter.add_argument('subtitle_group', help='Subtitle group name.') sub_parser_filter.add_argument('--remove', help='Remove subtitle group filter.') sub_parser_filter.add_argument( '--remove-all', help='Remove all the subtitle group filter.', mutex='--remove') sub_parser_del = action.add_sub_parser(ACTION_DELETE, help='Unsubscribe bangumi.') sub_parser_del.add_argument('--name', arg_type='+', mutex='--clear-all', help='Bangumi name to unsubscribe.') sub_parser_del.add_argument('--clear-all', help='Clear all the subscriptions.') sub_parser_del.add_argument('--batch', help='No confirmation.') sub_parser_fetch = action.add_sub_parser(ACTION_FETCH, help='Fetch a specific bangumi.') sub_parser_fetch.add_argument('name', help='Bangumi name to fetch.', required=True) sub_parser_update = action.add_sub_parser( ACTION_UPDATE, help='Update bangumi calendar and ' 'subscribed bangumi episode.') sub_parser_update.add_argument('--download', help='Download the bangumi when updated.') sub_parser_cal = action.add_sub_parser(ACTION_CAL, help='Print bangumi calendar.') sub_parser_cal.add_argument('filter', default='today', choice=FILTER_CHOICES, help='Calendar form filter %s.' % ', '.join(FILTER_CHOICES)) sub_parser_cal.add_argument('--today', help='Show bangumi calendar for today.') sub_parser_cal.add_argument( '--force-update', help='Get the newest bangumi calendar from dmhy.') sub_parser_cal.add_argument( '--no-save', help='Do not save the bangumi data when force update.') sub_parser_config = action.add_sub_parser(ACTION_CONFIG, help='Config BGmi.') sub_parser_config.add_argument('name', help='Config name') sub_parser_config.add_argument('value', help='Config value') sub_parser_followed = action.add_sub_parser( ACTION_FOLLOWED, help='Followed bangumi manager.') sub_parser_followed.add_sub_parser('list', help='List followed bangumi.') followed_mark = sub_parser_followed.add_sub_parser( 'mark', help='Mark specific bangumi\'s episode.') followed_mark.add_argument('name', help='Bangumi name.', required=True) followed_mark.add_argument('episode', help='Bangumi episode.') sub_parser_download = action.add_sub_parser(ACTION_DOWNLOAD, help='Download manager.') download_list = sub_parser_download.add_sub_parser( 'list', help='List download queue.') download_list.add_argument('status', help='Download status: 0, 1, 2', choice=(0, 1, 2, None)) download_mark = sub_parser_download.add_sub_parser( 'mark', help='Mark download status with a specific id.') download_mark.add_argument('id', help='Download id') download_mark.add_argument('status', help='Status will be marked', choice=(0, 1, 2)) positional = c.add_arg_group('positional') positional.add_argument('install', help='Install xunlei-lixian for BGmi.') c.add_argument('-h', help='Print help text.') c.add_argument('--version', help='Show the version of BGmi.') c.add_argument('--debug', help='Enable DEBUG mode.') ret = c.parse_command() if ret.version: print_version() raise SystemExit if ret.positional.install == 'install': import bgmi.setup bgmi.setup.install() raise SystemExit elif ret.action == ACTION_ADD: add(ret) elif ret.action == ACTION_FILTER: filter_(ret) elif ret.action == ACTION_FETCH: bangumi_obj = Bangumi(name=ret.action.fetch.name) bangumi_obj.select_obj() followed_obj = Followed(bangumi_name=bangumi_obj.name) followed_obj.select_obj() if bangumi_obj: print_info('Fetch bangumi {0} ...'.format(bangumi_obj.name)) _, data = get_maximum_episode(bangumi_obj) for i in data: print_success(i['title']) else: print_error('Bangumi {0} not exist'.format(ret.action.fetch.name)) elif ret.action == ACTION_DELETE: delete(ret) elif ret.action == ACTION_UPDATE: update(ret) elif ret.action == ACTION_CAL: cal(ret) elif ret.action == ACTION_CONFIG: write_config(ret.action.config.name, ret.action.config.value) elif ret.action == ACTION_FOLLOWED: if not ret.action.followed == 'mark' and not ret.action.followed.list: c.print_help() else: followed(ret) elif ret.action == ACTION_DOWNLOAD: if ret.action.download in DOWNLOAD_ACTION: download_manager(ret) else: c.print_help() else: c.print_help()
def setUpClass(): setup() Bangumi.recreate_source_relatively_table()