diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py index 5e1f08961d0ade56a28d7e0ce6658d009998106b..1a92d23375aedacc52caa42213434c67bb88bdf1 100644 --- a/mo/web/org_contest.py +++ b/mo/web/org_contest.py @@ -1750,39 +1750,25 @@ def org_contest_scans(ct_id: int, site_id: Optional[int] = None): if proc_form.validate_on_submit() and proc_form.process_scans.data: files = request.files.getlist(proc_form.files.name) if check_scan_files(files): - job_id = mo.jobs.protocols.schedule_process_scans( + mo.jobs.protocols.schedule_process_scans( contest, site, proc_form.scans_type.data, g.user, tasks=[t for t in tasks if getattr(proc_form, f'task_{t.task_id}').data], in_file_names=[f.stream.name for f in files], ) flash('Zpracování skenů zahájeno. Vyčkejte chvíli, než budou připraveny, a poté je roztřiďte.', 'success') - return redirect(ctx.url_for('org_contest_scans_process', job_id=job_id)) + return redirect(url_for('org_jobs', back=ctx.url_for('org_contest_scans'))) jobs_query = sess.query(db.Job).filter_by(type=db.JobType.process_scans) if not g.user.is_admin: jobs_query = jobs_query.filter_by(user=g.user) - jobs: List[Tuple[db.Job, str, List[db.Task]]] = [] - for job in jobs_query.all(): - if 'contest_id' not in job.in_json or job.in_json['contest_id'] != ct_id: - continue - if site_id is not None and ('site_id' not in job.in_json or job.in_json['site_id'] != site_id): - continue - - tasks = [] - for task_id in job.in_json['task_ids']: - if task_id in tasks_map: - tasks.append(tasks_map[task_id]) - scans_type = job.in_json['type'] if 'type' in job.in_json else 'solution' - scans_type_names = {'solution': 'Odevzdaná řešení', 'feedback': 'Opravená řešení'} - - jobs.append((job, scans_type_names[scans_type], tasks)) + num_scan_jobs = jobs_query.count() return render_template( 'org_contest_scans.html', ctx=ctx, proc_form=proc_form, proc_task_fields=proc_task_fields, - jobs=jobs, + num_scan_jobs=num_scan_jobs, ) @@ -1815,11 +1801,15 @@ def org_contest_scans_process(ct_id: int, job_id: int, site_id: Optional[int] = # Získáme job a zkontrolujeme, že je to správný job, máme na něj práva a už doběhl job = sess.query(db.Job).get(job_id) if not job or job.type != db.JobType.process_scans: - flash('Dávka naskenovaných úloh nenalezena, skeny již byly pravděpodobně zpracovány nebo smazány.') - return redirect(ctx.url_for('org_contest_scans')) + flash('Dávka naskenovaných úloh nenalezena, skeny již byly pravděpodobně zpracovány nebo smazány.', 'danger') + return redirect(url_for('org_jobs')) if not g.user.is_admin and g.user.user_id != job.user_id: raise werkzeug.exceptions.Forbidden() + if job.state != db.JobState.done: + flash('Počkejte prosím, až dávka naskenovaných úloh doběhne.', 'danger') + return redirect(url_for('org_jobs')) + if 'type' in job.in_json and job.in_json['type'] == 'feedback': scans_type = 'feedback' scans_type_name = 'oprava' @@ -1832,14 +1822,6 @@ def org_contest_scans_process(ct_id: int, job_id: int, site_id: Optional[int] = if scans_type == 'feedback' and not ctx.rights.can_upload_feedback(): raise werkzeug.exceptions.Forbidden() - if job.state != db.JobState.done: - return render_template( - 'org_contest_scans_process.html', - ctx=ctx, - job=job, - scans_type=scans_type, - ) - pages = sess.query(db.ScanPage).filter_by(job_id=job_id).order_by('file_nr', 'page_nr').all() tasks = sess.query(db.Task).filter(db.Task.task_id.in_(job.in_json['task_ids'])).order_by('code').all() pion_query = sess.query(db.Participation).filter( diff --git a/mo/web/org_jobs.py b/mo/web/org_jobs.py index 7851eab283ec46b899d7005f9f504c8dc2e4dd9d..5018eeab4562c44fdc1497b4cf96f475a3353e02 100644 --- a/mo/web/org_jobs.py +++ b/mo/web/org_jobs.py @@ -1,4 +1,4 @@ -from flask import render_template, g, redirect, url_for, flash +from flask import render_template, g, redirect, url_for, flash, request from flask_wtf.form import FlaskForm import os from sqlalchemy.orm import joinedload @@ -48,6 +48,7 @@ def org_jobs(): 'org_jobs.html', jobs=jobs, form_delete_job=form_delete_job, + back_url=request.args.get('back'), ) diff --git a/mo/web/templates/org_contest_scans.html b/mo/web/templates/org_contest_scans.html index 40fbb320cf04cd1ba6419578c545c8f2ce659155..b32222ca5d1a549e921a3cbb00deb78f4cb19700 100644 --- a/mo/web/templates/org_contest_scans.html +++ b/mo/web/templates/org_contest_scans.html @@ -44,42 +44,12 @@ jejich přiřazení jednotlivým soutěžícím. {{ field(proc_form.process_scans) }} </form> -<h3>Nahráno k roztřídění</h3> -{% if jobs %} -<p>Smazat dávky lze v <a href="{{ url_for('org_jobs') }}">přehledu všech dávek</a>.</p> -<table class=data> - <thead> - <tr> - <th>Datum - <th>Typ skenů - <th>Úlohy - <th>Stav - {% if g.user.is_admin %}<th>Vlastník{% endif %} - <th>Akce - </tr> - </thead> - {% for (job, type, tasks) in jobs %} - <tr class="job-{{ job.state.name }}"> - <td>{{ job.created_at|timeformat }} - <td>{{ type }} - <td>{{ tasks|map(attribute='code')|join(', ') }} - <td> - {% if job.state == JobState.done %} - Připraveno k roztřídění - {% else %} - {{ job.state.friendly_name() }} - {% endif %} - {% if g.user.is_admin %}<td>{{ job.user|user_link }}{% endif %} - <td><div class="btn-group"> - {% if job.state == JobState.done %} - <a class="btn btn-xs btn-primary" href="{{ ctx.url_for('org_contest_scans_process', job_id=job.job_id) }}">Roztřídit skeny</a> - {% endif %} - </div> - </tr> - {% endfor %} -</table> -{% else %} -<p>Žádné nahrané skeny k roztřídění.</p> +{% if num_scan_jobs > 0 %} +<h3>Rozpracované třídění</h3> + +<p>Už jste nahráli k roztřídění {{ num_scan_jobs|inflected('dávku', 'dávky', 'dávek') }} skenů. +Podívejte se do <a href='{{ url_for('org_jobs', back=ctx.url_for('org_contest_scans')) }}'>seznamu dávek</a>. + {% endif %} {% endblock %} diff --git a/mo/web/templates/org_contest_scans_process.html b/mo/web/templates/org_contest_scans_process.html index db0504c009dd1baa8445e764173a89c7cb14cca8..82596c619f18c95caf5e9c4afd1a4180a2ce92a7 100644 --- a/mo/web/templates/org_contest_scans_process.html +++ b/mo/web/templates/org_contest_scans_process.html @@ -16,16 +16,6 @@ Třídění skenů {{ scans_title }} pro {{ ctx.round.name|lower }} kategorie {{ {% endblock %} {% block body %} -{% if job.state in [JobState.preparing, JobState.ready, JobState.running] %} -<p>Právě běží zpracování, vyčkejte prosím několik okamžiků (stránka se sama obnoví).</p> - -<script> -setTimeout(function () { location.reload(1); }, 10_000); -</script> -{% elif job.state != JobState.done %} -<p>Zpracování selhalo, více detailů naleznete v <a href="{{ url_for('org_job', id=job.job_id) }}">detailu dávky</a>.</p> -{% else %} - <p>Napravo můžete klikáním vybírat jednotlivé naskenované stránky a pomocí vrchních políček je přiřazovat jednotlivým úlohám a soutěžícím. Pokud je nějaké řešení přes více stránek, musí na sebe navazovat číslování stránek. Až bude vše správně zatříděné, můžete aktuální stav uložit tlačítkem <b>[Uložit]</b>. Poté můžete celou dávku odeslat ke zpracování pomocí <b>[Ukončit a zpracovat]</b> @@ -461,5 +451,4 @@ selectRow(0); scrollToRow(0); </script> -{% endif %} {% endblock %} diff --git a/mo/web/templates/org_job.html b/mo/web/templates/org_job.html index b7f9e035f9195c4d56c7534818e069f5c1bc9bb8..6dc621b7237506c9c65061cc7307cee06bf43fd5 100644 --- a/mo/web/templates/org_job.html +++ b/mo/web/templates/org_job.html @@ -34,7 +34,7 @@ {% if job.out_file %} <a class='btn btn-primary' href='{{ url_for('org_job_output', id=job.job_id) }}'>Stáhnout výstup</a> -{% elif job.type == 'process_scans' and 'contest_id' in job.in_json and 'site_id' in job.in_json %} +{% elif job.type == 'process_scans' and job.state == JobState.done and 'contest_id' in job.in_json and 'site_id' in job.in_json %} <a class='btn btn-primary' href='{{ url_for('org_contest_scans_process', job_id=job.job_id, ct_id=job.in_json['contest_id'], site_id=job.in_json['site_id']) }}'>Roztřídit skeny</a> {% endif %} diff --git a/mo/web/templates/org_jobs.html b/mo/web/templates/org_jobs.html index 62eecf8d2bb651fa38b0b1718b3b369e2c40df25..cf7ed758664fe64c0e0d9583b9c112a54905e7a3 100644 --- a/mo/web/templates/org_jobs.html +++ b/mo/web/templates/org_jobs.html @@ -52,4 +52,10 @@ dávku po stažení výstupu smažete sami – šetří to místo na serveru. <p>Žádné dávky nejsou nyní naplánované. {% endif %} +{% if back_url %} +<div class="btn-group"> + <a class='btn btn-primary' href='{{ back_url }}'>Zpět na předchozí stránku</a> +</div> +{% endif %} + {% endblock %}