Files
mediacms/files/models/category.py
2025-08-07 13:21:12 +03:00

157 lines
4.9 KiB
Python

from django.db import models
from django.urls import reverse
from django.utils.html import strip_tags
from imagekit.models import ProcessedImageField
from imagekit.processors import ResizeToFit
from .. import helpers
from .utils import category_thumb_path, generate_uid
class Category(models.Model):
"""A Category base model"""
uid = models.CharField(unique=True, max_length=36, default=generate_uid)
add_date = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, db_index=True)
description = models.TextField(blank=True)
user = models.ForeignKey("users.User", on_delete=models.CASCADE, blank=True, null=True)
is_global = models.BooleanField(default=False, help_text="global categories or user specific")
media_count = models.IntegerField(default=0, help_text="number of media")
thumbnail = ProcessedImageField(
upload_to=category_thumb_path,
processors=[ResizeToFit(width=344, height=None)],
format="JPEG",
options={"quality": 85},
blank=True,
)
listings_thumbnail = models.CharField(max_length=400, blank=True, null=True, help_text="Thumbnail to show on listings")
is_rbac_category = models.BooleanField(default=False, db_index=True, help_text='If access to Category is controlled by role based membership of Groups')
identity_provider = models.ForeignKey(
'socialaccount.SocialApp',
blank=True,
null=True,
on_delete=models.CASCADE,
related_name='categories',
help_text='If category is related with a specific Identity Provider',
verbose_name='IDP Config Name',
)
def __str__(self):
return self.title
class Meta:
ordering = ["title"]
verbose_name_plural = "Categories"
def get_absolute_url(self):
return f"{reverse('search')}?c={self.title}"
def update_category_media(self):
"""Set media_count"""
# Always set number of Category the total number of media
# Depending on how RBAC is set and Permissions etc it is
# possible that users won't see all media in a Category
# but it's worth to handle this on the UI level
# (eg through a message that says that you see only files you have permissions to see)
self.media_count = Media.objects.filter(category=self).count()
self.save(update_fields=["media_count"])
# OLD logic
# if getattr(settings, 'USE_RBAC', False) and self.is_rbac_category:
# self.media_count = Media.objects.filter(category=self).count()
# else:
# self.media_count = Media.objects.filter(listable=True, category=self).count()
self.save(update_fields=["media_count"])
return True
@property
def thumbnail_url(self):
"""Return thumbnail for category
prioritize processed value of listings_thumbnail
then thumbnail
"""
if self.thumbnail:
return helpers.url_from_path(self.thumbnail.path)
if self.listings_thumbnail:
return self.listings_thumbnail
if Media.objects.filter(category=self, state="public").exists():
media = Media.objects.filter(category=self, state="public").order_by("-views").first()
if media:
return media.thumbnail_url
return None
def save(self, *args, **kwargs):
strip_text_items = ["title", "description"]
for item in strip_text_items:
setattr(self, item, strip_tags(getattr(self, item, None)))
super(Category, self).save(*args, **kwargs)
class Tag(models.Model):
"""A Tag model"""
title = models.CharField(max_length=100, unique=True, db_index=True)
user = models.ForeignKey("users.User", on_delete=models.CASCADE, blank=True, null=True)
media_count = models.IntegerField(default=0, help_text="number of media")
listings_thumbnail = models.CharField(
max_length=400,
blank=True,
null=True,
help_text="Thumbnail to show on listings",
db_index=True,
)
def __str__(self):
return self.title
class Meta:
ordering = ["title"]
def get_absolute_url(self):
return f"{reverse('search')}?t={self.title}"
def update_tag_media(self):
self.media_count = Media.objects.filter(state="public", is_reviewed=True, tags=self).count()
self.save(update_fields=["media_count"])
return True
def save(self, *args, **kwargs):
self.title = helpers.get_alphanumeric_only(self.title)
self.title = self.title[:99]
super(Tag, self).save(*args, **kwargs)
@property
def thumbnail_url(self):
if self.listings_thumbnail:
return self.listings_thumbnail
media = Media.objects.filter(tags=self, state="public").order_by("-views").first()
if media:
return media.thumbnail_url
return None
# Import Media to avoid circular imports
from .media import Media # noqa