def parse_bangumi_moe(self, tag_ids): result = {} r = bangumi_moe_request.post('https://bangumi.moe/api/torrent/search', tag_ids) if r.status_code > 399: r.raise_for_status() try: search_result = r.json() except Exception as error: logger.warn(error) result['message'] = 'fail to query bangumi' return json_resp(result, 500) for torrent in search_result['torrents']: torrent['eps_no_list'] = [] for content in torrent['content']: file_name = content[0] if not file_name.endswith(('.mp4', )): continue eps_no = self.parse_episode_number(file_name) torrent['eps_no_list'].append(eps_no) return json_resp(search_result)
def get_universal_meta(self): if self.universal is None: return json_resp({'data': [], 'status': 0}) else: return json_resp({ 'data': list(self.universal.keys()), 'status': 0 })
def search_bangumi(self, type, term, offset, count): ''' search bangumi from bangumi.tv, properly handling cookies is required for the bypass anti-bot mechanism :param term: a urlencoded word of the search term. :return: a json object ''' result = {"data": [], "total": 0} api_url = 'http://api.bgm.tv/search/subject/{0}?responseGroup=large&max_result={1}&start={2}&type={3}'.format( term.encode('utf-8'), count, offset, type) r = bangumi_request.get(api_url) if r.status_code > 399: r.raise_for_status() try: bgm_content = r.json() except Exception as error: logger.warn(error) result['message'] = 'fail to query bangumi' return json_resp(result, 500) if 'code' in bgm_content and bgm_content['code'] == 404: return json_resp(result, 200) bgm_list = bgm_content['list'] total_count = bgm_content['results'] if len(bgm_list) == 0: return json_resp(result) bgm_id_list = [bgm['id'] for bgm in bgm_list] bangumi_list = self.get_bangumi_from_bgm_id_list(bgm_id_list) for bgm in bgm_list: bgm['bgm_id'] = bgm.get('id') bgm['id'] = None # if bgm_id has found in database, give the database id to bgm.id # that's we know that this bangumi exists in our database for bangumi in bangumi_list: if bgm['bgm_id'] == bangumi.bgm_id: bgm['id'] = bangumi.id break bgm_images = bgm.get('images') if bgm_images: bgm['image'] = bgm_images.get('large') # remove useless keys bgm.pop('images', None) bgm.pop('collection', None) bgm.pop('url', None) bgm.pop('type', None) result['data'] = bgm_list result['total'] = total_count return json_resp(result)
def search_bangumi(self, type, term, offset, count): """ search bangumi from bangumi.tv, properly handling cookies is required for the bypass anti-bot mechanism :param term: a urlencoded word of the search term. :return: a json object """ result = {"data": [], "total": 0} api_url = 'http://api.bgm.tv/search/subject/{0}?responseGroup=large&max_result={1}&start={2}&type={3}'.format(term.encode('utf-8'), count, offset, type) r = bangumi_request.get(api_url) if r.status_code > 399: r.raise_for_status() try: bgm_content = r.json() except Exception as error: logger.warn(error) result['message'] = 'fail to query bangumi' return json_resp(result, 500) if 'code' in bgm_content and bgm_content['code'] == 404: return json_resp(result, 200) bgm_list = bgm_content['list'] total_count = bgm_content['results'] if len(bgm_list) == 0: return json_resp(result) bgm_id_list = [bgm['id'] for bgm in bgm_list] bangumi_list = self.get_bangumi_from_bgm_id_list(bgm_id_list) for bgm in bgm_list: bgm['bgm_id'] = bgm.get('id') bgm['id'] = None # if bgm_id has found in database, give the database id to bgm.id # that's we know that this bangumi exists in our database for bangumi in bangumi_list: if bgm['bgm_id'] == bangumi.bgm_id: bgm['id'] = bangumi.id break bgm_images = bgm.get('images') if bgm_images: bgm['image'] = bgm_images.get('large') # remove useless keys bgm.pop('images', None) bgm.pop('collection', None) bgm.pop('url', None) bgm.pop('type', None) result['data'] = bgm_list result['total'] = total_count return json_resp(result)
def my_favorites(self, user_id, status=None): session = SessionManager.Session() try: q = session.query(Favorites, Bangumi).\ join(Bangumi).\ options(joinedload(Bangumi.cover_image)).\ filter(Bangumi.delete_mark == None).\ filter(Favorites.user_id == user_id) if status is None: result = q.all() else: result = q.filter(Favorites.status == status).all() bangumi_id_list = [bangumi.id for favorite, bangumi in result] # print 'bangumi_id_list length: %d' % len(bangumi_id_list) if len(bangumi_id_list) == 0: return json_resp({'data': [], 'status': 0}) # subquery for watch_progress watch_progress = session.query(WatchProgress.episode_id).\ filter(WatchProgress.user_id == user_id).\ filter(WatchProgress.bangumi_id.in_(bangumi_id_list)) episode_count = session.query(func.count(Episode.id), Episode.bangumi_id).\ filter(Episode.status == Episode.STATUS_DOWNLOADED).\ filter(Episode.bangumi_id.in_(bangumi_id_list)).\ filter(~Episode.id.in_(watch_progress)).\ group_by(Episode.bangumi_id).\ all() logger.debug(episode_count) bangumi_dict_list = [] for fav, bgm in result: bangumi_dict = row2dict(bgm) bangumi_dict['favorite_status'] = fav.status bangumi_dict['cover'] = utils.generate_cover_link(bangumi) utils.process_bangumi_dict(bgm, bangumi_dict) for unwatched_count, bangumi_id in episode_count: if bangumi_id == bgm.id: bangumi_dict['unwatched_count'] = unwatched_count break bangumi_dict_list.append(bangumi_dict) return json_resp({'data': bangumi_dict_list, 'status': 0}) finally: SessionManager.Session.remove()
def register(): """ register a new user using invite code, note that a newly registered user is not administrator, you need to use an admin user to promote it :return: response """ content = request.get_data(True, as_text=True) register_data = json.loads(content) if ('name' in register_data) and ('password' in register_data) and ( 'password_repeat' in register_data) and ( 'invite_code' in register_data) and ('email' in register_data): name = register_data['name'] password = register_data['password'] password_repeat = register_data['password_repeat'] email = register_data['email'] invite_code = register_data['invite_code'] if password != password_repeat: raise ClientError(ClientError.PASSWORD_MISMATCH) if UserCredential.register_user(name=name, password=password, email=email, invite_code=invite_code): # login automatically credential = UserCredential.login_user(name, password) login_user(credential, remember=False) # send email credential.send_confirm_email() return json_resp({'message': 'ok'}, 201) else: raise ClientError(ClientError.INVALID_REQUEST)
def request_reset_pass(): data = json.loads(request.get_data(True, as_text=True)) if 'email' in data: UserCredential.send_pass_reset_email(data['email']) return json_resp({'message': 'ok'}) else: raise ClientError(ClientError.INVALID_REQUEST)
def register_web_hook(self, web_hook_dict, add_by_uid): """ register an web hook and send an initial keep alive event :param web_hook_dict: :param add_by_uid: :return: """ session = SessionManager.Session() try: web_hook = WebHook(name=web_hook_dict.get('name'), description=bleach.clean(web_hook_dict.get('description'), tags=self.ALLOWED_TAGS), url=web_hook_dict.get('url'), shared_secret=web_hook_dict.get('shared_secret'), created_by_uid=add_by_uid, permissions=web_hook_dict.get('permissions')) session.add(web_hook) session.commit() web_hook_id = str(web_hook.id) # send event via rpc rpc_request.send('initialize_web_hook', { 'web_hook_id': web_hook_id, 'web_hook_url': web_hook.url, 'shared_secret': web_hook.shared_secret }) return json_resp({'data': web_hook_id}) finally: SessionManager.Session.remove()
def add_web_hook_token(self, token_id, web_hook_id, user): session = SessionManager.Session() try: web_hook = session.query(WebHook).filter(WebHook.id == web_hook_id).one() web_hook_token = WebHookToken(web_hook_id=web_hook_id, user_id=user.id, token_id=token_id) session.add(web_hook_token) session.commit() method_args = { 'web_hook_id': web_hook_id, 'token_id': token_id, 'user_id': user.id, 'email': None } if web_hook.has_permission(WebHook.PERMISSION_EMAIL) and user.email is not None and user.email_confirmed: method_args['email'] = user.email rpc_request.send('token_add', method_args) return json_resp({'message': 'ok'}) except NoResultFound: raise ClientError('web hook not existed') finally: SessionManager.Session.remove()
def update_web_hook(self, web_hook_id, web_hook_dict): """ update a web hook :param web_hook_dict: :param web_hook_id: :return: """ session = SessionManager.Session() try: web_hook = session.query(WebHook).\ filter(WebHook.id == web_hook_id).\ one() web_hook.name = web_hook_dict.get('name') web_hook.description = bleach.clean(web_hook_dict.get('description'), tags=self.ALLOWED_TAGS) web_hook.url = web_hook_dict.get('url') web_hook.status = web_hook_dict.get('status') web_hook.consecutive_failure_count = web_hook_dict.get('consecutive_failure_count') web_hook.permissions = web_hook_dict.get('permissions') if 'shared_secret' in web_hook_dict and web_hook_dict.get('shared_secret') is not None: web_hook.shared_secret = web_hook_dict.get('shared_secret') session.commit() return json_resp({'message': 'ok'}) finally: SessionManager.Session.remove()
def get_bangumi(self, id): try: session = SessionManager.Session() bangumi = session.query(Bangumi).options(joinedload(Bangumi.episodes)).filter(Bangumi.id == id).one() episodes = [] for episode in bangumi.episodes: eps = row2dict(episode) eps['thumbnail'] = utils.generate_thumbnail_link(episode, bangumi) episodes.append(eps) bangumi_dict = row2dict(bangumi) bangumi_dict['episodes'] = episodes bangumi_dict['cover'] = utils.generate_cover_link(bangumi) return json_resp({'data': bangumi_dict}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) except Exception as exception: raise exception finally: SessionManager.Session.remove()
def update_bangumi(self, bangumi_id, bangumi_dict): try: session = SessionManager.Session() bangumi = session.query(Bangumi).filter(Bangumi.id == bangumi_id).one() bangumi.name = bangumi_dict['name'] bangumi.name_cn = bangumi_dict['name_cn'] bangumi.summary = bangumi_dict['summary'] bangumi.eps = bangumi_dict['eps'] bangumi.eps_regex = bangumi_dict['eps_regex'] bangumi.image = bangumi_dict['image'] bangumi.air_date = datetime.strptime(bangumi_dict['air_date'], '%Y-%m-%d') bangumi.air_weekday = bangumi_dict['air_weekday'] bangumi.rss = bangumi_dict['rss'] bangumi.update_time = datetime.now() session.commit() return json_resp({'msg': 'ok'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND) except Exception as exception: raise exception finally: SessionManager.Session.remove()
def get_all_announce(self, position, offset, count, content): session = SessionManager.Session() try: if content is not None: announce_list = session.query(Announce).\ filter(Announce.content == content).\ all() else: announce_list = session.query(Announce).\ filter(Announce.position == position).\ offset(offset).\ limit(count).\ all() total = session.query(func.count(Announce.id)). \ scalar() announce_dict_list = [] for announce in announce_list: announce_dict = row2dict(announce) announce_dict_list.append(announce_dict) if position == Announce.POSITION_BANGUMI: self.__add_bangumi_info(session, announce_dict_list) return json_resp({'data': announce_dict_list, 'total': total}) finally: SessionManager.Session.remove()
def add_web_hook_token(self, token_id, web_hook_id, user): session = SessionManager.Session() try: web_hook = session.query(WebHook).filter( WebHook.id == web_hook_id).one() web_hook_token = WebHookToken(web_hook_id=web_hook_id, user_id=user.id, token_id=token_id) session.add(web_hook_token) session.commit() method_args = { 'web_hook_id': web_hook_id, 'token_id': token_id, 'user_id': user.id, 'email': None } if web_hook.has_permission( WebHook.PERMISSION_EMAIL ) and user.email is not None and user.email_confirmed: method_args['email'] = user.email rpc_request.send('token_add', method_args) return json_resp({'message': 'ok'}) except NoResultFound: raise ClientError('web hook not existed') finally: SessionManager.Session.remove()
def on_air_bangumi(self): session = SessionManager.Session() current_day = datetime.today() start_time = datetime(current_day.year, current_day.month, 1) if current_day.month == 12: next_year = current_day.year + 1 next_month = 1 else: next_year = current_day.year next_month = current_day.month + 1 end_time = datetime(next_year, next_month, 1) try: result = session.query(distinct(Episode.bangumi_id), Bangumi).\ join(Bangumi).\ filter(Episode.airdate >= start_time).\ filter(Episode.airdate <= end_time) bangumi_list = [ row2dict(bangumi) for bangumi_id, bangumi in result ] return json_resp({'data': bangumi_list}) except Exception as error: raise error finally: SessionManager.Session.remove()
def update_bangumi(self, bangumi_id, bangumi_dict): try: session = SessionManager.Session() bangumi = session.query(Bangumi).filter( Bangumi.id == bangumi_id).one() bangumi.name = bangumi_dict['name'] bangumi.name_cn = bangumi_dict['name_cn'] bangumi.summary = bangumi_dict['summary'] bangumi.eps = bangumi_dict['eps'] # bangumi.eps_regex = bangumi_dict['eps_regex'] bangumi.image = bangumi_dict['image'] bangumi.air_date = datetime.strptime(bangumi_dict['air_date'], '%Y-%m-%d') bangumi.air_weekday = bangumi_dict['air_weekday'] # bangumi.rss = bangumi_dict['rss'] if 'dmhy' in bangumi_dict: bangumi.dmhy = bangumi_dict['dmhy'] else: bangumi.dmhy = None if 'acg_rip' in bangumi_dict: bangumi.acg_rip = bangumi_dict['acg_rip'] else: bangumi.acg_rip = None bangumi.update_time = datetime.now() session.commit() return json_resp({'msg': 'ok'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND) finally: SessionManager.Session.remove()
def episode_history(self, bangumi_id, episode_id, user_id, last_watch_position, percentage, is_finished): last_watch_time = datetime.now() watch_status = WatchProgress.WATCHED if is_finished else WatchProgress.WATCHING session = SessionManager.Session() try: watch_progress = session.query(WatchProgress).\ filter(WatchProgress.bangumi_id == bangumi_id).\ filter(WatchProgress.episode_id == episode_id).\ filter(WatchProgress.user_id == user_id).\ first() if watch_progress is None: watch_progress = WatchProgress( bangumi_id=bangumi_id, episode_id=episode_id, user_id=user_id, watch_status=watch_status, last_watch_position=last_watch_position, last_watch_time=last_watch_time, percentage=0) session.add(watch_progress) else: watch_progress.watch_status = watch_status watch_progress.last_watch_time = last_watch_time watch_progress.last_watch_position = last_watch_position watch_progress.percentage = percentage session.commit() return json_resp({'message': 'ok', 'status': 0}) finally: SessionManager.Session.remove()
def episode_detail(self, episode_id): session = SessionManager.Session() try: (episode, bangumi) = session.query(Episode, Bangumi).\ join(Bangumi).\ filter(Episode.id == episode_id).one() episode_dict = row2dict(episode) episode_dict['bangumi'] = row2dict(bangumi) episode_dict['thumbnail'] = utils.generate_thumbnail_link( episode, bangumi) if episode.status == Episode.STATUS_DOWNLOADED: episode_dict['videos'] = [] torrent_file_cur = session.query(TorrentFile).filter( TorrentFile.episode_id == episode_id) for torrent_file in torrent_file_cur: episode_dict['videos'].append( utils.generate_video_link(str(bangumi.id), torrent_file.file_path)) return json_resp(episode_dict) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) except Exception as error: raise error finally: SessionManager.Session.remove()
def update_web_hook(self, web_hook_id, web_hook_dict): """ update a web hook :param web_hook_dict: :param web_hook_id: :return: """ session = SessionManager.Session() try: web_hook = session.query(WebHook).\ filter(WebHook.id == web_hook_id).\ one() web_hook.name = web_hook_dict.get('name') web_hook.description = bleach.clean( web_hook_dict.get('description'), tags=self.ALLOWED_TAGS) web_hook.url = web_hook_dict.get('url') web_hook.status = web_hook_dict.get('status') web_hook.consecutive_failure_count = web_hook_dict.get( 'consecutive_failure_count') web_hook.permissions = web_hook_dict.get('permissions') if 'shared_secret' in web_hook_dict and web_hook_dict.get( 'shared_secret') is not None: web_hook.shared_secret = web_hook_dict.get('shared_secret') session.commit() return json_resp({'message': 'ok'}) finally: SessionManager.Session.remove()
def list_episode(self, page, count, sort_field, sort_order, status): try: session = SessionManager.Session() query_object = session.query(Episode).\ filter(Episode.delete_mark == None) if status is not None: query_object = query_object.filter(Episode.status==status) # count total rows total = session.query(func.count(Episode.id)).filter(Episode.status==status).scalar() else: total = session.query(func.count(Episode.id)).scalar() offset = (page - 1) * count if sort_order == 'desc': episode_list = query_object.\ order_by(desc(getattr(Episode, sort_field))).\ offset(offset).\ limit(count).\ all() else: episode_list = query_object.\ order_by(asc(getattr(Episode, sort_field))).\ offset(offset).limit(count).\ all() episode_dict_list = [row2dict(episode, Episode) for episode in episode_list] return json_resp({'data': episode_dict_list, 'total': total}) finally: SessionManager.Session.remove()
def update_password_with_token(new_pass, token, expiration=3600): from server import app serializer = URLSafeTimedSerializer(app.config['SECRET_KEY']) session = SessionManager.Session() try: combine_str = serializer.loads( token, salt=app.config['SECRET_PASSWORD_SALT'], max_age=expiration) email = combine_str[:-(PASSWORD_DIGEST_LENGTH + 1)] old_pass_digest = combine_str[-PASSWORD_DIGEST_LENGTH:] user = session.query(User).filter(User.email == email).one() if not user.email_confirmed: raise ClientError(ClientError.EMAIL_NOT_CONFIRMED) if old_pass_digest != UserCredential.get_password_digest( user.password): raise ClientError('invalid token') user.password = UserCredential.get_pass_hash(new_pass) session.commit() return json_resp({'message': 'ok'}) except NoResultFound: raise ClientError(ClientError.EMAIL_NOT_EXISTS, 400) finally: SessionManager.Session.remove()
def logout(): ''' logout a user :return: response ''' logout_user() return json_resp({'msg': 'ok'})
def get_bangumi(self, id): try: session = SessionManager.Session() bangumi = session.query(Bangumi).options(joinedload(Bangumi.episodes)).\ filter(Bangumi.id == id).\ filter(Bangumi.delete_mark == None).\ one() episodes = [] for episode in bangumi.episodes: if episode.delete_mark is not None: continue eps = row2dict(episode) eps['thumbnail'] = utils.generate_thumbnail_link( episode, bangumi) episodes.append(eps) bangumi_dict = row2dict(bangumi) bangumi_dict['episodes'] = episodes bangumi_dict['cover'] = utils.generate_cover_link(bangumi) return json_resp({'data': bangumi_dict}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) except Exception as exception: raise exception finally: SessionManager.Session.remove()
def register_web_hook(self, web_hook_dict, add_by_uid): """ register an web hook and send an initial keep alive event :param web_hook_dict: :param add_by_uid: :return: """ session = SessionManager.Session() try: web_hook = WebHook( name=web_hook_dict.get('name'), description=bleach.clean(web_hook_dict.get('description'), tags=self.ALLOWED_TAGS), url=web_hook_dict.get('url'), shared_secret=web_hook_dict.get('shared_secret'), created_by_uid=add_by_uid, permissions=web_hook_dict.get('permissions')) session.add(web_hook) session.commit() web_hook_id = str(web_hook.id) # send event via rpc rpc_request.send( 'initialize_web_hook', { 'web_hook_id': web_hook_id, 'web_hook_url': web_hook.url, 'shared_secret': web_hook.shared_secret }) return json_resp({'data': web_hook_id}) finally: SessionManager.Session.remove()
def recent_update(self, days): current = datetime.now() # from one week ago start_time = current - timedelta(days=days) session = SessionManager.Session() try: result = session.query(Episode, Bangumi).\ join(Bangumi).\ filter(Episode.status == Episode.STATUS_DOWNLOADED).\ filter(Episode.update_time >= start_time).\ filter(Episode.update_time <= current).\ order_by(desc(Episode.update_time)) episode_list = [] for eps, bgm in result: episode = row2dict(eps) episode['thumbnail'] = utils.generate_thumbnail_link(eps, bgm) episode['bangumi'] = row2dict(bgm) episode['bangumi']['cover'] = utils.generate_cover_link(bgm) episode_list.append(episode) return json_resp({'data': episode_list}) except Exception as error: raise error finally: SessionManager.Session.remove()
def list_pending_delete_episode(self): try: current = datetime.now() session = SessionManager.Session() result = session.query(Episode, Bangumi).\ join(Bangumi).\ filter(Episode.delete_mark != None).\ all() eps_list = [] for episode, bangumi in result: bgm = row2dict(bangumi) eps = row2dict(episode) # noinspection PyTypeChecker delete_eta = int( (episode.delete_mark + timedelta(minutes=self.delete_delay['episode']) - current).total_seconds() / 60) eps['delete_eta'] = delete_eta eps['bangumi'] = bgm eps_list.append(eps) return json_resp({ 'data': eps_list, 'delete_delay': self.delete_delay['episode'] }) finally: SessionManager.Session.remove()
def upload_episode(self, episode_id, file): try: filename = secure_filename(file.filename) session = SessionManager.Session() (episode, bangumi) = session.query(Episode, Bangumi).\ join(Bangumi).\ filter(Episode.id == episode_id).\ one() file.save( os.path.join(self.base_path, str(episode.bangumi_id), filename)) torrent_file = None try: torrent_file = session.query(TorrentFile).filter( TorrentFile.episode_id == episode_id).one() except NoResultFound: torrent_file = TorrentFile() session.add(torrent_file) torrent_file.torrent_id = str(-1) torrent_file.episode_id = episode_id torrent_file.file_path = filename episode.update_time = datetime.now() episode.status = Episode.STATUS_DOWNLOADED session.commit() return json_resp({'msg': 'ok'}) except NoResultFound: raise ClientError(ClientError.INVALID_REQUEST) except Exception as error: raise error finally: SessionManager.Session.remove()
def update_episode(self, episode_id, episode_dict): try: session = SessionManager.Session() episode = session.query(Episode).filter( Episode.id == episode_id).one() episode.episode_no = episode_dict.get('episode_no') episode.bgm_eps_id = episode_dict.get('bgm_eps_id') episode.name = episode_dict.get('name') episode.name_cn = episode_dict.get('name_cn') if 'airdate' in episode_dict: episode.airdate = datetime.strptime( episode_dict.get('airdate'), '%Y-%m-%d') episode.duration = episode_dict.get('duration') episode.update_time = datetime.utcnow() if 'status' in episode_dict: episode.status = episode_dict['status'] session.commit() return json_resp({'msg': 'ok'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove()
def list_pending_delete_banguimi(self): try: current = datetime.now() session = SessionManager.Session() bangumi_list = session.query(Bangumi).\ filter(Bangumi.delete_mark != None).\ all() bgm_list = [] for bangumi in bangumi_list: bgm = row2dict(bangumi) # noinspection PyTypeChecker delete_eta = int( (bangumi.delete_mark + timedelta(minutes=self.delete_delay['bangumi']) - current).total_seconds() / 60) bgm['delete_eta'] = delete_eta bgm_list.append(bgm) return json_resp({ 'data': bgm_list, 'delete_delay': self.delete_delay['bangumi'] }) finally: SessionManager.Session.remove()
def logout(): """ logout a user :return: response """ logout_user() return json_resp({'msg': 'ok'})
def get_all_announce(self, position, offset, count, content): session = SessionManager.Session() try: if content: announce_list = session.query(Announce).\ filter(Announce.content == content).\ all() else: announce_list = session.query(Announce).\ filter(Announce.position == position).\ offset(offset).\ limit(count).\ all() total = session.query(func.count(Announce.id)). \ scalar() announce_dict_list = [] for announce in announce_list: announce_dict = row2dict(announce, Announce) announce_dict_list.append(announce_dict) if position == Announce.POSITION_BANGUMI: self.__add_bangumi_info(session, announce_dict_list) return json_resp({'data': announce_dict_list, 'total': total}) finally: SessionManager.Session.remove()
def register(): """ register a new user using invite code, note that a newly registered user is not administrator, you need to use an admin user to promote it :return: response """ content = request.get_data(True, as_text=True) register_data = json.loads(content) if ('name' in register_data) and ('password' in register_data) and ('password_repeat' in register_data) and ('invite_code' in register_data) and ('email' in register_data): name = register_data['name'] password = register_data['password'] password_repeat = register_data['password_repeat'] email = register_data['email'] invite_code = register_data['invite_code'] if password != password_repeat: raise ClientError(ClientError.PASSWORD_MISMATCH) if UserCredential.register_user(name=name, password=password, email=email, invite_code=invite_code): # login automatically credential = UserCredential.login_user(name, password) login_user(credential, remember=False) # send email credential.send_confirm_email() return json_resp({'message': 'ok'}, 201) else: raise ClientError(ClientError.INVALID_REQUEST)
def list_user(self, name, count, offset): session = SessionManager.Session() try: query_object = session.query(User) if name is not None: name_pattern = '%{0}%'.format(name.encode('utf-8'), ) logger.debug(name_pattern) query_object = query_object. \ filter(User.name.like(name_pattern)) # count total rows total = session.query(func.count(User.id)). \ filter(User.name.like(name_pattern)). \ scalar() else: total = session.query(func.count(User.id)).scalar() # we now support query all method by passing count = -1 if count == -1: user_list = query_object.all() else: user_list = query_object.offset(offset).limit(count).all() user_dict_list = [] for user in user_list: user_dict_list.append({ 'id': str(user.id), 'name': user.name, 'level': user.level }) return json_resp({'data': user_dict_list, 'total': total}) finally: SessionManager.Session.remove()
def update_episode(self, episode_id, episode_dict): try: session = SessionManager.Session() episode = session.query(Episode).filter(Episode.id == episode_id).one() episode.episode_no = episode_dict.get('episode_no') episode.bgm_eps_id = episode_dict.get('bgm_eps_id') episode.name = episode_dict.get('name') episode.name_cn = episode_dict.get('name_cn') if 'airdate' in episode_dict: episode.airdate = datetime.strptime(episode_dict.get('airdate'), '%Y-%m-%d') episode.duration = episode_dict.get('duration') episode.update_time = datetime.utcnow() if 'status' in episode_dict: episode.status = episode_dict['status'] session.commit() return json_resp({'msg': 'ok'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove()
def on_air_bangumi(self): session = SessionManager.Session() current_day = datetime.today() start_time = datetime(current_day.year, current_day.month, 1) if current_day.month == 12: next_year = current_day.year + 1 next_month = 1 else: next_year = current_day.year next_month = current_day.month + 1 end_time = datetime(next_year, next_month, 1) try: result = session.query(distinct(Episode.bangumi_id), Bangumi).\ join(Bangumi).\ filter(Episode.airdate >= start_time).\ filter(Episode.airdate <= end_time) bangumi_list = [] for bangumi_id, bangumi in result: bangumi_dict = row2dict(bangumi) bangumi_dict['cover'] = utils.generate_cover_link(bangumi) bangumi_list.append(bangumi_dict) return json_resp({'data': bangumi_list}) except Exception as error: raise error finally: SessionManager.Session.remove()
def list_episode(self, page, count, sort_field, sort_order, status): try: session = SessionManager.Session() query_object = session.query(Episode) if status is not None: query_object = query_object.filter(Episode.status == status) # count total rows total = session.query(func.count( Episode.id)).filter(Episode.status == status).scalar() else: total = session.query(func.count(Episode.id)).scalar() offset = (page - 1) * count if sort_order == 'desc': episode_list = query_object.\ order_by(desc(getattr(Episode, sort_field))).\ offset(offset).\ limit(count).\ all() else: episode_list = query_object.\ order_by(asc(getattr(Episode, sort_field))).\ offset(offset).limit(count).\ all() episode_dict_list = [row2dict(episode) for episode in episode_list] return json_resp({'data': episode_dict_list, 'total': total}) except Exception as exception: raise exception finally: SessionManager.Session.remove()
def list_bangumi(self, page, count, sort_field, sort_order, name, user_id, bangumi_type): try: session = SessionManager.Session() query_object = session.query(Bangumi).\ options(joinedload(Bangumi.cover_image)).\ filter(Bangumi.delete_mark == None) if bangumi_type != -1: query_object = query_object.filter( Bangumi.type == bangumi_type) if name is not None: name_pattern = '%{0}%'.format(name.encode('utf-8'), ) logger.debug(name_pattern) query_object = query_object.\ filter(or_(Bangumi.name.ilike(name_pattern), Bangumi.name_cn.ilike(name_pattern))) # count total rows total = session.query(func.count(Bangumi.id)).\ filter(or_(Bangumi.name.ilike(name_pattern), Bangumi.name_cn.ilike(name_pattern))).\ scalar() else: total = session.query(func.count(Bangumi.id)).scalar() if sort_order == 'desc': query_object = query_object.\ order_by(desc(getattr(Bangumi, sort_field))) else: query_object = query_object.\ order_by(asc(getattr(Bangumi, sort_field))) if count == -1: bangumi_list = query_object.all() else: offset = (page - 1) * count bangumi_list = query_object.offset(offset).limit(count).all() bangumi_id_list = [bgm.id for bgm in bangumi_list] favorites = session.query(Favorites).\ filter(Favorites.bangumi_id.in_(bangumi_id_list)).\ filter(Favorites.user_id == user_id).\ all() bangumi_dict_list = [] for bgm in bangumi_list: bangumi = row2dict(bgm) bangumi['cover'] = utils.generate_cover_link(bgm) utils.process_bangumi_dict(bgm, bangumi) for fav in favorites: if fav.bangumi_id == bgm.id: bangumi['favorite_status'] = fav.status bangumi_dict_list.append(bangumi) return json_resp({'data': bangumi_dict_list, 'total': total}) finally: SessionManager.Session.remove()
def on_air_bangumi(self, user_id, type): session = SessionManager.Session() current_day = datetime.today() start_time = datetime(current_day.year, current_day.month, 1) if current_day.month == 12: next_year = current_day.year + 1 next_month = 1 else: next_year = current_day.year next_month = current_day.month + 1 end_time = datetime(next_year, next_month, 1) try: result = session.query(distinct(Episode.bangumi_id), Bangumi).\ join(Bangumi). \ options(joinedload(Bangumi.cover_image)).\ filter(Bangumi.delete_mark == None). \ filter(Bangumi.type == type).\ filter(Episode.airdate >= start_time).\ filter(Episode.airdate <= end_time). \ order_by(desc(getattr(Bangumi, 'air_date'))) bangumi_list = [] bangumi_id_list = [bangumi_id for bangumi_id, bangumi in result] if len(bangumi_id_list) == 0: return json_resp({'data': []}) favorites = session.query(Favorites).\ filter(Favorites.bangumi_id.in_(bangumi_id_list)).\ filter(Favorites.user_id == user_id).\ all() for bangumi_id, bangumi in result: bangumi_dict = row2dict(bangumi) bangumi_dict['cover'] = utils.generate_cover_link(bangumi) utils.process_bangumi_dict(bangumi, bangumi_dict) for fav in favorites: if fav.bangumi_id == bangumi_id: bangumi_dict['favorite_status'] = fav.status break bangumi_list.append(bangumi_dict) return json_resp({'data': bangumi_list}) finally: SessionManager.Session.remove()
def list_task(self): try: session = SessionManager.Session() result = session.query(Task).all() task_list = [row2dict(task) for task in result] return json_resp({'data': task_list}) finally: SessionManager.Session.remove()
def list_task(self): try: session = SessionManager.Session() result = session.query(Task).all() task_list = [row2dict(task, Task) for task in result] return json_resp({'data': task_list}) finally: SessionManager.Session.remove()
def on_air_bangumi(self, user_id, type): session = SessionManager.Session() current_day = datetime.today() start_time = datetime(current_day.year, current_day.month, 1) if current_day.month == 12: next_year = current_day.year + 1 next_month = 1 else: next_year = current_day.year next_month = current_day.month + 1 end_time = datetime(next_year, next_month, 1) try: result = session.query(distinct(Episode.bangumi_id), Bangumi).\ join(Bangumi). \ options(joinedload(Bangumi.cover_image)).\ filter(Bangumi.delete_mark == None). \ filter(Bangumi.type == type).\ filter(Episode.airdate >= start_time).\ filter(Episode.airdate <= end_time). \ order_by(desc(getattr(Bangumi, 'air_date'))) bangumi_list = [] bangumi_id_list = [bangumi_id for bangumi_id, bangumi in result] if len(bangumi_id_list) == 0: return json_resp({'data': []}) favorites = session.query(Favorites).\ filter(Favorites.bangumi_id.in_(bangumi_id_list)).\ filter(Favorites.user_id == user_id).\ all() for bangumi_id, bangumi in result: bangumi_dict = row2dict(bangumi, Bangumi) bangumi_dict['cover'] = utils.generate_cover_link(bangumi) utils.process_bangumi_dict(bangumi, bangumi_dict) for fav in favorites: if fav.bangumi_id == bangumi_id: bangumi_dict['favorite_status'] = fav.status break bangumi_list.append(bangumi_dict) return json_resp({'data': bangumi_list}) finally: SessionManager.Session.remove()
def get_user_info(): ''' get current user name and level :return: response ''' user_info = {} user_info['name'] = current_user.name user_info['level'] = current_user.level return json_resp({'data': user_info})
def list_bangumi(self, page, count, sort_field, sort_order, name, user_id, bangumi_type): try: session = SessionManager.Session() query_object = session.query(Bangumi).\ options(joinedload(Bangumi.cover_image)).\ filter(Bangumi.delete_mark == None) if bangumi_type != -1: query_object = query_object.filter(Bangumi.type == bangumi_type) if name is not None: name_pattern = '%{0}%'.format(name.encode('utf-8'),) logger.debug(name_pattern) query_object = query_object.\ filter(or_(Bangumi.name.ilike(name_pattern), Bangumi.name_cn.ilike(name_pattern))) # count total rows total = session.query(func.count(Bangumi.id)).\ filter(or_(Bangumi.name.ilike(name_pattern), Bangumi.name_cn.ilike(name_pattern))).\ scalar() else: total = session.query(func.count(Bangumi.id)).scalar() if sort_order == 'desc': query_object = query_object.\ order_by(desc(getattr(Bangumi, sort_field))) else: query_object = query_object.\ order_by(asc(getattr(Bangumi, sort_field))) if count == -1: bangumi_list = query_object.all() else: offset = (page - 1) * count bangumi_list = query_object.offset(offset).limit(count).all() bangumi_id_list = [bgm.id for bgm in bangumi_list] favorites = session.query(Favorites).\ filter(Favorites.bangumi_id.in_(bangumi_id_list)).\ filter(Favorites.user_id == user_id).\ all() bangumi_dict_list = [] for bgm in bangumi_list: bangumi = row2dict(bgm, Bangumi) bangumi['cover'] = utils.generate_cover_link(bgm) utils.process_bangumi_dict(bgm, bangumi) for fav in favorites: if fav.bangumi_id == bgm.id: bangumi['favorite_status'] = fav.status bangumi_dict_list.append(bangumi) return json_resp({'data': bangumi_dict_list, 'total': total}) finally: SessionManager.Session.remove()
def search_bangumi(): bangumi_tv_url_base = 'http://api.bgm.tv/search/subject/' bangumi_tv_url_param = '?responseGroup=simple&max_result=10&start=0' name = request.args.get('name', None) result = {"data": []} if name is not None and len(name) > 0: bangumi_tv_url = bangumi_tv_url_base + name + bangumi_tv_url_param h = httplib2.Http('.cache') (resp, content) = h.request(bangumi_tv_url, 'GET') if resp.status == 200: try: bgm_content = json.loads(content) except ValueError as e: return json_resp(result) list = [bgm for bgm in bgm_content['list'] if bgm['type'] == 2] if len(list) == 0: return json_resp(result) bgm_id_list = [bgm['id'] for bgm in list] bangumi_list = admin_service.get_bangumi_from_bgm_id_list( bgm_id_list) for bgm in list: bgm['bgm_id'] = bgm['id'] bgm['id'] = None # if bgm_id has found in database, give the database id to bgm.id # that's we know that this bangumi exists in our database for bangumi in bangumi_list: if bgm['bgm_id'] == bangumi.bgm_id: bgm['id'] = bangumi.id break bgm['image'] = bgm['images']['large'] # remove useless keys bgm.pop('images', None) bgm.pop('collection', None) bgm.pop('url', None) bgm.pop('type', None) result['data'] = list elif resp.status == 502: # when bangumi.tv is down result['msg'] = 'bangumi is down' return json_resp(result)
def get_bangumi(self, id, user_id): try: session = SessionManager.Session() bangumi = session.query(Bangumi).\ options(joinedload(Bangumi.episodes).joinedload(Episode.thumbnail_image)).\ options(joinedload(Bangumi.cover_image)).\ filter(Bangumi.delete_mark == None).\ filter(Bangumi.id == id).\ one() favorite = session.query(Favorites).\ filter(Favorites.bangumi_id == id).\ filter(Favorites.user_id == user_id).\ first() watch_progress_list = session.query(WatchProgress).\ filter(WatchProgress.bangumi_id == bangumi.id).\ filter(WatchProgress.user_id == user_id).\ all() episodes = [] watch_progress_hash_table = {} for watch_progress in watch_progress_list: watch_progress_dict = row2dict(watch_progress) watch_progress_hash_table[ watch_progress.episode_id] = watch_progress_dict for episode in bangumi.episodes: if episode.delete_mark is not None: continue eps = row2dict(episode) eps['thumbnail'] = utils.generate_thumbnail_link( episode, bangumi) utils.process_episode_dict(episode, eps) if episode.id in watch_progress_hash_table: eps['watch_progress'] = watch_progress_hash_table[ episode.id] episodes.append(eps) bangumi_dict = row2dict(bangumi) if favorite is not None: bangumi_dict['favorite_status'] = favorite.status bangumi_dict['episodes'] = episodes bangumi_dict['cover'] = utils.generate_cover_link(bangumi) utils.process_bangumi_dict(bangumi, bangumi_dict) return json_resp({'data': bangumi_dict}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove()
def parse_nyaa(self, qs): feed_url = 'https://nyaa.si/?page=rss&{0}'.format(qs,) feed_dict = self.parse_feed('nyaa', feed_url) title_list = [] for item in feed_dict.entries: item_title = item['title'] eps_no = self.parse_episode_number(item_title) title_list.append({'title': item_title, 'eps_no': eps_no}) return json_resp({'data': title_list, 'status': 0})
def query_one_bangumi(bgm_id): bangumi_tv_url_base = 'http://api.bgm.tv/subject/' bangumi_tv_url_param = '?responseGroup=large' if bgm_id is not None: bangumi_tv_url = bangumi_tv_url_base + bgm_id + bangumi_tv_url_param h = httplib2.Http('.cache') (resp, content) = h.request(bangumi_tv_url, 'GET') return content else: return json_resp({})
def logout(): ''' logout a user :return: response ''' try: logout_user() return json_resp({'msg': 'ok'}) except Exception as exception: raise exception
def search_bangumi(): bangumi_tv_url_base = 'http://api.bgm.tv/search/subject/' bangumi_tv_url_param = '?responseGroup=simple&max_result=10&start=0' name = request.args.get('name', None) result = {"data": []} if name is not None and len(name) > 0: bangumi_tv_url = bangumi_tv_url_base + name + bangumi_tv_url_param h = httplib2.Http('.cache') (resp, content) = h.request(bangumi_tv_url, 'GET') if resp.status == 200: try: bgm_content = json.loads(content) except ValueError as e: return json_resp(result) list = [bgm for bgm in bgm_content['list'] if bgm['type'] == 2] if len(list) == 0: return json_resp(result) bgm_id_list = [bgm['id'] for bgm in list] bangumi_list = admin_service.get_bangumi_from_bgm_id_list(bgm_id_list) for bgm in list: bgm['bgm_id'] = bgm['id'] bgm['id'] = None # if bgm_id has found in database, give the database id to bgm.id # that's we know that this bangumi exists in our database for bangumi in bangumi_list: if bgm['bgm_id'] == bangumi.bgm_id: bgm['id'] = bangumi.id break bgm['image'] = bgm['images']['large'] # remove useless keys bgm.pop('images', None) bgm.pop('collection', None) bgm.pop('url', None) bgm.pop('type', None) result['data'] = list elif resp.status == 502: # when bangumi.tv is down result['msg'] = 'bangumi is down' return json_resp(result)
def check_favorite(self, bangumi_id, user_id): session = SessionManager.Session() favorite = session.query(Favorites).\ filter(Favorites.bangumi_id == bangumi_id).\ filter(Favorites.user_id == user_id).\ first() if not favorite: raise ClientError(ClientError.NOT_FOUND, 404, {bangumi_id: bangumi_id}) else: favorite.check_time = datetime.utcnow() return json_resp({'data': favorite.check_time, 'status': 0})
def parse_dmhy(self, keywords): keywords_encoded = urllib.quote_plus(keywords.replace(u'+', u' ').encode('utf-8')) feed_url = 'https://share.dmhy.org/topics/rss/rss.xml?keyword=%s' % (keywords_encoded,) feed_dict = self.parse_feed('dmhy', feed_url) title_list = [] for item in feed_dict.entries: item_title = item['title'] eps_no = self.parse_episode_number(item_title) title_list.append({'title': item_title, 'eps_no': eps_no}) return json_resp({'data': title_list, 'status': 0})
def parse_acg_rip(self, keywords): keywords_encoded = urllib.quote_plus(keywords.replace(u'+', u' ').encode('utf-8')) feed_url = 'https://acg.rip/.xml?term=%s' % (keywords_encoded,) feed_dict = self.parse_feed('acg.rip', feed_url) title_list = [] for item in feed_dict.entries: item_title = item['title'] eps_no = self.parse_episode_number(item_title) title_list.append({'title': item_title, 'eps_no': eps_no}) return json_resp({'data': title_list, 'status': 0})
def get_episode_video_file_list(self, episode_id): try: session = SessionManager.Session() video_file_list = session.query(VideoFile).\ filter(VideoFile.episode_id == episode_id).\ all() result = [row2dict(video_file, VideoFile) for video_file in video_file_list] return json_resp({'data': result}) finally: SessionManager.Session.remove()
def get_bangumi(self, id, user_id): try: session = SessionManager.Session() bangumi = session.query(Bangumi).\ options(joinedload(Bangumi.episodes).joinedload(Episode.thumbnail_image)).\ options(joinedload(Bangumi.cover_image)).\ filter(Bangumi.delete_mark == None).\ filter(Bangumi.id == id).\ one() favorite = session.query(Favorites).\ filter(Favorites.bangumi_id == id).\ filter(Favorites.user_id == user_id).\ first() watch_progress_list = session.query(WatchProgress).\ filter(WatchProgress.bangumi_id == bangumi.id).\ filter(WatchProgress.user_id == user_id).\ all() episodes = [] watch_progress_hash_table = {} for watch_progress in watch_progress_list: watch_progress_dict = row2dict(watch_progress, WatchProgress) watch_progress_hash_table[watch_progress.episode_id] = watch_progress_dict for episode in bangumi.episodes: if episode.delete_mark is not None: continue eps = row2dict(episode, Episode) eps['thumbnail'] = utils.generate_thumbnail_link(episode, bangumi) utils.process_episode_dict(episode, eps) if episode.id in watch_progress_hash_table: eps['watch_progress'] = watch_progress_hash_table[episode.id] episodes.append(eps) bangumi_dict = row2dict(bangumi, Bangumi) if favorite is not None: bangumi_dict['favorite_status'] = favorite.status bangumi_dict['episodes'] = episodes bangumi_dict['cover'] = utils.generate_cover_link(bangumi) utils.process_bangumi_dict(bangumi, bangumi_dict) return json_resp({'data': bangumi_dict}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove()
def delete_announce(self, announce_id): session = SessionManager.Session() try: announce = session.query(Announce).\ filter(Announce.id == announce_id).\ one() session.delete(announce) session.commit() return json_resp({'message': 'ok'}) finally: SessionManager.Session.remove()
def get_user_info(): """ get current user name and level :return: response """ user_info = { 'name': current_user.name, 'level': current_user.level, 'email': current_user.email, 'email_confirmed': current_user.email_confirmed } return json_resp({'data': user_info})
def restore_episode(self, episode_id): try: session = SessionManager.Session() episode = session.query(Episode).\ options(joinedload(Episode.bangumi)).\ filter(Episode.id == episode_id).one() episode.delete_mark = None episode.bangumi.eps = episode.bangumi.eps + 1 session.commit() return json_resp({'msg': 'ok'}) finally: SessionManager.Session.remove()