Improved upload
This commit is contained in:
parent
53ec846f98
commit
59deeffefe
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,8 +2,9 @@ __pycache__
|
|||||||
*.pyc
|
*.pyc
|
||||||
db.sqlite3
|
db.sqlite3
|
||||||
credentials
|
credentials
|
||||||
polyphonic/settings.py
|
local_settings.py
|
||||||
env
|
env
|
||||||
|
old
|
||||||
test.*
|
test.*
|
||||||
static
|
static
|
||||||
teststore
|
teststore
|
||||||
|
|||||||
20
Dockerfile
Normal file
20
Dockerfile
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
FROM alpine:3.14
|
||||||
|
|
||||||
|
RUN apk add --no-cache python3 git ghostscript sqlite
|
||||||
|
|
||||||
|
WORKDIR /root
|
||||||
|
RUN python3 -m ensurepip
|
||||||
|
RUN pip3 install -U pip --no-cache-dir
|
||||||
|
|
||||||
|
COPY app /opt/polyphonic
|
||||||
|
WORKDIR /opt/polyphonic
|
||||||
|
|
||||||
|
COPY docker_settings.py polyphonic/local_settings.py
|
||||||
|
|
||||||
|
RUN pip3 install -r requirements.txt --no-cache-dir
|
||||||
|
|
||||||
|
RUN mkdir /var/polyphonic
|
||||||
|
RUN SECRET_KEY=_ python3 manage.py collectstatic --noinput
|
||||||
|
|
||||||
|
ENTRYPOINT ["python3", "manage.py"]
|
||||||
|
CMD ["runserver", "0.0.0.0:8000", "--insecure"]
|
||||||
@ -42,14 +42,14 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<p class="menu-label">Admin</p>
|
<p class="menu-label">Admin</p>
|
||||||
{% if request.is_admin %}
|
|
||||||
<ul class="menu-list">
|
<ul class="menu-list">
|
||||||
|
{% if request.is_admin %}
|
||||||
<li><a class="admin-link" href="{% url 'collection_list' %}">Collections</a></li>
|
<li><a class="admin-link" href="{% url 'collection_list' %}">Collections</a></li>
|
||||||
|
{% endif %}
|
||||||
{% if request.user.is_superuser %}
|
{% if request.user.is_superuser %}
|
||||||
<li><a class="admin-link" href="/admin" target="polyphonic_admin" rel="noopener noreferrer">Django Admin</a></li>
|
<li><a class="admin-link" href="/admin" target="polyphonic_admin" rel="noopener noreferrer">Django Admin</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<ul class="menu-list">
|
<ul class="menu-list">
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
|
|||||||
@ -28,3 +28,8 @@ urlpatterns = [
|
|||||||
path('projects/<int:project>/resources/<int:pk>/upload', views.ResourceUploadView.as_view(), name="resource_upload"),
|
path('projects/<int:project>/resources/<int:pk>/upload', views.ResourceUploadView.as_view(), name="resource_upload"),
|
||||||
path('projects/<int:project>/resources/<int:pk>/edit', views.ResourceEditView.as_view(), name="resource_edit"),
|
path('projects/<int:project>/resources/<int:pk>/edit', views.ResourceEditView.as_view(), name="resource_edit"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
if settings.DEBUG:
|
||||||
|
from django.views.static import serve
|
||||||
|
urlpatterns.append(path('local_storage/<path:path>', serve, {'document_root': 'local_storage'}))
|
||||||
@ -9,7 +9,7 @@ class WorkCreateForm(forms.ModelForm, BaseForm):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Work
|
model = Work
|
||||||
fields = ['name', 'code', 'running_time', 'notes']
|
fields = ['name', 'composer', 'edition', 'code', 'running_time', 'notes']
|
||||||
|
|
||||||
class PlaylistAddForm(forms.Form):
|
class PlaylistAddForm(forms.Form):
|
||||||
work = forms.ModelChoiceField(queryset=Work.objects.all())
|
work = forms.ModelChoiceField(queryset=Work.objects.all())
|
||||||
|
|||||||
28
app/library/migrations/0002_auto_20221201_0934.py
Normal file
28
app/library/migrations/0002_auto_20221201_0934.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Generated by Django 3.2.7 on 2022-11-30 22:34
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('library', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='work',
|
||||||
|
name='slug',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='work',
|
||||||
|
name='path',
|
||||||
|
field=models.CharField(default='', editable=False, help_text='Used as folder name', max_length=255),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='work',
|
||||||
|
name='composer',
|
||||||
|
field=models.CharField(default='Anon', help_text='Surname, Initials', max_length=255),
|
||||||
|
),
|
||||||
|
]
|
||||||
21
app/library/migrations/0003_auto_20221201_1540.py
Normal file
21
app/library/migrations/0003_auto_20221201_1540.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 3.2.7 on 2022-12-01 04:40
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('library', '0002_auto_20221201_0934'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='work',
|
||||||
|
unique_together={('collection', 'composer', 'name', 'edition')},
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='work',
|
||||||
|
name='path',
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -7,6 +7,8 @@ from django.utils.functional import cached_property
|
|||||||
from django.core.files.storage import get_storage_class
|
from django.core.files.storage import get_storage_class
|
||||||
from django.db.models import Q, Count, Min, Max
|
from django.db.models import Q, Count, Min, Max
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
|
||||||
from byostorage.user import BYOStorage
|
from byostorage.user import BYOStorage
|
||||||
from .imslp import Instrument
|
from .imslp import Instrument
|
||||||
|
|
||||||
@ -97,7 +99,7 @@ class ProjectItem(models.Model):
|
|||||||
ordering = ['order', 'work']
|
ordering = ['order', 'work']
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"<{self.project_id}:{self.work.slug}>"
|
return f"<{self.project_id}:{slugify(self.work.name)}>"
|
||||||
|
|
||||||
class Collection(models.Model):
|
class Collection(models.Model):
|
||||||
"""
|
"""
|
||||||
@ -143,15 +145,13 @@ class Work(models.Model):
|
|||||||
"""
|
"""
|
||||||
A musical work 'owned' by a collection from a licencing perspective.
|
A musical work 'owned' by a collection from a licencing perspective.
|
||||||
"""
|
"""
|
||||||
slug = models.SlugField(max_length=100, editable=False,
|
|
||||||
help_text="Used as folder name")
|
|
||||||
name = models.CharField(max_length=255, help_text="Original name of the work")
|
name = models.CharField(max_length=255, help_text="Original name of the work")
|
||||||
edition = models.CharField(max_length=255, blank=True,
|
edition = models.CharField(max_length=255, blank=True,
|
||||||
help_text="Edition details to distinguish multiple versions")
|
help_text="Edition details to distinguish multiple versions")
|
||||||
parent = models.ForeignKey('Work', null=True, blank=True, on_delete=models.SET_NULL, related_name="related_works",
|
parent = models.ForeignKey('Work', null=True, blank=True, on_delete=models.SET_NULL, related_name="related_works",
|
||||||
help_text="Arrangement of another work or part of an anthology")
|
help_text="Arrangement of another work or part of an anthology")
|
||||||
composer = models.CharField(max_length=255, blank=True,
|
composer = models.CharField(max_length=255, default='Anon',
|
||||||
help_text="Surname, First Name/Initials")
|
help_text="Surname, Initials")
|
||||||
|
|
||||||
original_parts = models.JSONField(default=dict, blank=True, help_text="Original printed parts (IMSLP format)")
|
original_parts = models.JSONField(default=dict, blank=True, help_text="Original printed parts (IMSLP format)")
|
||||||
|
|
||||||
@ -168,6 +168,10 @@ class Work(models.Model):
|
|||||||
# Allocation to projects
|
# Allocation to projects
|
||||||
projects = models.ManyToManyField('interface.Project', through='ProjectItem', related_name="works", help_text="Current usage")
|
projects = models.ManyToManyField('interface.Project', through='ProjectItem', related_name="works", help_text="Current usage")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def folder(self):
|
||||||
|
return f"{slugify(self.composer)}/{slugify(self.name)}-{self.pk:04d}"
|
||||||
|
|
||||||
def extract(self, *tags):
|
def extract(self, *tags):
|
||||||
|
|
||||||
qs = self.docs.filter(sections__tag__in=tags)
|
qs = self.docs.filter(sections__tag__in=tags)
|
||||||
@ -194,11 +198,6 @@ class Work(models.Model):
|
|||||||
def meta(self):
|
def meta(self):
|
||||||
return self.meta_info.exclude(name='tag')
|
return self.meta_info.exclude(name='tag')
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
if not self.slug:
|
|
||||||
self.slug = slugify(self.name)
|
|
||||||
super(Work, self).save(*args, **kwargs)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def active_projects(self):
|
def active_projects(self):
|
||||||
return self.projects.filter(active=True)
|
return self.projects.filter(active=True)
|
||||||
@ -235,10 +234,11 @@ class Work(models.Model):
|
|||||||
|
|
||||||
composer = self.composer or "Anon"
|
composer = self.composer or "Anon"
|
||||||
words = self.name.split()
|
words = self.name.split()
|
||||||
if len(words) > 2:
|
#if len(words) > 2:
|
||||||
work = ''.join([ x[0] for x in self.name.split() ])
|
# work = ''.join([ x[0] for x in self.name.split() ])
|
||||||
else:
|
#else:
|
||||||
work = words[0][:3]
|
# work = words[0][:3]
|
||||||
|
work = words[0][:3]
|
||||||
|
|
||||||
return f"{composer[:4]}-{work}-{self.pk:03d}".upper()
|
return f"{composer[:4]}-{work}-{self.pk:03d}".upper()
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ def doc_upload_filename(doc, filename):
|
|||||||
storage = collection.storage
|
storage = collection.storage
|
||||||
if not storage:
|
if not storage:
|
||||||
raise RuntimeError("Collection has no storage attached")
|
raise RuntimeError("Collection has no storage attached")
|
||||||
return f'{storage}:library/{collection.prefix}/{doc.work.slug}-{doc.work.pk}/{filename}'
|
return f'{storage}:library/{collection.prefix}/{doc.work.folder}/{filename}'
|
||||||
|
|
||||||
class Document(models.Model):
|
class Document(models.Model):
|
||||||
"""
|
"""
|
||||||
@ -268,6 +268,10 @@ class Document(models.Model):
|
|||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
version = models.CharField(max_length=30, blank=True)
|
version = models.CharField(max_length=30, blank=True)
|
||||||
|
|
||||||
|
def delete(self, *args, **kwargs):
|
||||||
|
self.upload.delete(save=False)
|
||||||
|
return super().delete(*args, **kwargs)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.upload.name
|
return self.upload.name
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,10 @@
|
|||||||
</a>
|
</a>
|
||||||
</header>
|
</header>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<p>{{ collection.location }}, {{ collection.works.count }} items.</p>
|
<p>
|
||||||
|
{% if collection.location %}{{ collection.location }},{% endif %}
|
||||||
|
{{ collection.works.count }} items.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
22
app/library/templates/library/document_confirm_delete.html
Normal file
22
app/library/templates/library/document_confirm_delete.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{% extends "interface/project_base.html" %}
|
||||||
|
|
||||||
|
{% block page %}
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column is-half is-centered">
|
||||||
|
<div class="block">
|
||||||
|
<p>Are you sure you want to delete<br>
|
||||||
|
<b>"{{ object.upload.name }}"</b>?</p>
|
||||||
|
</div>
|
||||||
|
<form method="post">{% csrf_token %}
|
||||||
|
<div class="field is-grouped">
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-link">Yes</button>
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<a class="button is-link is-light" href="{% url 'work_detail' object.work.pk %}">No</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
17
app/library/templates/library/document_entry.html
Normal file
17
app/library/templates/library/document_entry.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{% load path_filters %}
|
||||||
|
<tr>
|
||||||
|
<td><a href="{% url 'document_download' pk=doc.pk %}" target="_blank">
|
||||||
|
{{ doc.upload.name|basename }}</a></td>
|
||||||
|
<td>
|
||||||
|
{% for part in doc.sections.all %}
|
||||||
|
<a class="tag is-info" target="_blank" href="{% url 'part_download' pk=part.pk filename=part.filename %}">{{ part.instrument }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
<td class="has-text-right">
|
||||||
|
{% if request.is_admin %}
|
||||||
|
<a href="{% url 'document_annotate' pk=doc.pk %}"><i class="fas fa-tags"
|
||||||
|
title="Manage Tags"></i></a>
|
||||||
|
<a href="{% url 'document_delete' pk=doc.pk %}"><i class="fas fa-trash-alt" title="Delete Document"></i></a>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
@ -110,22 +110,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody id="doc-list">
|
<tbody id="doc-list">
|
||||||
{% for doc in work.docs.all %}
|
{% for doc in work.docs.all %}
|
||||||
<tr>
|
{% include 'library/document_entry.html' %}
|
||||||
<td><a href="{% url 'document_download' pk=doc.pk %}" target="_blank">
|
|
||||||
{{ doc.upload.name|basename }}</a></td>
|
|
||||||
<td>
|
|
||||||
{% for part in doc.sections.all %}
|
|
||||||
<a class="tag is-info" href="{% url 'part_download' pk=part.pk filename=part.filename %}">{{ part.instrument }}</a>
|
|
||||||
{% endfor %}
|
|
||||||
</td>
|
|
||||||
<td class="has-text-right">
|
|
||||||
{% if request.is_admin %}
|
|
||||||
<a href="{% url 'document_annotate' pk=doc.pk %}"><i class="fas fa-tags"
|
|
||||||
title="Manage Tags"></i></a>
|
|
||||||
<a href=""><i class="fas fa-trash-alt" title="Delete Document"></i></a>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@ -188,7 +173,7 @@
|
|||||||
<script>
|
<script>
|
||||||
Dropzone.options.docUpload = { // camelized version of the `id`
|
Dropzone.options.docUpload = { // camelized version of the `id`
|
||||||
paramName: "upload", // The name that will be used to transfer the file
|
paramName: "upload", // The name that will be used to transfer the file
|
||||||
maxFilesize: 12, // MB
|
maxFilesize: 50, // MB
|
||||||
createImageThumbnails: false,
|
createImageThumbnails: false,
|
||||||
thumbnailWidth: 60,
|
thumbnailWidth: 60,
|
||||||
thumbnailHeight: 60,
|
thumbnailHeight: 60,
|
||||||
|
|||||||
@ -20,10 +20,8 @@ urlpatterns = [
|
|||||||
path('library/works/<int:pk>/add_to_project', views.WorkAddToProject.as_view(), name="work_add_to_project"),
|
path('library/works/<int:pk>/add_to_project', views.WorkAddToProject.as_view(), name="work_add_to_project"),
|
||||||
path('library/works/<int:pk>/upload', views.WorkAddDocumentView.as_view(), name="document_add"),
|
path('library/works/<int:pk>/upload', views.WorkAddDocumentView.as_view(), name="document_add"),
|
||||||
|
|
||||||
|
path('library/documents/<int:pk>/delete', views.DocumentDeleteView.as_view(), name="document_delete"),
|
||||||
path('library/documents/<int:pk>/download', views.DocumentDownloadView.as_view(), name="document_download"),
|
path('library/documents/<int:pk>/download', views.DocumentDownloadView.as_view(), name="document_download"),
|
||||||
path('library/documents/<int:pk>/annotate', views.DocumentAnnotateView.as_view(), name="document_annotate"),
|
path('library/documents/<int:pk>/annotate', views.DocumentAnnotateView.as_view(), name="document_annotate"),
|
||||||
path('library/parts/<int:pk>/<str:filename>', views.PartDownloadView.as_view(), name="part_download"),
|
path('library/parts/<int:pk>/<str:filename>', views.PartDownloadView.as_view(), name="part_download"),
|
||||||
]
|
]
|
||||||
|
|
||||||
from django.views.static import serve
|
|
||||||
urlpatterns.append(path('docs/<path:path>', serve, {'document_root': 'local_storage'}))
|
|
||||||
@ -1,20 +1,22 @@
|
|||||||
from django.shortcuts import render, redirect, resolve_url
|
from django.shortcuts import render, redirect, resolve_url
|
||||||
from django.views.generic.detail import DetailView, SingleObjectMixin, View
|
from django.views.generic.detail import DetailView, SingleObjectMixin, View
|
||||||
from django.views.generic.list import ListView, MultipleObjectMixin
|
from django.views.generic.list import ListView, MultipleObjectMixin
|
||||||
from django.views.generic.edit import CreateView, FormView, UpdateView
|
from django.views.generic.edit import CreateView, FormView, UpdateView, DeleteView
|
||||||
from django.http import FileResponse, HttpResponse, JsonResponse
|
from django.http import FileResponse, HttpResponse, JsonResponse
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from django.db.models import Q, Count, Sum
|
from django.db.models import Q, Count, Sum
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.template.loader import render_to_string
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os.path
|
import os.path
|
||||||
|
import re
|
||||||
|
|
||||||
from interface.views import EnsembleMixin, ProjectMixin
|
from interface.views import EnsembleMixin, ProjectMixin
|
||||||
from interface.models import Project
|
from interface.models import Project
|
||||||
from .models import Collection, Work, Document, Section
|
from .models import Collection, Work, Document, Section
|
||||||
from .imslp import INSTRUMENTS
|
from .imslp import INSTRUMENTS, TAG_LOOKUP
|
||||||
from . import forms, models
|
from . import forms, models
|
||||||
from .pdf_utils import extract_pages, extract_and_concat
|
from .pdf_utils import extract_pages, extract_and_concat
|
||||||
|
|
||||||
@ -193,6 +195,8 @@ class WorkUpdateView(EnsembleMixin, WorkMixin, UpdateView):
|
|||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return resolve_url('work_detail', self.kwargs['pk'])
|
return resolve_url('work_detail', self.kwargs['pk'])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class WorkAddToProject(EnsembleMixin, FormView):
|
class WorkAddToProject(EnsembleMixin, FormView):
|
||||||
admin_required = True
|
admin_required = True
|
||||||
form_class = forms.ProjectSelectForm
|
form_class = forms.ProjectSelectForm
|
||||||
@ -269,20 +273,25 @@ class WorkAddDocumentView(EnsembleMixin, CreateView):
|
|||||||
doc = form.save(commit=False)
|
doc = form.save(commit=False)
|
||||||
doc.work_id = self.kwargs['pk']
|
doc.work_id = self.kwargs['pk']
|
||||||
doc.save()
|
doc.save()
|
||||||
|
|
||||||
|
# auto tag the document
|
||||||
|
|
||||||
|
name, _ = os.path.splitext(os.path.basename(doc.upload.name))
|
||||||
|
parts = re.split(r'[^A-Za-z]+', name.lower())
|
||||||
|
parts.reverse()
|
||||||
|
for word in parts:
|
||||||
|
print(word)
|
||||||
|
if word in TAG_LOOKUP:
|
||||||
|
doc.sections.create(tag=TAG_LOOKUP[word])
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
if self.request.headers['Accept'] == 'application/json':
|
if self.request.headers['Accept'] == 'application/json':
|
||||||
filename = os.path.basename(doc.upload.name)
|
filename = os.path.basename(doc.upload.name)
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
"message": "created",
|
"message": "created",
|
||||||
"id": doc.pk,
|
"id": doc.pk,
|
||||||
"entry": f"""
|
"entry": render_to_string('library/document_entry.html', {'doc': doc, 'request': self.request})
|
||||||
<td><a href="{reverse('document_download', args=[doc.pk])}">{filename}</a></td>
|
|
||||||
<td/>
|
|
||||||
<td class="has-text-right">
|
|
||||||
<a href="{reverse('document_annotate', args=[doc.pk])}"><i class="fas fa-tags"
|
|
||||||
title="Manage Tags"></i></a>
|
|
||||||
<a href=""><i class="fas fa-trash-alt" title="Delete Document"></i></a>
|
|
||||||
</td>
|
|
||||||
"""
|
|
||||||
}, status=201)
|
}, status=201)
|
||||||
|
|
||||||
return redirect('document_annotate', doc.pk)
|
return redirect('document_annotate', doc.pk)
|
||||||
@ -336,6 +345,13 @@ class DocumentAnnotateView(EnsembleMixin, DocumentMixin, DetailView):
|
|||||||
data['json_data'] = {'pageTags': pages, 'instruments': dict(INSTRUMENTS)}
|
data['json_data'] = {'pageTags': pages, 'instruments': dict(INSTRUMENTS)}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
class DocumentDeleteView(EnsembleMixin, DocumentMixin, DeleteView):
|
||||||
|
|
||||||
|
#def get_template_names(self):
|
||||||
|
# return ["interface/default_form.html"]
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return resolve_url('work_detail', self.object.work.pk)
|
||||||
|
|
||||||
class PartDownloadView(EnsembleMixin, SingleObjectMixin, View):
|
class PartDownloadView(EnsembleMixin, SingleObjectMixin, View):
|
||||||
|
|
||||||
|
|||||||
8
docker_settings.py
Normal file
8
docker_settings.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from .default_settings import *
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
|
'NAME': '/var/polyphonic/db.sqlite3',
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user