import uuid from django.db import models from django.utils import timezone from django.utils.functional import cached_property from django.template.defaultfilters import slugify from django.urls import reverse from django.contrib.postgres.fields import JSONField from taggit.managers import TaggableManager from django.conf import settings from utils.util import unique_slug_generator from django.utils.translation import ugettext_lazy as _ from taggit.managers import TaggableManager from taggit.models import TagBase, GenericTaggedItemBase class LuxTag(TagBase): color_rgb = models.CharField(max_length=20, blank=True) class Meta: verbose_name = _("Tag") verbose_name_plural = _("Tags") @cached_property def get_absolute_url(self): return reverse("notes:tags", kwargs={"slug": self.slug}) class TaggedNotes(GenericTaggedItemBase): tag = models.ForeignKey(LuxTag, related_name="%(app_label)s_%(class)s_items", on_delete=models.CASCADE) class NotebookManager(models.Manager): def get_queryset(self): return super().get_queryset().exclude(name='Trash') class Notebook(models.Model): """ Notebook model for Notes """ unique_id = models.UUIDField(default=uuid.uuid4, editable=False) owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) name = models.CharField(max_length=250) color_rgb = models.CharField(max_length=20, blank=True) slug = models.SlugField(blank=True) date_created = models.DateTimeField(blank=True, auto_now_add=True, editable=False) date_updated = models.DateTimeField(blank=True, auto_now=True, editable=False) include_trash = models.Manager() objects = NotebookManager() # The default manager never shows the Notebook 'Trash' class Meta: unique_together = ("owner", "name") ordering = ("name", "date_created", "date_updated") def __str__(self): return self.name def save(self, **kwargs): self.slug = unique_slug_generator(self) super(Notebook, self).save() @cached_property def get_absolute_url(self): return reverse("notebooks:detail", kwargs={"slug": self.slug}) @cached_property def color_rgba(self, opacity=".5"): try: color = self.color_rgb.split('(')[1].split(')')[0] rgba = "rgba(%s,%s)" % (color, opacity) except AttributeError: rgba = self.color_rgb return rgba class NoteManager(models.Manager): def get_queryset(self): return super().get_queryset().exclude(notebook__name='Trash') class Note(models.Model): unique_id = models.UUIDField(default=uuid.uuid4, editable=False) owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) date_created = models.DateTimeField(blank=True, auto_now_add=True, editable=False) date_updated = models.DateTimeField(blank=True, auto_now=True, editable=False) title = models.CharField(max_length=250) body_text = models.TextField(blank=True) body_html = models.TextField(blank=True) body_qjson = JSONField(null=True, blank=True) url = models.CharField(max_length=250, blank=True) slug = models.SlugField(blank=True) notebook = models.ForeignKey(Notebook, null=True, blank=True, on_delete=models.SET_NULL) tags = TaggableManager(through=TaggedNotes, blank=True, help_text='Tags') is_public = models.BooleanField(default=False) include_trash = models.Manager() objects = NoteManager() # The default manager never shows the notes in 'Trash' class Meta: unique_together = ("owner", "slug") ordering = ("-date_created", "-date_updated") def __str__(self): return self.title @cached_property def get_absolute_url(self): return reverse("notes:detail", kwargs={"slug": self.slug, 'pk': self.pk}) def save(self, **kwargs): if not self.title: self.title = str(self.body_text)[:50] if self._state.adding: self.slug = unique_slug_generator(self) super(Note, self).save() class Annotation(models.Model): unique_id = models.UUIDField(default=uuid.uuid4, editable=False) owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) date_created = models.DateTimeField(blank=True, auto_now_add=True, editable=False) date_updated = models.DateTimeField(blank=True, auto_now=True, editable=False) highlight_text = models.TextField(blank=True) body_text = models.TextField(blank=True) body_html = models.TextField(blank=True) body_qjson = JSONField(null=True, blank=True) note = models.ForeignKey(Note, null=True, blank=True, on_delete=models.SET_NULL) is_public = models.BooleanField(default=False) def __str__(self): return self.body_text[:30]