2013-01-19 08:33:03 -08:00
|
|
|
from datetime import datetime, time
|
|
|
|
from pytz import utc
|
2010-02-02 20:36:41 -08:00
|
|
|
|
2011-04-07 12:39:14 -07:00
|
|
|
from django.contrib.sites.models import Site
|
2010-06-08 08:52:53 -07:00
|
|
|
from django.contrib.syndication.views import Feed
|
2014-10-19 12:19:05 -07:00
|
|
|
from django.db import connection
|
2010-02-02 20:36:41 -08:00
|
|
|
from django.db.models import Q
|
2011-04-07 13:07:37 -07:00
|
|
|
from django.utils.feedgenerator import Rss201rev2Feed
|
2010-09-14 15:42:12 -07:00
|
|
|
from django.views.decorators.http import condition
|
2010-09-07 22:23:55 -07:00
|
|
|
|
|
|
|
from main.models import Arch, Repo, Package
|
|
|
|
from news.models import News
|
2013-01-19 08:33:03 -08:00
|
|
|
from releng.models import Release
|
2009-10-30 14:24:26 -07:00
|
|
|
|
2011-04-07 13:07:37 -07:00
|
|
|
|
2014-01-11 11:07:40 -08:00
|
|
|
class BatchWritesWrapper(object):
|
2014-10-26 20:06:08 -07:00
|
|
|
def __init__(self, outfile):
|
2014-01-11 11:07:40 -08:00
|
|
|
self.outfile = outfile
|
|
|
|
self.buf = []
|
2014-10-26 19:56:24 -07:00
|
|
|
|
2014-01-11 11:07:40 -08:00
|
|
|
def write(self, s):
|
|
|
|
buf = self.buf
|
|
|
|
buf.append(s)
|
2014-10-26 20:06:08 -07:00
|
|
|
if len(buf) >= 40:
|
2014-01-11 11:07:40 -08:00
|
|
|
self.outfile.write(''.join(buf))
|
|
|
|
self.buf = []
|
2014-10-26 19:56:24 -07:00
|
|
|
|
2014-01-11 11:07:40 -08:00
|
|
|
def flush(self):
|
|
|
|
self.outfile.write(''.join(self.buf))
|
|
|
|
self.outfile.flush()
|
|
|
|
|
|
|
|
|
2014-10-26 19:56:24 -07:00
|
|
|
class FasterRssFeed(Rss201rev2Feed):
|
2014-01-11 11:07:40 -08:00
|
|
|
def write(self, outfile, encoding):
|
|
|
|
'''
|
|
|
|
Batch the underlying 'write' calls on the outfile because Python's
|
|
|
|
default saxutils XmlGenerator is a POS that insists on unbuffered
|
|
|
|
write/flush calls. This sucks when it is making 1-byte calls to write
|
|
|
|
'>' closing tags and over 1600 write calls in our package feed.
|
|
|
|
'''
|
|
|
|
wrapper = BatchWritesWrapper(outfile)
|
2014-10-26 19:56:24 -07:00
|
|
|
super(FasterRssFeed, self).write(wrapper, encoding)
|
2014-01-11 11:07:40 -08:00
|
|
|
wrapper.flush()
|
|
|
|
|
2011-04-07 13:07:37 -07:00
|
|
|
|
2010-10-07 17:52:31 -07:00
|
|
|
def package_last_modified(request, *args, **kwargs):
|
2014-10-19 12:19:05 -07:00
|
|
|
cursor = connection.cursor()
|
|
|
|
cursor.execute("SELECT MAX(last_update) FROM packages")
|
|
|
|
return cursor.fetchone()[0]
|
2010-10-07 17:52:31 -07:00
|
|
|
|
2012-07-30 22:09:28 -07:00
|
|
|
|
2009-10-30 14:24:26 -07:00
|
|
|
class PackageFeed(Feed):
|
2014-10-26 19:56:24 -07:00
|
|
|
feed_type = FasterRssFeed
|
2011-04-07 13:07:37 -07:00
|
|
|
|
2010-05-04 08:02:54 -07:00
|
|
|
link = '/packages/'
|
|
|
|
|
2010-09-14 15:42:12 -07:00
|
|
|
def __call__(self, request, *args, **kwargs):
|
2014-10-26 19:44:11 -07:00
|
|
|
wrapper = condition(last_modified_func=package_last_modified)
|
2010-09-14 15:42:12 -07:00
|
|
|
return wrapper(super(PackageFeed, self).__call__)(request, *args, **kwargs)
|
|
|
|
|
2013-01-13 19:43:11 -08:00
|
|
|
__name__ = 'package_feed'
|
|
|
|
|
2010-06-08 08:52:53 -07:00
|
|
|
def get_object(self, request, arch='', repo=''):
|
2010-02-02 20:36:41 -08:00
|
|
|
obj = dict()
|
2012-07-30 22:09:28 -07:00
|
|
|
qs = Package.objects.normal().order_by('-last_update')
|
2010-02-02 20:36:41 -08:00
|
|
|
|
2010-06-08 08:52:53 -07:00
|
|
|
if arch != '':
|
2010-02-02 20:36:41 -08:00
|
|
|
# feed for a single arch, also include 'any' packages everywhere
|
2010-06-08 08:52:53 -07:00
|
|
|
a = Arch.objects.get(name=arch)
|
2010-09-08 09:12:43 -07:00
|
|
|
qs = qs.filter(Q(arch=a) | Q(arch__agnostic=True))
|
2010-02-02 20:36:41 -08:00
|
|
|
obj['arch'] = a
|
2010-06-08 08:52:53 -07:00
|
|
|
if repo != '':
|
2010-02-02 20:36:41 -08:00
|
|
|
# feed for a single arch AND repo
|
2010-11-27 13:04:44 -08:00
|
|
|
r = Repo.objects.get(name__iexact=repo)
|
2010-02-02 20:36:41 -08:00
|
|
|
qs = qs.filter(repo=r)
|
|
|
|
obj['repo'] = r
|
2012-07-30 22:09:28 -07:00
|
|
|
else:
|
|
|
|
qs = qs.filter(repo__staging=False)
|
2010-02-02 20:36:41 -08:00
|
|
|
obj['qs'] = qs[:50]
|
|
|
|
return obj
|
|
|
|
|
|
|
|
def title(self, obj):
|
|
|
|
s = 'Arch Linux: Recent package updates'
|
2012-07-30 22:16:36 -07:00
|
|
|
if 'repo' in obj and 'arch' in obj:
|
2010-02-02 20:36:41 -08:00
|
|
|
s += ' (%s [%s])' % (obj['arch'].name, obj['repo'].name.lower())
|
2012-07-30 22:16:36 -07:00
|
|
|
elif 'repo' in obj:
|
|
|
|
s += ' [%s]' % (obj['repo'].name.lower())
|
2010-02-02 20:36:41 -08:00
|
|
|
elif 'arch' in obj:
|
|
|
|
s += ' (%s)' % (obj['arch'].name)
|
|
|
|
return s
|
|
|
|
|
|
|
|
def description(self, obj):
|
|
|
|
s = 'Recently updated packages in the Arch Linux package repositories'
|
|
|
|
if 'arch' in obj:
|
|
|
|
s += ' for the \'%s\' architecture' % obj['arch'].name.lower()
|
2010-09-08 09:12:43 -07:00
|
|
|
if not obj['arch'].agnostic:
|
2010-02-02 20:36:41 -08:00
|
|
|
s += ' (including \'any\' packages)'
|
|
|
|
if 'repo' in obj:
|
|
|
|
s += ' in the [%s] repository' % obj['repo'].name.lower()
|
|
|
|
s += '.'
|
|
|
|
return s
|
|
|
|
|
2011-04-07 12:39:14 -07:00
|
|
|
subtitle = description
|
|
|
|
|
2010-02-02 20:36:41 -08:00
|
|
|
def items(self, obj):
|
|
|
|
return obj['qs']
|
2009-10-30 14:24:26 -07:00
|
|
|
|
2014-10-26 19:56:24 -07:00
|
|
|
item_guid_is_permalink = False
|
|
|
|
|
2011-04-07 12:39:14 -07:00
|
|
|
def item_guid(self, item):
|
|
|
|
# http://diveintomark.org/archives/2004/05/28/howto-atom-id
|
|
|
|
date = item.last_update
|
|
|
|
return 'tag:%s,%s:%s%s' % (Site.objects.get_current().domain,
|
|
|
|
date.strftime('%Y-%m-%d'), item.get_absolute_url(),
|
|
|
|
date.strftime('%Y%m%d%H%M'))
|
|
|
|
|
2009-10-30 14:24:26 -07:00
|
|
|
def item_pubdate(self, item):
|
2012-11-06 06:22:44 -08:00
|
|
|
return item.last_update
|
2009-10-30 14:24:26 -07:00
|
|
|
|
2014-10-19 16:30:32 -07:00
|
|
|
def item_title(self, item):
|
|
|
|
return '%s %s %s' % (item.pkgname, item.full_version, item.arch.name)
|
|
|
|
|
2013-07-13 07:50:45 -07:00
|
|
|
def item_description(self, item):
|
|
|
|
return item.pkgdesc
|
|
|
|
|
2009-10-30 14:24:26 -07:00
|
|
|
def item_categories(self, item):
|
2010-08-28 09:37:39 -07:00
|
|
|
return (item.repo.name, item.arch.name)
|
2009-10-30 14:24:26 -07:00
|
|
|
|
2010-02-02 20:36:41 -08:00
|
|
|
|
2010-10-07 17:16:40 -07:00
|
|
|
def news_last_modified(request, *args, **kwargs):
|
2014-10-19 12:19:05 -07:00
|
|
|
cursor = connection.cursor()
|
|
|
|
cursor.execute("SELECT MAX(last_modified) FROM news")
|
|
|
|
return cursor.fetchone()[0]
|
2010-10-07 17:16:40 -07:00
|
|
|
|
2012-07-30 22:09:28 -07:00
|
|
|
|
2009-10-30 14:24:26 -07:00
|
|
|
class NewsFeed(Feed):
|
2014-10-26 19:56:24 -07:00
|
|
|
feed_type = FasterRssFeed
|
2011-04-07 13:07:37 -07:00
|
|
|
|
2010-02-02 20:36:41 -08:00
|
|
|
title = 'Arch Linux: Recent news updates'
|
|
|
|
link = '/news/'
|
2010-01-31 13:36:42 -08:00
|
|
|
description = 'The latest and greatest news from the Arch Linux distribution.'
|
2011-04-07 12:39:14 -07:00
|
|
|
subtitle = description
|
2009-10-30 14:24:26 -07:00
|
|
|
|
2010-09-14 15:42:12 -07:00
|
|
|
def __call__(self, request, *args, **kwargs):
|
2014-10-26 19:44:11 -07:00
|
|
|
wrapper = condition(last_modified_func=news_last_modified)
|
2010-09-14 15:42:12 -07:00
|
|
|
return wrapper(super(NewsFeed, self).__call__)(request, *args, **kwargs)
|
|
|
|
|
2013-01-13 19:43:11 -08:00
|
|
|
__name__ = 'news_feed'
|
|
|
|
|
2009-10-30 14:24:26 -07:00
|
|
|
def items(self):
|
2011-02-15 11:49:20 -08:00
|
|
|
return News.objects.select_related('author').order_by(
|
|
|
|
'-postdate', '-id')[:10]
|
2009-10-30 14:24:26 -07:00
|
|
|
|
2014-10-26 19:56:24 -07:00
|
|
|
item_guid_is_permalink = False
|
|
|
|
|
2011-04-07 12:39:14 -07:00
|
|
|
def item_guid(self, item):
|
|
|
|
return item.guid
|
|
|
|
|
2009-10-30 14:24:26 -07:00
|
|
|
def item_pubdate(self, item):
|
2012-11-06 06:22:44 -08:00
|
|
|
return item.postdate
|
2009-10-30 14:24:26 -07:00
|
|
|
|
2014-10-26 20:23:56 -07:00
|
|
|
def item_updateddate(self, item):
|
|
|
|
return item.last_modified
|
|
|
|
|
2009-10-30 14:24:26 -07:00
|
|
|
def item_author_name(self, item):
|
|
|
|
return item.author.get_full_name()
|
|
|
|
|
2013-07-13 07:50:45 -07:00
|
|
|
def item_title(self, item):
|
|
|
|
return item.title
|
|
|
|
|
2014-10-19 16:30:32 -07:00
|
|
|
def item_description(self, item):
|
|
|
|
return item.html()
|
|
|
|
|
2013-01-19 08:33:03 -08:00
|
|
|
|
|
|
|
class ReleaseFeed(Feed):
|
2014-10-26 19:56:24 -07:00
|
|
|
feed_type = FasterRssFeed
|
2013-01-19 08:33:03 -08:00
|
|
|
|
|
|
|
title = 'Arch Linux: Releases'
|
|
|
|
link = '/download/'
|
|
|
|
description = 'Release ISOs'
|
|
|
|
subtitle = description
|
|
|
|
|
|
|
|
__name__ = 'release_feed'
|
|
|
|
|
|
|
|
def items(self):
|
|
|
|
return Release.objects.filter(available=True)[:10]
|
|
|
|
|
|
|
|
def item_title(self, item):
|
|
|
|
return item.version
|
|
|
|
|
|
|
|
def item_description(self, item):
|
|
|
|
return item.info_html()
|
|
|
|
|
|
|
|
def item_pubdate(self, item):
|
|
|
|
return datetime.combine(item.release_date, time()).replace(tzinfo=utc)
|
|
|
|
|
2014-10-26 20:23:56 -07:00
|
|
|
def item_updateddate(self, item):
|
|
|
|
return item.last_modified
|
|
|
|
|
2014-10-26 19:56:24 -07:00
|
|
|
item_guid_is_permalink = False
|
|
|
|
|
2013-01-19 08:33:03 -08:00
|
|
|
def item_guid(self, item):
|
|
|
|
# http://diveintomark.org/archives/2004/05/28/howto-atom-id
|
|
|
|
date = item.release_date
|
|
|
|
return 'tag:%s,%s:%s' % (Site.objects.get_current().domain,
|
2013-01-19 10:06:47 -08:00
|
|
|
date.strftime('%Y-%m-%d'), item.get_absolute_url())
|
2013-01-19 08:33:03 -08:00
|
|
|
|
|
|
|
def item_enclosure_url(self, item):
|
|
|
|
domain = Site.objects.get_current().domain
|
|
|
|
proto = 'https'
|
|
|
|
return "%s://%s/%s.torrent" % (proto, domain, item.iso_url())
|
|
|
|
|
2013-01-19 08:55:58 -08:00
|
|
|
def item_enclosure_length(self, item):
|
2014-01-09 06:40:34 -08:00
|
|
|
if item.torrent_data:
|
|
|
|
torrent = item.torrent()
|
|
|
|
return torrent['file_length'] or ""
|
|
|
|
return ""
|
2013-01-19 08:55:58 -08:00
|
|
|
|
2013-01-19 08:33:03 -08:00
|
|
|
item_enclosure_mime_type = 'application/x-bittorrent'
|
|
|
|
|
2009-10-30 14:24:26 -07:00
|
|
|
# vim: set ts=4 sw=4 et:
|