Implemented makefile building

This commit is contained in:
Tris 2020-11-23 13:49:30 +11:00
parent 1b24a9258f
commit c7d30e9b35
5 changed files with 89 additions and 2 deletions

View File

@ -131,5 +131,16 @@ class Submission(models.Model):
slugify(self.instrument)
)
@property
def short_name(self):
_, ext = os.path.splitext(self.download_name)
return "{}_{}_{}{}".format(
#timezone.localtime(self.date).strftime("%Y%m%d%H%M%S"),
slugify(self.name),
slugify(self.instrument),
self.pk,
ext
)
def __str__(self):
return f"{self.name}: {self.date}"

View File

@ -0,0 +1,11 @@
ALL = {{ targets|join:" " }}
-include "local.mk"
all: ${ALL}
{% for s in submissions %}
{{ s.name }}:
curl -o $@ -L {{ s.url }}
{% endfor %}

View File

@ -1,6 +1,12 @@
{% extends "interface/project_base.html" %}
{% block page %}
<div class="admin-tools">
<a href="{{ signed_url }}">
<i class="fas fa-list"></i>
</a>
</div>
<table style="max-width: 800px; margin: 10pt auto;">
<thead>
<tr>

View File

@ -12,6 +12,7 @@ urlpatterns = [
path('', views.EnsembleDetailView.as_view(), name='ensemble_detail'),
path('projects/<int:pk>', views.ProjectDetailView.as_view(), name="project_detail"),
path('projects/<int:pk>/submissions.mk', views.ProjectMakefileView.as_view(), name="project_makefile"),
path('projects/<int:project>/page/<int:pk>', views.WikiView.as_view(), name="wiki"),
path('projects/<int:project>/page/<int:pk>/edit', views.WikiEditView.as_view(), name="wiki_edit"),
@ -23,6 +24,7 @@ urlpatterns = [
path('projects/<int:project>/submission/<int:pk>/upload', views.SubmissionUploadView.as_view(), name="submission_upload"),
path('projects/<int:project>/submission/<int:pk>/cancel', views.SubmissionCancelView.as_view(), name="submission_cancel"),
path('projects/<int:project>/submission/<int:pk>/complete', views.SubmissionCompleteView.as_view(), name="submission_complete"),
path('projects/<int:project>/submission/<int:pk>/download', views.SubmissionDownloadView.as_view(), name="submission_download"),
path('projects/<int:project>/submissions', views.SubmissionListView.as_view(), name="submission_list"),
path('projects/<int:project>/resources', views.ResourceListView.as_view(), name="resource_list"),

View File

@ -6,6 +6,7 @@ from django.views.generic.edit import CreateView, UpdateView, FormView
from django.views.generic.base import ContextMixin
from django.http import HttpResponseRedirect
from django.core.exceptions import SuspiciousOperation
from django.core.signing import Signer
from django.contrib import auth
from markdown2 import markdown
@ -20,6 +21,13 @@ from base64 import b64decode
import logging
logger = logging.getLogger(__name__)
signer = Signer()
def signed_url(name, **kwargs):
url = resolve_url(name, **kwargs)
sig = signer.sign(url)
return sig.replace(":", "?auth=")
class EnsembleMixin(object):
admin_required = False
@ -28,6 +36,15 @@ class EnsembleMixin(object):
request.ensemble_id = request.session.get('ensemble')
request.is_admin = request.user.is_superuser
if 'auth' in request.GET:
sig = signer.sign(request.path)
if sig[len(request.path)+1:] == request.GET['auth']:
logger.info("Allowing auth key")
request.is_admin = True
return super().dispatch(request, *args, **kwargs)
else:
raise SuspiciousOperation("Bad auth code")
if not request.ensemble_id:
return redirect('register')
@ -47,8 +64,11 @@ class ProjectMixin(EnsembleMixin):
def get_project(self):
if not hasattr(self, '_project'):
self._project = get_object_or_404(models.Project,
pk=self.kwargs['project'], ensemble=self.request.ensemble_id)
if self.request.is_admin: # can access any ensemble
self._project = get_object_or_404(models.Project, pk=self.kwargs['project'])
else:
self._project = get_object_or_404(models.Project,
pk=self.kwargs['project'], ensemble=self.request.ensemble_id)
return self._project
def get_queryset(self):
@ -192,6 +212,31 @@ class ProjectDetailView(EnsembleMixin, DetailView):
def get_queryset(self):
return models.Project.objects.filter(ensemble=self.request.ensemble_id)
class ProjectMakefileView(EnsembleMixin, DetailView):
template_name = 'interface/project_submissions.mk'
content_type = 'text/plain'
def get_queryset(self):
if self.request.is_admin:
return models.Project.objects.all()
return models.Project.objects.filter(ensemble=self.request.ensemble_id)
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
data['submissions'] = []
data['targets'] = []
for s in self.object.submissions:
name = s.short_name
data['targets'].append(name)
data['submissions'].append({
'url': self.request.build_absolute_uri(signed_url('submission_download', project=self.kwargs['pk'], pk=s.pk)),
'name': name,
})
return data
class WikiView(ProjectMixin, DetailView):
template_name = 'interface/wiki.html'
model = models.WikiPage
@ -245,6 +290,13 @@ class SubmissionCompleteView(ProjectMixin, S3CompleteView):
def get_redirect_url(self, **kwargs):
return resolve_url('submission_detail', **self.kwargs)
class SubmissionDownloadView(ProjectMixin, SingleObjectMixin, RedirectView):
model = models.Submission
admin_required = True
def get_redirect_url(self, **kwargs):
return self.get_object().download_url
class SubmissionDetailView(ProjectMixin, DetailView):
model = models.Submission
@ -307,6 +359,11 @@ class SubmissionListView(ProjectMixin, ListView):
def get_queryset(self):
return super().get_queryset().filter(complete=True).order_by('-pk')
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
data['signed_url'] = self.request.build_absolute_uri(signed_url('project_makefile', pk=self.kwargs['project']))
return data
class ResourceCreateView(ProjectMixin, CreateView):
model = models.Resource
fields = ['name', 'media_type', 'description']