Example #1
0
def token():
    res = dict(code=1, msg=None)
    usr = g.userinfo.username
    tk = rsp("tokens")
    ak = rsp("account", usr)

    def gen_token(key):
        """生成可以用key校验的token"""
        return b64encode(
            ("%s.%s.%s.%s" %
             (generate_random(), usr, get_current_timestamp(),
              hmac_sha256(key, usr))).encode("utf-8")).decode("utf-8")

    Action = request.args.get("Action")
    if Action == "create":
        if g.rc.hget(ak, "token"):
            res.update(msg="Existing token")
        else:
            tkey = generate_random(randint(6, 12))
            token = gen_token(tkey)
            try:
                pipe = g.rc.pipeline()
                pipe.hset(tk, token, usr)
                pipe.hmset(ak, dict(token=token, token_key=tkey))
                pipe.execute()
            except RedisError:
                res.update(msg="Program data storage service error")
            else:
                res.update(code=0, token=token)
    elif Action == "revoke":
        token = g.rc.hget(ak, "token")
        if token:
            try:
                pipe = g.rc.pipeline()
                pipe.hdel(tk, token)
                pipe.hdel(ak, "token")
                pipe.execute()
            except RedisError:
                res.update(msg="Program data storage service error")
            else:
                res.update(code=0)
        else:
            res.update(msg="No tokens yet")
    elif Action == "reset":
        oldToken = g.rc.hget(ak, "token")
        tkey = generate_random(randint(6, 12))
        token = gen_token(tkey)
        try:
            pipe = g.rc.pipeline()
            if oldToken:
                pipe.hdel(tk, oldToken)
            pipe.hset(tk, token, usr)
            pipe.hmset(ak, dict(token=token, token_key=tkey))
            pipe.execute()
        except RedisError:
            res.update(msg="Program data storage service error")
        else:
            res.update(code=0, token=token)
    return res
Example #2
0
    def test_comment_login_logout(self):
        user = ("test_" + generate_random()).lower()
        pwd = "pwd123"
        rv = self.login(user, pwd)
        self.assertEqual(200, rv.status_code)
        self.assertIn(b"No valid username found", rv.data)

        exec_createuser(user, pwd)
        rv = self.login(user, pwd)
        data = rv.get_json()
        self.assertIsInstance(data, dict)
        self.assertIn("sid", data)
        self.assertIn("code", data)
        self.assertIn("expire", data)
        self.assertEqual(data["code"], 0)
        with self.app.test_request_context():
            self.app.preprocess_request()
            (signin, userinfo) = default_login_auth(data["sid"])
            self.assertTrue(signin)
            self.assertIsInstance(userinfo, dict)
            self.assertEqual(user, userinfo["username"])

        rv = self.client.get("/api/config")
        self.assertEqual(405, rv.status_code)
        rv = self.client.post("/api/config")
        self.assertEqual(403, rv.status_code)

        self.logout()
        rv = self.client.post("/api/config")
        self.assertEqual(404, rv.status_code)
Example #3
0
File: views.py Project: hooops/lps2
def coupon_list_view(request):
    Money = request.REQUEST.get("Money","")
    if Money !="":
        c = Coupon()
        c.surplus = 100
        c.coupon_price = str(Money)
        c.save()
        save_obj = Coupon.objects.order_by('-id')[0]
        for i in range(100):
            cd = Coupon_Details()
            code_sno = generate_random(16,1)
            cd.code_sno = code_sno.upper()
            cd.coupon = save_obj
            cd.use_time = '0000-00-00 00:00:00'
            try:
                cd.save()
            except:
                i = i - 1
        status = '优惠码生成成功!'
        return render(request, 'mz_backend/coupon_list.html', locals())    
    else:
        coupon_list = Coupon.objects.order_by("id")
        paginator = Paginator(coupon_list, 20)
        try:
            current_page = int(request.GET.get('page', '1'))
            coupon_list = paginator.page(current_page)
        except(PageNotAnInteger, ValueError):
            coupon_list = paginator.page(1)
        except EmptyPage:
            coupon_list = paginator.page(paginator.num_pages)
        return render(request, 'mz_backend/coupon_list.html', locals())
Example #4
0
 def gen_token(): return b64encode(
     ("%s.%s.%s.%s" % (
         generate_random(),
         usr,
         get_current_timestamp(),
         hmac_sha256(g.rc.hget(ak, "password"), usr)
     )).encode("utf-8")
 ).decode("utf-8")
 Action = request.args.get("Action")
Example #5
0
def token():
    if request.method == "GET":
        return abort(404)
    res = dict(code=1)
    usr = g.userinfo.username
    tk = rsp("tokens")
    ak = rsp("account", usr)
    #: 生成token
    gen_token = lambda: b64encode(
        ("%s.%s.%s.%s" % (generate_random(), usr, get_current_timestamp(),
                          hmac_sha256(g.rc.hget(ak, "password"), usr))).encode(
                              "utf-8")).decode("utf-8")
    Action = request.args.get("Action")
    if Action == "create":
        if g.rc.hget(ak, "token"):
            res.update(msg="Existing token")
        else:
            token = gen_token()
            try:
                pipe = g.rc.pipeline()
                pipe.hset(tk, token, usr)
                pipe.hset(ak, "token", token)
                pipe.execute()
            except RedisError:
                res.update(msg="Program data storage service error")
            else:
                res.update(code=0, token=token)
    elif Action == "revoke":
        token = g.rc.hget(ak, "token")
        if token:
            try:
                pipe = g.rc.pipeline()
                pipe.hdel(tk, token)
                pipe.hdel(ak, "token")
                pipe.execute()
            except RedisError:
                res.update(msg="Program data storage service error")
            else:
                res.update(code=0)
        else:
            res.update(msg="No tokens yet")
    elif Action == "reset":
        oldToken = g.rc.hget(ak, "token")
        token = gen_token()
        try:
            pipe = g.rc.pipeline()
            if oldToken:
                pipe.hdel(tk, oldToken)
            pipe.hset(tk, token, usr)
            pipe.hset(ak, "token", token)
            pipe.execute()
        except RedisError:
            res.update(msg="Program data storage service error")
        else:
            res.update(code=0, token=token)
    return res
Example #6
0
File: api.py Project: qdjx/picbed
 def gen_token(key):
     """生成可以用key校验的token"""
     return b64encode(
         ("%s.%s.%s.%s" % (
             generate_random(),
             usr,
             get_current_timestamp(),
             hmac_sha256(key, usr)
         )).encode("utf-8")
     ).decode("utf-8")
Example #7
0
File: views.py Project: hooops/lps2
def create_live_room(request):
    if request.method == "POST":
        try:
            # 接受当前的班级号
            coding = request.REQUEST.get("coding",None)
            classobj = Class.objects.get(coding=coding)
            if LiveRoom.objects.filter(live_class=classobj).count() > 0:
                return render(request, 'mz_common/failure.html',{'reason':'该班级已经创建直播室,不能重复创建。'})
            # 创建直播室接口处理地址
            url = settings.LIVE_ROOM_CREATE_API
            values = {
                'loginName':settings.LIVE_ROOM_USERNAME,
                'password':settings.LIVE_ROOM_PASSWORD,
                'sec':'true',
                'subject':classobj.coding,
                'startDate':datetime.now(),
                'scene':1,
                'speakerInfo':classobj.teacher.nick_name+','+classobj.teacher.description,
                'scheduleInfo':classobj.career_course.description,
                'studentToken':generate_random(6,0),
                'description':'这里是'+coding+'班的直播课堂,欢迎加入课堂',
                'realtime':True,
                }
            data = urllib.urlencode(values)
            req = urllib2.Request(url, data)
            response = urllib2.urlopen(req)
            result = json.loads(response.read())
            # 保存直播室相关数据
            if result['code'] == '0':
                live_room = LiveRoom()
                live_room.live_id = result['id']
                live_room.live_code = result['number']
                live_room.assistant_token = result['assistantToken']
                live_room.student_token = result['studentToken']
                live_room.teacher_token = result['teacherToken']
                live_room.student_client_token = result['studentClientToken']
                live_room.student_join_url = result['studentJoinUrl']
                live_room.teacher_join_url = result['teacherJoinUrl']
                live_room.live_class = classobj
                live_room.save()
            else:
                return render(request, 'mz_common/failure.html',{'reason':'直播室创建失败。错误代码:'+str(result['code'])})
        except Class.DoesNotExist:
            return render(request, 'mz_common/failure.html',{'reason':'没有该班级。'})
        except Exception as e:
            logger.error(e)
            return render(request, 'mz_common/failure.html',{'reason':'服务器出错。'})
        return render(request, 'mz_common/success.html',{'reason':'直播室创建成功。'})
    else:
        return render(request, 'mz_backend/live_room_add.html')
Example #8
0
File: views.py Project: hooops/lps2
def do_send_mail(email, ip, type=0):

    '''
    生成邮件发送记录并发送注册激活邮件
    :param request:
    :param email:目标邮箱地址
    :param type:邮件类型(0:注册激活邮件;1:找回密码邮件)
    :return:
    '''

    #查询同IP是否超出最大发送邮件限制
    start = datetime.now() - timedelta(hours=23, minutes=59, seconds=59)
    send_count=EmailVerifyRecord.objects.filter(Q(ip=ip),Q(created__gt = start)).count()
    if send_count > settings.EMAIL_COUNT:
        return
        #生成激活码
    random_str = generate_random(10, 1)
    #邮件发送记录写入数据库
    email_record = EmailVerifyRecord()
    email_record.code = random_str
    email_record.email = email
    email_record.type = type
    email_record.ip = ip
    email_record.save()

    #发送验证邮件
    email_title=email_body=""
    if type == 0:
        email_title = settings.EMAIL_SUBJECT_PREFIX + "注册账号激活邮件"
        email_body = """欢迎使用麦子学院账号激活功能 \r\n
请点击链接激活账号:\r
%(site_url)s/user/active/%(email)s/%(random_str)s \r\n
(该链接在24小时内有效)  \r
如果上面不是链接形式,请将地址复制到您的浏览器(例如IE)的地址栏再访问。 \r
        """ % {'site_url': settings.SITE_URL, 'email': base64.b64encode(email), 'random_str': random_str}
    elif type == 1:
        email_title = settings.EMAIL_SUBJECT_PREFIX + "找回密码邮件"
        email_body = """欢迎使用麦子学院找回密码功能 \r\n
请点击链接重置密码:\r
%(site_url)s/user/password/reset/%(email)s/%(random_str)s \r\n
(该链接在24小时内有效)  \r
如果上面不是链接形式,请将地址复制到您的浏览器(例如IE)的地址栏再访问。 \r
        """ % {'site_url': settings.SITE_URL, 'email': base64.b64encode(email), 'random_str': random_str}

    try:
        return send_mail(email_title, email_body, settings.EMAIL_FROM, [email])
    except Exception,e:
        logger.error(e)
Example #9
0
    def test_admin(self):
        user = "******" + generate_random()
        pwd = "pwd123"
        exec_createuser(user, pwd, is_admin=1)
        rv = self.login(user, pwd)
        self.assertIn(b"sid", rv.data)

        rv = self.client.post("/api/config", data=dict(hello='world'))
        self.assertEqual(200, rv.status_code)
        site = get_site_config()
        self.assertIn("hello", site)
        self.assertEqual(site["hello"], "world")

        hm = self.app.extensions["hookmanager"]
        self.client.post("/api/hook?Action=disable",
                         data=dict(name='up2local'))
        self.assertEqual(2, len(hm.get_enabled_hooks))
        self.client.post("/api/hook?Action=enable", data=dict(name='up2local'))
        self.assertEqual(3, len(hm.get_enabled_hooks))
Example #10
0
File: views.py Project: hooops/lps2
def acauser_import(request):
    try:

        # 上传excel文件
        files = request.FILES.get("Filedata",None)
        file_name=str(uuid.uuid1())+"."+str(files.name.split(".")[-1])
        path_file=os.path.join(settings.MEDIA_ROOT, 'temp', file_name)
        open(path_file, 'wb').write(files.file.read())

        # 写入excel文件内容到数据库
        data = xlrd.open_workbook(path_file)
        table = data.sheets()[0]
        for i in range(table.nrows):
            if i == 0: continue
            table_row = table.row_values(i)
            # 0 姓名 1 学号 2 大学 3 学院 4 专业
            # 获取大学对象
            university = AcademicOrg.objects.get(name=table_row[2].strip(), level=1, parent=None)
            # 获取学院对象
            college = AcademicOrg.objects.get(name=table_row[3].strip(), level=2, parent=university)
            # 获取专业对象
            academic_course = AcademicCourse.objects.get(name=table_row[4].strip(), owner=college)
            # 增加高校用户对象
            academic_user = AcademicUser()
            academic_user.user_no = int(table_row[1])
            academic_user.stu_name = table_row[0].strip()
            academic_user.academic_course = academic_course
            academic_user.owner_college = college
            academic_user.owner_university = university
            # 唯一标识码
            academic_user.verify_code = generate_random(8, 1)
            academic_user.save()
        transaction.commit()
    except Exception as e:
        logger.error(e)
        transaction.rollback()
        return HttpResponse("failure", content_type="text/plain")
    return HttpResponse("success", content_type="text/plain")
Example #11
0
File: views.py Project: hooops/lps2
def do_send_sms(mobile, ip, type=0):
    '''
    生成短信发送记录并发送手机验证码
    :param request:
    :param mobile:
    :return:
    '''

    #查询同IP是否超出最大短信数量发送限制
    start = datetime.now() - timedelta(hours=23, minutes=59, seconds=59)
    send_count=MobileVerifyRecord.objects.filter(Q(ip=ip),Q(created__gt = start)).count()
    if send_count > settings.SMS_COUNT:
        return '{"status":"failure","mobile": "该IP超过当日短信发送限制数量"}'
    #生成激活码
    random_str = generate_random(6, 0)
    #邮件发送记录写入数据库
    mobile_record = MobileVerifyRecord()
    mobile_record.code = random_str
    mobile_record.mobile = mobile
    mobile_record.type = type
    mobile_record.ip = ip
    mobile_record.save()

    #发送短信
    apikey = settings.SMS_APIKEY
    tpl_id = settings.SMS_TPL_ID  #短信模板ID
    tpl_value = '#code#=%(code)s&#company#=%(company)s' % {'code': random_str, 'company':settings.SMS_COMPANY}
    try:
        result=json.loads(tpl_send_sms(apikey, tpl_id, tpl_value, mobile))
        if(result['code'] == 0):
            result='{"status":"success"}'
        else:
            result='{"status":"failure"}'
        return result
    except Exception,e:
        logger.error(e)
Example #12
0
def upload():
    """上传逻辑:
    0. 判断是否登录,如果未登录则判断是否允许匿名上传
    1. 获取上传的文件,判断允许格式
    2. 生成文件名、唯一sha值、上传目录等,选择图片存储的后端钩子(单一)
        - 存储图片的钩子目前版本仅一个,默认是up2local(如果禁用则保存失败)
    3. 解析钩子数据,钩子回调数据格式:{code=?, sender=hook_name, src=?}
        - 后端保存失败或无后端的情况都要立刻返回响应
    4. 此时保存图片成功,持久化存储到全局索引、用户索引
    5. 返回响应:{code:0, data={src=?, sender=success_saved_hook_name}}
    """
    res = dict(code=1, msg=None)
    #: 匿名上传开关检测
    if not is_true(g.cfg.anonymous) and not g.signin:
        res.update(code=403, msg="Anonymous user is not sign in")
        return res
    f = request.files.get('picbed')
    #: 实时获取后台配置中允许上传的后缀,如: jpg|jpeg|png
    allowed_suffix = partial(allowed_file,
                             suffix=parse_valid_verticaline(g.cfg.upload_exts))
    if f and allowed_suffix(f.filename):
        try:
            g.rc.ping()
        except RedisError as e:
            logger.error(e, exc_info=True)
            res.update(code=2, msg="Program data storage service error")
            return res
        stream = f.stream.read()
        suffix = splitext(f.filename)[-1]
        filename = secure_filename(f.filename)
        if "." not in filename:
            filename = "%s%s" % (generate_random(8), suffix)
        #: 根据文件名规则重定义图片名
        upload_file_rule = g.cfg.upload_file_rule
        if upload_file_rule in ("time1", "time2", "time3"):
            filename = "%s%s" % (gen_rnd_filename(upload_file_rule), suffix)
        #: 上传文件位置前缀规则
        upload_path_rule = g.cfg.upload_path_rule
        if upload_path_rule == 'date1':
            upload_path = get_today("%Y/%m/%d")
        elif upload_path_rule == 'date2':
            upload_path = get_today("%Y%m%d")
        else:
            upload_path = ''
        upload_path = join(g.userinfo.username or 'anonymous', upload_path)
        #: 定义文件名唯一索引
        sha = "sha1.%s.%s" % (get_current_timestamp(True), sha1(filename))
        #: 定义保存图片时仅使用某些钩子,如: up2local
        #: TODO 目前版本仅允许设置了一个,后续考虑聚合
        includes = parse_valid_comma(g.cfg.upload_includes or 'up2local')
        if len(includes) > 1:
            includes = [choice(includes)]
        #: TODO 定义保存图片时排除某些钩子,如: up2local, up2other
        # excludes = parse_valid_comma(g.cfg.upload_excludes or '')
        #: 钩子返回结果(目前版本最终结果中应该最多只有1条数据)
        data = []

        #: 保存图片的钩子回调
        def callback(result):
            logger.info(result)
            if result["sender"] == "up2local":
                result["src"] = url_for("static",
                                        filename=join(UPLOAD_FOLDER,
                                                      upload_path, filename),
                                        _external=True)
            data.append(dfr(result))

        #: 调用钩子中upimg_save方法
        current_app.extensions["hookmanager"].call(
            _funcname="upimg_save",
            _callback=callback,
            _include=includes,
            filename=filename,
            stream=stream,
            upload_path=upload_path,
            local_basedir=join(current_app.root_path,
                               current_app.static_folder, UPLOAD_FOLDER))
        #: 判定后端存储全部失败时,上传失败
        if not data:
            res.update(code=1, msg="No valid backend storage service")
            return res
        if len(data) == len([i for i in data if i.get("code") != 0]):
            res.update(
                code=1,
                msg="All backend storage services failed to save pictures")
            return res
        #: 存储数据
        defaultSrc = data[0]["src"]
        pipe = g.rc.pipeline()
        pipe.sadd(rsp("index", "global"), sha)
        if g.signin and g.userinfo.username:
            pipe.sadd(rsp("index", "user", g.userinfo.username), sha)
        pipe.hmset(
            rsp("image", sha),
            dict(
                sha=sha,
                filename=filename,
                upload_path=upload_path,
                user=g.userinfo.username if g.signin else 'anonymous',
                ctime=get_current_timestamp(),
                status='enabled',  # disabled, deleted
                src=defaultSrc,
                sender=data[0]["sender"],
                senders=json.dumps(data)))
        try:
            pipe.execute()
        except RedisError as e:
            logger.error(e, exc_info=True)
            res.update(code=3, msg="Program data storage service error")
        else:
            res.update(
                code=0,
                filename=filename,
                sender=data[0]["sender"],
                api=url_for("api.shamgr", sha=sha, _external=True),
            )
            #: format指定图片地址的显示字段,默认src,可以用点号指定
            #: 比如data.src,那么返回格式{code, filename..., data:{src}, ...}
            fmt = request.form.get("format", request.args.get("format"))
            res.update(format_upload_src(fmt, defaultSrc))
    else:
        res.update(msg="No file or image format allowed")
    return res
Example #13
0
def upload():
    """上传逻辑:
    0. 判断是否登录,如果未登录则判断是否允许匿名上传
    1. 获取上传的文件,判断允许格式
        - 拦截下判断文件,如果为空,尝试获取body中提交的picbed
        - 如果picbed是合法base64,那么会返回Base64FileStorage类;
          如果picbed是合法url[图片],那么服务端会自动下载,返回ImgUrlFileStorage类;
          否则为空。
          PS: 允许DATA URI形式, eg: data:image/png;base64,the base64 of image
    2. 生成文件名、唯一sha值、上传目录等,选择图片存储的后端钩子(单一)
        - 存储图片的钩子目前版本仅一个,默认是up2local(如果禁用则保存失败)
        - 如果提交album参数会自动创建相册,否则归档到默认相册
    3. 解析钩子数据,钩子回调数据格式:{code=?, sender=hook_name, src=?}
        - 后端保存失败或无后端的情况都要立刻返回响应
    4. 此时保存图片成功,持久化存储到全局索引、用户索引
    5. 返回响应:{code:0, data={src=?, sender=success_saved_hook_name}}
        - 允许使用一些参数调整响应数据、格式
    """
    res = dict(code=1, msg=None)
    #: 文件域或base64上传字段
    FIELD_NAME = g.cfg.upload_field or "picbed"
    #: 匿名上传开关检测
    if not is_true(g.cfg.anonymous) and not g.signin:
        res.update(code=403, msg="Anonymous user is not sign in")
        return res
    #: 相册名称,可以是任意字符串
    album = (request.form.get("album")
             or getattr(g, "up_album", "")) if g.signin else 'anonymous'
    #: 实时获取后台配置中允许上传的后缀,如: jpg|jpeg|png
    allowed_suffix = partial(allowed_file,
                             suffix=parse_valid_verticaline(g.cfg.upload_exts))
    #: 尝试读取上传数据
    fp = request.files.get(FIELD_NAME)
    #: 当fp无效时尝试读取base64或url
    if not fp:
        picstrurl = request.form.get(FIELD_NAME)
        filename = request.form.get("filename")
        if picstrurl:
            if picstrurl.startswith("http://") or \
                    picstrurl.startswith("https://"):
                fp = ImgUrlFileStorage(picstrurl, filename).getObj
            else:
                try:
                    #: base64在部分场景发起http请求时,+可能会换成空格导致异常
                    fp = Base64FileStorage(picstrurl, filename)
                except ValueError as e:
                    logger.debug(e)
    if fp and allowed_suffix(fp.filename):
        try:
            g.rc.ping()
        except RedisError as e:
            logger.error(e, exc_info=True)
            res.update(code=2, msg="Program data storage service error")
            return res
        stream = fp.stream.read()
        suffix = splitext(fp.filename)[-1]
        filename = secure_filename(fp.filename)
        if "." not in filename:
            filename = "%s%s" % (generate_random(8), suffix)
        #: 根据文件名规则重定义图片名
        upload_file_rule = (
            g.userinfo.ucfg_upload_file_rule
            or g.cfg.upload_file_rule) if is_true(
                g.cfg.upload_rule_overridden) else g.cfg.upload_file_rule
        if upload_file_rule in ("time1", "time2", "time3"):
            filename = "%s%s" % (gen_rnd_filename(upload_file_rule), suffix)
        #: 上传文件位置前缀规则
        upload_path_rule = (
            g.userinfo.ucfg_upload_path_rule
            or g.cfg.upload_path_rule) if is_true(
                g.cfg.upload_rule_overridden) else g.cfg.upload_path_rule
        if upload_path_rule == 'date1':
            upload_path = get_today("%Y/%m/%d")
        elif upload_path_rule == 'date2':
            upload_path = get_today("%Y%m%d")
        else:
            upload_path = ''
        upload_path = join(g.userinfo.username or 'anonymous', upload_path)
        #: 定义文件名唯一索引
        sha = "sha1.%s.%s" % (get_current_timestamp(True), sha1(filename))
        #: 定义保存图片时仅使用某些钩子,如: up2local
        #: TODO 目前版本仅允许设置了一个,后续聚合
        includes = parse_valid_comma(g.cfg.upload_includes or 'up2local')
        if len(includes) > 1:
            includes = [choice(includes)]
        #: TODO 定义保存图片时排除某些钩子,如: up2local, up2other
        # excludes = parse_valid_comma(g.cfg.upload_excludes or '')
        #: 钩子返回结果(目前版本最终结果中应该最多只有1条数据)
        data = []

        #: 保存图片的钩子回调

        def callback(result):
            logger.info(result)
            if result["sender"] == "up2local":
                result["src"] = url_for("static",
                                        filename=join(UPLOAD_FOLDER,
                                                      upload_path, filename),
                                        _external=True)
            data.append(dfr(result))

        #: 调用钩子中upimg_save方法
        current_app.extensions["hookmanager"].call(
            _funcname="upimg_save",
            _callback=callback,
            _include=includes,
            filename=filename,
            stream=stream,
            upload_path=upload_path,
            local_basedir=join(current_app.root_path,
                               current_app.static_folder, UPLOAD_FOLDER))
        #: 判定后端存储全部失败时,上传失败
        if not data:
            res.update(code=1, msg="No valid backend storage service")
            return res
        if len(data) == len([i for i in data if i.get("code") != 0]):
            res.update(
                code=1,
                msg="All backend storage services failed to save pictures",
                errors={
                    i["sender"]: i["msg"]
                    for i in data if i.get("code") != 0
                },
            )
            return res
        #: 存储数据
        defaultSrc = data[0]["src"]
        pipe = g.rc.pipeline()
        pipe.sadd(rsp("index", "global"), sha)
        if g.signin and g.userinfo.username:
            pipe.sadd(rsp("index", "user", g.userinfo.username), sha)
        pipe.hmset(
            rsp("image", sha),
            dict(
                sha=sha,
                album=album,
                filename=filename,
                upload_path=upload_path,
                user=g.userinfo.username if g.signin else 'anonymous',
                ctime=get_current_timestamp(),
                status='enabled',  # disabled, deleted
                src=defaultSrc,
                sender=data[0]["sender"],
                senders=json.dumps(data),
                agent=request.form.get("origin",
                                       request.headers.get('User-Agent', '')),
                method=getUploadMethod(fp.__class__.__name__),
            ))
        try:
            pipe.execute()
        except RedisError as e:
            logger.error(e, exc_info=True)
            res.update(code=3, msg="Program data storage service error")
        else:
            res.update(
                code=0,
                filename=filename,
                sender=data[0]["sender"],
                api=url_for("api.shamgr", sha=sha, _external=True),
            )
            #: format指定图片地址的显示字段,默认src,可以用点号指定
            #: 比如data.src,那么返回格式{code, filename..., data:{src}, ...}
            #: 比如imgUrl,那么返回格式{code, filename..., imgUrl(=src), ...}
            fmt = request.form.get("format", request.args.get("format"))
            res.update(format_upload_src(fmt, defaultSrc))
    else:
        res.update(msg="No file or image format error")
    return res
Example #14
0
 def test_utils(self):
     self.assertEqual("900150983cd24fb0d6963f7d28e17f72", md5("abc"))
     self.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d",
                      sha1("abc"))
     self.assertEqual("picbed:a:b", rsp("a", "b"))
     self.assertEqual(parse_valid_comma("a,b, c,"), ["a", "b", "c"])
     self.assertEqual(parse_valid_verticaline("a|b| c"), ["a", "b", "c"])
     self.assertTrue(is_true(1))
     self.assertTrue(is_true("on"))
     self.assertTrue(is_true("true"))
     self.assertFalse(is_true(0))
     self.assertIsInstance(get_current_timestamp(), int)
     self.assertTrue(allowed_file("test.PNG"))
     self.assertTrue(allowed_file(".jpeg"))
     self.assertFalse(allowed_file("my.psd"))
     self.assertFalse(allowed_file("ha.gif", ["jpg"]))
     self.assertFalse(allowed_file("ha.jpeg", ["jpg"]))
     self.assertFalse(allowed_file("ha.png", ["jpg"]))
     self.assertTrue(allowed_file("ha.jpg", ["jpg"]))
     v = "6afa9046a9579cad143a384c1b564b9a250d27d6f6a63f9f20bf3a7594c9e2c6"
     self.assertEqual(v, hmac_sha256("key", "text"))
     self.assertEqual(v, hmac_sha256(b"key", b"text"))
     self.assertEqual(v, hmac_sha256(u"key", u"text"))
     self.assertEqual(
         "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
         sha256("abc"),
     )
     #: test format_upload_src
     baseimg = "img-url"
     basefmt = {"src": baseimg}
     self.assertEqual(format_upload_src(123, baseimg), basefmt)
     self.assertEqual(format_upload_src(None, baseimg), basefmt)
     self.assertEqual(format_upload_src([0], baseimg), basefmt)
     self.assertEqual(format_upload_src("", baseimg), basefmt)
     self.assertEqual(format_upload_src(".", baseimg), basefmt)
     self.assertEqual(format_upload_src(".1", baseimg), basefmt)
     self.assertEqual(format_upload_src("1.", baseimg), basefmt)
     self.assertEqual(format_upload_src(1.1, baseimg), basefmt)
     self.assertEqual(format_upload_src("1.1", baseimg),
                      {"1": {
                          "1": baseimg
                      }})
     self.assertEqual(format_upload_src("u", baseimg), basefmt)
     self.assertEqual(format_upload_src("im", baseimg), {"im": baseimg})
     self.assertEqual(format_upload_src("url", baseimg), {"url": baseimg})
     self.assertEqual(format_upload_src("i.am.src", baseimg), basefmt)
     self.assertEqual(format_upload_src("src.url", baseimg),
                      {"src": {
                          "url": baseimg
                      }})
     #: test format_apires
     self.assertEqual(format_apires({"code": 0}, "success", "bool"),
                      {"success": True})
     self.assertEqual(format_apires({"code": 0}, oc="200"), {"code": 200})
     self.assertEqual(format_apires({"code": -1}, "status", "bool"),
                      {"status": False})
     self.assertEqual(
         format_apires(dict(code=-1, msg="xxx"), "errno", "200"),
         {
             "errno": -1,
             "msg": "xxx"
         },
     )
     self.assertEqual(
         format_apires(dict(code=-1, msg="xxx"), "errno", "200", "errmsg"),
         {
             "errno": -1,
             "errmsg": "xxx"
         },
     )
     self.assertEqual(
         format_apires(dict(code=0, msg="xxx"), "", "200", "errmsg"),
         {
             "code": 200,
             "errmsg": "xxx"
         },
     )
     self.assertEqual(len(generate_random()), 6)
     self.assertIn("Mozilla/5.0", gen_ua())
     # bleach
     self.assertEqual(bleach_html("<i>abc</i>"), "<i>abc</i>")
     self.assertEqual(
         bleach_html("<script>var abc</script>"),
         "&lt;script&gt;var abc&lt;/script&gt;",
     )
     # re
     self.assertEqual(parse_author_mail("staugur"), ("staugur", None))
     self.assertEqual(parse_author_mail("staugur <mail>"),
                      ("staugur", "mail"))
Example #15
0
def upload():
    #: 视频上传接口,上传流程:
    #: 1. 必须登录,通过固定的picbed字段获取上传内容
    #: 2. 生成sha,文件名规则是年月日时分秒原名,上传到用户目录下
    #: 3. 保存到后端,存储数据返回响应
    res = dict(code=1, msg=None)
    if not g.signin:
        res.update(code=403, msg="Anonymous user is not sign in")
        return res
    if g.userinfo.status != 1:
        msg = ("Pending review, cannot upload pictures" if g.userinfo.status
               in (-2, -1) else "The user is disabled, no operation")
        res.update(code=403, msg=msg)
        return res
    allowed_suffix = partial(allowed_file,
                             suffix=("mp4", "ogg", "ogv", "webm", "3gp",
                                     "mov"))
    fp = request.files.get("picbed")
    title = request.form.get("title") or ""
    if not fp or not allowed_suffix(fp.filename):
        res.update(msg="No file or image format error")
        return res
    suffix = splitext(fp.filename)[-1]
    filename = secure_filename(fp.filename)
    if "." not in filename:
        filename = "%s%s" % (generate_random(8), suffix)
    stream = fp.stream.read()
    upload_path = join(g.userinfo.username, get_today("%Y/%m/%d"))
    sha = "sha256.%s.%s" % (get_current_timestamp(True), sha256(filename))
    includes = parse_valid_comma(g.cfg.upload_includes or 'up2local')
    if len(includes) > 1:
        includes = [choice(includes)]
    data = current_app.extensions["hookmanager"].call(
        _funcname="upimg_save",
        _include=includes,
        _kwargs=dict(filename=filename,
                     stream=stream,
                     upload_path=upload_path,
                     local_basedir=join(current_app.root_path,
                                        current_app.static_folder,
                                        UPLOAD_FOLDER)))
    for i, result in enumerate(data):
        if result["sender"] == "up2local":
            data.pop(i)
            result["src"] = url_for("static",
                                    filename=join(UPLOAD_FOLDER, upload_path,
                                                  filename),
                                    _external=True)
            data.insert(i, result)
    #: 判定后端存储全部失败时,上传失败
    if not data:
        res.update(code=1, msg="No valid backend storage service")
        return res
    if is_all_fail(data):
        res.update(
            code=1,
            msg="All backend storage services failed to save pictures",
        )
        return res
    #: 存储数据
    defaultSrc = data[0]["src"]
    pipe = g.rc.pipeline()
    pipe.sadd(rsp("index", "video", g.userinfo.username), sha)
    pipe.hmset(
        rsp("video", sha),
        dict(
            sha=sha,
            user=g.userinfo.username,
            title=title,
            filename=filename,
            upload_path=upload_path,
            ctime=get_current_timestamp(),
            src=defaultSrc,
            sender=data[0]["sender"],
            senders=json.dumps(data),
        ))
    try:
        pipe.execute()
    except RedisError:
        res.update(code=3, msg="Program data storage service error")
    else:
        res.update(
            code=0,
            sender=data[0]["sender"],
            src=defaultSrc,
        )
    return res
Example #16
0
 def test_utils(self):
     self.assertEqual("900150983cd24fb0d6963f7d28e17f72", md5("abc"))
     self.assertEqual(
         "a9993e364706816aba3e25717850c26c9cd0d89d", sha1("abc")
     )
     self.assertEqual("picbed:a:b", rsp("a", "b"))
     self.assertEqual(parse_valid_comma("a,b, c,"), ["a", "b", "c"])
     self.assertEqual(parse_valid_verticaline("a|b| c"), ["a", "b", "c"])
     self.assertTrue(is_true(1))
     self.assertTrue(is_true("on"))
     self.assertTrue(is_true("true"))
     self.assertFalse(is_true(0))
     self.assertIsInstance(get_current_timestamp(), int)
     self.assertTrue(allowed_file("test.PNG"))
     self.assertTrue(allowed_file(".jpeg"))
     self.assertFalse(allowed_file("my.psd"))
     self.assertFalse(allowed_file("ha.gif", ["jpg"]))
     self.assertFalse(allowed_file("ha.jpeg", ["jpg"]))
     self.assertFalse(allowed_file("ha.png", ["jpg"]))
     self.assertTrue(allowed_file("ha.jpg", ["jpg"]))
     v = "6afa9046a9579cad143a384c1b564b9a250d27d6f6a63f9f20bf3a7594c9e2c6"
     self.assertEqual(v, hmac_sha256('key', 'text'))
     self.assertEqual(v, hmac_sha256(b'key', b'text'))
     self.assertEqual(v, hmac_sha256(u'key', u'text'))
     self.assertEqual(
         "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
         sha256("abc")
     )
     #: test format_upload_src
     baseimg = 'img-url'
     basefmt = {'src': baseimg}
     self.assertEqual(format_upload_src(123, baseimg), basefmt)
     self.assertEqual(format_upload_src(None, baseimg), basefmt)
     self.assertEqual(format_upload_src([0], baseimg), basefmt)
     self.assertEqual(format_upload_src('', baseimg), basefmt)
     self.assertEqual(format_upload_src('.', baseimg), basefmt)
     self.assertEqual(format_upload_src('.1', baseimg), basefmt)
     self.assertEqual(format_upload_src('1.', baseimg), basefmt)
     self.assertEqual(format_upload_src(1.1, baseimg), basefmt)
     self.assertEqual(
         format_upload_src('1.1', baseimg), {'1': {'1': baseimg}}
     )
     self.assertEqual(format_upload_src('u', baseimg), basefmt)
     self.assertEqual(format_upload_src('im', baseimg), {'im': baseimg})
     self.assertEqual(format_upload_src('url', baseimg), {'url': baseimg})
     self.assertEqual(format_upload_src('i.am.src', baseimg), basefmt)
     self.assertEqual(
         format_upload_src('src.url', baseimg), {'src': {'url': baseimg}}
     )
     #: test format_apires
     self.assertEqual(
         format_apires({'code': 0}, "success", "bool"), {'success': True}
     )
     self.assertEqual(
         format_apires({'code': 0}, oc="200"), {'code': 200}
     )
     self.assertEqual(
         format_apires({'code': -1}, "status", "bool"), {'status': False}
     )
     self.assertEqual(
         format_apires(dict(code=-1, msg='xxx'), 'errno', '200'),
         {'errno': -1, 'msg': 'xxx'}
     )
     self.assertEqual(
         format_apires(dict(code=-1, msg='xxx'), 'errno', '200', 'errmsg'),
         {'errno': -1, 'errmsg': 'xxx'}
     )
     self.assertEqual(
         format_apires(dict(code=0, msg='xxx'), '', '200', 'errmsg'),
         {'code': 200, 'errmsg': 'xxx'}
     )
     self.assertEqual(len(generate_random()), 6)
     self.assertIn("Mozilla/5.0", gen_ua())