def libyk_so(): t = request.args.get('t', None) q = request.args.get('q', None) if t is None or q is None: raise ClientError('t an q must have value', 400) else: return feed_service.parse_libyk_so(t, q)
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.now() 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 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_password(self, old_pass, new_pass): from server import app, mail session = SessionManager.Session() try: user = session.query(User).filter(User.id == self.id).one() if check_password_hash(user.password, old_pass): user.password = UserCredential.get_pass_hash(new_pass) session.commit() if user.email is not None and user.email_confirmed: # send notification mail subject = u'[{0}] Password Update Notification'.format( app.config['SITE_NAME']) email_content = render_template( 'update-pass-notification.html', info={ 'title': subject, 'user_name': user.name, 'site_name': app.config['SITE_NAME'] }) msg = Message(subject, recipients=[self.email], html=email_content) try: mail.send(msg) except SMTPAuthenticationError: raise ServerError('SMTP authentication failed', 500) return True else: raise ClientError(ClientError.PASSWORD_INCORRECT) except NoResultFound: raise ServerError('user not found') finally: SessionManager.Session.remove()
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 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 revive(self, web_hook_id, token_id_list, signature): session = SessionManager.Session() try: # reset its status web_hook = session.query(WebHook).\ filter(WebHook.id == web_hook_id).\ one() if signature != self.__get_hmac_hash(web_hook.shared_secret, web_hook_id, token_id_list): raise ClientError('Authenticate Failed', 401) web_hook.status = WebHook.STATUS_IS_ALIVE session.commit() fav_dict_list = [] if len(token_id_list) > 0: web_hook_token_list = session.query(WebHookToken).\ filter(WebHookToken.web_hook_id == web_hook_id).\ filter(WebHookToken.token_id.in_(token_id_list)).\ all() user_id_list = [ web_hook.user_id for web_hook in web_hook_token_list ] favorites_list = session.query(Favorites).\ filter(Favorites.user_id.in_(user_id_list)).\ group_by(Favorites.user_id, Favorites.id).\ all() for favorite in favorites_list: fav_dict = row2dict(favorite, Favorites) for web_hook in web_hook_token_list: if fav_dict['user_id'] == web_hook.user_id: fav_dict['token_id'] = web_hook.token_id break fav_dict.pop('user_id', None) fav_dict_list.append(fav_dict) return json_resp({'data': fav_dict_list}) except NoResultFound as error: logger.warn(error, exc_info=True) raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove()
def feed_back(): data = json.loads(request.get_data(as_text=True)) episode_id = data.get('episode_id', None) video_file_id = data.get('video_file_id', None) message = data.get('message', None) if not episode_id or not video_file_id: raise ClientError(ClientError, ClientError.INVALID_REQUEST) return bangumi_service.feed_back(episode_id, video_file_id, current_user, message)
def update_thumbnail(self, episode_id, time): try: session = SessionManager.Session() episode = session.query(Episode).\ filter(Episode.delete_mark == None).\ filter(Episode.id == episode_id).one() if episode.status != Episode.STATUS_DOWNLOADED: raise ClientError('Episode not downloaded', 412) torrent_file = session.query(TorrentFile).filter(TorrentFile.episode_id == episode_id).all()[0] video_manager.create_episode_thumbnail(episode, torrent_file.file_path, time) return json_resp({'msg': 'ok'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove()
def update_pass(): """ update a user password, the original password is needed :return: response """ content = request.get_data(True, as_text=True) user_data = json.loads(content) if ('new_password' in user_data) and ('new_password_repeat' in user_data) and ('password' in user_data): if user_data['new_password'] != user_data['new_password_repeat']: raise ClientError('password not match') current_user.update_password(user_data['password'], user_data['new_password']) return logout() else: raise ClientError(ClientError.INVALID_REQUEST)
def update_email(): data = json.loads(request.get_data(as_text=True)) email = data.get('email') # password = data.get('password') if email is None: raise ClientError(ClientError.INVALID_EMAIL) # if password is None: # raise ClientError('Invalid password') return current_user.update_email(email)
def search_bangumi(): name = request.args.get('name', None) type = request.args.get('type', 2) # search type = 2 for anime or type = 6 for japanese tv drama series offset = request.args.get('offset', 0) count = request.args.get('count', 10) if name is not None and len(name) > 0: return admin_service.search_bangumi(type, name, offset, count) else: raise ClientError('Name cannot be None', 400)
def send_pass_reset_email(email): """ Send a password reset email which includes a link to navigate user to a endpoint to reset his/her password. The link contains a token get from self.generate_reset_email_token method. end point has the responsibility to verify the token. :param email: the user email from user input. this must be a confirmed email of a valid user. :return: """ from server import app, mail session = SessionManager.Session() try: user = session.query(User). \ filter(User.email == email). \ one() if not user.email_confirmed: raise ClientError(ClientError.EMAIL_NOT_CONFIRMED) # generate token token = UserCredential.generate_reset_email_token(user) reset_url = '{0}://{1}/reset-pass?token={2}'.format( app.config['SITE_PROTOCOL'], app.config['SITE_HOST'], token) subject = '[{0}] Password Request for {1}'.format( app.config['SITE_NAME'], user.name) reset_content = render_template('reset-pass.html', info={ 'reset_title': subject, 'reset_url': reset_url, 'site_name': app.config['SITE_NAME'], 'user_name': user.name }) msg = Message(subject, recipients=[email], html=reset_content) mail.send(msg) session.commit() except SMTPAuthenticationError: raise ServerError('SMTP authentication failed', 500) except NoResultFound: raise ClientError(ClientError.EMAIL_NOT_EXISTS, 400) 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) 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 reset_pass(): ''' reset a user password, invite_code is required :return: ''' content = request.get_data(True, as_text=True) user_data = json.loads(content) if ('name' in user_data) and ('password' in user_data) and ( 'password_repeat' in user_data) and ('invite_code' in user_data): name = user_data['name'] password = user_data['password'] password_repeat = user_data['password_repeat'] invite_code = user_data['invite_code'] if password != password_repeat: raise ClientError('password not match') if UserCredential.reset_pass(name, password, invite_code): return json_resp({'msg': 'OK'}) else: raise ClientError('invalid parameters')
def confirm_token(self, token, expiration=3600): from server import app serializer = URLSafeTimedSerializer(app.config['SECRET_KEY']) session = SessionManager.Session() try: email = serializer.loads(token, salt=app.config['SECRET_PASSWORD_SALT'], max_age=expiration) if (email == self.email) and (not self.email_confirmed): self.email_confirmed = True user = session.query(User).filter(User.id == self.id).one() user.email_confirmed = True session.commit() return json_resp({'message': 'ok'}) else: raise ClientError('Invalid Token') except: raise ClientError('Invalid Token') finally: SessionManager.Session.remove()
def promote_user(self, id, to_level): session = SessionManager.Session() try: user = session.query(User).filter(User.id == id).one() user.level = to_level session.commit() return json_resp({'msg': 'OK'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove()
def login_user(cls, name, password): session = SessionManager.Session() try: user = session.query(User).filter(User.name == name).one() if check_password_hash(user.password, password): credential = cls(user) SessionManager.Session.remove() return credential else: raise ClientError(ClientError.LOGIN_FAIL) except NoResultFound: raise ClientError(ClientError.LOGIN_FAIL) except DataError: raise ClientError(ClientError.LOGIN_FAIL) except ClientError as error: raise error except Exception as error: raise ServerError(error.message) 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): name = register_data['name'] password = register_data['password'] password_repeat = register_data['password_repeat'] invite_code = register_data['invite_code'] if password != password_repeat: raise ClientError(ClientError.PASSWORD_MISMATCH) if UserCredential.register_user(name, password, invite_code): return json_resp({'msg': 'OK'}) else: raise ClientError(ClientError.INVALID_REQUEST)
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 register_user(name, password, email, invite_code): email_patteren = re.compile( "(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)") if not email_patteren.match(email): raise ClientError(ClientError.INVALID_EMAIL) session = SessionManager.Session() try: code = session.query(InviteCode).filter( InviteCode.code == invite_code).one() if code.used_by is not None: raise ClientError(ClientError.INVALID_INVITE_CODE) user = User(name=name, password=UserCredential.get_pass_hash(password), email=email, level=0) session.add(user) session.commit() code.used_by = user.id session.commit() return True except NoResultFound: raise ClientError(ClientError.INVALID_INVITE_CODE) except DataError: raise ClientError(ClientError.INVALID_INVITE_CODE) except IntegrityError as error: if error.diag.column_name == 'name': raise ClientError(ClientError.DUPLICATE_NAME) elif error.diag.column_name == 'email': raise ClientError(ClientError.DUPLICATE_EMAIL) except ClientError as error: raise error except Exception as error: raise ServerError(error.message) finally: SessionManager.Session.remove()
def get_episode(self, episode_id): try: session = SessionManager.Session() episode = session.query(Episode).filter(Episode.id == episode_id).one() episode_dict = row2dict(episode) return json_resp({'data': episode_dict}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) except Exception as error: raise error finally: SessionManager.Session.remove()
def reset_pass(name, password, invite_code): session = SessionManager.Session() try: user = session.query(User).filter(User.name == name).one() code = session.query(InviteCode).filter( and_(InviteCode.code == invite_code, InviteCode.used_by == user.id)).one() user.password = generate_password_hash(password) session.commit() return True except NoResultFound: raise ClientError(ClientError.INVALID_INVITE_CODE) except DataError: raise ClientError(ClientError.INVALID_INVITE_CODE) except ClientError as error: raise error except Exception as error: raise ServerError(error.message) 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).\ filter(Bangumi.delete_mark == None).\ 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.status = bangumi_dict['status'] bangumi.dmhy = bangumi_dict.get('dmhy') bangumi.acg_rip = bangumi_dict.get('acg_rip') bangumi.libyk_so = bangumi_dict.get('libyk_so') bangumi.bangumi_moe = bangumi_dict.get('bangumi_moe') bangumi.nyaa = bangumi_dict.get('nyaa') bangumi.universal = bangumi_dict.get('universal') bangumi.eps_no_offset = bangumi_dict.get('eps_no_offset') if not bangumi.eps_no_offset: # in case the eps_no_offset is empty string bangumi.eps_no_offset = None maintained_by = bangumi_dict.get('maintained_by') if maintained_by is None: bangumi.maintained_by_uid = None # add this try to trace the mysterious bug on maintained_by_uid changing. logger.error('maintained_by_uid is setting to None', exc_info=True) else: bangumi.maintained_by_uid = maintained_by['id'] bangumi.alert_timeout = bangumi_dict.get('alert_timeout') bangumi.update_time = datetime.utcnow() session.commit() return json_resp({'message': 'ok'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND) finally: SessionManager.Session.remove()
def delete_bangumi(self, bangumi_id): try: session = SessionManager.Session() bangumi = session.query(Bangumi).filter(Bangumi.id == bangumi_id).one() bangumi.delete_mark = datetime.now() session.commit() return json_resp({'data': {'delete_delay': self.delete_delay['bangumi']}}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove()
def login(): ''' login a user :return: response ''' content = request.get_data(True, as_text=True) login_data = json.loads(content) if ('name' in login_data) and ('password' in login_data): name = login_data['name'] password = login_data['password'] remember = login_data['remember'] if 'remember' in login_data else False credential = UserCredential.login_user(name, password) login_user(credential, remember=remember) return json_resp({'msg': 'OK'}) else: raise ClientError(ClientError.INVALID_REQUEST)
def update_pass(): ''' update a user password, the original password is needed :return: response ''' try: content = request.get_data(True, as_text=True) user_data = json.loads(content) if ('new_password' in user_data) and ('new_password_repeat' in user_data) and ('password' in user_data): if(user_data['new_password'] != user_data['new_password_repeat']): raise ClientError('password not match') current_user.update_password(user_data['password'], user_data['new_password']) return logout() except Exception as exception: raise exception
def restore_bangumi(self, bangumi_id): try: session = SessionManager.Session() bangumi = session.query(Bangumi).filter( Bangumi.id == bangumi_id).one() bangumi.delete_mark = None session.commit() return json_resp({'msg': 'ok'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove()
def get_episode(self, episode_id): try: session = SessionManager.Session() episode = session.query(Episode).\ options(joinedload(Episode.thumbnail_image)).\ filter(Episode.id == episode_id).\ filter(Episode.delete_mark == None).\ all() episode_dict = row2dict(episode) utils.process_episode_dict(episode, episode_dict) return json_resp({'data': episode_dict}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove()