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
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)
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())
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")
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
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")
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')
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)
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))
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")
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)
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
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
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>"), "<script>var abc</script>", ) # re self.assertEqual(parse_author_mail("staugur"), ("staugur", None)) self.assertEqual(parse_author_mail("staugur <mail>"), ("staugur", "mail"))
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
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())