feed_plugin: fix bug of overwriting entries before returning them
The entries variables was shared by two threads, the thread of the request and the relodaing thread.
This commit is contained in:
parent
ff517765c6
commit
4528aaa943
|
@ -48,7 +48,7 @@ class ShowUserFeedPlugin(CMSPluginBase):
|
|||
feeds = models.Feed.objects.filter(feedpreference__user=user) \
|
||||
.order_by('id')
|
||||
for feed in feeds:
|
||||
feed_entries = feed.get_feed_entries(feed, instance.limit,
|
||||
feed_entries = feed.get_feed_entries(instance.limit,
|
||||
instance.timeout)
|
||||
if feed_entries:
|
||||
for date, title, link in feed_entries:
|
||||
|
|
|
@ -42,37 +42,43 @@ class Feed(models.Model):
|
|||
verbose_name=_('CSS classes'),
|
||||
blank=True)
|
||||
|
||||
def get_feed_entries(self, feed, limit=10, timeout=3600):
|
||||
url = feed.url
|
||||
h = hashlib.md5(url).hexdigest()
|
||||
key = 'rss-feed-{0}'.format(h)
|
||||
entries, stamp = cache.get(key, (None, None))
|
||||
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):
|
||||
def load():
|
||||
feed = feedparser.parse(url)
|
||||
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', url, duration.seconds)
|
||||
utils.launch_in_thread(key, load)
|
||||
utils.launch_in_thread(key, self.load, now, limit)
|
||||
return entries
|
||||
|
||||
|
||||
|
|
Reference in New Issue