Skip to content

Commit cfc0394

Browse files
committed
added spooling view
1 parent 9c46b88 commit cfc0394

File tree

6 files changed

+136
-4
lines changed

6 files changed

+136
-4
lines changed

swp/converters.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from django.urls.converters import StringConverter
2+
from django.utils.dateparse import parse_date
3+
4+
5+
class DateConverter(StringConverter):
6+
regex = '[0-9]{1,4}-[0-9]{2}-[0-9]{2}'
7+
8+
def to_python(self, value: str):
9+
return parse_date(value)
10+
11+
def to_url(self, value):
12+
if isinstance(value, str):
13+
value = parse_date(value)
14+
15+
return value.isoformat()

swp/site.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,37 @@
1+
from django.conf import settings
12
from django.contrib import admin
3+
from django.core.exceptions import PermissionDenied
4+
from django.urls import path
25
from django.utils.translation import gettext_lazy as _
36

7+
from swp.views.spooling import SpoolingView
8+
49

510
class AdminSite(admin.AdminSite):
611
site_title = site_header = _('SWP Administration')
712
index_title = _('Overview')
813
enable_nav_sidebar = False
14+
15+
def get_urls(self):
16+
return [
17+
path('spooling/', self.admin_view(self.spooling_view), name='spooling'),
18+
path('spooling/<state>/<date:date>/<path:filename>', self.admin_view(self.spooling_view), name='spooling'),
19+
*admin.AdminSite.get_urls(self),
20+
]
21+
22+
def spooling_view(self, request, **kwargs):
23+
if not request.user.is_superuser:
24+
raise PermissionDenied
25+
26+
directory = settings.EMBEDDING_SPOOLING_DIR
27+
28+
if kwargs:
29+
return SpoolingView.file_response(directory, **kwargs)
30+
31+
view = SpoolingView.as_view(
32+
site=self,
33+
directory=directory,
34+
extra_context=self.each_context(request),
35+
)
36+
37+
return view(request)

swp/templates/admin/spooling.html

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{% extends 'admin/base_site.html' %}
2+
3+
{% block content %}
4+
{% for state, dates in files.items %}
5+
{% if dates %}
6+
<h3>{{ state }}</h3>
7+
<ul>
8+
{% for date, files in dates.items %}
9+
<h4>{{ date }}</h4>
10+
<ul>
11+
{% for publication_url, download_url, filename in files %}
12+
<li>
13+
<a href="{{ download_url }}">{{ filename }}</a>
14+
</li>
15+
{% endfor %}
16+
</ul>
17+
{% endfor %}
18+
</ul>
19+
{% endif %}
20+
{% endfor %}
21+
{% endblock %}

swp/urls.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
from django.conf import settings
22
from django.contrib import admin
3-
from django.urls import include, path
3+
from django.urls import include, path, register_converter
44

5-
from swp.views import *
65
from swp.api import default_router as v1
6+
from swp.converters import DateConverter
7+
from swp.views import *
78

8-
react = SWPView.as_view()
9+
register_converter(DateConverter, 'date')
910

11+
react = SWPView.as_view()
1012

1113
urlpatterns = [
1214
path('', react, name='index'),

swp/utils/spooling.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@
2626
}
2727

2828

29+
def get_date(value: datetime.date):
30+
return value.strftime(DATE_FMT)
31+
32+
2933
def get_filepath(directory: Path, state: State, publication: Publication, extension: Extension = 'pdf'):
3034
created = localtime(publication.created)
31-
date = created.strftime(DATE_FMT)
35+
date = get_date(created)
3236
timestamp = get_timestamp(created)
3337

3438
return directory / state / date / f'{timestamp}-{publication.id}.{extension}'

swp/views/spooling.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import datetime
2+
3+
from collections import defaultdict
4+
from pathlib import Path
5+
from typing import List
6+
7+
from django.contrib.admin.sites import AdminSite
8+
from django.http import Http404, FileResponse
9+
from django.shortcuts import resolve_url
10+
from django.views.generic import TemplateView
11+
12+
from swp.models import Publication
13+
from swp.utils.admin import admin_url
14+
from swp.utils.spooling import iter_files, State, get_date
15+
16+
SPOOLING_STATES: List[State] = [
17+
'error',
18+
'todo',
19+
'lost',
20+
'done',
21+
]
22+
23+
24+
class SpoolingView(TemplateView):
25+
template_name = 'admin/spooling.html'
26+
27+
site: AdminSite = None
28+
directory: Path = None
29+
30+
def get_context_data(self, **kwargs):
31+
kwargs['title'] = 'Spooling'
32+
kwargs['files'] = {state: self.get_state_info(state) for state in SPOOLING_STATES}
33+
34+
return TemplateView.get_context_data(self, **kwargs)
35+
36+
def get_state_info(self, state: State):
37+
dates = defaultdict(list)
38+
39+
for publication_id, filepath in iter_files(self.directory, state):
40+
filename = filepath.name
41+
date = filepath.parent.name
42+
43+
publication_url = admin_url(Publication, 'change', publication_id, site=self.site)
44+
download_url = resolve_url('admin:spooling', state=state, date=date, filename=filename)
45+
46+
info = publication_url, download_url, filename
47+
48+
dates[date].append(info)
49+
50+
return dict(dates)
51+
52+
@staticmethod
53+
def file_response(directory: Path, state: State, date: datetime.date, filename: str):
54+
filepath = directory / state / get_date(date) / filename
55+
56+
try:
57+
fp = open(filepath, 'rb')
58+
except FileNotFoundError as error:
59+
raise Http404 from error
60+
61+
return FileResponse(fp, filename=filename)

0 commit comments

Comments
 (0)