summaryrefslogtreecommitdiff
path: root/app/books/models.py
blob: eafa9beab02ac0890afb65f73786880208e432b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import os
from PIL import Image
from django.db import models
from django.db.models.signals import post_save
from django.contrib.sitemaps import Sitemap
from django.dispatch import receiver
from django.urls import reverse
from django.apps import apps
from django.utils.html import format_html
from django.conf import settings
from django.template.defaultfilters import slugify

from photos.utils import resize_image
from utils.util import markdown_to_html


def get_upload_path(self, filename):
    return "images/book-covers/%s" % (filename)


class Book(models.Model):
    title = models.CharField(max_length=200)
    author_name = models.CharField(max_length=200)
    slug = models.CharField(max_length=50)
    read_date = models.DateTimeField()
    isbn = models.CharField(max_length=100, blank=True, null=True)
    body_markdown = models.TextField(blank=True)
    body_html = models.TextField(null=True, blank=True)
    read_in = models.TextField(null=True, blank=True)
    url = models.CharField(max_length=200, blank=True, null=True)
    pages = models.CharField(max_length=5, blank=True, null=True)
    publish_date = models.CharField(max_length=40, blank=True, null=True)
    publish_place = models.CharField(max_length=100, blank=True, null=True)
    openlib_url = models.CharField(max_length=400, blank=True, null=True)
    afflink = models.CharField(max_length=400, blank=True, null=True)
    RATINGS = (
        ('1', "1 Star"),
        ('2', "2 Stars"),
        ('3', "3 Stars"),
        ('4', "4 Stars"),
        ('5', "5 Stars"),
    )
    rating = models.CharField(max_length=1, choices=RATINGS, null=True, blank=True)
    enable_comments = models.BooleanField(default=False)
    is_public = models.BooleanField(default=True)
    image = models.FileField(upload_to=get_upload_path, null=True, blank=True)

    class Meta:
        ordering = ('-read_date',)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse("books:detail", kwargs={"slug": self.slug})

    def get_image_url(self):
        return '%sbook-covers/%s' % (settings.IMAGES_URL, self.image.name.split('/')[-1])

    def get_small_image_url(self):
        filename, file_extension = os.path.splitext(self.image.path)
        return "%s/book-covers/%s_small%s" % (settings.IMAGES_URL, filename.split('/')[-1], file_extension)

    def get_rating(self):
        return int(self.rating)

    @property
    def ratings_range(cls):
        return range(1, 6)

    @property
    def get_previous_admin_url(self):
        n = self.get_previous_by_read_date()
        return reverse('admin:%s_%s_change' % (self._meta.app_label,  self._meta.model_name),  args=[n.id])

    @property
    def get_next_admin_url(self):
        model = apps.get_model(app_label=self._meta.app_label, model_name=self._meta.model_name)
        try:
            return reverse('admin:%s_%s_change' % (self._meta.app_label,  self._meta.model_name),  args=[self.get_next_by_read_date().pk])
        except model.DoesNotExist:
            return ''

    def admin_thumbnail(self):
        return format_html('<img src="%s" width="100" style="width:100px" />' % (self.get_image_url()))
    admin_thumbnail.short_description = 'Thumbnail'

    def save(self, *args, **kwargs):
        if self.body_markdown:
            self.body_html = markdown_to_html(self.body_markdown)
        self.slug = slugify(self.title[:50])
        super(Book, self).save()


@receiver(post_save, sender=Book)
def post_save_events(sender, update_fields, created, instance, **kwargs):
    if instance.image:
        base_path = "%s/%s/" % (settings.MEDIA_ROOT, "/".join(str(i) for i in instance.image.name.split('/')[:-1]))
        filename, file_extension = os.path.splitext(instance.image.path)
        img = Image.open(instance.image.path)
        resize_image(img, None, 160, 78, base_path, "%s_tn%s" % (filename.split('/')[-1], file_extension))
        resize_image(img, None, 650, 78, base_path, "%s_small%s" % (filename.split('/')[-1], file_extension))


class BookHighlight(models.Model):
    book = models.ForeignKey(Book, on_delete=models.CASCADE, blank=True)
    page = models.PositiveSmallIntegerField()
    date_added = models.DateTimeField(blank=True, auto_now_add=True)
    body_markdown = models.TextField()
    body_html = models.TextField(blank=True)

    class Meta:
        ordering = ('-date_added', '-page',)
        get_latest_by = 'date_added'

    def __str__(self):
        return "%s - %s" % (self.book.title, self.id)

    def save(self, *args, **kwargs):
        if not self.pk:
            if self.book_id is None:
                self.book = BookHighlight.objects.latest().book
        self.body_html = markdown_to_html(self.body_markdown)
        super(BookHighlight, self).save()


class BookSitemap(Sitemap):
    changefreq = "never"
    priority = 0.7
    protocol = "https"

    def items(self):
        return Book.objects.filter(is_public=True).exclude(body_markdown='')

    def lastmod(self, obj):
        return obj.read_date