This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
portail-citoyen2/portail_citoyen2/apps/feed_plugin/models.py

91 lines
2.8 KiB
Python

import hashlib
import datetime
import logging
from django.db import models
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.utils.html import strip_tags
from django.core.cache import cache
import feedparser
from cms.models import CMSPlugin
from . import utils
logger = logging.getLogger(__name__)
class FeedPreference(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
feed = models.ForeignKey('Feed')
class Meta:
verbose_name = _('user feed subscription')
verbose_name_plural = _('user feed subscriptions')
class SelectUserFeed(CMSPlugin):
pass
class ShowUserFeed(CMSPlugin):
limit = models.PositiveIntegerField(default=10)
timeout = models.PositiveIntegerField(default=60)
class Feed(models.Model):
name = models.CharField(max_length=32, verbose_name=_('name'))
url = models.URLField()
color_hex = models.CharField(max_length=6,
verbose_name=_('Color'),
help_text=_('as an hexadecimal number'),
blank=True)
css_classes = models.CharField(max_length=128,
verbose_name=_('CSS classes'),
blank=True)
def load(self, now=None, limit=9999):
if now is None:
now = datetime.datetime.utcnow()
feed = feedparser.parse(self.url)
key = self.cache_key()
entries = []
for entry in feed.entries:
for attribute in ('published_parsed', 'updated_parsed',
'created_parsed', 'expired_parsed'):
date = getattr(entry, attribute, None)
if date is not None:
break
if date is None:
continue
title = strip_tags(entry.title.strip())
if not title:
title = strip_tags(entry.description.strip())
title = ' '.join(title.split(' ')[:30])
if not title:
continue
entries.append((date, title, entry.link))
entries.sort(reverse=True)
entries = entries[:limit]
cache.set(key, (entries, now))
duration = datetime.datetime.utcnow()-now
logger.debug('loaded RSS feed %r in %s seconds', self.url, duration.seconds)
return entries
def cache_key(self):
return hashlib.md5(self.url).hexdigest()
def get_feed_entries(self, limit=10, timeout=3600):
key = self.cache_key()
now = datetime.datetime.utcnow()
entries, stamp = cache.get(key, (None, None))
if entries is None or now-stamp > datetime.timedelta(seconds=timeout):
utils.launch_in_thread(key, self.load, now, limit)
return entries
class Meta:
verbose_name = _('feed')
verbose_name_plural = _('feeds')
def __unicode__(self):
return self.name