class MusicView(View): @staticmethod @Analyse.r(b=[ PList(name='targetsrcs', read_name='音乐平台').set_child( P('targetsrc', '音乐平台').validate(is_platform) ), P('musicname', '名字').process(str), P('searchsize', '搜索阈值').process(int), ]) def post(request): # print(request.d.musicname) # print(request.d.targetsrcs) searchsize = request.d.searchsize config = {'logfilepath': 'musicdl.log', 'savedir': 'downloaded', 'search_size_per_source': searchsize, 'proxies': {}} target_srcs = request.d.targetsrcs client = musicdl.musicdl(config=config) search_results = client.search(request.d.musicname, target_srcs) items = [] idx = 0 for key, values in search_results.items(): for value in values: print("singer: "+value["singers"] + "download_url" + value["download_url"]) items.append(value) idx += 1 # print(search_results) return dict(items=items)
class Avatar(View): @staticmethod @Analyse.r(q=[P('filename', '文件名')]) @Auth.require_login(deny_auth_token=True) def get(r): """ GET /api/user/avatar 获取七牛上传token """ user = r.user filename = r.d.filename import datetime crt_time = datetime.datetime.now().timestamp() key = 'user/%s/avatar/%s/%s' % (user.user_str_id, crt_time, filename) qn_token, key = qn_public_manager.get_upload_token( key, Policy.avatar(user.user_str_id)) return dict(upload_token=qn_token, key=key) @staticmethod @Analyse.r([P('key', '七牛存储键'), UserP.user]) def post(r): """ POST /api/user/avatar 七牛上传用户头像回调函数 """ qn_public_manager.auth_callback(r) key = r.d.key user = r.d.user user.modify_avatar(key) return user.d()
class AppP: name, info, desc, redirect_uri, test_redirect_uri, secret, max_user_num = App.P( 'name', 'info', 'desc', 'redirect_uri', 'test_redirect_uri', 'secret', 'max_user_num') scopes = P('scopes', '应用权限列表').process(Scope.list_to_scope_list) premises = P('premises', '应用要求列表').process(Premise.list_to_premise_list) app = P('app_id', '应用ID', 'app').process(App.get_by_id) user_app = P('user_app_id', '用户绑定应用ID', 'user_app').process(UserApp.get_by_id)
class UserP: birthday, password, nickname, description, qitian, idcard, male, real_name = User.P( 'birthday', 'password', 'nickname', 'description', 'qitian', 'idcard', 'male', 'real_name') user = P('user_id', '用户唯一ID', 'user').process(User.get_by_str_id) back = P('back', '侧别').process(int) birthday.process( lambda s: datetime.datetime.strptime(s, '%Y-%m-%d').date(), begin=True)
class IDCardV(View): @staticmethod @Analyse.r(q=[P('filename', '文件名'), UserP.back]) @Auth.require_login(deny_auth_token=True) def get(r): """ GET /api/user/idcard?back=[0, 1] 获取七牛上传token """ user = r.user filename = r.d.filename back = int(bool(r.d.back)) if user.verify_status != User.VERIFY_STATUS_UNVERIFIED: if user.verify_status == User.VERIFY_STATUS_UNDER_AUTO or \ user.verify_status == User.VERIFY_STATUS_UNDER_MANUAL: raise IDCardError.VERIFYING('无法重新上传') else: raise IDCardError.REAL_VERIFIED('无法重新上传') import datetime crt_time = datetime.datetime.now().timestamp() key = 'user/%s/card/%s/%s/%s' % ( user.user_str_id, ['front', 'back'][back], crt_time, filename) policy = Policy.verify_back if back else Policy.verify_front qn_token, key = qn_res_manager.get_upload_token( key, policy(user.user_str_id)) return dict(upload_token=qn_token, key=key) @staticmethod @Analyse.r(b=[P('key', '七牛存储键'), UserP.user], q=[UserP.back]) def post(r): """ POST /api/user/idcard?back=[0, 1] 七牛上传用户实名认证回调函数 """ qn_public_manager.auth_callback(r) key = r.d.key back = r.d.back user = r.d.user if user.verify_status != User.VERIFY_STATUS_UNVERIFIED: if user.verify_status == User.VERIFY_STATUS_UNDER_AUTO or \ user.verify_status == User.VERIFY_STATUS_UNDER_MANUAL: raise IDCardError.VERIFYING('无法重新上传') else: raise IDCardError.REAL_VERIFIED('无法重新上传') if back: return user.upload_verify_back(key) else: return user.upload_verify_front(key)
class ReviewView(View): @staticmethod @Analyse.r(q=[ PM_TAG_ID, P('count').process(int).process(PL.number(100, 1)), P('last').process(int) ]) def get(r): tag = r.d.tag last = r.d.last count = r.d.count objects = TagMap.objects.search(tag=tag) return Pager().page(objects, last, count).dict(TagMap.d)
class DownloadView(View): @staticmethod @Auth.maybe_login def get_dl_link(r, visit_key): user = r.user res = r.d.res # type: Resource if not res.readable(user, visit_key): raise ResourceError.NOT_READABLE if res.rtype == RtypeChoice.FOLDER.value: raise ResourceError.REQUIRE_FILE return HttpResponseRedirect(res.get_dl_url()) @staticmethod @Analyse.r(q=[P('token', '登录口令').null(), P_VISIT_KEY.clone().null()], a=[P_RES]) def get(r): """ GET /api/res/:res_str_id/dl 获取下载资源链接 """ r.META['HTTP_TOKEN'] = r.d.token visit_key = r.d.visit_key return DownloadView.get_dl_link(r, visit_key)
class OAuthToken(View): @staticmethod @Analyse.r([P('code', '授权码'), AppP.secret.clone().rename('app_secret')]) def post(r): """POST /api/oauth/token""" code = r.d.code dict_ = JWT.decrypt(code) if dict_['type'] != JWType.AUTH_CODE: raise AuthError.REQUIRE_AUTH_CODE user_app_id = dict_['user_app_id'] user_app = UserApp.get_by_id(user_app_id, check_bind=True) ctime = dict_['ctime'] if user_app.app.field_change_time > ctime: raise AuthError.APP_FIELD_CHANGE if user_app.last_auth_code_time != str(ctime): raise AuthError.NEW_AUTH_CODE_CREATED token, dict_ = JWT.encrypt( dict( user_app_id=user_app.user_app_id, type=JWType.AUTH_TOKEN, ), expire_second=OAUTH_TOKEN_EXPIRE_TIME, ) dict_['token'] = token dict_['avatar'] = user_app.user.get_avatar_url() return dict_
class UserAppId(View): @staticmethod @Analyse.r(b=[AppP.secret.clone().rename('app_secret')], a=[AppP.user_app]) def post(r): """ POST /api/app/user/:user_app_id 通过app获取user信息 """ app_secret = r.d.app_secret user_app = r.d.user_app if not user_app.app.authentication(app_secret): raise AppError.APP_SECRET return user_app.user.d() @staticmethod @Analyse.r(b=[P('mark', '应用评分').process(int)], a=[AppP.user_app]) @Auth.require_login(deny_auth_token=True) def put(r): """ PUT /api/app/user/:user_app_id 给app评分 """ user_app = r.d.user_app mark = r.d.mark if user_app.user.user_str_id != r.user.user_str_id: raise AppError.ILLEGAL_ACCESS_RIGHT user_app.do_mark(mark) return user_app.app.mark_as_list()
class BaseView(View): @staticmethod @Analyse.r({ ProjectP.project, SegmentP.time, PList(name='waves').set_child(PDict().set_fields( WaveP.label, WaveP.value)), ProjectP.ticket, }) def post(r): project = r.d.project ticket = r.d.ticket if not project.auth_ticket(ticket): return ProjectError.TICKET_INVALID segment = Segment.new(**r.d.dict('project', 'time')) for data in r.d.waves: Wave.new(segment=segment, **data) @staticmethod @Analyse.r(q=[ ProjectP.project, SegmentP.time_for_search.clone().rename('last'), P('count', '获取数据段个数').process(int).process(PL.number(10, 1)), ]) def get(r): project = r.d.project last = r.d.last count = r.d.count page = time_pager.page(Segment.objects.filter(project=project), last=last, count=count) return page.dict(object_dictor=Segment.d, next_dictor=time_dictor)
class AppV(View): @staticmethod @Analyse.r(q=[ P('relation').default(App.R_USER).process(relation_process), P('frequent').null(), P('count').default(3).process(int), P('last_time').null().process(float).process(datetime.datetime.fromtimestamp) ]) @Auth.require_login([SI.read_app_list]) def get(r): """ GET /api/app/ 获取与我相关的app列表 """ user = r.user relation = r.d.relation if relation == App.R_OWNER: return App.objects.filter(owner=user).dict(App.d_base) elif relation == App.R_NONE: count = r.d.count last_time = r.d.last_time pager = Pager(compare_field='create_time') page = App.objects.page(pager, last_time, count) # type: Page return page.object_list.dict(App.d_base) else: frequent = r.d.frequent count = r.d.count objects = UserApp.objects.filter(user=user, bind=True) if frequent: pager = Pager(mode=Pager.CHOOSE_AMONG, order_by=('-frequent_score', )) objects = objects.page(pager, 0, count).object_list return list(map(lambda o: o.app.d_base(), objects)) @staticmethod @Analyse.r([AppP.name, AppP.desc, AppP.redirect_uri, AppP.test_redirect_uri, AppP.scopes, AppP.premises]) @Auth.require_login(deny_auth_token=True) def post(r): """ POST /api/app/ 创建我的app """ app = App.create(owner=r.user, **r.d.dict()) return app.d_base()
class CharacterToPinyin(BaseHandler): APP_NAME = '汉字转拼音' APP_DESC = '支持多音字判别,拼音自带音调' BODY = [ P('text', '汉字').validate(PL.str_len(500)), P('heteronym_when_single', '单个汉字返回多音字').process(bool).default(True), ] REQUEST_EXAMPLE = {'text': '林俊杰'} RESPONSE_EXAMPLE = ["lín", "jùn", "jié"] @staticmethod @Analyse.r(b=BODY) def run(r): text = r.d.text if len(text) == 1: pinyin = pypinyin.pinyin(text, heteronym=r.d.heteronym_when_single, errors=lambda _: [None]) return pinyin[0] pinyin = pypinyin.pinyin(text, errors=lambda _: [None]) return list(map(lambda x: x[0], pinyin))
class LibraryBooking(BaseHandler): APP_NAME = '图书馆一键预约' APP_DESC = '浙江工商大学疫情期间的图书馆便捷预约' BODY = [ P('id', '一卡通号').default(None), P('password', '密码').default('000'), P('phone', '电话号码').default(None), P('view_only').default(False), P('list_date').default(False), P('date').default(False), ] @staticmethod @Analyse.r(b=BODY) def run(r): student_id = r.d.id password = r.d.password phone = r.d.phone view_only = r.d.view_only list_date = r.d.list_date date = r.d.date if list_date: return LibraryBookingService.list_date() if not date: date = datetime.datetime.now().strftime('%Y-%m-%d') if view_only: return LibraryBookingService.view_remain(date) return LibraryBookingService.book(date, str(student_id), password, phone)
class FormatSyllable(BaseHandler): APP_NAME = '格式化音节' APP_DESC = '将带数字的不标准音节格式化为标准带声调音节' BODY = [P('syllables', '音节列表').validate(list)] REQUEST_EXAMPLE = {"syllables": ["hua", "fe3ng", "lv2", "shān"]} RESPONSE_EXAMPLE = ["hua", "fěng", "lǘ", "shān"] @staticmethod @Analyse.r(b=BODY) def run(r): syllables = r.d.syllables # type: list return list(map(phraseService.format_syllable, syllables))
class SoulMatch(BaseHandler): APP_NAME = '朋友圈默契度偷窥' APP_DESC = '2020朋友圈默契大考验偷窥工具' BODY = [P('openid', '微信用户ID')] @staticmethod @Analyse.r(b=BODY) def run(r): openid = r.d.openid data = requests.get( 'https://2020luck.news.qq.com/friend/getInfo?openId=' + openid).json() return data['data']
class AppLogo(View): @staticmethod @Analyse.r(q=[P('filename', '文件名'), AppP.app]) @Auth.require_login(deny_auth_token=True) def get(r): """ GET /api/app/logo 获取七牛上传token """ user = r.user filename = r.d.filename app = r.d.app # type: App if app.owner != user: raise AppError.APP_NOT_BELONG import datetime crt_time = datetime.datetime.now().timestamp() key = 'app/%s/logo/%s/%s' % (app.id, crt_time, filename) qn_token, key = qn_public_manager.get_upload_token(key, Policy.logo(app.id)) return dict(upload_token=qn_token, key=key) @staticmethod @Analyse.r([P('key', '七牛存储键'), AppP.app]) def post(r): """ POST /api/app/logo 七牛上传应用logo回调函数 """ qn_public_manager.auth_callback(r) key = r.d.key app = r.d.app app.modify_logo(key) return app.d()
class Region(View): @staticmethod @Analyse.r(q=[P('lang', '语言').default('cn').process(process_lang)]) def get(r): lang = r.d.lang lang_cn = lang == country.LANG_CN regions = [ dict( num=c['num'], name=c['cname'] if lang_cn else c['ename'], flag=c['flag'], detail=c.get('detail'), ) for c in country.countries ] return regions
class PhraseView(View): @staticmethod @Analyse.r(q=[PM_TAG_ID, P('count').process(int).process(PL.number(100, 1))]) def get(r): tag = r.d.tag count = r.d.count phrases = phraseService.phrases \ .exclude(pk__in=TagMap.objects.filter( tag=tag, match__isnull=False).values_list('phrase', flat=True)) \ .order_by('pk')[:count] return phrases.dict(Phrase.d) @staticmethod @Analyse.r(b=['cy', PM_ENTRANCE, PM_ACTION, PM_TAG_ID.clone().null()]) def post(r): cy = r.d.cy action = r.d.action if action == 'add': cy = Phrase.new(cy) contributor = r.d.contributor add_key = 'LangPhraseAdd-' + contributor add_count = int(Config.get_value_by_key(add_key, 0)) Config.update_value(add_key, str(add_count + 1)) return cy.d() else: if not r.d.tag: return BaseError.MISS_PARAM(('tag_id', '标签')) tag = r.d.tag cy = Phrase.get(cy) tagmap = TagMap.get(cy, tag) return tagmap.d() @staticmethod @Analyse.r(b=[PM_TAG_ID, PM_MATCHED, PM_UNMATCHED, PM_ENTRANCE]) def put(r): tag = r.d.tag contributor = r.d.contributor contributor_key = 'LangPhraseContributor-' + contributor contribute_page = int(Config.get_value_by_key(contributor_key, 0)) Config.update_value(contributor_key, str(contribute_page+1)) for phrase in r.d.matched: TagMap.new_or_put(phrase, tag, match=True) for phrase in r.d.unmatched: TagMap.new_or_put(phrase, tag, match=False)
class OAuthView(View): @staticmethod @Analyse.r([P('code', '授权码')]) def post(r): """POST /user/oauth 打通齐天簿OAuth """ code = r.d.code data = qt_manager.get_token(code) qt_token = data['token'] qt_user_app_id = data['user_app_id'] user = User.create(qt_user_app_id, qt_token) user.update() return Auth.get_login_token(user)
class LinkView(View): @staticmethod @Analyse.r(b=[P_RNAME.clone().rename('link_name'), P('link')], a=[P_RES]) @Auth.require_owner def post(r): """ POST /api/res/:res_str_id/link 上传链接资源 """ user = r.user link_name = r.d.link_name link = r.d.link res_parent = r.d.res res = Resource.create_link(link_name, user, res_parent, link) return res.d()
class QitianManager: QITIAN_HOST = 'https://ssoapi.6-79.cn' GET_TOKEN_URL = '%s/api/oauth/token' % QITIAN_HOST GET_USER_INFO_URL = '%s/api/user/' % QITIAN_HOST GET_USER_PHONE_URL = '%s/api/user/phone' % QITIAN_HOST def __init__(self, app_id, app_secret): self.app_id = app_id self.app_secret = app_secret @Analyse.p(PDict(name='res').set_fields('code', 'msg', P('body').null())) def _res_checker(self, res, error: E): if res['code'] != BaseError.OK.eid: raise error(append_message=res['msg']) return res['body'] def _req_extractor(self, req: requests.Response, error: E): if req.status_code != requests.codes.ok: raise error try: res = req.json() except Exception as err: raise error(debug_message=err) return self._res_checker(res, error) def get_token(self, code): req = requests.post(self.GET_TOKEN_URL, json=dict( code=code, app_secret=self.app_secret, ), timeout=3) return self._req_extractor(req, QitianError.QITIAN_REQ_FAIL('身份认证')) def get_user_info(self, token): req = requests.get(self.GET_USER_INFO_URL, headers=dict( token=token, ), timeout=3) return self._req_extractor(req, QitianError.QITIAN_REQ_FAIL('用户信息')) def get_user_phone(self, token): req = requests.get(self.GET_USER_PHONE_URL, headers=dict( token=token, ), timeout=3) return self._req_extractor(req, QitianError.QITIAN_REQ_FAIL('用户手机号'))
class UserV(View): @staticmethod @Auth.require_login([SI.read_base_info]) def get(r): """ GET /api/user/ 获取我的信息 """ user = r.user return user.d_oauth() if r.type_ == JWType.AUTH_TOKEN else user.d() @staticmethod @Analyse.r([UserP.password, P('code', '验证码')]) def post(r): """ POST /api/user/ 创建用户 """ code = r.d.code password = r.d.password phone = SendMobile.check_captcha(r, code) user = User.create(phone, password) return Auth.get_login_token(user) @staticmethod @Analyse.r([ UserP.nickname.clone().null(), UserP.description.clone().null(), UserP.qitian.clone().null(), UserP.birthday.clone().null(), ]) @Auth.require_login(deny_auth_token=True) def put(r): """ PUT /api/user/ 修改用户信息 """ user = r.user user.modify_info(**r.d.dict()) return user.d()
def readable_param(cls, param: P): if isinstance(param, str): param = P(param) d_ = dict( name=param.name, desc=param.read_name, allow_null=param.allow_null, has_default=param.has_default, type_='dict' if param.is_dict else 'list' if param.is_list else 'atom', ) if param.has_default: d_['default_value'] = param.default_value d_['default_through_processors'] = param.default_through_processors if param.is_dict: d_['dict_fields'] = list(map(cls.readable_param, param.dict_fields)) if param.is_list and param.list_child: d_['list_child'] = cls.readable_param(param.list_child) return d_
class IPLookup(BaseHandler): APP_NAME = '国内IP查询' APP_DESC = '获取地域和IP段' BODY = [P('ip', 'ip地址').process(PL.ip_dot2int).process(IP.lookup)] REQUEST_EXAMPLE = {"ip": "39.174.135.244"} RESPONSE_EXAMPLE = { "city": "杭州", "line": "移动", "province": "浙江省", "ip_start": "39.174.128.0", "ip_end": "39.174.255.255", "owner": "", "country": "中国" } @staticmethod @Analyse.r(b=BODY) def run(r): return r.d.ip.d()
class Rythme(BaseHandler): class RythmeCluster(BaseHandler): APP_NAME = '押韵拼音组' APP_DESC = 'cluster和cluster_type的取值说明。\n' \ '通过POST请求获取音节(syllable)数据。\n' \ 'syllables分为22个组,每组的音节视为互可押韵。\n' \ 'cluster_type参数可以是strict, normal, custom。\n' \ '当其为strict时,此22组相互独立。组内相互押韵,组间不为押韵;\n' \ '当其为normal时,以下组间相互押韵:%s;\n' \ '当其为custom时,cluster表示自定义组间押韵,格式与normal的例子相同' % \ ', '.join(map(str, SyllableClusters['normal'])) @staticmethod def run(r): return dict(syllables=Syllables) APP_NAME = '押韵' APP_DESC = '查找和目标押韵(支持二押及以上)的词语' BODY = [ P('py', '拼音').validate(list), PDict(name='phrase', read_name='目标词语长度限制').null().set_fields( P('max', '词语最大长度').null(), P('min', '词语最小长度').null()), PDict(name='rythme', read_name='目标词语押韵限制').null().set_fields( P('max', '词语最长押韵数').null(), P('min', '词语最短押韵数').null()), P('cluster', '押韵拼音组').null(), P('cluster_type', '押韵拼音组模式').default('normal').process(PL.choices(SyllableClusters)), ] SUB_ROUTER = Router() SUB_ROUTER.register_param('cluster', RythmeCluster) @staticmethod @Analyse.r(b=BODY) def run(r): py = r.d.py phrase_limit = r.d.phrase or dict(max=None, min=None) rythme_limit = r.d.rythme or dict(max=None, min=None) cluster = r.d.cluster cluster_type = r.d.cluster_type
class OAuthView(View): @staticmethod @Analyse.r(q=[P('code', '齐天簿授权码')]) def get(r): code = r.d.code body = qt_manager.get_token(code) token = body['token'] qt_user_app_id = body['user_app_id'] user = User.create(qt_user_app_id, token) try: Resource.get_root_folder(user) except E as e: if e.eis(ResourceError.GET_ROOT_FOLDER): root = Resource.get_by_pk(Resource.ROOT_ID) Resource.create_folder(user.qt_user_app_id, user, root, ROOT_DESC) user.update() return Auth.get_login_token(user)
class WechatConfigView(View): @staticmethod @Analyse.r([P('url', '链接')]) def post(request): url = request.d.url return Weixin.get_config(url)
class Verify(View): @staticmethod @Auth.require_login(deny_auth_token=True) def get(r): """ GET /api/user/verify 自动识别身份信息 """ user = r.user if user.verify_status != User.VERIFY_STATUS_UNVERIFIED: if user.verify_status == User.VERIFY_STATUS_UNDER_AUTO or \ user.verify_status == User.VERIFY_STATUS_UNDER_MANUAL: raise IDCardError.VERIFYING('无法继续识别') else: raise IDCardError.REAL_VERIFIED('无法继续识别') urls = user.get_card_urls() if not urls['front'] or not urls['back']: raise IDCardError.CARD_NOT_COMPLETE front_info = IDCard.detect_front(urls['front']) back_info = IDCard.detect_back(urls['back']) back_info.update(front_info) back_info['type'] = 'idcard-verify' back_info['user_id'] = user.user_str_id token, verify_info = JWT.encrypt(back_info, expire_second=60 * 5) verify_info['token'] = token user.update_verify_type(User.VERIFY_CHINA) return verify_info VERIFY_PARAMS = [ UserP.real_name.clone().rename('name'), UserP.birthday.clone().null(), UserP.idcard.clone().null(), UserP.male.clone().null(), ] @staticmethod @Analyse.r([ *VERIFY_PARAMS, P('token', '认证口令').null(), P('auto', '自动认证').default(True).process(bool), ]) @Auth.require_login(deny_auth_token=True) def post(r): """ POST /api/user/verify 确认认证信息 """ user = r.user if user.verify_status != User.VERIFY_STATUS_UNVERIFIED: if user.verify_status == User.VERIFY_STATUS_UNDER_AUTO or \ user.verify_status == User.VERIFY_STATUS_UNDER_MANUAL: raise IDCardError.VERIFYING('无法继续确认') else: raise IDCardError.REAL_VERIFIED('无法继续确认') if r.d.auto: # 自动验证 token = r.d.token dict_ = JWT.decrypt(token) if 'user_id' not in dict_: raise IDCardError.AUTO_VERIFY_FAILED if user.user_str_id != dict_['user_id']: raise IDCardError.AUTO_VERIFY_FAILED crt_time = datetime.datetime.now().timestamp() valid_start = datetime.datetime.strptime(dict_['valid_start'], '%Y-%m-%d').timestamp() valid_end = datetime.datetime.strptime(dict_['valid_end'], '%Y-%m-%d').timestamp() if valid_start > crt_time or crt_time > valid_end: raise IDCardError.CARD_VALID_EXPIRED user.update_card_info( dict_['name'], dict_['male'], dict_['idcard'], datetime.datetime.strptime(dict_['birthday'], '%Y-%m-%d').date(), ) user.update_verify_status(User.VERIFY_STATUS_DONE) else: # 人工验证 for param in Verify.VERIFY_PARAMS: if not getattr(r.d, param.name): return PError.NULL_NOT_ALLOW(param.name, param.read_name) user.update_card_info( **r.d.dict('name', 'birthday', 'idcard', 'male')) user.update_verify_status(User.VERIFY_STATUS_UNDER_MANUAL) Email.real_verify(user, '') return user.d()
class CoverView(View): @staticmethod @Analyse.r(q=[P_RNAME.clone().rename('filename')], a=[P_RES]) @Auth.require_owner def get(r): """ GET /api/res/:res_str_id/cover 获取七牛上传资源封面token """ filename = r.d.filename filename = QnManager.encode_key(filename) res = r.d.res import datetime crt_time = datetime.datetime.now().timestamp() salt = get_random_string(4) key = 'cover/%s/%s/%s' % (salt, crt_time, filename) qn_token, key = qn_res_manager.get_upload_token( key, Policy.cover(res.res_str_id)) return dict(upload_token=qn_token, key=key) @staticmethod @Analyse.r(b=[P('key')], a=[P_RES]) def post(r): """ POST /api/res/:res_str_id/cover 七牛上传资源封面成功后的回调函数 """ qn_res_manager.auth_callback(r) key = r.d.key res = r.d.res # type: Resource res.modify_cover(key, CoverChoice.UPLOAD.value) return res.d() @staticmethod @Analyse.r(b=[P_COVER, P_COVER_TYPE], a=[P_RES]) @Auth.require_owner def put(r): """ PUT /api/res/:res_str_id/cover 修改封面信息 """ cover = r.d.cover cover_type = r.d.cover_type res = r.d.res user = r.user if cover_type == CoverChoice.UPLOAD.value: raise ResourceError.NOT_ALLOWED_COVER_UPLOAD if cover_type == CoverChoice.SELF.value and res.sub_type != StypeChoice.IMAGE.value: raise ResourceError.NOT_ALLOWED_COVER_SELF_OF_NOT_IMAGE if cover_type == CoverChoice.RESOURCE.value: resource_chain = [cover] next_str_id = cover while True: next_res = Resource.get_by_id(next_str_id) if next_res.res_str_id == res.res_str_id: raise ResourceError.RESOURCE_CIRCLE if not next_res.belong(user): raise ResourceError.RESOURCE_NOT_BELONG if next_res.cover_type == CoverChoice.RESOURCE.value: next_str_id = next_res.cover elif next_res.cover_type == CoverChoice.PARENT.value: next_str_id = next_res.parent.res_str_id else: break if next_str_id in resource_chain: raise ResourceError.RESOURCE_CIRCLE resource_chain.append(next_str_id) res.modify_cover(cover, cover_type) return res.d()
""" Adel Liu 180111 用户API处理函数 """ from SmartDjango import Analyse, P from django.views import View from Base.auth import Auth from User.models import User P_QITIAN_USER = P('qt_user_app_id', yield_name='user').process(User.get_by_qtid) class BaseView(View): @staticmethod @Auth.require_login def get(r): """ GET /api/user/ 获取我的信息 """ user = r.user user.update() return user.d() class QitianView(View): @staticmethod @Analyse.r(a=[P_QITIAN_USER])