Exemple #1
0
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)
Exemple #2
0
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()
Exemple #3
0
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)
Exemple #4
0
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)
Exemple #5
0
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)
Exemple #6
0
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)
Exemple #7
0
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)
Exemple #8
0
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_
Exemple #9
0
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()
Exemple #10
0
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)
Exemple #11
0
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()
Exemple #12
0
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))
Exemple #13
0
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)
Exemple #14
0
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))
Exemple #15
0
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']
Exemple #16
0
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()
Exemple #17
0
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
Exemple #18
0
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)
Exemple #19
0
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)
Exemple #20
0
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()
Exemple #21
0
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('用户手机号'))
Exemple #22
0
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()
Exemple #23
0
 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_
Exemple #24
0
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()
Exemple #25
0
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
Exemple #26
0
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)
Exemple #27
0
class WechatConfigView(View):
    @staticmethod
    @Analyse.r([P('url', '链接')])
    def post(request):
        url = request.d.url
        return Weixin.get_config(url)
Exemple #28
0
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()
Exemple #29
0
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()
Exemple #30
0
""" 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])