Select Git revision

jan.bednarik authored
models.py 4.33 KiB
import requests
from django.core.cache import cache
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.utils import timezone
from wagtail.admin.edit_handlers import FieldPanel
from wagtail.core.fields import RichTextField
from wagtail.core.models import Page
from wagtail.images.edit_handlers import ImageChooserPanel
class SubpageMixin:
"""Must be used in class definition before MetadataPageMixin!"""
@property
def root_page(self):
if not hasattr(self, "_root_page"):
# vypada to hackove ale lze takto pouzit: dle dokumentace get_ancestors
# vraci stranky v poradi od rootu, tedy domovska stranka je druha v poradi
self._root_page = self.get_ancestors().specific()[1]
return self._root_page
def get_meta_image(self):
return self.search_image or self.root_page.get_meta_image()
class ArticleMixin(models.Model):
"""
Common fields for articles
If you want to tag articles, add tags as `tags` field in article page model.
"""
RICH_TEXT_FEATURES = [
"h2",
"h3",
"h4",
"bold",
"italic",
"ol",
"ul",
"link",
"document-link",
]
### FIELDS
date = models.DateField("datum", default=timezone.now)
perex = models.TextField("perex")
text = RichTextField("článek", blank=True, features=RICH_TEXT_FEATURES)
author = models.CharField("autor", max_length=250, blank=True, null=True)
image = models.ForeignKey(
"wagtailimages.Image",
on_delete=models.PROTECT,
blank=True,
null=True,
verbose_name="obrázek",
)
### PANELS
content_panels = Page.content_panels + [
FieldPanel("date"),
FieldPanel("perex"),
FieldPanel("text"),
FieldPanel("author"),
ImageChooserPanel("image"),
]
class Meta:
abstract = True
@classmethod
def has_tags(cls):
try:
cls._meta.get_field("tags")
except models.FieldDoesNotExist:
return False
return True
def tag_filter_page(self):
"""Page used for filtering by tags in url like `?tag=foo`."""
return self.get_parent()
class Person(models.Model):
"""Informace o Piratovi. Slouzi prevazne jako cache informaci o osobe pro
uziti v ramci Majaku. Snaha je zadavat tady minimum informaci o osobe a
zbytek vytahovat via API z jinych zdroju, neb nechceme dalsi databazi lidi.
"""
# ve formatu iapi: https://iapi.pirati.cz/v1/user?username=john.doe
username = models.TextField("Uživatelské jméno osoby", blank=False)
profile_id = models.IntegerField(
"Číslo medailonku (0..2) z lide.pirati.cz",
blank=True,
default=0,
validators=[MinValueValidator(0), MaxValueValidator(2)],
)
perex = models.TextField("Defaultni perex osoby", blank=True)
panels = [
FieldPanel("username"),
FieldPanel("profile_id"),
FieldPanel("perex"),
]
def _iapi(self):
""" Vrati data o osobe z piratskeho IAPI jako json. Cached via django cache"""
key = f"profile_{self.username}"
profile = cache.get(key)
if profile is None:
profile = requests.get(
f"https://iapi.pirati.cz/v1/user?username={self.username}"
).json()
cache.set(key, profile, 3600)
return profile
@property
def name(self):
return self._iapi().get("displayname")
@property
def email(self):
try:
return self._iapi()["profiles"][self.profile_id]["email"]
except (IndexError, KeyError):
return None
@property
def phone(self):
try:
return self._iapi()["profiles"][self.profile_id]["phone"]
except (IndexError, KeyError):
return None
@property
def longtext(self): # medailonek
return "" # TODO
@property
def portrait(self): # profilova fotka
try:
return self._iapi()["profiles"][self.profile_id]["photo"]
except (IndexError, KeyError):
return None
@property
def facebook(self):
return None # TODO
def __str__(self):
return self.username
class Meta:
verbose_name_plural = "Piráti"
verbose_name = "Pirát"