testingwebapp fixes, weeek tasks 2948-2958
This commit is contained in:
@@ -35,6 +35,7 @@ from ..services.ai_editor import (
|
||||
generate_full_test_by_shape,
|
||||
generate_or_rephrase_question,
|
||||
generate_test_by_title,
|
||||
improve_single_option_text,
|
||||
improve_test_full,
|
||||
parse_and_validate_shape,
|
||||
)
|
||||
@@ -50,6 +51,7 @@ from ..services.test_attempt import (
|
||||
check_question_for_attempt,
|
||||
count_missing_hints,
|
||||
generate_missing_hints_for_test,
|
||||
generate_next_missing_hint_for_test,
|
||||
get_attempt_review_for_user,
|
||||
get_play_content,
|
||||
list_test_attempts_for_author,
|
||||
@@ -350,6 +352,17 @@ def api_test_hints_generate(test_id):
|
||||
return jsonify(out)
|
||||
|
||||
|
||||
@tests_bp.route('/api/tests/<test_id>/ai/hints/generate-next', methods=['POST'])
|
||||
@login_required
|
||||
def api_test_hints_generate_next(test_id):
|
||||
user = current_user()
|
||||
try:
|
||||
out = generate_next_missing_hint_for_test(None, user.id, test_id)
|
||||
except AttemptHttpError as e:
|
||||
return jsonify(error=e.message), e.status
|
||||
return jsonify(out)
|
||||
|
||||
|
||||
@tests_bp.route('/api/tests/<test_id>/attempts/<attempt_id>/check', methods=['POST'])
|
||||
@login_required
|
||||
def api_attempt_check_question(test_id, attempt_id):
|
||||
@@ -511,6 +524,26 @@ def api_ai_improve_test(test_id):
|
||||
body.get('testTitle') or '',
|
||||
body.get('testDescription') or '',
|
||||
body.get('questions') or [],
|
||||
focus=body.get('focus') or 'all',
|
||||
)
|
||||
except (AiHttpError, LlmError) as e:
|
||||
return _ai_error_response(e)
|
||||
return jsonify(ok=True, **out)
|
||||
|
||||
|
||||
@tests_bp.route('/api/tests/<test_id>/ai/improve-option', methods=['POST'])
|
||||
@login_required
|
||||
def api_ai_improve_option(test_id):
|
||||
user = current_user()
|
||||
_check_test_author_or_404(test_id, user.id)
|
||||
body = request.get_json(silent=True) or {}
|
||||
try:
|
||||
out = improve_single_option_text(
|
||||
body.get('testTitle') or '',
|
||||
body.get('testDescription') or '',
|
||||
body.get('questionText') or '',
|
||||
body.get('options') or [],
|
||||
body.get('optionIndex'),
|
||||
)
|
||||
except (AiHttpError, LlmError) as e:
|
||||
return _ai_error_response(e)
|
||||
@@ -522,25 +555,44 @@ def api_ai_improve_test(test_id):
|
||||
@tests_bp.route('/api/tests/import/document', methods=['POST'])
|
||||
@login_required
|
||||
def api_import_document():
|
||||
"""Шаг 1: загрузить файл и извлечь текст. Генерация — отдельным запросом."""
|
||||
f = request.files.get('file')
|
||||
if f is None or not f.filename:
|
||||
return jsonify(error='Прикрепите файл к полю file.'), 400
|
||||
try:
|
||||
extracted = extract_text_from_file(f.mimetype, f, f.filename)
|
||||
except DocExtractHttpError as e:
|
||||
return jsonify(error=e.message), e.status
|
||||
except Exception:
|
||||
log.exception('extract_text_from_file failed')
|
||||
return jsonify(error='Не удалось разобрать файл.'), 500
|
||||
"""Шаг 1: загрузить один или несколько файлов и извлечь текст. Генерация — отдельным запросом."""
|
||||
files = request.files.getlist('files')
|
||||
if not files:
|
||||
f = request.files.get('file')
|
||||
files = [f] if f is not None and getattr(f, 'filename', None) else []
|
||||
files = [x for x in files if x is not None and getattr(x, 'filename', None)]
|
||||
if not files:
|
||||
return jsonify(error='Прикрепите файл(ы) к полю file или files.'), 400
|
||||
if len(files) > 5:
|
||||
return jsonify(error='Не более 5 файлов за один раз.'), 400
|
||||
|
||||
parts: list[str] = []
|
||||
names: list[str] = []
|
||||
mimes: list[str] = []
|
||||
for f in files:
|
||||
try:
|
||||
extracted = extract_text_from_file(f.mimetype, f, f.filename)
|
||||
except DocExtractHttpError as e:
|
||||
return jsonify(error=e.message), e.status
|
||||
except Exception:
|
||||
log.exception('extract_text_from_file failed')
|
||||
return jsonify(error='Не удалось разобрать файл.'), 500
|
||||
parts.append(extracted)
|
||||
names.append(f.filename or '')
|
||||
mimes.append(f.mimetype or '')
|
||||
|
||||
combined = '\n\n---\n\n'.join(parts)
|
||||
primary = files[0]
|
||||
return jsonify(
|
||||
received=True,
|
||||
originalName=f.filename,
|
||||
mime=f.mimetype,
|
||||
size=len(extracted.encode('utf-8')),
|
||||
extractedText=extracted,
|
||||
textLength=len(extracted),
|
||||
originalName=primary.filename,
|
||||
originalNames=names,
|
||||
mime=primary.mimetype,
|
||||
mimes=mimes,
|
||||
size=len(combined.encode('utf-8')),
|
||||
extractedText=combined,
|
||||
textLength=len(combined),
|
||||
fileCount=len(files),
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user