import os import hashlib import mimetypes from django import forms from django.core.exceptions import ValidationError from django.core.files.storage import default_storage from university.models import UserOnlineExam, OnlineExamEvent, OnlineExam, Upload class AdminMessageForm(forms.Form): comment = forms.CharField(required=True, max_length=64) def __init__(self, user_online_exam, *args, **kwargs): self.user_online_exam = user_online_exam super(AdminMessageForm, self).__init__(*args, **kwargs) def clean(self): if self.user_online_exam.status != UserOnlineExam.STATUS_UNDERWAY: self.add_error('', '考试状态错误,只有考试进行中才能使用该功能') return self.cleaned_data def send_warning_message(self): comment = self.cleaned_data.get('comment', '') OnlineExamEvent.objects.create( user=self.user_online_exam.user, online_exam=self.user_online_exam.online_exam, user_online_exam=self.user_online_exam, event_type=OnlineExamEvent.EVENT_ADMIN_WARING_MESSAGE, comment=comment ) self.user_online_exam.send_warning_ws_message(comment) def send_force_submit(self): comment = self.cleaned_data.get('comment', '') self.user_online_exam.is_force_submitted = True self.user_online_exam.force_submit_reason = comment self.user_online_exam.save(update_fields=['is_force_submitted', 'force_submit_reason']) OnlineExamEvent.objects.create( user=self.user_online_exam.user, online_exam=self.user_online_exam.online_exam, user_online_exam=self.user_online_exam, event_type=OnlineExamEvent.EVENT_ADMIN_FORCE_SUBMIT, comment=comment ) self.user_online_exam.send_admin_force_submit_ws_message(comment) class OnlineExamEditForm(forms.ModelForm): def clean(self): if self._errors: return start_at = self.cleaned_data.get('start_at') end_at = self.cleaned_data.get('end_at') registration_deadline = self.cleaned_data.get('registration_deadline') if start_at >= end_at: self.add_error('start_at', '开始时间不能晚于结束时间') if registration_deadline >= start_at: self.add_error('registration_deadline', '报名截止时间不能晚于开始时间') return self.cleaned_data class Meta: model = OnlineExam fields = [ 'name', 'short_description', 'detailed_description', 'rules', 'registration_deadline', 'start_at', 'end_at', 'allowed_cheating_times', 'alert_wechat_webhook' ] class OnlineExamUploadCertForm(forms.Form): file = forms.FileField() def __init__(self, user_online_exam, *args, **kwargs): self.user_online_exam = user_online_exam return super(OnlineExamUploadCertForm, self).__init__(*args, **kwargs) def clean_file(self): file = self.cleaned_data.get('file') if file: try: file._size except Exception: pass else: if file._size > 3 * 1 << 20: raise ValidationError('文件大小超过限制') return file def save(self): file_obj = self.cleaned_data.get('file') if file_obj: content_hash = hashlib.sha1(file_obj.read()).hexdigest() content_type, _temp = mimetypes.guess_type(file_obj.name, strict=False) file_path = self.generate_filepath_by_hash(content_hash) _temp, file_extension = os.path.splitext(file_obj.name) if file_extension: file_path += file_extension file_obj.seek(0) file_path = default_storage.save(file_path, file_obj) upload = Upload.objects.create( user=self.user_online_exam.user, original_filename=file_obj.name, filesize=file_obj.size, path=file_path, sha1=content_hash, extension=content_type, is_private=True ) self.user_online_exam.cert = upload self.user_online_exam.save(update_fields=['cert']) def generate_filepath_by_hash(self, file_hash): return '{}/{}/{}'.format( file_hash[0], file_hash[1], file_hash )