class AdminService: def __init__(self): fr = open('./config/config.yml', 'r') config = yaml.load(fr) self.base_path = config['download']['location'] self.image_domain = config['domain']['image'] self.file_downloader = FileDownloader() self.delete_delay = {'bangumi': 10, 'episode': 1} if config['task'].get('delete_delay') is None: logger.warn( 'delete_delay section is not set, please update your config file' ) else: self.delete_delay = config['task'].get('delete_delay') try: if not os.path.exists(self.base_path): os.makedirs(self.base_path) print 'create base dir %s successfully' % self.base_path except OSError as exception: if exception.errno == errno.EACCES: # permission denied raise exception else: print exception def __get_eps_len(self, eps): EPISODE_TYPE = 0 # episode type = 0 is the normal episode type, even the episode is not a 24min length eps_length = 0 for eps_item in eps: if eps_item['type'] == EPISODE_TYPE: eps_length = eps_length + 1 return eps_length def __get_bangumi_status(sefl, air_date): _air_date = datetime.strptime(air_date, '%Y-%m-%d') _today = datetime.today() if _today >= _air_date: return Bangumi.STATUS_ON_AIR else: return Bangumi.STATUS_PENDING def __save_bangumi_cover(self, bangumi): if not bangumi.image: return bangumi_path = self.base_path + '/' + str(bangumi.id) try: if not os.path.exists(bangumi_path): os.makedirs(bangumi_path) print 'create base dir %s successfully' % self.base_path except OSError as exception: if exception.errno == errno.EACCES: # permission denied raise exception else: print exception path = urlparse(bangumi.image).path extname = os.path.splitext(path)[1] cover_path = bangumi_path + '/cover' + extname self.file_downloader.download_file(bangumi.image, cover_path) 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 query_bangumi_detail(self, bgm_id): api_url = 'http://api.bgm.tv/subject/' + bgm_id + '?responseGroup=large' r = bangumi_request.get(api_url) if r.status_code > 399: r.raise_for_status() return r.text def list_bangumi(self, page, count, sort_field, sort_order, name): try: session = SessionManager.Session() query_object = session.query(Bangumi).\ filter(Bangumi.delete_mark == None) 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.like(name_pattern), Bangumi.name_cn.like(name_pattern))) # count total rows total = session.query(func.count(Bangumi.id)).\ filter(or_(Bangumi.name.like(name_pattern), Bangumi.name_cn.like(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))) # we now support query all method by passing count = -1 if count == -1: bangumi_list = query_object.all() else: offset = (page - 1) * count bangumi_list = query_object.offset(offset).limit(count).all() bangumi_dict_list = [] for bgm in bangumi_list: bangumi = row2dict(bgm) bangumi['cover'] = utils.generate_cover_link(bgm) bangumi_dict_list.append(bangumi) return json_resp({'data': bangumi_dict_list, 'total': total}) # raise ClientError('something happened') finally: SessionManager.Session.remove() def add_bangumi(self, content): try: bangumi_data = json.loads(content) bangumi = Bangumi(bgm_id=bangumi_data.get('bgm_id'), name=bangumi_data.get('name'), name_cn=bangumi_data.get('name_cn'), type=bangumi_data.get('type'), summary=bangumi_data.get('summary'), eps=bangumi_data.get('eps'), image=bangumi_data.get('image'), air_date=bangumi_data.get('air_date'), air_weekday=bangumi_data.get('air_weekday'), status=self.__get_bangumi_status( bangumi_data.get('air_date'))) # bangumi.dmhy = bangumi_data.get('dmhy') # bangumi.acg_rip = bangumi_data.get('acg_rip') # bangumi.libyk_so = bangumi_data.get('libyk_so') bangumi.eps_no_offset = bangumi_data.get('eps_no_offset') session = SessionManager.Session() session.add(bangumi) bangumi.episodes = [] for eps_item in bangumi_data['episodes']: eps = Episode(bgm_eps_id=eps_item.get('bgm_eps_id'), episode_no=eps_item.get('episode_no'), name=eps_item.get('name'), name_cn=eps_item.get('name_cn'), duration=eps_item.get('duration'), status=Episode.STATUS_NOT_DOWNLOADED) if eps_item.get('airdate') != '': eps.airdate = eps_item.get('airdate') eps.bangumi = bangumi bangumi.episodes.append(eps) session.commit() bangumi_id = str(bangumi.id) self.__save_bangumi_cover(bangumi) return json_resp({'data': {'id': bangumi_id}}) 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.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 bangumi.update_time = datetime.now() session.commit() return json_resp({'msg': 'ok'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND) 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).\ 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 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 get_bangumi_from_bgm_id_list(self, bgm_id_list): s = select([Bangumi.id, Bangumi.bgm_id]).where( Bangumi.bgm_id.in_(bgm_id_list) & (Bangumi.delete_mark == None)).select_from(Bangumi) return SessionManager.engine.execute(s).fetchall() def add_episode(self, episode_dict): try: session = SessionManager.Session() episode = Episode(bangumi_id=episode_dict['bangumi_id'], bgm_eps_id=episode_dict.get('bgm_eps_id', -1), episode_no=episode_dict['episode_no'], name=episode_dict.get('name'), name_cn=episode_dict.get('name_cn'), duration=episode_dict.get('duration'), airdate=episode_dict.get('airdate'), status=Episode.STATUS_NOT_DOWNLOADED) session.add(episode) session.commit() episode_id = str(episode.id) return json_resp({'data': {'id': episode_id}}) 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.name = episode_dict['name'] episode.name_cn = episode_dict['name_cn'] episode.airdate = datetime.strptime(episode_dict['airdate'], '%Y-%m-%d') episode.duration = episode_dict['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 get_episode(self, episode_id): try: session = SessionManager.Session() episode = session.query(Episode).\ filter(Episode.id == episode_id).\ filter(Episode.delete_mark == None).\ all() episode_dict = row2dict(episode) return json_resp({'data': episode_dict}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove() def delete_episode(self, episode_id): try: session = SessionManager.Session() episode = session.query(Episode).filter( Episode.id == episode_id).one() episode.delete_mark = datetime.now() session.commit() return json_resp( {'data': { 'delete_delay': self.delete_delay['episode'] }}) 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) 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 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 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) for video_file in video_file_list] return json_resp({'data': result}) finally: SessionManager.Session.remove() def add_video_file(self, video_dict): try: session = SessionManager.Session() video_file = VideoFile(bangumi_id=video_dict['bangumi_id'], episode_id=video_dict['episode_id'], download_url=video_dict.get('download_url'), file_path=video_dict.get('file_path'), file_name=video_dict.get('file_name'), status=video_dict.get('status', 1), resolution_w=video_dict.get('resolution_w'), resolution_h=video_dict.get('resolution_h'), duration=video_dict.get('duration'), label=video_dict.get('label')) session.add(video_file) session.commit() video_file_id = str(video_file.id) return json_resp({'data': video_file_id}) finally: SessionManager.Session.remove() def update_video_file(self, video_file_id, video_dict): try: session = SessionManager.Session() video_file = session.query(VideoFile).filter( VideoFile.id == video_file_id).one() video_file.download_url = video_dict.get('download_url') video_file.file_path = video_dict.get('file_path') video_file.file_name = video_dict.get('file_name') video_file.status = video_dict.get('status', 1) video_file.resolution_w = video_dict.get('resolution_w') video_file.resolution_h = video_dict.get('resolution_h') video_file.duration = video_dict.get('duration') video_file.label = video_dict.get('label') session.commit() return json_resp({'msg': 'OK'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove() def delete_video_file(self, video_file_id): try: session = SessionManager.Session() video_file = session.query(VideoFile).filter( VideoFile.id == video_file_id).one() if video_file.file_path is not None and video_file.status == VideoFile.STATUS_DOWNLOADED: file_abs_path = u'{0}/{1}/{2}'.format( self.base_path, str(video_file.bangumi_id), video_file.file_path) try: os.remove(file_abs_path) except Exception as error: logger.warn(error) session.delete(video_file) session.commit() return json_resp({'msg': 'ok'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove()
class AdminService: def __init__(self): fr = open('./config/config.yml', 'r') config = yaml.load(fr) self.base_path = config['download']['location'] self.image_domain = config['domain']['image'] self.file_downloader = FileDownloader() self.delete_delay = {'bangumi': 10, 'episode': 1} if config['task'].get('delete_delay') is None: logger.warn('delete_delay section is not set, please update your config file') else: self.delete_delay = config['task'].get('delete_delay') try: if not os.path.exists(self.base_path): os.makedirs(self.base_path) print 'create base dir %s successfully' % self.base_path except OSError as exception: if exception.errno == errno.EACCES: # permission denied raise exception else: print exception def __get_eps_len(self, eps): EPISODE_TYPE = 0 # episode type = 0 is the normal episode type, even the episode is not a 24min length eps_length = 0 for eps_item in eps: if eps_item['type'] == EPISODE_TYPE: eps_length = eps_length + 1 return eps_length def __get_bangumi_status(sefl, air_date): _air_date = datetime.strptime(air_date, '%Y-%m-%d') _today = datetime.today() if _today >= _air_date: return Bangumi.STATUS_ON_AIR else: return Bangumi.STATUS_PENDING def __save_bangumi_cover(self, bangumi): if not bangumi.image: return bangumi_path = self.base_path + '/' + str(bangumi.id) try: if not os.path.exists(bangumi_path): os.makedirs(bangumi_path) print 'create base dir %s successfully' % self.base_path except OSError as exception: if exception.errno == errno.EACCES: # permission denied raise exception else: sentry_wrapper.sentry_middleware.captureException() print exception path = urlparse(bangumi.image).path extname = os.path.splitext(path)[1] cover_path = '{0}/cover{1}'.format(str(bangumi.id), extname) file_path = '{0}/{1}'.format(self.base_path, cover_path) self.file_downloader.download_file(bangumi.image, file_path) return file_path, cover_path def __process_user_obj_in_bangumi(self, bangumi, bangumi_dict): if bangumi.created_by is not None: bangumi_dict['created_by'] = row2dict(bangumi.created_by, User) bangumi_dict['created_by'].pop('password', None) if bangumi.maintained_by is not None: bangumi_dict['maintained_by'] = row2dict(bangumi.maintained_by, User) bangumi_dict['maintained_by'].pop('password', None) bangumi_dict.pop('created_by_uid', None) bangumi_dict.pop('maintained_by_uid', None) 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 query_bangumi_detail(self, bgm_id): api_url = 'http://api.bgm.tv/subject/' + bgm_id + '?responseGroup=large' r = bangumi_request.get(api_url) if r.status_code > 399: r.raise_for_status() return r.text def list_bangumi(self, page, count, sort_field, sort_order, name, bangumi_type): try: session = SessionManager.Session() query_object = session.query(Bangumi).\ options(joinedload(Bangumi.cover_image)).\ options(joinedload(Bangumi.created_by)).\ options(joinedload(Bangumi.maintained_by)).\ 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))) # we now support query all method by passing count = -1 if count == -1: bangumi_list = query_object.all() else: offset = (page - 1) * count bangumi_list = query_object.offset(offset).limit(count).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) self.__process_user_obj_in_bangumi(bgm, bangumi) bangumi_dict_list.append(bangumi) return json_resp({'data': bangumi_dict_list, 'total': total}) # raise ClientError('something happened') finally: SessionManager.Session.remove() def add_bangumi(self, content, uid): try: bangumi_data = json.loads(content) bangumi = Bangumi(bgm_id=bangumi_data.get('bgm_id'), name=bangumi_data.get('name'), name_cn=bangumi_data.get('name_cn'), type=bangumi_data.get('type'), summary=bangumi_data.get('summary'), eps=bangumi_data.get('eps'), image=bangumi_data.get('image'), air_date=bangumi_data.get('air_date'), air_weekday=bangumi_data.get('air_weekday'), status=self.__get_bangumi_status(bangumi_data.get('air_date')), created_by_uid=uid, maintained_by_uid=uid) # bangumi.dmhy = bangumi_data.get('dmhy') # bangumi.acg_rip = bangumi_data.get('acg_rip') # bangumi.libyk_so = bangumi_data.get('libyk_so') bangumi.eps_no_offset = bangumi_data.get('eps_no_offset') session = SessionManager.Session() session.add(bangumi) bangumi.episodes = [] for eps_item in bangumi_data['episodes']: eps = Episode(bgm_eps_id=eps_item.get('bgm_eps_id'), episode_no=eps_item.get('episode_no'), name=eps_item.get('name'), name_cn=eps_item.get('name_cn'), duration=eps_item.get('duration'), status=Episode.STATUS_NOT_DOWNLOADED) if is_valid_date(eps_item.get('airdate')): eps.airdate = eps_item.get('airdate') eps.bangumi = bangumi bangumi.episodes.append(eps) session.commit() bangumi_id = str(bangumi.id) try: (cover_file_path, cover_path) = self.__save_bangumi_cover(bangumi) # get dominant color bangumi.cover_color = get_dominant_color(cover_file_path) (width, height) = get_dimension(cover_file_path) bangumi.cover_image = Image(file_path=cover_path, dominant_color=bangumi.cover_color, width=width, height=height) session.commit() except Exception as error: sentry_wrapper.sentry_middleware.captureException() logger.warn(error) # delete bangumi for download error session.delete(bangumi) session.commit() raise ServerError('Fail to Download Image') return json_resp({'data': {'id': bangumi_id}}) 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.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 get_bangumi(self, id): try: session = SessionManager.Session() bangumi = session.query(Bangumi).\ options(joinedload(Bangumi.episodes).joinedload(Episode.thumbnail_image)).\ options(joinedload(Bangumi.cover_image)). \ options(joinedload(Bangumi.created_by)). \ options(joinedload(Bangumi.maintained_by)). \ 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, Episode) eps['thumbnail'] = utils.generate_thumbnail_link(episode, bangumi) utils.process_episode_dict(episode, eps) episodes.append(eps) bangumi_dict = row2dict(bangumi, Bangumi) bangumi_dict['episodes'] = episodes utils.process_bangumi_dict(bangumi, bangumi_dict) self.__process_user_obj_in_bangumi(bangumi, bangumi_dict) 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 delete_bangumi(self, bangumi_id): try: session = SessionManager.Session() bangumi = session.query(Bangumi).filter(Bangumi.id == bangumi_id).one() bangumi.delete_mark = datetime.utcnow() 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 get_bangumi_from_bgm_id_list(self, bgm_id_list): s = select([Bangumi.id, Bangumi.bgm_id]).where(Bangumi.bgm_id.in_(bgm_id_list) & (Bangumi.delete_mark == None)).select_from(Bangumi) return SessionManager.engine.execute(s).fetchall() def add_episode(self, episode_dict): try: session = SessionManager.Session() bangumi = session.query(Bangumi).filter(Bangumi.id == episode_dict['bangumi_id']).one() if is_valid_date(episode_dict.get('airdate')): episode_dict['airdate'] = episode_dict.get('airdate') else: episode_dict['airdate'] = None episode = Episode(bangumi_id=episode_dict['bangumi_id'], bgm_eps_id=episode_dict.get('bgm_eps_id', -1), episode_no=episode_dict['episode_no'], name=episode_dict.get('name'), name_cn=episode_dict.get('name_cn'), duration=episode_dict.get('duration'), airdate=episode_dict.get('airdate'), status=Episode.STATUS_NOT_DOWNLOADED) session.add(episode) bangumi.eps = bangumi.eps + 1 session.commit() episode_id = str(episode.id) return json_resp({'data': {'id': episode_id}}) 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 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, 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() def delete_episode(self, episode_id): session = SessionManager.Session() try: (episode, bangumi) = session.query(Episode, Bangumi).\ join(Bangumi).\ filter(Episode.id == episode_id).one() # remove files of episode bangumi_folder_path = '{0}/{1}'.format(self.base_path, str(episode.bangumi_id)) video_file_list = session.query(VideoFile). \ filter(VideoFile.episode_id == episode_id). \ all() watch_progress_list = session.query(WatchProgress).filter( WatchProgress.episode_id == episode_id).all() for video_file in video_file_list: # remove torrent try: file_path = '{0}/{1}'.format(bangumi_folder_path, video_file.file_path) os.remove(file_path) except Exception as error: logger.error(error) # remove torrent from deluge rpc_request.send('delete_deluge_torrent', {'torrent_id': video_file.torrent_id}) # remove video_file session.delete(video_file) # remove watch-progress for watch_progress in watch_progress_list: session.delete(watch_progress) # remove image if episode.thumbnail_image_id is not None: image = session.query(Image).filter(Image.id == episode.thumbnail_image_id).one() session.delete(image) # remove episode session.delete(episode) bangumi.eps = bangumi.eps - 1 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_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 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 add_video_file(self, video_dict): try: session = SessionManager.Session() video_file = VideoFile(bangumi_id=video_dict['bangumi_id'], episode_id=video_dict['episode_id'], download_url=video_dict.get('download_url'), file_path=video_dict.get('file_path'), file_name=video_dict.get('file_name'), status=video_dict.get('status', 1), resolution_w=video_dict.get('resolution_w'), resolution_h=video_dict.get('resolution_h'), duration=video_dict.get('duration'), label=video_dict.get('label')) session.add(video_file) session.commit() video_file_id = str(video_file.id) return json_resp({'data': video_file_id}) finally: SessionManager.Session.remove() def update_video_file(self, video_file_id, video_dict): try: session = SessionManager.Session() video_file = session.query(VideoFile).filter(VideoFile.id == video_file_id).one() video_file.download_url = video_dict.get('download_url') video_file.file_path = video_dict.get('file_path') video_file.file_name = video_dict.get('file_name') video_file.status = video_dict.get('status', 1) video_file.resolution_w = video_dict.get('resolution_w') video_file.resolution_h = video_dict.get('resolution_h') video_file.duration = video_dict.get('duration') video_file.label = video_dict.get('label') session.commit() return json_resp({'msg': 'OK'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove() def delete_video_file(self, video_file_id): try: session = SessionManager.Session() video_file = session.query(VideoFile).filter(VideoFile.id == video_file_id).one() if video_file.file_path is not None and video_file.status == VideoFile.STATUS_DOWNLOADED: file_abs_path = u'{0}/{1}/{2}'.format(self.base_path, str(video_file.bangumi_id), video_file.file_path) try: os.remove(file_abs_path) except Exception as error: logger.warn(error) rpc_request.send('delete_deluge_torrent', {'torrent_id': video_file.torrent_id}) session.delete(video_file) session.commit() return json_resp({'msg': 'ok'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) finally: SessionManager.Session.remove()
class AdminService: def __init__(self): fr = open('./config/config.yml', 'r') config = yaml.load(fr) self.base_path = config['download']['location'] self.image_domain = config['domain']['image'] self.file_downloader = FileDownloader() try: if not os.path.exists(self.base_path): os.makedirs(self.base_path) print 'create base dir %s successfully' % self.base_path except OSError as exception: if exception.errno == errno.EACCES: # permission denied raise exception else: print exception def __get_eps_len(self, eps): EPISODE_TYPE = 0 # episode type = 0 is the normal episode type, even the episode is not a 24min length eps_length = 0 for eps_item in eps: if eps_item['type'] == EPISODE_TYPE: eps_length = eps_length + 1 return eps_length def __get_bangumi_status(sefl, air_date): _air_date = datetime.strptime(air_date, '%Y-%m-%d') _today = datetime.today() if _today >= _air_date: return Bangumi.STATUS_ON_AIR else: return Bangumi.STATUS_PENDING def __save_bangumi_cover(self, bangumi): if not bangumi.image: return bangumi_path = self.base_path + '/' + str(bangumi.id) try: if not os.path.exists(bangumi_path): os.makedirs(bangumi_path) print 'create base dir %s successfully' % self.base_path except OSError as exception: if exception.errno == errno.EACCES: # permission denied raise exception else: print exception path = urlparse(bangumi.image).path extname = os.path.splitext(path)[1] cover_path = bangumi_path + '/cover' + extname self.file_downloader.download_file(bangumi.image, cover_path) def search_bangumi(self, term): ''' 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": []} api_url = 'http://api.bgm.tv/search/subject/' + term + '?responseGroup=simple&max_result=25&start=0&type=2' 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) 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['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'] = bgm_list result['total_count'] = total_count return json_resp(result) def query_bangumi_detail(self, bgm_id): api_url = 'http://api.bgm.tv/subject/' + bgm_id + '?responseGroup=large' r = bangumi_request.get(api_url) if r.status_code > 399: r.raise_for_status() return r.text def list_bangumi(self, page, count, sort_field, sort_order, name): try: session = SessionManager.Session() query_object = session.query(Bangumi) 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.like(name_pattern), Bangumi.name_cn.like(name_pattern))) # count total rows total = session.query(func.count(Bangumi.id)).\ filter(or_(Bangumi.name.like(name_pattern), Bangumi.name_cn.like(name_pattern))).\ scalar() else: total = session.query(func.count(Bangumi.id)).scalar() offset = (page - 1) * count if sort_order == 'desc': bangumi_list = query_object.\ order_by(desc(getattr(Bangumi, sort_field))).\ offset(offset).limit(count).\ all() else: bangumi_list = query_object.\ order_by(asc(getattr(Bangumi, sort_field))).\ offset(offset).limit(count).\ all() bangumi_dict_list = [] for bgm in bangumi_list: bangumi = row2dict(bgm) bangumi['cover'] = utils.generate_cover_link(bgm) bangumi_dict_list.append(bangumi) return json_resp({'data': bangumi_dict_list, 'total': total}) except Exception as exception: raise exception finally: SessionManager.Session.remove() def add_bangumi(self, content): try: bangumi_data = json.loads(content) bangumi = Bangumi(bgm_id=bangumi_data['bgm_id'], name=bangumi_data['name'], name_cn=bangumi_data['name_cn'], summary=bangumi_data['summary'], eps=bangumi_data['eps'], image=bangumi_data['image'], air_date=bangumi_data['air_date'], air_weekday=bangumi_data['air_weekday'], status=self.__get_bangumi_status( bangumi_data['air_date'])) if 'dmhy' in bangumi_data: bangumi.dmhy = bangumi_data['dmhy'] if 'acg_rip' in bangumi_data: bangumi.acg_rip = bangumi_data['acg_rip'] session = SessionManager.Session() session.add(bangumi) bangumi.episodes = [] for eps_item in bangumi_data['episodes']: eps = Episode(bgm_eps_id=eps_item['bgm_eps_id'], episode_no=eps_item['episode_no'], name=eps_item['name'], name_cn=eps_item['name_cn'], duration=eps_item['duration'], airdate=eps_item['airdate'], status=Episode.STATUS_NOT_DOWNLOADED) eps.bangumi = bangumi bangumi.episodes.append(eps) session.commit() bangumi_id = str(bangumi.id) self.__save_bangumi_cover(bangumi) return json_resp({'data': {'id': bangumi_id}}) 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 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 delete_bangumi(self, bangumi_id): try: session = SessionManager.Session() bangumi = session.query(Bangumi).filter( Bangumi.id == bangumi_id).one() session.delete(bangumi) session.commit() return json_resp({'msg': 'ok'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) except Exception as exception: raise exception finally: SessionManager.Session.remove() def get_bangumi_from_bgm_id_list(self, bgm_id_list): s = select([Bangumi.id, Bangumi.bgm_id]).where( Bangumi.bgm_id.in_(bgm_id_list)).select_from(Bangumi) return SessionManager.engine.execute(s).fetchall() def update_episode(self, episode_id, episode_dict): try: session = SessionManager.Session() episode = session.query(Episode).filter( Episode.id == episode_id).one() episode.name = episode_dict['name'] episode.name_cn = episode_dict['name_cn'] episode.airdate = datetime.strptime(episode_dict['airdate'], '%Y-%m-%d') episode.duration = episode_dict['duration'] episode.update_time = datetime.now() session.commit() return json_resp({'msg': 'ok'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) except Exception as error: raise error 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 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 update_thumbnail(self, episode_id, time): try: session = SessionManager.Session() episode = session.query(Episode).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 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()
if bangumi.image is not None: try: bangumi_dir = download_location + '/' + str(bangumi.id) # if bangumi folder is not existence create it if not os.path.exists(bangumi_dir): os.makedirs(bangumi_dir) print 'bangumi %s folder created' % (str(bangumi.id), ) path = urlparse(bangumi.image).path extname = os.path.splitext(path)[1] bangumi_cover_path = bangumi_dir + '/cover' + extname if not os.path.exists(bangumi_cover_path): # download bangumi image print 'start to download bangumi cover of %s (%s)' % ( bangumi.name, str(bangumi.id)) file_downloader.download_file(bangumi.image, bangumi_cover_path) if bangumi.cover_color is None: try: bangumi.cover_color = get_dominant_color( bangumi_cover_path, 5) session.commit() except Exception as err: print err if bangumi.cover_image_id is None: try: width, height = get_dimension(bangumi_cover_path) cover_image = Image(file_path='{0}/cover{1}'.format( str(bangumi.id), extname), dominant_color=bangumi.cover_color, width=width, height=height)
class AdminService: def __init__(self): fr = open('./config/config.yml', 'r') config = yaml.load(fr) self.base_path = config['download']['location'] self.image_domain = config['domain']['image'] self.file_downloader = FileDownloader() try: if not os.path.exists(self.base_path): os.makedirs(self.base_path) print 'create base dir %s successfully' % self.base_path except OSError as exception: if exception.errno == errno.EACCES: # permission denied raise exception else: print exception def __get_eps_len(self, eps): EPISODE_TYPE = 0 # episode type = 0 is the normal episode type, even the episode is not a 24min length eps_length = 0 for eps_item in eps: if eps_item['type'] == EPISODE_TYPE: eps_length = eps_length + 1 return eps_length def __get_bangumi_status(sefl, air_date): _air_date = datetime.strptime(air_date, '%Y-%m-%d') _today = datetime.today() if _today >= _air_date: return Bangumi.STATUS_ON_AIR else: return Bangumi.STATUS_PENDING def __save_bangumi_cover(self, bangumi): if not bangumi.image: return bangumi_path = self.base_path + '/' + str(bangumi.id) try: if not os.path.exists(bangumi_path): os.makedirs(bangumi_path) print 'create base dir %s successfully' % self.base_path except OSError as exception: if exception.errno == errno.EACCES: # permission denied raise exception else: print exception path = urlparse(bangumi.image).path extname = os.path.splitext(path)[1] cover_path = bangumi_path + '/cover' + extname self.file_downloader.download_file(bangumi.image, cover_path) def list_bangumi(self, page, count, sort_field, sort_order, name): try: session = SessionManager.Session() query_object = session.query(Bangumi) if name is not None: query_object = query_object.\ filter(or_(Bangumi.name==name, Bangumi.name_cn==name)) # count total rows total = session.query(func.count(Bangumi.id)).\ filter(or_(Bangumi.name==name, Bangumi.name_cn==name)).\ scalar() else: total = session.query(func.count(Bangumi.id)).scalar() offset = (page - 1) * count if sort_order == 'desc': bangumi_list = query_object.\ order_by(desc(getattr(Bangumi, sort_field))).\ offset(offset).limit(count).\ all() else: bangumi_list = query_object.\ order_by(asc(getattr(Bangumi, sort_field))).\ offset(offset).limit(count).\ all() bangumi_dict_list = [] for bgm in bangumi_list: bangumi = row2dict(bgm) bangumi['cover'] = utils.generate_cover_link(bgm) bangumi_dict_list.append(bangumi) return json_resp({'data': bangumi_dict_list, 'total': total}) except Exception as exception: raise exception finally: SessionManager.Session.remove() def add_bangumi(self, content): try: bangumi_data = json.loads(content) bangumi = Bangumi(bgm_id=bangumi_data['bgm_id'], name=bangumi_data['name'], name_cn=bangumi_data['name_cn'], summary=bangumi_data['summary'], eps=bangumi_data['eps'], image=bangumi_data['image'], air_date=bangumi_data['air_date'], air_weekday=bangumi_data['air_weekday'], status=self.__get_bangumi_status(bangumi_data['air_date'])) if 'rss' in bangumi_data: bangumi.rss = bangumi_data['rss'] if 'eps_regex' in bangumi_data: bangumi.eps_regex = bangumi_data['eps_regex'] session = SessionManager.Session() session.add(bangumi) bangumi.episodes = [] for eps_item in bangumi_data['episodes']: eps = Episode(bgm_eps_id=eps_item['bgm_eps_id'], episode_no=eps_item['episode_no'], name=eps_item['name'], name_cn=eps_item['name_cn'], duration=eps_item['duration'], airdate=eps_item['airdate'], status=Episode.STATUS_NOT_DOWNLOADED) eps.bangumi = bangumi bangumi.episodes.append(eps) session.commit() bangumi_id = str(bangumi.id) self.__save_bangumi_cover(bangumi) return json_resp({'data': {'id': bangumi_id}}) 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_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 delete_bangumi(self, bangumi_id): try: session = SessionManager.Session() bangumi = session.query(Bangumi).filter(Bangumi.id == bangumi_id).one() session.delete(bangumi) session.commit() return json_resp({'msg': 'ok'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) except Exception as exception: raise exception finally: SessionManager.Session.remove() def get_bangumi_from_bgm_id_list(self, bgm_id_list): s = select([Bangumi.id, Bangumi.bgm_id]).where(Bangumi.bgm_id.in_(bgm_id_list)).select_from(Bangumi) return SessionManager.engine.execute(s).fetchall() def update_episode(self, episode_id, episode_dict): try: session = SessionManager.Session() episode = session.query(Episode).filter(Episode.id == episode_id).one() episode.name = episode_dict['name'] episode.name_cn = episode_dict['name_cn'] episode.airdate = datetime.strptime(episode_dict['airdate'], '%Y-%m-%d') episode.duration = episode_dict['duration'] episode.update_time = datetime.now() session.commit() return json_resp({'msg': 'ok'}) except NoResultFound: raise ClientError(ClientError.NOT_FOUND, 404) except Exception as error: raise error 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 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 update_thumbnail(self, episode_id, time): try: session = SessionManager.Session() episode = session.query(Episode).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) except Exception as error: raise error finally: SessionManager.Session.remove()
download_location = config['download']['location'] session = SessionManager.Session() cur = session.query(Bangumi) resp_cookies = None file_downloader = FileDownloader() for bangumi in cur: if bangumi.image is not None: try: bangumi_dir = download_location + '/' + str(bangumi.id) # if bangumi folder is not existence create it if not os.path.exists(bangumi_dir): os.makedirs(bangumi_dir) print 'bangumi %s folder created' % (str(bangumi.id),) path = urlparse(bangumi.image).path extname = os.path.splitext(path)[1] bangumi_cover_path = bangumi_dir + '/cover' + extname if not os.path.exists(bangumi_cover_path): # download bangumi image print 'start to download bangumi cover of %s (%s)' % (bangumi.name, str(bangumi.id)) file_downloader.download_file(bangumi.image, bangumi_cover_path) except OSError as exception: if exception.errno == errno.EACCES: # permission denied raise exception else: print exception else: parser.print_help()