Added private links
This commit is contained in:
parent
ad0db64f3c
commit
f0a942dfc6
3
.gitignore
vendored
3
.gitignore
vendored
@ -4,5 +4,6 @@ db.sqlite3
|
|||||||
credentials
|
credentials
|
||||||
polyphonic/settings.py
|
polyphonic/settings.py
|
||||||
env
|
env
|
||||||
text.*
|
test.*
|
||||||
static
|
static
|
||||||
|
teststore
|
||||||
9
Makefile
9
Makefile
@ -25,3 +25,12 @@ static/fonts/Quicksand_Book.otf:
|
|||||||
mkdir -p static/fonts
|
mkdir -p static/fonts
|
||||||
unzip -d static/fonts quicksand.zip
|
unzip -d static/fonts quicksand.zip
|
||||||
rm quicksand.zip
|
rm quicksand.zip
|
||||||
|
|
||||||
|
start_s3_storage:
|
||||||
|
test ! -f teststore/pid
|
||||||
|
mkdir -p teststore
|
||||||
|
MINIO_ACCESS_KEY=polyphonic_test_key MINIO_SECRET_KEY=polyphonic_secret minio server teststore & echo "$$!" > teststore/pid
|
||||||
|
cat teststore/pid
|
||||||
|
|
||||||
|
stop_s3_storage:
|
||||||
|
kill `cat teststore/pid` && rm teststore/pid
|
||||||
@ -7,6 +7,11 @@ class CodeForm(forms.Form):
|
|||||||
passphrase = forms.CharField(max_length=32)
|
passphrase = forms.CharField(max_length=32)
|
||||||
|
|
||||||
class SubmissionForm(forms.ModelForm):
|
class SubmissionForm(forms.ModelForm):
|
||||||
|
method = forms.ChoiceField(choices=(
|
||||||
|
('upload', 'I need to upload a file'),
|
||||||
|
('link', 'I have a link from my own cloud storage provider')
|
||||||
|
), initial='upload')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Submission
|
model = Submission
|
||||||
fields = ['name', 'instrument', 'notes']
|
fields = ['name', 'instrument', 'method', 'notes']
|
||||||
23
interface/migrations/0020_auto_20201003_2103.py
Normal file
23
interface/migrations/0020_auto_20201003_2103.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 3.1.1 on 2020-10-03 11:03
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('interface', '0019_project_owner'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='submission',
|
||||||
|
old_name='key',
|
||||||
|
new_name='url',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='submission',
|
||||||
|
name='private',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -9,10 +9,11 @@ import random
|
|||||||
import boto3
|
import boto3
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
s3client = boto3.client('s3')
|
s3client = boto3.client('s3', **getattr(settings, 'S3_CREDENTIALS', {}))
|
||||||
|
|
||||||
BUCKET = settings.AWS_BUCKET
|
BUCKET = settings.AWS_BUCKET
|
||||||
|
|
||||||
@ -102,15 +103,29 @@ class Submission(models.Model):
|
|||||||
instrument = models.CharField(max_length=100, verbose_name="Instrument / Voice")
|
instrument = models.CharField(max_length=100, verbose_name="Instrument / Voice")
|
||||||
notes = models.TextField(blank=True)
|
notes = models.TextField(blank=True)
|
||||||
complete = models.BooleanField(default=False)
|
complete = models.BooleanField(default=False)
|
||||||
key = models.CharField(max_length=512, blank=True)
|
url = models.CharField(max_length=512, blank=True)
|
||||||
|
private = models.BooleanField(default=False)
|
||||||
|
|
||||||
def presigned_url(self):
|
@property
|
||||||
params = {'Bucket': BUCKET, 'Key': self.key}
|
def download_url(self):
|
||||||
|
if not self.complete:
|
||||||
|
raise RuntimeError("Submission not complete")
|
||||||
|
|
||||||
|
if self.private:
|
||||||
|
return self.url
|
||||||
|
|
||||||
|
params = {'Bucket': BUCKET, 'Key': self.url}
|
||||||
return s3client.generate_presigned_url('get_object', Params=params, ExpiresIn=3600)
|
return s3client.generate_presigned_url('get_object', Params=params, ExpiresIn=3600)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def download_name(self):
|
||||||
|
uri = urlparse(self.download_url)
|
||||||
|
_, name = os.path.split(uri.path)
|
||||||
|
return name or "<Unknown>"
|
||||||
|
|
||||||
def key_template(self):
|
def key_template(self):
|
||||||
return "{}_{}_{}_${{filename}}".format(
|
return "submissions/{}_{}_{}_${{filename}}".format(
|
||||||
timezone.localtime(self.date).isoformat(timespec='seconds').replace(':', ''),
|
timezone.localtime(self.date).isoformat(timespec='seconds').replace(':', '')[:17],
|
||||||
slugify(self.name),
|
slugify(self.name),
|
||||||
slugify(self.instrument)
|
slugify(self.instrument)
|
||||||
)
|
)
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
<h3>
|
<h3>
|
||||||
{{ resource.name }}
|
{{ resource.name }}
|
||||||
{% if download %}
|
{% if download %}
|
||||||
<small><a href="{{ download }}">
|
<small><a href="{{ download }}" target="_blank" rel="noopener noreferrer">
|
||||||
<i class="fas fa-download"></i> Download
|
<i class="fas fa-download"></i> Download
|
||||||
</a></small>
|
</a></small>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="narrow">
|
<div class="narrow">
|
||||||
<h3 id="status">Select a file for upload</h3>
|
<h3 id="status">File upload</h3>
|
||||||
<form method="POST" action="{{ upload.url }}" enctype="multipart/form-data" id="item-upload" class="dropzone">
|
<form method="POST" action="{{ upload.url }}" enctype="multipart/form-data" id="item-upload" class="dropzone">
|
||||||
<div class="fallback">
|
<div class="fallback">
|
||||||
{% for field, value in upload.fields.items %}
|
{% for field, value in upload.fields.items %}
|
||||||
@ -55,11 +55,11 @@ Dropzone.options.itemUpload = {
|
|||||||
autoProcessQueue: false,
|
autoProcessQueue: false,
|
||||||
createImageThumbnails: false,
|
createImageThumbnails: false,
|
||||||
//acceptedFiles: acceptFiles,
|
//acceptedFiles: acceptFiles,
|
||||||
timeout: 3600000,
|
timeout: 3600000,
|
||||||
maxFiles: 1,
|
maxFiles: 1,
|
||||||
addRemoveLinks: true,
|
addRemoveLinks: true,
|
||||||
maxFilesize: 500,
|
maxFilesize: 500,
|
||||||
dictDefaultMessage: "Select a file to upload (max 500Mb)",
|
dictDefaultMessage: "Click to select a file to upload (max 500Mb)",
|
||||||
dictFallbackMessage: "Your browser is old!, using alternative method",
|
dictFallbackMessage: "Your browser is old!, using alternative method",
|
||||||
init: function() {
|
init: function() {
|
||||||
let dz = this;
|
let dz = this;
|
||||||
@ -79,6 +79,9 @@ Dropzone.options.itemUpload = {
|
|||||||
let s3_location = f.xhr.getResponseHeader("Location");
|
let s3_location = f.xhr.getResponseHeader("Location");
|
||||||
location.href = "{{ success_url }}?location=" + s3_location;
|
location.href = "{{ success_url }}?location=" + s3_location;
|
||||||
});
|
});
|
||||||
|
this.on('error', function(file, msg) {
|
||||||
|
status.html('There was an issue - please see troubleshooting');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,10 @@
|
|||||||
<h3>Excellent, you are ready to make a submission!</h3>
|
<h3>Excellent, you are ready to make a submission!</h3>
|
||||||
<p>
|
<p>
|
||||||
Please enter some basic information so we can identify your submission and
|
Please enter some basic information so we can identify your submission and
|
||||||
note anything that might be relevant.
|
note anything that might be relevant.<br/>
|
||||||
|
Most people will want to upload their
|
||||||
|
file directly but if you have your own cloud storage provider you can send a
|
||||||
|
public link to your submission instead.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@ -13,6 +16,7 @@
|
|||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form }}
|
{{ form }}
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
|
<a href="{% url 'project_detail' project.pk %}">Cancel</a>
|
||||||
<button type="submit" class="btn-primary">Continue</button>
|
<button type="submit" class="btn-primary">Continue</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -8,8 +8,8 @@
|
|||||||
<tr><th>From:</th><td>{{ submission.name }}</td></tr>
|
<tr><th>From:</th><td>{{ submission.name }}</td></tr>
|
||||||
<tr><th>Instrument:</th><td>{{ submission.instrument }}</td></tr>
|
<tr><th>Instrument:</th><td>{{ submission.instrument }}</td></tr>
|
||||||
<tr><th>Notes:</th><td>{{ submission.notes }}</td></tr>
|
<tr><th>Notes:</th><td>{{ submission.notes }}</td></tr>
|
||||||
{% if download %}
|
{% if can_download %}
|
||||||
<tr><th>Download:</th><td><a href="{{ download }}">{{ submission.key }}</a></td></tr>
|
<tr><th>Download:</th><td><a href="{{ submission.download_url }}" target="_blank" rel="noopener noreferrer">{{ submission.download_name }}</a></td></tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
18
interface/templates/interface/submission_link.html
Normal file
18
interface/templates/interface/submission_link.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{% extends "interface/project_base.html" %}
|
||||||
|
|
||||||
|
{% block page %}
|
||||||
|
<div class="narrow">
|
||||||
|
<h3>Link to cloud storage</h3>
|
||||||
|
<p>Please paste the full link from your storage provider</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<form class="vertical" action="" method="POST" enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form }}
|
||||||
|
<div class="form-actions">
|
||||||
|
<a href="{{ cancel_url }}">Cancel</a>
|
||||||
|
<button type="submit" class="btn-primary">Continue</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<td>{{ submission.instrument }}</td>
|
<td>{{ submission.instrument }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{% url 'submission_detail' project=project.pk pk=submission.pk %}"><i class="fas fa-info-circle"></i></a>
|
<a href="{% url 'submission_detail' project=project.pk pk=submission.pk %}"><i class="fas fa-info-circle"></i></a>
|
||||||
<a href="{{ submission.presigned_url }}"><i class="fas fa-download"></i></a>
|
<a href="{{ submission.download_url }}" target="_blank" rel="noopener noreferrer"><i class="fas fa-download"></i></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@ -4,27 +4,50 @@ from interface import models
|
|||||||
|
|
||||||
class SubmissionTestCase(TestCase):
|
class SubmissionTestCase(TestCase):
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def setUpTestData():
|
||||||
|
e1 = models.Ensemble.objects.create(name='The Be Sharps', code="1234", passphrase='Homer')
|
||||||
|
e1.projects.create(name='Baby on Board')
|
||||||
|
e2 = models.Ensemble.objects.create(name='Lisa and the Bleeding Gums', code="2345", passphrase="Maggie")
|
||||||
|
e2.projects.create(name='Baker St')
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
|
||||||
def test_submission(self):
|
def test_submission_upload(self):
|
||||||
ensemble = models.Ensemble.objects.create(name="The Be Sharps", passphrase="Homer")
|
response = self.client.post('/register', {'code': '12-34', 'passphrase': 'Homer'})
|
||||||
project = ensemble.projects.create(name='Baby on Board')
|
|
||||||
|
|
||||||
response = self.client.post('/register', {'code': ensemble.code, 'passphrase': ensemble.passphrase})
|
|
||||||
self.assertRedirects(response, '/')
|
self.assertRedirects(response, '/')
|
||||||
|
|
||||||
response = self.client.post(f"/projects/{project.pk}/submission", {'name': 'Ned', 'instrument': 'God'})
|
response = self.client.post(f"/projects/1/submission", {'name': 'Ned', 'instrument': 'Harp', 'method': 'upload'})
|
||||||
#self.assertRedirects(response, '/projects/1/submission/1/upload')
|
self.assertRedirects(response, '/projects/1/submission/1/upload')
|
||||||
|
|
||||||
self.skipTest("Need to mock S3")
|
|
||||||
|
|
||||||
response = self.client.get(response.url)
|
response = self.client.get(response.url)
|
||||||
upload = response.context['upload']
|
upload = response.context['upload']
|
||||||
self.assertEqual(upload['url'], f"https://{ensemble.bucket}.s3.amazonaws.com/")
|
self.assertEqual(upload['url'], f"http://localhost:9000/{models.BUCKET}")
|
||||||
self.assertRegex(upload['fields']['key'], r'^baby-on-board\/[0-9T\-]+_ned_god_\$\{filename\}$')
|
self.assertRegex(upload['fields']['key'], r'^baby-on-board\/submissions\/[0-9T\-]+_ned_harp_\$\{filename\}$')
|
||||||
self.assertEqual(upload['fields']['success_action_redirect'], 'http://testserver/projects/1/submission/1/complete')
|
self.assertEqual(upload['fields']['success_action_redirect'], 'http://testserver/projects/1/submission/1/complete')
|
||||||
|
|
||||||
self.assertEqual(models.Submission.objects.count(), 1)
|
self.assertEqual(models.Submission.objects.count(), 1)
|
||||||
self.assertRedirects(self.client.get(f"/projects/{project.pk}/submission/1/cancel"), '/projects/1')
|
self.assertRedirects(self.client.get(f"/projects/1/submission/1/cancel"), '/projects/1')
|
||||||
self.assertEqual(models.Submission.objects.count(), 0)
|
self.assertEqual(models.Submission.objects.count(), 0)
|
||||||
|
|
||||||
|
def test_submission_link(self):
|
||||||
|
response = self.client.post('/register', {'code': '12-34', 'passphrase': 'Homer'})
|
||||||
|
self.assertRedirects(response, '/')
|
||||||
|
|
||||||
|
response = self.client.post(f"/projects/1/submission", {'name': 'Ned', 'instrument': 'Harp', 'method': 'link'})
|
||||||
|
self.assertRedirects(response, '/projects/1/submission/1/link')
|
||||||
|
|
||||||
|
url = 'https://drive.google.com/a/path/to/a/video.mp4#g6e6e4a23'
|
||||||
|
|
||||||
|
response = self.client.post(f"/projects/1/submission/1/link", {'url': url})
|
||||||
|
self.assertRedirects(response, '/projects/1/submission/1')
|
||||||
|
|
||||||
|
response = self.client.get('/projects/1/submission/1')
|
||||||
|
self.assertContains(response, "Thankyou for your submission")
|
||||||
|
|
||||||
|
response = self.client.get('/projects/1')
|
||||||
|
self.assertContains(response, 'Ned')
|
||||||
|
|
||||||
|
s = models.Submission.objects.get(pk=1)
|
||||||
|
self.assertEqual(s.download_url, url)
|
||||||
@ -18,8 +18,10 @@ urlpatterns = [
|
|||||||
|
|
||||||
path('projects/<int:project>/submission', views.SubmissionCreateView.as_view(), name="submission_create"),
|
path('projects/<int:project>/submission', views.SubmissionCreateView.as_view(), name="submission_create"),
|
||||||
path('projects/<int:project>/submission/<int:pk>', views.SubmissionDetailView.as_view(), name="submission_detail"),
|
path('projects/<int:project>/submission/<int:pk>', views.SubmissionDetailView.as_view(), name="submission_detail"),
|
||||||
|
path('projects/<int:project>/submission/<int:pk>/link', views.SubmissionLinkView.as_view(), name="submission_link"),
|
||||||
path('projects/<int:project>/submission/<int:pk>/upload', views.SubmissionUploadView.as_view(), name="submission_upload"),
|
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>/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>/submissions', views.SubmissionListView.as_view(), name="submission_list"),
|
path('projects/<int:project>/submissions', views.SubmissionListView.as_view(), name="submission_list"),
|
||||||
|
|
||||||
path('projects/<int:project>/resources', views.ResourceListView.as_view(), name="resource_list"),
|
path('projects/<int:project>/resources', views.ResourceListView.as_view(), name="resource_list"),
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from django.shortcuts import render, get_object_or_404, redirect, resolve_url
|
|||||||
from django.views.generic import TemplateView, View, RedirectView
|
from django.views.generic import TemplateView, View, RedirectView
|
||||||
from django.views.generic.detail import DetailView, SingleObjectMixin
|
from django.views.generic.detail import DetailView, SingleObjectMixin
|
||||||
from django.views.generic.list import ListView
|
from django.views.generic.list import ListView
|
||||||
from django.views.generic.edit import CreateView, UpdateView
|
from django.views.generic.edit import CreateView, UpdateView, FormView
|
||||||
from django.views.generic.base import ContextMixin
|
from django.views.generic.base import ContextMixin
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.core.exceptions import SuspiciousOperation
|
from django.core.exceptions import SuspiciousOperation
|
||||||
@ -11,6 +11,7 @@ from django.contrib import auth
|
|||||||
from markdown2 import markdown
|
from markdown2 import markdown
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from urllib.parse import urlparse, urlencode
|
from urllib.parse import urlparse, urlencode
|
||||||
|
import os.path
|
||||||
|
|
||||||
from . import models, forms
|
from . import models, forms
|
||||||
|
|
||||||
@ -84,8 +85,7 @@ class S3UploadMixin(ProjectMixin):
|
|||||||
context['accept_files'] = self.accept_files
|
context['accept_files'] = self.accept_files
|
||||||
return context
|
return context
|
||||||
|
|
||||||
class S3CompleteMixin(View):
|
class S3CompleteView(SingleObjectMixin, RedirectView):
|
||||||
always_set = False
|
|
||||||
|
|
||||||
def complete(self, key):
|
def complete(self, key):
|
||||||
self.object.key = key
|
self.object.key = key
|
||||||
@ -94,14 +94,14 @@ class S3CompleteMixin(View):
|
|||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
|
|
||||||
if self.always_set or not self.object.key:
|
if 'key' in request.GET:
|
||||||
if 'location' in request.GET:
|
self.complete(request.GET['key'])
|
||||||
uri = urlparse(request.GET['location'])
|
elif 'location' in request.GET:
|
||||||
self.complete(uri.path[1:])
|
uri = urlparse(request.GET['location'])
|
||||||
elif 'key' in request.GET:
|
_bucket, key = uri.path[1:].split('/', 1)
|
||||||
self.complete(request.GET['key'])
|
self.complete(key)
|
||||||
else:
|
else:
|
||||||
raise KeyError("No key or location found")
|
raise KeyError("No key or location found")
|
||||||
|
|
||||||
return super().get(request, *args, **kwargs)
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
@ -209,9 +209,10 @@ class WikiEditView(ProjectMixin, UpdateView):
|
|||||||
model = models.WikiPage
|
model = models.WikiPage
|
||||||
fields = ['title', 'markdown']
|
fields = ['title', 'markdown']
|
||||||
|
|
||||||
class SubmissionCreateView(ProjectMixin, CreateView):
|
class SubmissionCreateView(ProjectMixin, FormView):
|
||||||
model = models.Submission
|
#model = models.Submission
|
||||||
fields = ['name', 'instrument', 'notes']
|
#fields = ['name', 'instrument', 'url', 'notes']
|
||||||
|
form_class = forms.SubmissionForm
|
||||||
template_name = "interface/submission_create.html"
|
template_name = "interface/submission_create.html"
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
@ -222,23 +223,32 @@ class SubmissionCreateView(ProjectMixin, CreateView):
|
|||||||
self.request.session['name'] = self.object.name
|
self.request.session['name'] = self.object.name
|
||||||
self.request.session['instrument'] = self.object.instrument
|
self.request.session['instrument'] = self.object.instrument
|
||||||
|
|
||||||
|
if form.cleaned_data['method'] == 'link':
|
||||||
|
return redirect('submission_link', project=self.object.project.pk, pk=self.object.pk)
|
||||||
|
|
||||||
return redirect('submission_upload', project=self.object.project.pk, pk=self.object.pk)
|
return redirect('submission_upload', project=self.object.project.pk, pk=self.object.pk)
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
return { k: self.request.session.get(k) for k in ('name', 'instrument') }
|
return { k: self.request.session.get(k) for k in ('name', 'instrument') }
|
||||||
|
|
||||||
|
class SubmissionCompleteView(ProjectMixin, S3CompleteView):
|
||||||
class SubmissionDetailView(ProjectMixin, S3CompleteMixin, DetailView):
|
|
||||||
model = models.Submission
|
model = models.Submission
|
||||||
|
|
||||||
def complete(self, key):
|
def complete(self, key):
|
||||||
|
self.object.url = key
|
||||||
|
self.object.private = False
|
||||||
self.object.complete = True
|
self.object.complete = True
|
||||||
super().complete(key)
|
self.object.save()
|
||||||
|
|
||||||
|
def get_redirect_url(self, **kwargs):
|
||||||
|
return resolve_url('submission_detail', **self.kwargs)
|
||||||
|
|
||||||
|
class SubmissionDetailView(ProjectMixin, DetailView):
|
||||||
|
model = models.Submission
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
if self.request.is_admin:
|
context['can_download'] = self.request.is_admin
|
||||||
context['download'] = self.object.presigned_url()
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
class SubmissionUploadView(S3UploadMixin, DetailView):
|
class SubmissionUploadView(S3UploadMixin, DetailView):
|
||||||
@ -246,12 +256,35 @@ class SubmissionUploadView(S3UploadMixin, DetailView):
|
|||||||
model = models.Submission
|
model = models.Submission
|
||||||
accept_files = "video/*"
|
accept_files = "video/*"
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return resolve_url('submission_complete', **self.kwargs)
|
||||||
|
|
||||||
|
def get_cancel_url(self):
|
||||||
|
return resolve_url('submission_cancel', **self.kwargs)
|
||||||
|
|
||||||
|
class SubmissionLinkView(ProjectMixin, UpdateView):
|
||||||
|
model = models.Submission
|
||||||
|
template_name = 'interface/submission_link.html'
|
||||||
|
fields = ['url']
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['cancel_url'] = self.get_cancel_url()
|
||||||
|
return context
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return resolve_url('submission_detail', **self.kwargs)
|
return resolve_url('submission_detail', **self.kwargs)
|
||||||
|
|
||||||
def get_cancel_url(self):
|
def get_cancel_url(self):
|
||||||
return resolve_url('submission_cancel', **self.kwargs)
|
return resolve_url('submission_cancel', **self.kwargs)
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
self.object = form.save(commit=False)
|
||||||
|
self.object.complete = True
|
||||||
|
self.object.private = True
|
||||||
|
self.object.save()
|
||||||
|
return redirect(self.get_success_url())
|
||||||
|
|
||||||
class SubmissionCancelView(ProjectMixin, SingleObjectMixin, View):
|
class SubmissionCancelView(ProjectMixin, SingleObjectMixin, View):
|
||||||
model = models.Submission
|
model = models.Submission
|
||||||
|
|
||||||
@ -294,9 +327,8 @@ class ResourceUploadView(S3UploadMixin, DetailView):
|
|||||||
def get_cancel_url(self):
|
def get_cancel_url(self):
|
||||||
return resolve_url('resource_list', project=self.kwargs['project'])
|
return resolve_url('resource_list', project=self.kwargs['project'])
|
||||||
|
|
||||||
class ResourceCompleteView(S3CompleteMixin, SingleObjectMixin, RedirectView):
|
class ResourceCompleteView(ProjectMixin, S3CompleteView):
|
||||||
model = models.Resource
|
model = models.Resource
|
||||||
always_set = True
|
|
||||||
|
|
||||||
def get_redirect_url(self, **kwargs):
|
def get_redirect_url(self, **kwargs):
|
||||||
return resolve_url('resource_list', project=self.kwargs['project'])
|
return resolve_url('resource_list', project=self.kwargs['project'])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user