Package zinnia :: Module feeds
[hide private]

Source Code for Module zinnia.feeds

  1  """Feeds for Zinnia""" 
  2  from sgmllib import SGMLParser 
  3   
  4  from django.contrib.auth.models import User 
  5  from django.contrib.sites.models import Site 
  6  from django.core.urlresolvers import reverse 
  7  from django.core.urlresolvers import NoReverseMatch 
  8  from django.utils.feedgenerator import Atom1Feed 
  9  from django.utils.translation import ugettext as _ 
 10  from django.contrib.syndication.views import Feed 
 11  from django.shortcuts import get_object_or_404 
 12   
 13  from tagging.models import Tag 
 14  from tagging.models import TaggedItem 
 15   
 16  from zinnia.models import Entry 
 17  from zinnia.settings import COPYRIGHT 
 18  from zinnia.settings import PROTOCOL 
 19  from zinnia.settings import FEEDS_MAX_ITEMS 
 20  from zinnia.managers import entries_published 
 21  from zinnia.views.categories import get_category_or_404 
 22   
 23   
24 -class ImgParser(SGMLParser):
25 """Parser for getting IMG markups""" 26
27 - def __init__(self):
28 SGMLParser.__init__(self) 29 self.img_locations = []
30
31 - def start_img(self, attr):
32 """Save each image's location""" 33 attr = dict(attr) 34 if attr.get('src', ''): 35 self.img_locations.append(attr['src'])
36 37
38 -class EntryFeed(Feed):
39 """Base Entry Feed""" 40 title_template = 'feeds/entry_title.html' 41 description_template = 'feeds/entry_description.html' 42 feed_copyright = COPYRIGHT 43
44 - def __init__(self):
45 self.site = Site.objects.get_current()
46
47 - def item_pubdate(self, item):
48 """Publication date of an entry""" 49 return item.creation_date
50
51 - def item_categories(self, item):
52 """Entry's categories""" 53 return [category.title for category in item.categories.all()]
54
55 - def item_author_name(self, item):
56 """Returns the first author of an entry""" 57 return item.authors.all()[0].username
58
59 - def item_author_email(self, item):
60 """Returns the first author's email""" 61 return item.authors.all()[0].email
62 72
73 - def item_enclosure_url(self, item):
74 """Returns an image for enclosure""" 75 if item.image: 76 return item.image.url 77 parser = ImgParser() 78 try: 79 parser.feed(item.content) 80 except UnicodeEncodeError: 81 return 82 if len(parser.img_locations): 83 if self.site.domain in parser.img_locations[0]: 84 return parser.img_locations[0] 85 else: 86 return '%s://%s%s' % (PROTOCOL, 87 self.site.domain, 88 parser.img_locations[0]) 89 return None
90
91 - def item_enclosure_length(self, item):
92 """Hardcoded enclosure length""" 93 return '100000'
94
95 - def item_enclosure_mime_type(self, item):
96 """Hardcoded enclosure mimetype""" 97 return 'image/jpeg'
98 99
100 -class LatestEntries(EntryFeed):
101 """Feed for the latest entries""" 102 title = _('Latest entries') 103 107
108 - def items(self):
109 """Items are published entries""" 110 return Entry.published.all()[:FEEDS_MAX_ITEMS]
111
112 - def description(self, obj):
113 """Description of the feed""" 114 return _('The latest entries for the site %s') % self.site.domain
115 116
117 -class CategoryEntries(EntryFeed):
118 """Feed filtered by a category""" 119
120 - def get_object(self, request, path):
121 """Retrieve the category by his path""" 122 return get_category_or_404(path)
123
124 - def items(self, obj):
125 """Items are the published entries of the category""" 126 return obj.entries_published_set()[:FEEDS_MAX_ITEMS]
127 131
132 - def title(self, obj):
133 """Title of the feed""" 134 return _('Entries for the category %s') % obj.title
135
136 - def description(self, obj):
137 """Description of the feed""" 138 return _('The latest entries for the category %s') % obj.title
139 140
141 -class AuthorEntries(EntryFeed):
142 """Feed filtered by an author""" 143
144 - def get_object(self, request, username):
145 """Retrieve the author by his username""" 146 return get_object_or_404(User, username=username)
147
148 - def items(self, obj):
149 """Items are the published entries of the author""" 150 return entries_published(obj.entry_set)[:FEEDS_MAX_ITEMS]
151 155
156 - def title(self, obj):
157 """Title of the feed""" 158 return _('Entries for author %s') % obj.username
159
160 - def description(self, obj):
161 """Description of the feed""" 162 return _('The latest entries by %s') % obj.username
163 164
165 -class TagEntries(EntryFeed):
166 """Feed filtered by a tag""" 167
168 - def get_object(self, request, slug):
169 """Retrieve the tag by his name""" 170 return get_object_or_404(Tag, name=slug)
171
172 - def items(self, obj):
173 """Items are the published entries of the tag""" 174 return TaggedItem.objects.get_by_model( 175 Entry.published.all(), obj)[:FEEDS_MAX_ITEMS]
176 180
181 - def title(self, obj):
182 """Title of the feed""" 183 return _('Entries for the tag %s') % obj.name
184
185 - def description(self, obj):
186 """Description of the feed""" 187 return _('The latest entries for the tag %s') % obj.name
188 189
190 -class SearchEntries(EntryFeed):
191 """Feed filtered by a search pattern""" 192
193 - def get_object(self, request, slug):
194 """The slug is the pattern to search""" 195 return slug
196
197 - def items(self, obj):
198 """Items are the published entries founds""" 199 return Entry.published.search(obj)[:FEEDS_MAX_ITEMS]
200 204
205 - def title(self, obj):
206 """Title of the feed""" 207 return _('Results of the search for %s') % obj
208
209 - def description(self, obj):
210 """Description of the feed""" 211 return _('The entries containing the pattern %s') % obj
212 213
214 -class EntryDiscussions(Feed):
215 """Feed for discussions in an entry""" 216 title_template = 'feeds/discussion_title.html' 217 description_template = 'feeds/discussion_description.html' 218 feed_copyright = COPYRIGHT 219
220 - def get_object(self, request, slug):
221 """Retrieve the discussions by entry's slug""" 222 return get_object_or_404(Entry, slug=slug)
223
224 - def items(self, obj):
225 """Items are the discussions on the entry""" 226 return obj.discussions[:FEEDS_MAX_ITEMS]
227
228 - def item_pubdate(self, item):
229 """Publication date of a discussion""" 230 return item.submit_date
231 235 239
240 - def item_author_name(self, item):
241 """Author of the discussion""" 242 return item.userinfo['name']
243
244 - def item_author_email(self, item):
245 """Author's email of the discussion""" 246 return item.userinfo['email']
247 251
252 - def title(self, obj):
253 """Title of the feed""" 254 return _('Discussions on %s') % obj.title
255
256 - def description(self, obj):
257 """Description of the feed""" 258 return _('The latest discussions for the entry %s') % obj.title
259 260
261 -class EntryComments(EntryDiscussions):
262 """Feed for comments in an entry""" 263 title_template = 'feeds/comment_title.html' 264 description_template = 'feeds/comment_description.html' 265
266 - def items(self, obj):
267 """Items are the comments on the entry""" 268 return obj.comments[:FEEDS_MAX_ITEMS]
269 273
274 - def title(self, obj):
275 """Title of the feed""" 276 return _('Comments on %s') % obj.title
277
278 - def description(self, obj):
279 """Description of the feed""" 280 return _('The latest comments for the entry %s') % obj.title
281 282
283 -class EntryPingbacks(EntryDiscussions):
284 """Feed for pingbacks in an entry""" 285 title_template = 'feeds/pingback_title.html' 286 description_template = 'feeds/pingback_description.html' 287
288 - def items(self, obj):
289 """Items are the pingbacks on the entry""" 290 return obj.pingbacks[:FEEDS_MAX_ITEMS]
291 295
296 - def title(self, obj):
297 """Title of the feed""" 298 return _('Pingbacks on %s') % obj.title
299
300 - def description(self, obj):
301 """Description of the feed""" 302 return _('The latest pingbacks for the entry %s') % obj.title
303 304
305 -class EntryTrackbacks(EntryDiscussions):
306 """Feed for trackbacks in an entry""" 307 title_template = 'feeds/trackback_title.html' 308 description_template = 'feeds/trackback_description.html' 309
310 - def items(self, obj):
311 """Items are the trackbacks on the entry""" 312 return obj.trackbacks[:FEEDS_MAX_ITEMS]
313 317
318 - def title(self, obj):
319 """Title of the feed""" 320 return _('Trackbacks on %s') % obj.title
321
322 - def description(self, obj):
323 """Description of the feed""" 324 return _('The latest trackbacks for the entry %s') % obj.title
325 326 327 # Atom versions of the feeds
328 -class AtomLatestEntries(LatestEntries):
329 """Atom feed for the latest entries""" 330 feed_type = Atom1Feed 331 subtitle = LatestEntries.description
332 333
334 -class AtomCategoryEntries(CategoryEntries):
335 """Atom feed filtered by a category""" 336 feed_type = Atom1Feed 337 subtitle = CategoryEntries.description
338 339
340 -class AtomAuthorEntries(AuthorEntries):
341 """Atom feed filtered by an author""" 342 feed_type = Atom1Feed 343 subtitle = AuthorEntries.description
344 345
346 -class AtomTagEntries(TagEntries):
347 """Atom feed filtered by a tag""" 348 feed_type = Atom1Feed 349 subtitle = TagEntries.description
350 351
352 -class AtomSearchEntries(SearchEntries):
353 """Atom feed filtered by a search pattern""" 354 feed_type = Atom1Feed 355 subtitle = SearchEntries.description
356 357
358 -class AtomEntryDiscussions(EntryDiscussions):
359 """Atom feed for discussions in an entry""" 360 feed_type = Atom1Feed 361 subtitle = EntryDiscussions.description
362 363
364 -class AtomEntryComments(EntryComments):
365 """Atom feed for comments in an entry""" 366 feed_type = Atom1Feed 367 subtitle = EntryComments.description
368 369
370 -class AtomEntryPingbacks(EntryPingbacks):
371 """Atom feed for pingbacks in an entry""" 372 feed_type = Atom1Feed 373 subtitle = EntryPingbacks.description
374 375
376 -class AtomEntryTrackbacks(EntryTrackbacks):
377 """Atom feed for trackbacks in an entry""" 378 feed_type = Atom1Feed 379 subtitle = EntryTrackbacks.description
380