diff --git a/ram/bookshelf/models.py b/ram/bookshelf/models.py index 0aa0be8..d8a98ed 100644 --- a/ram/bookshelf/models.py +++ b/ram/bookshelf/models.py @@ -81,6 +81,15 @@ def book_image_upload(instance, filename): ) +def magazine_image_upload(instance, filename): + return os.path.join( + "images", + "magazines", + str(instance.uuid), + filename + ) + + class BaseBookImage(Image): book = models.ForeignKey( BaseBook, on_delete=models.CASCADE, related_name="image" @@ -163,7 +172,7 @@ class Magazine(BaseModel): ISBN = models.CharField(max_length=17, blank=True) # 13 + dashes image = models.ImageField( blank=True, - upload_to=book_image_upload, + upload_to=magazine_image_upload, storage=DeduplicatedStorage, ) language = models.CharField( @@ -192,8 +201,8 @@ class Magazine(BaseModel): def get_absolute_url(self): return reverse( - "bookshelf_item", - kwargs={"selector": "magazine", "uuid": self.uuid} + "magazine", + kwargs={"uuid": self.uuid} ) @@ -224,3 +233,12 @@ class MagazineIssue(BaseBook): def preview(self): return self.image.first().image_thumbnail(100) + + def get_absolute_url(self): + return reverse( + "issue", + kwargs={ + "uuid": self.uuid, + "magazine": self.magazine.uuid + } + ) diff --git a/ram/portal/templates/cards.html b/ram/portal/templates/cards.html index d80659b..ba81806 100644 --- a/ram/portal/templates/cards.html +++ b/ram/portal/templates/cards.html @@ -18,6 +18,8 @@ {% include "cards/consist.html" %} {% elif d.type == "manufacturer" %} {% include "cards/manufacturer.html" %} + {% elif d.type == "magazine" or d.type == "issue" %} + {% include "cards/magazine.html" %} {% elif d.type == "book" or d.type == "catalog" %} {% include "cards/book.html" %} {% endif %} diff --git a/ram/portal/templates/cards/book.html b/ram/portal/templates/cards/book.html index 6205aee..5110276 100644 --- a/ram/portal/templates/cards/book.html +++ b/ram/portal/templates/cards/book.html @@ -24,8 +24,7 @@ - {% if d.type == "catalog" %}Catalog - {% elif d.type == "book" %}Book{% endif %} + {{ d.type | capfirst }}
{% if not d.item.published %} Unpublished @@ -53,7 +52,7 @@ Publisher - {{ d.item.publisher }} + {{ d.item.publisher.country }} {{ d.item.publisher }} {% endif %} diff --git a/ram/portal/templates/cards/consist.html b/ram/portal/templates/cards/consist.html index 5d22611..e3da341 100644 --- a/ram/portal/templates/cards/consist.html +++ b/ram/portal/templates/cards/consist.html @@ -63,7 +63,7 @@
Show all data - {% if request.user.is_staff %}Edit{% endif %} + {% if request.user.is_staff %}Edit{% endif %}
diff --git a/ram/portal/templates/cards/magazine.html b/ram/portal/templates/cards/magazine.html new file mode 100644 index 0000000..3d23d19 --- /dev/null +++ b/ram/portal/templates/cards/magazine.html @@ -0,0 +1,73 @@ +{% load static %} + +
+
+ {% if d.type == "magazine" %} + + {% if d.item.image and d.type == "magazine" %} + {{ d.item }} + {% elif d.item.issue.first.image.exists %} + {% with d.item.issue.first as i %} + {{ d.item }} + {% endwith %} + {% else %} + + {{ d.item }} + {% endif %} + + {% endif %} + + {% if d.type == "issue" %} + + {% if d.item.image.exists %} + {{ d.item }} + {% else %} + + {{ d.item }} + {% endif %} + + {% endif %} + +
+

+ {{ d.item }} + +

+ {% if d.item.tags.all %} +

Tags: + {% for t in d.item.tags.all %} + {{ t.name }}{# new line is required #} + {% endfor %} +

+ {% endif %} + + + + + + + + + + + + + + + + +
+ {{ d.type | capfirst }} +
+ {% if not d.item.published %} + Unpublished + {% endif %} +
+
Publisher{{ d.item.publisher.country }} {{ d.item.publisher }}
Language{{ d.item.get_language_display }}
+
+ Show all data + {% if request.user.is_staff %}Edit{% endif %} +
+
+
+
diff --git a/ram/portal/templates/magazine.html b/ram/portal/templates/magazine.html new file mode 100644 index 0000000..40f64d1 --- /dev/null +++ b/ram/portal/templates/magazine.html @@ -0,0 +1,122 @@ +{% extends "cards.html" %} + + {% block header %} + {% if magazine.tags.all %} +

Tags: + {% for t in magazine.tags.all %} + {{ t.name }}{# new line is required #} + {% endfor %} +

+ {% if not magazine.published %} + Unpublished | + {% endif %} + Updated {{ magazine.updated_time | date:"M d, Y H:i" }} + {% endif %} + {% endblock %} + {% block carousel %} + {% if magazine.image %} +
+ +
+ {% endif %} + {% endblock %} + {% block pagination %} + {% if data.has_other_pages %} + + {% endif %} + {% endblock %} + {% block extra_content %} +
+
+
+ + + +
+ {% if request.user.is_staff %}Edit{% endif %} +
+
+
+
+ {% endblock %} diff --git a/ram/portal/urls.py b/ram/portal/urls.py index b12943e..d517a55 100644 --- a/ram/portal/urls.py +++ b/ram/portal/urls.py @@ -15,6 +15,9 @@ from portal.views import ( Types, Books, Catalogs, + Magazines, + GetMagazine, + GetMagazineIssue, GetBookCatalog, SearchObjects, ) @@ -98,6 +101,31 @@ urlpatterns = [ Books.as_view(), name="books_pagination" ), + path( + "bookshelf/magazine/", + GetMagazine.as_view(), + name="magazine" + ), + path( + "bookshelf/magazine//page/", + GetMagazine.as_view(), + name="magazine_pagination", + ), + path( + "bookshelf/magazine//issue/", + GetMagazineIssue.as_view(), + name="issue", + ), + path( + "bookshelf/magazines", + Magazines.as_view(), + name="magazines" + ), + path( + "bookshelf/magazines/page/", + Magazines.as_view(), + name="magazines_pagination" + ), path( "bookshelf//", GetBookCatalog.as_view(), diff --git a/ram/portal/views.py b/ram/portal/views.py index 7b90bc2..88a19be 100644 --- a/ram/portal/views.py +++ b/ram/portal/views.py @@ -16,7 +16,7 @@ from portal.utils import get_site_conf from portal.models import Flatpage from roster.models import RollingStock from consist.models import Consist -from bookshelf.models import Book, Catalog +from bookshelf.models import Book, Catalog, Magazine, MagazineIssue from metadata.models import ( Company, Manufacturer, @@ -73,7 +73,8 @@ class GetData(View): .filter(self.filter) ) - def get(self, request, page=1): + def get(self, request, filter=Q(), page=1): + self.filter = filter data = [] for item in self.get_data(request): data.append({"type": self.item_type, "item": item}) @@ -491,7 +492,8 @@ class Manufacturers(GetData): def get_data(self, request): return ( - Manufacturer.objects.filter(self.filter).annotate( + Manufacturer.objects.filter(self.filter) + .annotate( num_rollingstock=( Count( "rollingstock", @@ -592,9 +594,7 @@ class Scales(GetData): num_consists=Count( "consist", filter=Q( - consist__in=Consist.objects.get_published( - request.user - ) + consist__in=Consist.objects.get_published(request.user) ), distinct=True, ), @@ -637,6 +637,84 @@ class Catalogs(GetData): return Catalog.objects.get_published(request.user).all() +class Magazines(GetData): + title = "Magazines" + item_type = "magazine" + + def get_data(self, request): + return ( + Magazine.objects.get_published(request.user) + .all() + .annotate( + num_issues=Count( + "issue", + filter=Q( + issue__in=( + MagazineIssue.objects.get_published(request.user) + ) + ), + ) + ) + ) + + +class GetMagazine(View): + def get(self, request, uuid, page=1): + try: + magazine = Magazine.objects.get_published(request.user).get( + uuid=uuid + ) + except ObjectDoesNotExist: + raise Http404 + data = [ + { + "type": "issue", + "item": i, + } + for i in magazine.issue.get_published(request.user).all() + ] + paginator = Paginator(data, get_items_per_page()) + data = paginator.get_page(page) + page_range = paginator.get_elided_page_range( + data.number, on_each_side=1, on_ends=1 + ) + + return render( + request, + "magazine.html", + { + "title": magazine, + "magazine": magazine, + "data": data, + "page_range": page_range, + }, + ) + + +class GetMagazineIssue(View): + def get(self, request, uuid, magazine, page=1): + try: + issue = MagazineIssue.objects.get_published(request.user).get( + uuid=uuid, + magazine__uuid=magazine, + ) + except ObjectDoesNotExist: + raise Http404 + properties = issue.property.get_public(request.user) + documents = issue.document.get_public(request.user) + return render( + request, + "bookshelf/book.html", + { + "title": issue, + "book": issue, + "documents": documents, + "properties": properties, + "type": "magazineissue", + }, + ) + + class GetBookCatalog(View): def get_object(self, request, uuid, selector): if selector == "book":