dump
This commit is contained in:
parent
76a74efbe7
commit
80e0867526
30
Main/migrations/0028_dump.py
Normal file
30
Main/migrations/0028_dump.py
Normal file
@ -0,0 +1,30 @@
|
||||
# Generated by Django 3.2.4 on 2022-03-15 19:08
|
||||
|
||||
import Main.models.mixins
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('Main', '0027_task_allow_sharing'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Dump',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('timestamp', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('fs_id', models.IntegerField(null=True)),
|
||||
('ready', models.BooleanField(default=False)),
|
||||
('executor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
('task', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='Main.task')),
|
||||
],
|
||||
bases=(Main.models.mixins.FileStorageMixin, models.Model),
|
||||
),
|
||||
]
|
17
Main/migrations/0029_remove_dump_ready.py
Normal file
17
Main/migrations/0029_remove_dump_ready.py
Normal file
@ -0,0 +1,17 @@
|
||||
# Generated by Django 3.2.4 on 2022-03-15 19:20
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('Main', '0028_dump'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='dump',
|
||||
name='ready',
|
||||
),
|
||||
]
|
@ -10,3 +10,4 @@ from Main.models.progress import Progress
|
||||
from Main.models.solution_file import SolutionFile
|
||||
from Main.models.friendship import Friendship
|
||||
from Main.models.language_apply import LanguageApply
|
||||
from Main.models.dump import Dump
|
||||
|
25
Main/models/dump.py
Normal file
25
Main/models/dump.py
Normal file
@ -0,0 +1,25 @@
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
||||
from .mixins import FileStorageMixin
|
||||
|
||||
|
||||
class Dump(FileStorageMixin, models.Model):
|
||||
timestamp = models.DateTimeField(default=timezone.now)
|
||||
fs_id = models.IntegerField(null=True)
|
||||
executor = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
task = models.ForeignKey("Task", on_delete=models.CASCADE, null=True)
|
||||
|
||||
@property
|
||||
def ready(self):
|
||||
return self.fs_id is not None
|
||||
|
||||
@property
|
||||
def str_date(self):
|
||||
return self.timestamp.strftime("%Y-%m-%dT%H:%M:%S")
|
||||
|
||||
@property
|
||||
def filename(self):
|
||||
if self.task is not None:
|
||||
return f"dump-task-{self.task.id}-{self.str_date}"
|
@ -2,6 +2,7 @@ from django.contrib.postgres.fields import ArrayField
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from Main.models.dump import Dump
|
||||
from Main.models.extrafile import ExtraFile
|
||||
|
||||
|
||||
@ -21,6 +22,10 @@ class Task(models.Model):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@property
|
||||
def dumps(self):
|
||||
return Dump.objects.filter(task=self).order_by("-timestamp")
|
||||
|
||||
@property
|
||||
def files(self):
|
||||
return ExtraFile.objects.filter(task=self, is_test=False)
|
||||
|
@ -1,7 +1,8 @@
|
||||
from django.http import HttpResponse
|
||||
|
||||
from Main.models import ExtraFile
|
||||
from Main.models import ExtraFile, Dump
|
||||
from SprintLib.BaseView import BaseView, AccessError
|
||||
from SprintLib.queue import send_to_queue
|
||||
|
||||
|
||||
class TaskSettingsView(BaseView):
|
||||
@ -23,6 +24,11 @@ class TaskSettingsView(BaseView):
|
||||
self.entities.task.save()
|
||||
return f"/admin/task?task_id={self.entities.task.id}"
|
||||
|
||||
def post_dump(self):
|
||||
dump = Dump.objects.create(executor=self.request.user, task=self.entities.task)
|
||||
send_to_queue("files", {"id": dump.id})
|
||||
return f"/admin/task?task_id={self.entities.task.id}"
|
||||
|
||||
def _upload(self, is_test):
|
||||
filename = self.request.FILES["file"].name
|
||||
ef, created = None, None
|
||||
|
@ -1,9 +1,68 @@
|
||||
import json
|
||||
from os import mkdir, listdir, remove
|
||||
from os.path import exists, join
|
||||
from shutil import rmtree
|
||||
from zipfile import ZipFile
|
||||
|
||||
from Main.models import Dump, ExtraFile
|
||||
from SprintLib.queue import MessagingSupport
|
||||
from SprintLib.utils import write_bytes
|
||||
|
||||
|
||||
class Command(MessagingSupport):
|
||||
help = "starts file generator"
|
||||
queue_name = "files"
|
||||
|
||||
def process_task(self, dump):
|
||||
task_fields = [
|
||||
'name',
|
||||
'public',
|
||||
'legend',
|
||||
'input_format',
|
||||
'output_format',
|
||||
'specifications',
|
||||
'time_limit',
|
||||
'time_estimation',
|
||||
]
|
||||
task_data = {field: getattr(dump.task, field) for field in task_fields}
|
||||
files_fields = [
|
||||
'id',
|
||||
'filename',
|
||||
'is_test',
|
||||
'is_sample',
|
||||
'readable',
|
||||
'test_number'
|
||||
]
|
||||
task_data['files'] = [
|
||||
{
|
||||
field: getattr(file, field)
|
||||
for field in files_fields
|
||||
}
|
||||
for file in ExtraFile.objects.filter(task=dump.task)
|
||||
]
|
||||
tempdir = "/var/tmp/dump/"
|
||||
dump_filename = 'dump.zip'
|
||||
try:
|
||||
mkdir(tempdir)
|
||||
with open(join(tempdir, 'meta.json'), 'w') as fs:
|
||||
json.dump(task_data, fs)
|
||||
for ef in ExtraFile.objects.filter(task=dump.task):
|
||||
with open(join(tempdir, ef.id), 'wb') as fs:
|
||||
fs.write(ef.bytes)
|
||||
with ZipFile(dump_filename, 'w') as zipfile:
|
||||
for file in listdir(tempdir):
|
||||
zipfile.write(join(tempdir, file))
|
||||
fs_id = write_bytes(open(dump_filename, 'rb').read())
|
||||
dump.fs_id = fs_id
|
||||
dump.save()
|
||||
finally:
|
||||
if exists(tempdir):
|
||||
rmtree(tempdir)
|
||||
if exists(dump_filename):
|
||||
remove(dump_filename)
|
||||
|
||||
def process(self, payload: dict):
|
||||
...
|
||||
id = payload['id']
|
||||
dump = Dump.objects.get(id=id)
|
||||
if dump.task:
|
||||
self.process_task(dump)
|
||||
|
@ -311,5 +311,28 @@
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<hr><hr>
|
||||
<h3>Дампы</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th scope="col">Id дампа</th>
|
||||
<th scope="col">Время запроса</th>
|
||||
<th scope="col">Инициатор</th>
|
||||
<th scope="col">Готовность</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for dump in task.dumps %}
|
||||
<tr>
|
||||
<td>{{ dump.id }}</td>
|
||||
<td>{{ dump.timestamp }}</td>
|
||||
<td>{{ dump.executor.username }}</td>
|
||||
<td>{% if dump.ready %}<a href="#">Скачать</a>{% else %}<badge class="badge badge-info"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="circle-notch" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="width: 20px;" class="svg-inline--fa fa-circle-notch fa-w-16 fa-spin fa-lg"><path fill="currentColor" d="M288 39.056v16.659c0 10.804 7.281 20.159 17.686 23.066C383.204 100.434 440 171.518 440 256c0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-84.47 56.786-155.564 134.312-177.219C216.719 75.874 224 66.517 224 55.712V39.064c0-15.709-14.834-27.153-30.046-23.234C86.603 43.482 7.394 141.206 8.003 257.332c.72 137.052 111.477 246.956 248.531 246.667C393.255 503.711 504 392.788 504 256c0-115.633-79.14-212.779-186.211-240.236C302.678 11.889 288 23.456 288 39.056z" class=""></path></svg> В процессе</badge>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
<button type="submit" name="action" value="dump" class="btn btn-primary"><i class="fa fa-arrow-right"></i> Создать дамп</button>
|
||||
</form>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user