Esempio n. 1
0
    def upload_instructor_archive(self, request, suffix):
        """
        Обработчик загрузки архива инструктора.

        Вызывается, когда в студии инструктор нажимает кнопку "Загрузить"
        напротив поля "Архив инструктора".

        Проводит валидацию архива и временно сохраняет его. Позднее, он может
        быт восстановлен обработчиком "save_settings". Защиты от параллельной
        загрузки несколькими инструкторами (или в нескольких окнах браузера)
        не предусмотрено.

        :param request:
        :param suffix:
        :return:
        """
        def get_archive_signature(archive):
            """
            Формирует подпись архива (файла) на основании sha1 и текущего времени

            :param archive: file-object
            :return: tuple(sha1, signature)
            """
            import hashlib
            import datetime
            sha1 = get_sha1(archive)
            md5 = hashlib.md5()
            md5.update(sha1)
            md5.update(datetime.datetime.isoformat(datetime.datetime.now()))
            return sha1, md5.hexdigest()

        upload = request.params['instructor_archive']

        self.validate_instructor_archive(upload.file)

        uploaded_file = File(upload.file)

        archive_sha1, archive_signature = get_archive_signature(uploaded_file)
        archive_name = "instructor.{signature}.~draft".format(
            name=upload.file.name, signature=archive_signature)
        fs_path = file_storage_path(self.location, archive_name)

        # Сохраняем временную информацию до того как нажата кнопка "Save"
        self.instructor_archive_meta['draft'] = {
            'filename': upload.file.name,
            'sha1': get_sha1(uploaded_file),
            'upload_at': None,
            'upload_by': None,
            'fs_path': fs_path,
        }

        if default_storage.exists(fs_path):
            default_storage.delete(fs_path)
        default_storage.save(fs_path, uploaded_file)

        return Response(json_body={})
Esempio n. 2
0
        def get_archive_signature(archive):
            """
            Формирует подпись архива (файла) на основании sha1 и текущего времени

            :param archive: file-object
            :return: tuple(sha1, signature)
            """
            import hashlib
            import datetime
            sha1 = get_sha1(archive)
            md5 = hashlib.md5()
            md5.update(sha1)
            md5.update(datetime.datetime.isoformat(datetime.datetime.now()))
            return sha1, md5.hexdigest()
Esempio n. 3
0
    def upload_submission(self, request, suffix):
        def _return_response(response_update=None):
            if response_update is None:
                response_update = {}
            response = self.get_student_context()
            response.update(response_update)
            return self.get_response_user_state(response)

        if self.queue_details:
            return _return_response({
                'message': {
                    'text': 'Проверка другого решения уже запущена.',
                    'type': 'error',
                }
            })

        try:

            self.message = None

            # Извлечение данных о загруженном файле
            upload = request.params['submission']
            uploaded_file = File(upload.file)
            uploaded_filename = upload.file.name
            uploaded_sha1 = get_sha1(upload.file)
            uploaded_mimetype = mimetypes.guess_type(upload.file.name)[0]

            # Реальные названия файлов в ФС
            fs_path = file_storage_path(self.location, uploaded_sha1)
            instructor_fs_path = self.get_instructor_path()

            # Сохраняем данные о решении
            student_id = self.student_submission_dict()
            student_answer = {
                "sha1": uploaded_sha1,
                "filename": uploaded_filename,
                "mimetype": uploaded_mimetype,
                "real_path": fs_path,
                "instructor_real_path": instructor_fs_path,
            }
            submission = submissions_api.create_submission(
                student_id, student_answer)

            # Сохраняем файл с решением
            if default_storage.exists(fs_path):
                default_storage.delete(fs_path)
            default_storage.save(fs_path, uploaded_file)

            payload = {
                'method':
                'check',
                'student_info':
                self.queue_student_info,
                'grader_payload':
                json.dumps({
                    'pregenerated':
                    self.pregenerated if self.need_generate else None,
                    'time_limit_execute':
                    self.time_limit_execute,
                    'time_limit_check':
                    self.time_limit_check,
                }),
                'student_response':
                self.get_queue_student_response(submission),
            }

            self.send_to_queue(header=self.get_submission_header(
                access_key_prefix=submission.get('uuid'), ),
                               body=json.dumps(payload))

        except Exception as e:
            return _return_response({
                'message': {
                    'text':
                    'Ошибка при попытке поставить проверку решения в очередь: '
                    + e.message,
                    'type':
                    'error',
                }
            })

        return _return_response()