def handle(self, *args, **options): try: admin = User.objects.get(username="******") if admin.admin_type == SUPER_ADMIN: self.stdout.write(self.style.WARNING("Super admin user 'root' already exists, " "would you like to reset it's password?\n" "Input yes to confirm: ")) if raw_input() == "yes": rand_password = rand_str(length=6) admin.set_password(rand_password) admin.save() self.stdout.write(self.style.SUCCESS("Successfully created super admin user password.\n" "Username: root\nPassword: %s\n" "Remember to change password and turn on two factors auth " "after installation." % rand_password)) else: self.stdout.write(self.style.SUCCESS("Nothing happened")) else: self.stdout.write(self.style.ERROR("User 'root' is not super admin.")) except User.DoesNotExist: user = User.objects.create(username="******", real_name="root", email="*****@*****.**", admin_type=SUPER_ADMIN) rand_password = rand_str(length=6) user.set_password(rand_password) user.save() UserProfile.objects.create(user=user) self.stdout.write(self.style.SUCCESS("Successfully created super admin user.\n" "Username: root\nPassword: %s\n" "Remember to change password and turn on two factors auth " "after installation." % rand_password))
def put(self, request): """ Edit user api """ data = request.data try: user = User.objects.get(id=data["id"]) except User.DoesNotExist: return self.error("User does not exist") if User.objects.filter(username=data["username"]).exclude( id=user.id).exists(): return self.error("Username already exists") if User.objects.filter(email=data["email"].lower()).exclude( id=user.id).exists(): return self.error("Email already exists") pre_username = user.username user.username = data["username"] user.email = data["email"] user.admin_type = data["admin_type"] user.is_disabled = data["is_disabled"] user.is_vip = data["is_vip"] if data["admin_type"] == AdminType.ADMIN: user.problem_permission = data["problem_permission"] elif data["admin_type"] == AdminType.SUPER_ADMIN: user.problem_permission = ProblemPermission.ALL else: user.problem_permission = ProblemPermission.NONE if data["password"]: user.set_password(data["password"]) if data["open_api"]: # Avoid reset user appkey after saving changes if not user.open_api: user.open_api_appkey = rand_str() else: user.open_api_appkey = None user.open_api = data["open_api"] if data["two_factor_auth"]: # Avoid reset user tfa_token after saving changes if not user.two_factor_auth: user.tfa_token = rand_str() else: user.tfa_token = None user.two_factor_auth = data["two_factor_auth"] user.save() if pre_username != user.username: Submission.objects.filter(username=pre_username).update( username=user.username) UserProfile.objects.filter(user=user).update( real_name=data["real_name"]) return self.success(UserAdminSerializer(user).data)
def put(self, request): """ Edit user api """ data = request.data try: user = User.objects.get(id=data["id"]) except User.DoesNotExist: return self.error("User does not exist") if User.objects.filter(username=data["username"].lower()).exclude(id=user.id).exists(): return self.error("Username already exists") if User.objects.filter(email=data["email"].lower()).exclude(id=user.id).exists(): return self.error("Email already exists") pre_username = user.username user.username = data["username"].lower() user.email = data["email"].lower() user.admin_type = data["admin_type"] user.is_disabled = data["is_disabled"] if data["admin_type"] == AdminType.ADMIN: user.problem_permission = data["problem_permission"] elif data["admin_type"] == AdminType.SUPER_ADMIN: user.problem_permission = ProblemPermission.ALL else: user.problem_permission = ProblemPermission.NONE if data["password"]: user.set_password(data["password"]) if data["open_api"]: # Avoid reset user appkey after saving changes if not user.open_api: user.open_api_appkey = rand_str() else: user.open_api_appkey = None user.open_api = data["open_api"] if data["two_factor_auth"]: # Avoid reset user tfa_token after saving changes if not user.two_factor_auth: user.tfa_token = rand_str() else: user.tfa_token = None user.two_factor_auth = data["two_factor_auth"] user.save() if pre_username != user.username: Submission.objects.filter(username=pre_username).update(username=user.username) UserProfile.objects.filter(user=user).update(real_name=data["real_name"]) return self.success(UserAdminSerializer(user).data)
def put(self, request): """ 用户编辑json api接口 --- request_serializer: EditUserSerializer response_serializer: UserSerializer """ serializer = EditUserSerializer(data=request.data) if serializer.is_valid(): data = serializer.data try: user = User.objects.get(id=data["id"]) except User.DoesNotExist: return error_response(u"该用户不存在!") try: user = User.objects.get(username=data["username"]) if user.id != data["id"]: return error_response(u"昵称已经存在") except User.DoesNotExist: pass user.username = data["username"] user.real_name = data["real_name"] user.email = data["email"] user.admin_type = data["admin_type"] if data["password"]: user.set_password(data["password"]) # 后台控制用户是否可以使用openapi if data["openapi"] is False: user.openapi_appkey = None elif data["openapi"] and user.openapi_appkey is None: user.openapi_appkey = rand_str() # 后台控制用户是否使用两步验证 # 注意:用户没开启,后台开启的话,用户没有绑定过两步验证token,会造成无法登陆的! if data["tfa_auth"] is False: user.two_factor_auth = False elif data["tfa_auth"] and user.two_factor_auth is False: user.two_factor_auth = True user.tfa_token = rand_str() # 后台控制用户是否被禁用 user.is_forbidden = data["is_forbidden"] user.save() return success_response(UserSerializer(user).data) else: return serializer_invalid_response(serializer)
def post(self, request): """ 提交请求重置密码 --- request_serializer: ApplyResetPasswordSerializer """ serializer = ApplyResetPasswordSerializer(data=request.data) if serializer.is_valid(): data = serializer.data captcha = Captcha(request) if not captcha.check(data["captcha"]): return error_response(u"验证码错误") try: user = User.objects.get(username=data["username"], email=data["email"]) except User.DoesNotExist: return error_response(u"用户不存在") if user.reset_password_token_create_time and (now() - user.reset_password_token_create_time).total_seconds() < 20 * 60: return error_response(u"20分钟内只能找回一次密码") user.reset_password_token = rand_str() user.reset_password_token_create_time = now() user.save() email_template = codecs.open(settings.TEMPLATES[0]["DIRS"][0] + "utils/reset_password_email.html", "r", "utf-8").read() email_template = email_template.replace("{{ username }}", user.username).\ replace("{{ website_name }}", settings.WEBSITE_INFO["website_name"]).\ replace("{{ link }}", request.scheme + "://" + request.META['HTTP_HOST'] + "/reset_password/?token=" + user.reset_password_token) send_email(settings.WEBSITE_INFO["website_name"], user.email, user.username, settings.WEBSITE_INFO["website_name"] + u" 密码找回邮件", email_template) return success_response(u"邮件发送成功") else: return serializer_invalid_response(serializer)
def post(self, request): if "image" not in request.FILES: return Response(data={ "success": False, "msg": "上传失败", "file_path": "/" }) img = request.FILES["image"] image_name = rand_str() + '.' + str( request.FILES["image"].name.split('.')[-1]) image_dir = settings.IMAGE_UPLOAD_DIR + image_name try: with open(image_dir, "wb") as imageFile: for chunk in img: imageFile.write(chunk) except IOError as e: logger.error(e) return Response( data={ "success": True, "msg": "上传错误", "file_path": "/static/upload/" + image_name }) return Response( data={ "success": True, "msg": "", "file_path": "/static/upload/" + image_name })
def post(self, request): form = UploadProblemForm(request.POST, request.FILES) if form.is_valid(): file = form.cleaned_data["file"] with tempfile.NamedTemporaryFile("wb") as tf: for chunk in file.chunks(4096): tf.file.write(chunk) problems = FPSParser(tf.name).parse() else: return self.error("Parse upload file error") helper = FPSHelper() with transaction.atomic(): for _problem in problems: test_case_id = rand_str() test_case_dir = os.path.join(settings.TEST_CASE_DIR, test_case_id) os.mkdir(test_case_dir) helper.save_test_case(_problem, test_case_dir) problem_data = helper.save_image(_problem, settings.UPLOAD_DIR, settings.UPLOAD_PREFIX) s = FPSProblemSerializer(data=problem_data) if not s.is_valid(): return self.error(f"Parse FPS file error: {s.errors}") problem_data = s.data problem_data["test_case_id"] = test_case_id self._create_problem(problem_data, request.user) return self.success({"import_count": len(problems)})
def handle(self, *args, **options): file_path = options['file_path'] if os.path.exists(settings.IMPORT_TEMP_FILE_PATH) is not True: os.mkdir(settings.IMPORT_TEMP_FILE_PATH) subprocess.check_call( ['unzip', file_path, '-d', settings.IMPORT_TEMP_FILE_PATH]) if validate_dir( os.path.join(settings.IMPORT_TEMP_FILE_PATH, 'style_image')): path = os.path.join(settings.IMPORT_TEMP_FILE_PATH, 'style_image') for name in os.listdir(path): if not name.split('.')[1] in ['.jpg', '.png', '.jpeg']: continue name = name.split('.')[0] now_name = rand_str() + '.png' image_path = os.path.join(settings.STYLE_IMAGE_PATH, now_name) with open(os.path.join(path, name), 'r') as upload_f: with open(image_path, 'wb+') as now_f: now_f.write(upload_f) StyleImage.obejects.create(upload_name=name, image_path=image_path) remove_temp_dir(settings.IMPORT_TEMP_FILE_PATH) logger.info(f"Style images has been add success")
def post(self, request): operation = request.data['operation'] if operation == TrainingModeTypeEnum.start: old_style_images = StyleImage.objects.filter( image_type=StyleImageTypeEnum.trained) for image in old_style_images: delete_file(image.now_name, path=settings.STYLE_IMAGE_PATH) old_style_images.delete() for_train_images = StyleImage.objects.filter( image_type=StyleImageTypeEnum.for_train) bulk_create_list = [] for image in for_train_images: image_name = rand_str() copy_file(image.now_name, image_name, from_path=settings.STYLE_IMAGE_FORTRAIN_PATH, to_path=settings.STYLE_IMAGE_PATH) bulk_create_list.append( StyleImage(upload_name=image.upload_name, now_name=image_name, image_type=StyleImageTypeEnum.trained)) StyleImage.objects.bulk_create(bulk_create_list) try: resp = rpc_interface.training_mode(operation) except grpc._channel._Rendezvous: return self.error('operation failed') if resp.status is not True: return self.error('operation failed') return self.success({'status': resp.message})
def post(self, request): if request.user.is_authenticated(): return self.error("Вы уже вошли в систему, у вас всё норм? ") data = request.data captcha = Captcha(request) if not captcha.check(data["captcha"]): return self.error("Неверная капча") try: user = User.objects.get(email__iexact=data["email"]) except User.DoesNotExist: return self.error("Пользователь не существует") if user.reset_password_token_expire_time and 0 < int( (user.reset_password_token_expire_time - now()).total_seconds()) < 20 * 60: return self.error( "Вы можете сбросить пароль не больше раза за 20 минут") user.reset_password_token = rand_str() user.reset_password_token_expire_time = now() + timedelta(minutes=20) user.save() render_data = { "username": user.username, "website_name": SysOptions.website_name, "link": f"{SysOptions.website_base_url}/reset-password/{user.reset_password_token}" } email_html = render_to_string("reset_password_email.html", render_data) send_email_async.delay(from_name=SysOptions.website_name_shortcut, to_email=user.email, to_name=user.username, subject=f"Reset your password", content=email_html) return self.success("Успешно")
def post(self, request): """ 提交请求重置密码 --- request_serializer: ApplyResetPasswordSerializer """ serializer = ApplyResetPasswordSerializer(data=request.data) if serializer.is_valid(): data = serializer.data captcha = Captcha(request) if not captcha.check(data["captcha"]): return error_response(u"验证码错误") try: user = User.objects.get(email=data["email"]) except User.DoesNotExist: return error_response(u"用户不存在") if user.reset_password_token_create_time and (now() - user.reset_password_token_create_time).total_seconds() < 20 * 60: return error_response(u"20分钟内只能找回一次密码") user.reset_password_token = rand_str() user.reset_password_token_create_time = now() user.save() email_template = codecs.open(settings.TEMPLATES[0]["DIRS"][0] + "utils/reset_password_email.html", "r", "utf-8").read() email_template = email_template.replace("{{ username }}", user.username).\ replace("{{ website_name }}", settings.WEBSITE_INFO["website_name"]).\ replace("{{ link }}", request.scheme + "://" + request.META['HTTP_HOST'] + "/reset_password/t/" + user.reset_password_token) send_email(settings.WEBSITE_INFO["website_name"], user.email, user.username, settings.WEBSITE_INFO["website_name"] + u" 登录信息找回邮件", email_template) return success_response(u"邮件发送成功,请前往您的邮箱查收") else: return serializer_invalid_response(serializer)
def post(self, request): if request.user.is_authenticated: return self.error( "You have already logged in, are you kidding me? ") data = request.data captcha = Captcha(request) if not captcha.check(data["captcha"]): return self.error("Invalid captcha") try: user = User.objects.get(email__iexact=data["email"]) except User.DoesNotExist: return self.error("User does not exist") if user.reset_password_token_expire_time and 0 < int( (user.reset_password_token_expire_time - now()).total_seconds()) < 20 * 60: return self.error( "You can only reset password once per 20 minutes") user.reset_password_token = rand_str() user.reset_password_token_expire_time = now() + timedelta(minutes=20) user.save() render_data = { "username": user.username, "website_name": SysOptions.website_name, "link": f"{SysOptions.website_base_url}/reset-password/{user.reset_password_token}" } email_html = render_to_string("reset_password_email.html", render_data) send_email_async.send(from_name=SysOptions.website_name_shortcut, to_email=user.email, to_name=user.username, subject=f"Reset your password", content=email_html) return self.success("Succeeded")
def post(self, request): form = ImageUploadForm(request.POST, request.FILES) if form.is_valid(): img = form.cleaned_data["image"] else: return self.response({ "success": False, "msg": "Upload failed", "file_path": ""}) suffix = os.path.splitext(img.name)[-1].lower() if suffix not in [".gif", ".jpg", ".jpeg", ".bmp", ".png"]: return self.response({ "success": False, "msg": "Unsupported file format", "file_path": ""}) img_name = rand_str(10) + suffix try: with open(os.path.join(settings.UPLOAD_DIR, img_name), "wb") as imgFile: for chunk in img: imgFile.write(chunk) except IOError as e: logger.error(e) return self.response({ "success": True, "msg": "Upload Error", "file_path": f"{settings.UPLOAD_PREFIX}/{img_name}"}) return self.response({ "success": True, "msg": "Success", "file_path": f"{settings.UPLOAD_PREFIX}/{img_name}"})
def post(self, request): """ SSO User Register API """ if not SysOptions.allow_register: return self.error("Register function has been disabled by admin") data = request.data data["username"] = data["username"].lower() if User.objects.filter(username=data["username"]).exists(): user = User.objects.get(username=data["username"], is_disabled=False) return self.success({ "username": user.username, "open_api_appkey": user.open_api_appkey }) token = rand_str() user = User.objects.create(username=data["username"], email=data["username"] + "@1024lesson.com", open_api_appkey=token, open_api="t") user.set_password(data["password"]) user.save() UserProfile.objects.create(user=user) return self.success({ "username": user.username, "open_api_appkey": user.open_api_appkey })
def post(self, request): """ 提交请求重置密码 --- request_serializer: ApplyResetPasswordSerializer """ serializer = ApplyResetPasswordSerializer(data=request.data) if serializer.is_valid(): data = serializer.data captcha = Captcha(request) if not captcha.check(data["captcha"]): return error_response(u"验证码错误") try: user = User.objects.get(username=data["username"], email=data["email"]) except User.DoesNotExist: return error_response(u"用户不存在") user.reset_password_token = rand_str() user.save() email_template = codecs.open(settings.TEMPLATES[0]["DIRS"][0] + "utils/reset_password_email.html", "r", "utf-8").read() email_template = email_template.replace("{{ username }}", user.username).replace("{{ link }}", request.scheme + "://" + request.META['HTTP_HOST'] + "/reset_password/?token=" + user.reset_password_token) send_email(user.email, user.username, u"qduoj 密码找回邮件", email_template) return success_response(u"邮件发生成功") else: return serializer_invalid_response(serializer)
def post(self, request): if request.user.is_authenticated(): return self.error("You have already logged in, are you kidding me? ") data = request.data captcha = Captcha(request) if not captcha.check(data["captcha"]): return self.error("Invalid captcha") try: user = User.objects.get(email__iexact=data["email"]) except User.DoesNotExist: return self.error("User does not exist") if user.reset_password_token_expire_time and 0 < int( (user.reset_password_token_expire_time - now()).total_seconds()) < 20 * 60: return self.error("You can only reset password once per 20 minutes") user.reset_password_token = rand_str() user.reset_password_token_expire_time = now() + timedelta(minutes=20) user.save() render_data = { "username": user.username, "website_name": SysOptions.website_name, "link": f"{SysOptions.website_base_url}/reset-password/{user.reset_password_token}" } email_html = render_to_string("reset_password_email.html", render_data) send_email_async.delay(from_name=SysOptions.website_name_shortcut, to_email=user.email, to_name=user.username, subject=f"Reset your password", content=email_html) return self.success("Succeeded")
def post(self, request): self.serializer_class = GenerateUserSerializer """ Generate User """ data = request.data number_max_length = max(len(str(data["number_from"])), len(str(data["number_to"]))) if number_max_length + len(data["prefix"]) + len(data["suffix"]) > 32: return self.error("Username should not more than 32 characters") if data["number_from"] > data["number_to"]: return self.error("Start number must be lower than end number") file_id = rand_str(8) filename = f"/tmp/{file_id}.xlsx" workbook = xlsxwriter.Workbook(filename) worksheet = workbook.add_worksheet() worksheet.set_column("A:B", 20) worksheet.write("A1", "Username") worksheet.write("B1", "Password") i = 1 user_list = [] for number in range(data["number_from"], data["number_to"] + 1): raw_password = rand_str(data["password_length"]) user = User(username=f"{data['prefix']}{number}{data['suffix']}", password=make_password(raw_password)) user.raw_password = raw_password user_list.append(user) try: with transaction.atomic(): ret = User.objects.bulk_create(user_list) UserProfile.objects.bulk_create( [UserProfile(user=user) for user in ret]) for item in user_list: worksheet.write_string(i, 0, item.username) worksheet.write_string(i, 1, item.raw_password) i += 1 workbook.close() return self.success({"file_id": file_id}) except IntegrityError as e: # Extract detail from exception message # duplicate key value violates unique constraint "user_username_key" # DETAIL: Key (username)=(root11) already exists. return self.error(str(e).split("\n")[1])
def process_zip(self, uploaded_zip_file, spj, dir=""): # 读取压缩包 try: zip_file = zipfile.ZipFile(uploaded_zip_file, "r") # python内置函数 except zipfile.BadZipFile: raise APIError("Bad zip file") # 得到.in/.ou的文件名list name_list = zip_file.namelist() test_case_list = self.filter_name_list(name_list, spj=spj, dir=dir) if not test_case_list: raise APIError("Empty file") # 随机一个test_case_id作为存储数据的文件夹名字,给操作权限 test_case_id = rand_str() test_case_dir = os.path.join(settings.TEST_CASE_DIR, test_case_id) os.mkdir(test_case_dir) os.chmod(test_case_dir, 0o710) size_cache = {} md5_cache = {} # 将压缩包里.in/.out文件中的"\r\n"换成"\n",并重新写到这个目录下 for item in test_case_list: with open(os.path.join(test_case_dir, item), "wb") as f: content = zip_file.read(f"{dir}{item}").replace(b"\r\n", b"\n") size_cache[item] = len(content) if item.endswith(".out"): md5_cache[item] = hashlib.md5(content.rstrip()).hexdigest() f.write(content) test_case_info = {"spj": spj, "test_cases": {}} # 新建一个info文件,写入相关信息 info = [] if spj: for index, item in enumerate(test_case_list): data = {"input_name": item, "input_size": size_cache[item]} info.append(data) test_case_info["test_cases"][str(index + 1)] = data else: # ["1.in", "1.out", "2.in", "2.out"] => [("1.in", "1.out"), ("2.in", "2.out")] test_case_list = zip(*[test_case_list[i::2] for i in range(2)]) for index, item in enumerate(test_case_list): data = { "stripped_output_md5": md5_cache[item[1]], "input_size": size_cache[item[0]], "output_size": size_cache[item[1]], "input_name": item[0], "output_name": item[1] } info.append(data) test_case_info["test_cases"][str(index + 1)] = data with open(os.path.join(test_case_dir, "info"), "w", encoding="utf-8") as f: f.write(json.dumps(test_case_info, indent=4)) for item in os.listdir(test_case_dir): os.chmod(os.path.join(test_case_dir, item), 0o640) return info, test_case_id
def post(self, request): """ 批量导入用户 """ if "file" not in request.FILES: return error_response(u"未上传文件") f = request.FILES["file"] tmp = "/tmp/" + rand_str() + ".xls" import xlrd try: with open(tmp, "wb") as user_info: for line in f: user_info.write(line) except Exception as e: logger.error(e) return error_response(u"写入文件失败") excel_list = {} try: user_info = xlrd.open_workbook(tmp) sheet = user_info.sheet_by_index(0) rows, cols = sheet.nrows, sheet.ncols try: with transaction.atomic(): for row in range(1, rows): username = sheet.cell(row, 0).value real_name = sheet.cell(row, 1).value email = sheet.cell(row, 2).value password = sheet.cell(row, 3).value student_id = sheet.cell(row, 4).value excel_list[str(row)] = { "username": username, "real_name": real_name, "email": email, "password": password, "student_id": student_id } try: User.objects.get(username=username) return error_response(u"{}.该用户名已经存在,请修改".format(username)) except: pass try: User.objects.get(email=email) return error_response(u"{}.该邮箱已经存在,请修改".format(email)) except: pass user = User.objects.create(username=username, real_name=real_name, email=email) user.set_password(password) user.save() UserProfile.objects.create(user=user, student_id=str(int(student_id))) except: return error_response(u"导入用户出错") return success_response({"excel_list": excel_list}) except: return error_response(u"读取文件失败")
def post(self, request): """ 批量生成用户json API接口 """ serializer = UserPrefixSerializer(data=request.data) if serializer.is_valid(): data = serializer.data if data["groupname"] == "": isGroup = False else: isGroup = True try: tarGroup = Group.objects.get(name=data["groupname"]) except: tarGroup = Group.objects.create(name=data["groupname"], created_by=request.user) try: pref = UserPrefix.objects.get(prefixname=data["prefixname"]) except: pref = UserPrefix.objects.create(prefixname=data["prefixname"]) pref.amount = data['amount'] output = [] for i in range(data["amount"]): username = "******" % (data["prefixname"], i) password = rand_str(6) email = "%03d@%s.temp" % (i, data["prefixname"]) try: user = User.objects.get(username=username) user.set_password(password) user.save() if isGroup: UserGroupRelation.objects.create(group=tarGroup, user=user) except User.DoesNotExist: pass try: user = User.objects.get(email=email) except MultipleObjectsReturned: continue except User.DoesNotExist: user = User.objects.create(username=username, real_name=username, email=email) user.set_password(password) user.save() UserProfile.objects.create(user=user, school="unknown", student_id=9527) try: UserPrefixRelation.objects.create(user=user, prefix=pref) except IntegrityError: pass user.tps = password output.append(user) rendered = render(request, "oj/account/output.html", {"output": output}) return success_response({"content": rendered.content}) else: return serializer_invalid_response(serializer)
def post(self, request): user = request.user if not user.open_api: return self.error("Функция OpenAPI для вас отключена") api_appkey = rand_str() user.open_api_appkey = api_appkey user.save() return self.success({"appkey": api_appkey})
def post(self, request): user = request.user if not user.open_api: return self.error("OpenAPI function is truned off for you") api_appkey = rand_str() user.open_api_appkey = api_appkey user.save() return self.success({"appkey": api_appkey})
def get(self, request): callback = request.GET.get("callback", None) if not callback or callback != settings.SSO["callback"]: return error_page(request, u"参数错误") token = rand_str() request.user.auth_token = token request.user.save() return render(request, "oj/account/sso.html", {"redirect_url": callback + "?token=" + token, "callback": callback})
def post(self, request): data = request.data spj_version = rand_str(8) error = SPJCompiler(data["spj_code"], spj_version, data["spj_language"]).compile_spj() if error: return self.error(error) else: return self.success()
def post(self, request): user = request.user if not user.open_api: return self.error("Permission denied") api_appkey = rand_str() user.open_api_appkey = api_appkey user.save() return self.success({"appkey": api_appkey})
def setUp(self): self.client = APIClient() self.register_url = self.reverse("user_register_api") self.captcha = rand_str(4) self.data = {"username": "******", "password": "******","classNum": "1822107", "real_name": "real_name", "email": "*****@*****.**", "captcha": self._set_captcha(self.client.session)}
def get(self,request): problem_id=request.GET.get("problem_id", None) try: Problem.objects.get(id=problem_id) except Problem.DoesNotExist: return error_response(u"题目不存在") sim_info=submit_cache(rand_str(15),problem_id) return Response(data={"code": sim_info["code"], "data": sim_info["data"]})
def process_json(self, data, spj): if 'testcases' not in data: return APIError("No testcases in data") testcases = data['testcases'] test_case_id = rand_str() test_case_dir = os.path.join(settings.TEST_CASE_DIR, test_case_id) os.mkdir(test_case_dir) os.chmod(test_case_dir, 0o710) for i, testcase in enumerate(testcases): in_path = os.path.join(test_case_dir, "{}.in".format(i + 1)) with open(in_path, "w") as f: f.write(testcase['input']) if 'output' in testcase: out_path = os.path.join(test_case_dir, "{}.out".format(i + 1)) with open(out_path, "w") as f: f.write(testcase['output']) test_case_info = {"spj": spj, "test_cases": {}} info = [] if spj: for i, testcase in enumerate(testcases): data = { "input_name": str(i + 1) + ".in", "input_size": len(testcase["input"]) } info.append(data) test_case_info["test_cases"][str(i + 1)] = data else: for i, testcase in enumerate(testcases): data = { 'stripped_output_md5': hashlib.md5(testcase['output'].rstrip().encode( 'utf-8')).hexdigest(), 'input_size': len(testcase['input']), 'output_size': len(testcase['output']), 'input_name': str(i + 1) + ".in", 'output_name': str(i + 1) + ".out" } info.append(data) test_case_info["test_cases"][str(i + 1)] = data with open(os.path.join(test_case_dir, "info"), "w", encoding="utf-8") as f: f.write(json.dumps(test_case_info, indent=4)) for item in os.listdir(test_case_dir): os.chmod(os.path.join(test_case_dir, item), 0o640) return info, test_case_id
def post(self, request): """ User register api """ if not SysOptions.allow_register: return self.error("Register function has been disabled by admin") data = request.data data["username"] = data["username"].lower() data["email"] = data["email"].lower() captcha = Captcha(request) if not captcha.check(data["captcha"]): return self.error("Invalid captcha") if User.objects.filter(username=data["username"]).exists(): return self.error("Username already exists") if not data["email"].endswith("@shanghaitech.edu.cn"): return self.error("Email not in shanghaitech") if User.objects.filter(email=data["email"]).exists(): return self.error("Email already exists") user = User.objects.create(username=data["username"], email=data["email"]) data["password"] = rand_str() user.set_password(data["password"]) user.save() UserProfile.objects.create(user=user) user.reset_password_token = rand_str() user.reset_password_token_expire_time = now() + timedelta(minutes=20) user.save() render_data = { "username": user.username, "website_name": SysOptions.website_name, "link": f"{SysOptions.website_base_url}/reset-password/{user.reset_password_token}" } email_html = render_to_string("reset_password_email.html", render_data) send_email_async.send(from_name=SysOptions.website_name_shortcut, to_email=user.email, to_name=user.username, subject=f"Reset your password", content=email_html) return self.success("Succeeded, 但是请找回密码:)")
def auth_page(request): if not request.user.is_authenticated(): return render(request, "oj/account/oauth.html") callback = request.GET.get("callback", None) if not callback: return error_page(request, u"参数错误") token = rand_str() request.user.auth_token = token return render(request, "oj/account/oauth.html", {"callback": callback, "token": token})
def handle(self, *args, **options): user = User.objects.create(username="******", real_name="root", email="*****@*****.**", admin_type=SUPER_ADMIN) rand_password = rand_str(length=6) user.set_password(rand_password) user.save() UserProfile.objects.create(user=user) self.stdout.write(self.style.SUCCESS("Successfully created super admin user.\nUsername: root\nPassword: %s\n" "Remember to change password and turn on two factors auth " "after installation." % rand_password))
def post(self, request): """ Generate User """ data = request.data number_max_length = max(len(str(data["num_from"])), len(str(data["num_to"]))) if number_max_length + len(data["prefix"]) + len(data["suffix"]) > 32: return Response("Username should not more than 32 characters", HTTP_400_BAD_REQUEST) if data["num_from"] > data["num_to"]: return Response("Start number must be lower than end number", HTTP_400_BAD_REQUEST) file_id = rand_str(8) # return Response({'file_id': file_id}, HTTP_200_OK) filename = os.path.join(GENERATED_USER_DIR, "{}.xlsx".format(file_id)) workbook = xlsxwriter.Workbook(filename) worksheet = workbook.add_worksheet() worksheet.set_column("A:B", 20) worksheet.write("A1", "Username") worksheet.write("B1", "Password") user_list = [] password_list = [] for number in range(data["num_from"], data["num_from"] + 1): raw_password = rand_str(data.get("password_length", 8)) user = User(username=f"{data.get('prefix', '')}{number}{data.get('suffix', '')}", password=make_password(raw_password)) user_list.append(user) password_list.append(raw_password) try: with transaction.atomic(): ret = User.objects.bulk_create(user_list) UserData.objects.bulk_create([UserData(username=user) for user in ret]) for idx, item in enumerate(user_list): worksheet.write_string(idx + 1, 0, item.username) worksheet.write_string(idx + 1, 1, password_list[idx]) workbook.close() return Response({"file_id": file_id}, HTTP_200_OK) except IntegrityError as e: # Extract detail from exception message # duplicate key value violates unique constraint "user_username_key" # DETAIL: Key (username)=(root11) already exists. return Response(str(e).split("\n")[1], HTTP_500_INTERNAL_SERVER_ERROR)
def post(self, request): """ Generate User """ data = request.data number_max_length = max(len(str(data["number_from"])), len(str(data["number_to"]))) if number_max_length + len(data["prefix"]) + len(data["suffix"]) > 32: return self.error("Username should not more than 32 characters") if data["number_from"] > data["number_to"]: return self.error("Start number must be lower than end number") file_id = rand_str(8) filename = f"/tmp/{file_id}.xlsx" workbook = xlsxwriter.Workbook(filename) worksheet = workbook.add_worksheet() worksheet.set_column("A:B", 20) worksheet.write("A1", "Username") worksheet.write("B1", "Password") i = 1 user_list = [] for number in range(data["number_from"], data["number_to"] + 1): raw_password = rand_str(data["password_length"]) user = User(username=f"{data['prefix']}{number}{data['suffix']}", password=make_password(raw_password)) user.raw_password = raw_password user_list.append(user) try: with transaction.atomic(): ret = User.objects.bulk_create(user_list) UserProfile.objects.bulk_create([UserProfile(user=user) for user in ret]) for item in user_list: worksheet.write_string(i, 0, item.username) worksheet.write_string(i, 1, item.raw_password) i += 1 workbook.close() return self.success({"file_id": file_id}) except IntegrityError as e: # Extract detail from exception message # duplicate key value violates unique constraint "user_username_key" # DETAIL: Key (username)=(root11) already exists. return self.error(str(e).split("\n")[1])
def process_zip(self, uploaded_zip_file, spj, dir=""): src_testcase_dir = uploaded_zip_file + dir name_list = os.listdir(src_testcase_dir) test_case_list = self.filter_name_list(name_list, spj=spj, dir='') if not test_case_list: raise APIError("Empty file") test_case_id = rand_str() test_case_dir = os.path.join(settings.TEST_CASE_DIR, test_case_id) os.mkdir(test_case_dir) os.chmod(test_case_dir, 0o710) size_cache = {} md5_cache = {} for item in test_case_list: with open(os.path.join(test_case_dir, item), "w") as f: with open(f"{src_testcase_dir}{item}") as fsrc: content = fsrc.read().replace("\r\n", "\n") size_cache[item] = len(content) if item.endswith(".out"): md5_cache[item] = hashlib.md5( content.rstrip().encode('utf-8')).hexdigest() f.write(content) test_case_info = {"spj": spj, "test_cases": {}} info = [] if spj: for index, item in enumerate(test_case_list): data = {"input_name": item, "input_size": size_cache[item]} info.append(data) test_case_info["test_cases"][str(index + 1)] = data else: # ["1.in", "1.out", "2.in", "2.out"] => [("1.in", "1.out"), ("2.in", "2.out")] test_case_list = zip(*[test_case_list[i::2] for i in range(2)]) for index, item in enumerate(test_case_list): data = { "stripped_output_md5": md5_cache[item[1]], "input_size": size_cache[item[0]], "output_size": size_cache[item[1]], "input_name": item[0], "output_name": item[1] } info.append(data) test_case_info["test_cases"][str(index + 1)] = data with open(os.path.join(test_case_dir, "info"), "w", encoding="utf-8") as f: f.write(json.dumps(test_case_info, indent=4)) for item in os.listdir(test_case_dir): os.chmod(os.path.join(test_case_dir, item), 0o640) return info, test_case_id
def test_tfa_code_required(self): self.user.two_factor_auth = True self.user.tfa_token = "tfa_token" self.user.save() self.assertTrue(self.client.login(username=self.username, password=self.old_password)) self.data["tfa_code"] = rand_str(6) resp = self.client.post(self.url, data=self.data) self.assertEqual(resp.data, {"error": "error", "data": "Invalid two factor verification code"}) self.data["tfa_code"] = self._get_tfa_code() resp = self.client.post(self.url, data=self.data) self.assertSuccess(resp)
def process_zip(self, uploaded_zip_file, spj, dir=""): try: zip_file = zipfile.ZipFile(uploaded_zip_file, "r") except zipfile.BadZipFile: raise APIError("Bad zip file") name_list = zip_file.namelist() test_case_list = self.filter_name_list(name_list, spj=spj, dir=dir) if not test_case_list: raise APIError("Empty file") test_case_id = rand_str() test_case_dir = os.path.join(settings.TEST_CASE_DIR, test_case_id) os.mkdir(test_case_dir) os.chmod(test_case_dir, 0o710) size_cache = {} md5_cache = {} for item in test_case_list: with open(os.path.join(test_case_dir, item), "wb") as f: content = zip_file.read(f"{dir}{item}").replace(b"\r\n", b"\n") size_cache[item] = len(content) if item.endswith(".out"): md5_cache[item] = hashlib.md5(content.rstrip()).hexdigest() f.write(content) test_case_info = {"spj": spj, "test_cases": {}} info = [] if spj: for index, item in enumerate(test_case_list): data = {"input_name": item, "input_size": size_cache[item]} info.append(data) test_case_info["test_cases"][str(index + 1)] = data else: # ["1.in", "1.out", "2.in", "2.out"] => [("1.in", "1.out"), ("2.in", "2.out")] test_case_list = zip(*[test_case_list[i::2] for i in range(2)]) for index, item in enumerate(test_case_list): data = {"stripped_output_md5": md5_cache[item[1]], "input_size": size_cache[item[0]], "output_size": size_cache[item[1]], "input_name": item[0], "output_name": item[1]} info.append(data) test_case_info["test_cases"][str(index + 1)] = data with open(os.path.join(test_case_dir, "info"), "w", encoding="utf-8") as f: f.write(json.dumps(test_case_info, indent=4)) for item in os.listdir(test_case_dir): os.chmod(os.path.join(test_case_dir, item), 0o640) return info, test_case_id
def handle(self, *args, **options): try: admin = User.objects.get(username="******") if admin.admin_type == SUPER_ADMIN: self.stdout.write( self.style.WARNING( "Super admin user 'root' already exists, " "would you like to reset it's password?\n" "Input yes to confirm: ")) if raw_input() == "yes": rand_password = rand_str(length=6) admin.set_password(rand_password) admin.save() self.stdout.write( self.style.SUCCESS( "Successfully created super admin user password.\n" "Username: root\nPassword: %s\n" "Remember to change password and turn on two factors auth " "after installation." % rand_password)) else: self.stdout.write(self.style.SUCCESS("Nothing happened")) else: self.stdout.write( self.style.ERROR("User 'root' is not super admin.")) except User.DoesNotExist: user = User.objects.create(username="******", real_name="root", email="*****@*****.**", admin_type=SUPER_ADMIN) rand_password = rand_str(length=6) user.set_password(rand_password) user.save() UserProfile.objects.create(user=user) self.stdout.write( self.style.SUCCESS( "Successfully created super admin user.\n" "Username: root\nPassword: %s\n" "Remember to change password and turn on two factors auth " "after installation." % rand_password))
def post(self, request): if "file" not in request.FILES: return error_response(u"文件上传失败") f = request.FILES["file"] if f.size > 1024 * 1024: return error_response(u"图片过大") if os.path.splitext(f.name)[-1].lower() not in [".gif", ".jpg", ".jpeg", ".bmp", ".png"]: return error_response(u"需要上传图片格式") name = "avatar_" + rand_str(5) + os.path.splitext(f.name)[-1] with open(os.path.join(settings.IMAGE_UPLOAD_DIR, name), "wb") as img: for chunk in request.FILES["file"]: img.write(chunk) return success_response({"path": "/static/upload/" + name})
def get(self, request): """ Get QR code """ user = request.user if user.two_factor_auth: return self.error("2FA is already turned on") token = rand_str() user.tfa_token = token user.save() label = f"{SysOptions.website_name_shortcut}:{user.username}" image = qrcode.make(OtpAuth(token).to_uri("totp", label, SysOptions.website_name.replace(" ", ""))) return self.success(img2base64(image))
def get(self, request): """ Get QR code """ user = request.user if user.two_factor_auth: return self.error("2FA is already turned on") token = rand_str() user.tfa_token = token user.save() label = f"{SysOptions.website_name_shortcut}:{user.username}" image = qrcode.make(OtpAuth(token).to_uri("totp", label, SysOptions.website_name)) return self.success(img2base64(image))
def post(self, request): upload_file_form = UploadFileForm(request.POST, request.FILES) if not upload_file_form.is_valid(): return self.error(msg='文件上传失败') file = request.FILES['file'] upload_file_name = file.name upload_name = upload_file_name.split('.')[0] now_name = rand_str(length=16) save_file(file, now_name, path=settings.STYLE_IMAGE_FORTRAIN_PATH) StyleImage.objects.create(upload_name=upload_name, now_name=now_name, image_type=StyleImageTypeEnum.for_train) return self.success()
def get(self, request): """ 获取绑定二维码 """ user = request.user if user.two_factor_auth: return error_response(u"已经开启两步验证了") token = rand_str() user.tfa_token = token user.save() image = qrcode.make(OtpAuth(token).to_uri("totp", settings.WEBSITE_INFO["url"], "OnlineJudgeAdmin")) buf = StringIO.StringIO() image.save(buf, 'gif') return HttpResponse(buf.getvalue(), 'image/gif')
def post(self, request): serializer = ApplyResetPasswordSerializer(data=request.data) if serializer.is_valid(): data = serializer.data captcha = Captcha(request) if not captcha.check(data["captcha"]): return error_response(u"验证码错误") try: user = User.objects.get(username=data["username"], email=data["email"]) except User.DoesNotExist: return error_response(u"用户不存在") user.reset_password_token = rand_str() user.save() # todo email_template = open(settings.TEMPLATES[0]["DIRS"][0] + "utils/reset_password_email.html", "r").read() email_template.replace("{{ username }}", user.username).replace("{{ link }}", "/reset_password/?token=" + user.reset_password_token) return success_response(u"邮件发生成功") else: return serializer_invalid_response(serializer)
def post(self, request): form = ImageUploadForm(request.POST, request.FILES) if form.is_valid(): avatar = form.cleaned_data["image"] else: return self.error("Invalid file content") if avatar.size > 2 * 1024 * 1024: return self.error("Picture is too large") suffix = os.path.splitext(avatar.name)[-1].lower() if suffix not in [".gif", ".jpg", ".jpeg", ".bmp", ".png"]: return self.error("Unsupported file format") name = rand_str(10) + suffix with open(os.path.join(settings.AVATAR_UPLOAD_DIR, name), "wb") as img: for chunk in avatar: img.write(chunk) user_profile = request.user.userprofile user_profile.avatar = f"{settings.AVATAR_URI_PREFIX}/{name}" user_profile.save() return self.success("Succeeded")
def _create_problem(self, problem_data, creator): if problem_data["time_limit"]["unit"] == "ms": time_limit = problem_data["time_limit"]["value"] else: time_limit = problem_data["time_limit"]["value"] * 1000 template = {} prepend = {} append = {} for t in problem_data["prepend"]: prepend[t["language"]] = t["code"] for t in problem_data["append"]: append[t["language"]] = t["code"] for t in problem_data["template"]: our_lang = lang = t["language"] if lang == "Python": our_lang = "Python3" template[our_lang] = TEMPLATE_BASE.format(prepend.get(lang, ""), t["code"], append.get(lang, "")) spj = problem_data["spj"] is not None Problem.objects.create(_id=f"fps-{rand_str(4)}", title=problem_data["title"], description=problem_data["description"], input_description=problem_data["input"], output_description=problem_data["output"], hint=problem_data["hint"], test_case_score=[], time_limit=time_limit, memory_limit=problem_data["memory_limit"]["value"], samples=problem_data["samples"], template=template, rule_type=ProblemRuleType.ACM, source=problem_data.get("source", ""), spj=spj, spj_code=problem_data["spj"]["code"] if spj else None, spj_language=problem_data["spj"]["language"] if spj else None, spj_version=rand_str(8) if spj else "", visible=False, languages=language_names, created_by=creator, difficulty=Difficulty.MID, test_case_id=problem_data["test_case_id"])
def post(self, request): if "image" not in request.FILES: return Response(data={ "success": False, "msg": "上传失败", "file_path": "/"}) img = request.FILES["image"] image_name = rand_str() + '.' + str(request.FILES["image"].name.split('.')[-1]) image_dir = settings.IMAGE_UPLOAD_DIR + image_name try: with open(image_dir, "wb") as imageFile: for chunk in img: imageFile.write(chunk) except IOError as e: logger.error(e) return Response(data={ "success": True, "msg": "上传错误", "file_path": "/static/upload/" + image_name}) return Response(data={ "success": True, "msg": "", "file_path": "/static/upload/" + image_name})
def post(self, request): if "file" not in request.FILES: return error_response(u"文件上传失败") f = request.FILES["file"] tmp_zip = "/tmp/" + rand_str() + ".zip" try: with open(tmp_zip, "wb") as test_case_zip: for chunk in f: test_case_zip.write(chunk) except IOError as e: logger.error(e) return error_response(u"上传失败") test_case_file = zipfile.ZipFile(tmp_zip, 'r') name_list = test_case_file.namelist() l = [] # 如果文件是直接打包的,那么name_list 就是["1.in", "1.out"]这样的 # 如果文件还有一层文件夹test_case,那么name_list就是["test_case/", "test_case/1.in", "test_case/1.out"] # 现在暂时只支持第一种,先判断一下是什么格式的 # 第一种格式的 if "1.in" in name_list and "1.out" in name_list: for file_name in name_list: if self._is_legal_test_case_file_name(file_name): name = file_name.split(".") # 有了.in 判断对应的.out 在不在 if name[1] == "in": if (name[0] + ".out") in name_list: l.append(file_name) else: return error_response(u"测试用例文件不完整,缺少" + name[0] + ".out") else: # 有了.out 判断对应的 .in 在不在 if (name[0] + ".in") in name_list: l.append(file_name) else: return error_response(u"测试用例文件不完整,缺少" + name[0] + ".in") problem_test_dir = rand_str() test_case_dir = settings.TEST_CASE_DIR + problem_test_dir + "/" # 得到了合法的测试用例文件列表 然后去解压缩 os.mkdir(test_case_dir) for name in l: f = open(test_case_dir + name, "wb") try: f.write(test_case_file.read(name).replace("\r\n", "\n")) except MemoryError: return error_response(u"单个测试数据体积过大!") finally: f.close() l.sort() file_info = {"test_case_number": len(l) / 2, "test_cases": {}} # 计算输出文件的md5 for i in range(len(l) / 2): md5 = hashlib.md5() striped_md5 = hashlib.md5() f = open(test_case_dir + str(i + 1) + ".out", "r") # 完整文件的md5 while True: data = f.read(2 ** 8) if not data: break md5.update(data) # 删除标准输出最后的空格和换行 # 这时只能一次全部读入了,分块读的话,没办法确定文件结尾 f.seek(0) striped_md5.update(f.read().rstrip()) file_info["test_cases"][str(i + 1)] = {"input_name": str(i + 1) + ".in", "output_name": str(i + 1) + ".out", "output_md5": md5.hexdigest(), "striped_output_md5": striped_md5.hexdigest(), "output_size": os.path.getsize(test_case_dir + str(i + 1) + ".out")} # 写入配置文件 open(test_case_dir + "info", "w").write(json.dumps(file_info)) return success_response({"test_case_id": problem_test_dir, "file_list": {"input": l[0::2], "output": l[1::2]}}) else: return error_response(u"测试用例压缩文件格式错误,请保证测试用例文件在根目录下直接压缩")
def post(self, request): if "file" not in request.FILES: return error_response(u"文件上传失败") f = request.FILES["file"] tmp_zip = "/tmp/" + rand_str() + ".zip" try: with open(tmp_zip, "wb") as test_case_zip: for chunk in f: test_case_zip.write(chunk) except IOError as e: logger.error(e) return error_response(u"上传失败") try: test_case_file = zipfile.ZipFile(tmp_zip, 'r') except Exception: return error_response(u"解压失败") name_list = test_case_file.namelist() # 如果文件是直接打包的,那么name_list 就是["1.in", "1.out"]这样的 if len(name_list) == 0: return error_response(u"压缩包内没有文件") if len(name_list) % 2 == 1: return error_response(u"测试用例文件格式错误,文件数目为奇数") for index in range(1, len(name_list) / 2 + 1): if not (str(index) + ".in" in name_list and str(index) + ".out" in name_list): return error_response(u"测试用例文件格式错误,缺少" + str(index) + u".in/.out文件") problem_test_dir = rand_str() test_case_dir = settings.TEST_CASE_DIR + problem_test_dir + "/" # 得到了合法的测试用例文件列表 然后去解压缩 os.mkdir(test_case_dir) for name in name_list: f = open(test_case_dir + name, "wb") try: f.write(test_case_file.read(name).replace("\r\n", "\n")) except MemoryError: return error_response(u"单个测试数据体积过大!") finally: f.close() name_list.sort() file_info = {"test_case_number": len(name_list) / 2, "test_cases": {}} # 计算输出文件的md5 for i in range(1, len(name_list) / 2 + 1): md5 = hashlib.md5() striped_md5 = hashlib.md5() f = open(test_case_dir + str(i) + ".out", "r") # 完整文件的md5 while True: data = f.read(2 ** 8) if not data: break md5.update(data) # 删除标准输出最后的空格和换行 # 这时只能一次全部读入了,分块读的话,没办法确定文件结尾 f.seek(0) striped_md5.update(f.read().rstrip()) file_info["test_cases"][str(i)] = {"input_name": str(i) + ".in", "output_name": str(i) + ".out", "output_md5": md5.hexdigest(), "striped_output_md5": striped_md5.hexdigest(), "input_size": os.path.getsize(test_case_dir + str(i) + ".in"), "output_size": os.path.getsize(test_case_dir + str(i) + ".out")} # 写入配置文件 with open(test_case_dir + "info", "w") as f: f.write(json.dumps(file_info)) return success_response({"test_case_id": problem_test_dir, "file_list": file_info["test_cases"]})
def get(self, request): token = rand_str() request.user.auth_token = token request.user.save() return self.success({"token": token})
def post(self, request): form = UploadProblemForm(request.POST, request.FILES) if form.is_valid(): file = form.cleaned_data["file"] tmp_file = f"/tmp/{rand_str()}.zip" with open(tmp_file, "wb") as f: for chunk in file: f.write(chunk) else: return self.error("Upload failed") count = 0 with zipfile.ZipFile(tmp_file, "r") as zip_file: name_list = zip_file.namelist() for item in name_list: if "/problem.json" in item: count += 1 with transaction.atomic(): for i in range(1, count + 1): with zip_file.open(f"{i}/problem.json") as f: problem_info = json.load(f) serializer = ImportProblemSerializer(data=problem_info) if not serializer.is_valid(): return self.error(f"Invalid problem format, error is {serializer.errors}") else: problem_info = serializer.data for item in problem_info["template"].keys(): if item not in language_names: return self.error(f"Unsupported language {item}") problem_info["display_id"] = problem_info["display_id"][:24] for k, v in problem_info["template"].items(): problem_info["template"][k] = build_problem_template(v["prepend"], v["template"], v["append"]) spj = problem_info["spj"] is not None rule_type = problem_info["rule_type"] test_case_score = problem_info["test_case_score"] # process test case _, test_case_id = self.process_zip(tmp_file, spj=spj, dir=f"{i}/testcase/") problem_obj = Problem.objects.create(_id=problem_info["display_id"], title=problem_info["title"], description=problem_info["description"]["value"], input_description=problem_info["input_description"][ "value"], output_description=problem_info["output_description"][ "value"], hint=problem_info["hint"]["value"], test_case_score=test_case_score if test_case_score else [], time_limit=problem_info["time_limit"], memory_limit=problem_info["memory_limit"], samples=problem_info["samples"], template=problem_info["template"], rule_type=problem_info["rule_type"], source=problem_info["source"], spj=spj, spj_code=problem_info["spj"]["code"] if spj else None, spj_language=problem_info["spj"][ "language"] if spj else None, spj_version=rand_str(8) if spj else "", languages=language_names, created_by=request.user, visible=False, difficulty=Difficulty.MID, total_score=sum(item["score"] for item in test_case_score) if rule_type == ProblemRuleType.OI else 0, test_case_id=test_case_id ) for tag_name in problem_info["tags"]: tag_obj, _ = ProblemTag.objects.get_or_create(name=tag_name) problem_obj.tags.add(tag_obj) return self.success({"import_count": count})
def default_token(): token = os.environ.get("JUDGE_SERVER_TOKEN") return token if token else rand_str()
def post(self, request): if "file" not in request.FILES: return error_response(u"文件上传失败") f = request.FILES["file"] tmp_zip = "/tmp/" + rand_str() + ".zip" try: with open(tmp_zip, "wb") as test_case_zip: for chunk in f: test_case_zip.write(chunk) except IOError as e: logger.error(e) return error_response(u"上传失败") try: test_case_file = zipfile.ZipFile(tmp_zip, 'r') except Exception: return error_response(u"解压失败") name_list = test_case_file.namelist() # 如果文件是直接打包的,那么name_list 就是["1.in", "1.out"]这样的 if len(name_list) == 0: return error_response(u"压缩包内没有文件") for item in name_list: if not self._is_legal_test_case_file_name(item): return error_response(u"%s 文件名不符合规范" % item) # 排序,这样name_list就是[1.in, 1.out, 2.in, 2.out]的形式了 name_list.sort() spj = False for item in name_list: # 代表里面有.out文件,所以应该是普通题目的测试用例 if item.endswith(".out"): break else: # 否则就应该是spj的测试用例 spj = True if not spj: if len(name_list) % 2 == 1: return error_response(u"测试用例文件格式错误,文件数目为奇数") for index in range(1, len(name_list) / 2 + 1): if not (str(index) + ".in" in name_list and str(index) + ".out" in name_list): return error_response(u"测试用例文件格式错误,缺少" + str(index) + u".in/.out文件") test_case_number = len(name_list) / 2 else: for index in range(1, len(name_list) + 1): if str(index) + ".in" not in name_list: return error_response(u"测试用例文件格式错误,缺少" + str(index) + u".in文件") test_case_number = len(name_list) problem_test_dir = rand_str() test_case_dir = os.path.join(settings.TEST_CASE_DIR, problem_test_dir) # 得到了合法的测试用例文件列表 然后去解压缩 os.mkdir(test_case_dir) for name in name_list: f = open(os.path.join(test_case_dir, name), "wb") try: f.write(test_case_file.read(name).replace("\r\n", "\n")) except MemoryError: return error_response(u"单个测试数据体积过大!") finally: f.close() file_info = {"test_case_number": test_case_number, "test_cases": {}, "spj": spj} # 计算输出文件的md5 for i in range(1, test_case_number + 1): if not spj: md5 = hashlib.md5() striped_md5 = hashlib.md5() f = open(os.path.join(test_case_dir, str(i) + ".out"), "r") # 完整文件的md5 while True: data = f.read(2 ** 8) if not data: break md5.update(data) # 删除标准输出最后的空格和换行 # 这时只能一次全部读入了,分块读的话,没办法确定文件结尾 f.seek(0) striped_md5.update(f.read().rstrip()) output_md5 = md5.hexdigest() striped_output_md5 = striped_md5.hexdigest() output_name = str(i) + ".out" output_size = os.path.getsize(os.path.join(test_case_dir, output_name)) else: output_md5 = striped_output_md5 = output_name = output_size = None file_info["test_cases"][str(i)] = {"input_name": str(i) + ".in", "output_name": output_name, "output_md5": output_md5, "striped_output_md5": striped_output_md5, "input_size": os.path.getsize(os.path.join(test_case_dir, str(i) + ".in")), "output_size": output_size} # 写入配置文件 with open(os.path.join(test_case_dir, "info"), "w") as f: f.write(json.dumps(file_info)) return success_response({"test_case_id": problem_test_dir, "file_list": file_info["test_cases"], "spj": spj})