| commit 78: | c155d9f07388 |
| parent 77: | 7844ea14c41e |
| branch: | default |
Changed (Δ6.1 KB):
biologeek/feeds.py (6 lines added, 1 lines removed)
biologeek/templates/photologue/gallery_base.html (4 lines added, 0 lines removed)
biologeek/templates/photologue/gallery_detail.html (6 lines added, 0 lines removed)
biologeek/templates/photologue/gallery_list.html (6 lines added, 0 lines removed)
biologeek/urls.py (3 lines added, 3 lines removed)
photologue/feeds.py (156 lines added, 0 lines removed)
Up to file-list biologeek/feeds.py:
| … | … | @@ -8,6 +8,7 @@ from django.contrib.comments.models impo |
8 |
8 |
from journal.models import Post |
9 |
9 |
from bistrot.models import Thought |
10 |
10 |
from tagging.models import Tag, TaggedItem |
11 |
from photologue.feeds import PhotologueFeed |
|
11 |
12 |
|
12 |
13 |
|
13 |
14 |
class RSSFeed(Feed): |
| … | … | @@ -142,7 +143,6 @@ class RSSFeed(Feed): |
142 |
143 |
return obj.publication_date |
143 |
144 |
except AttributeError: |
144 |
145 |
return obj.submit_date |
145 |
||
146 |
146 |
|
147 |
147 |
|
148 |
148 |
class AtomFeed(RSSFeed): |
| … | … | @@ -152,3 +152,8 @@ class AtomFeed(RSSFeed): |
152 |
152 |
|
153 |
153 |
def subtitle(self, obj): |
154 |
154 |
return RSSFeed.begin_description % self.end_description |
155 |
||
156 |
||
157 |
class MediaFeed(PhotologueFeed): |
|
158 |
title = u'Photos BioloGeek.com' |
|
159 |
description = u'Dernières photos sur Biologeek.com' |
Up to file-list biologeek/templates/photologue/gallery_base.html:
1 |
1 |
{% extends "layout/base_unicol.html" %} |
2 |
2 |
|
3 |
{% block extra_head %} |
|
4 |
<script type="text/javascript" src="http://lite.piclens.com/current/piclens_optimized.js"></script> |
|
5 |
{% endblock %} |
|
6 |
||
3 |
7 |
{% block extra_content %} |
4 |
8 |
<div id="contextual"> |
5 |
9 |
<hr /> |
Up to file-list biologeek/templates/photologue/gallery_detail.html:
3 |
3 |
|
4 |
4 |
{% block title %}{{ gallery.title }} dans les photos{% endblock %} |
5 |
5 |
|
6 |
{% block extra_head %} |
|
7 |
{{ block.super }} |
|
8 |
<link rel="alternate" href="/data/media/{{ gallery.title_slug }}/" |
|
9 |
type="application/rss+xml" title="Photos de la gallerie {{ gallery.title }}" id="gallery" /> |
|
10 |
{% endblock %} |
|
11 |
||
6 |
12 |
{% block extra_body %}class="photos unicol"{% endblock %} |
7 |
13 |
|
8 |
14 |
{% block info %} |
Up to file-list biologeek/templates/photologue/gallery_list.html:
2 |
2 |
|
3 |
3 |
{% block title %}Album photos{% endblock %} |
4 |
4 |
|
5 |
{% block extra_head %} |
|
6 |
{{ block.super }} |
|
7 |
<link rel="alternate" href="/data/media/" |
|
8 |
type="application/rss+xml" title="Photos de biologeek.com" id="gallery" /> |
|
9 |
{% endblock %} |
|
10 |
||
5 |
11 |
{% block extra_body %}class="photos unicol"{% endblock %} |
6 |
12 |
|
7 |
13 |
{% block info %} |
Up to file-list biologeek/urls.py:
| … | … | @@ -18,7 +18,7 @@ from journal.models import Post |
18 |
18 |
from bistrot.models import Thought |
19 |
19 |
from journal.views import view_tag, add_tag, redirect_to_archives, \ |
20 |
20 |
archive_month, archives, post_detail, post_data, index_data |
21 |
from feeds import RSSFeed, AtomFeed |
|
21 |
from feeds import RSSFeed, AtomFeed, MediaFeed |
|
22 |
22 |
from tagging.models import Tag |
23 |
23 |
from search.views import search |
24 |
24 |
from photologue.views import galleries, gallery, photo |
| … | … | @@ -73,8 +73,8 @@ urlpatterns = patterns('', |
73 |
73 |
|
74 |
74 |
## Sem Web |
75 |
75 |
# RSS/Atom |
76 |
url(r'^data/(?P<url>(rss|atom).*)/$', feed, |
|
77 |
{'feed_dict': { 'rss': RSSFeed, 'atom': AtomFeed }}, name="feeds"), |
|
76 |
url(r'^data/(?P<url>(rss|atom|media).*)/$', feed, |
|
77 |
{'feed_dict': { 'rss': RSSFeed, 'atom': AtomFeed, 'media': MediaFeed }}, name="feeds"), |
|
78 |
78 |
|
79 |
79 |
# RDFa |
80 |
80 |
url(r'^data/%(tags_re)s/%(slug_re)s/$' % locals(), post_data, |
Up to file-list photologue/feeds.py:
1 |
"""Comes from http://www.djangosnippets.org/snippets/1648/ |
|
2 |
||
3 |
Provides basic Feed implementation for generating a MediaRSS feed for photologue galleries |
|
4 |
||
5 |
Sample usage (in urls.py): |
|
6 |
||
7 |
from feedgenerator import PhotologueFeed |
|
8 |
||
9 |
class MyPhotoFeed(PhotologueFeed): |
|
10 |
title = 'My Photologue Galleries' |
|
11 |
description = 'Latest updates to My Photologue Galleries' |
|
12 |
title_template = 'feeds/gallery_feed_title.html' |
|
13 |
description_template = 'feeds/gallery_feed_description.html' |
|
14 |
||
15 |
photofeeds = { |
|
16 |
'gallery': MyPhotoFeed, |
|
17 |
} |
|
18 |
||
19 |
urlpatterns += patterns('', |
|
20 |
url(r'^photologue/feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': photofeeds}), |
|
21 |
) |
|
22 |
||
23 |
""" |
|
24 |
from django.core.urlresolvers import reverse |
|
25 |
from django.contrib.syndication.feeds import Feed |
|
26 |
from django.contrib.sites.models import Site |
|
27 |
from django.utils.feedgenerator import Rss201rev2Feed |
|
28 |
from django.utils.http import urlquote |
|
29 |
||
30 |
from photologue.models import Gallery |
|
31 |
||
32 |
class MediaRSSFeed(Rss201rev2Feed): |
|
33 |
"""Basic implementation of Yahoo Media RSS (mrss) |
|
34 |
http://video.search.yahoo.com/mrss |
|
35 |
||
36 |
Includes these elements in the Item feed: |
|
37 |
media:content |
|
38 |
url, width, height |
|
39 |
media:thumbnail |
|
40 |
url, width, height |
|
41 |
media:description |
|
42 |
media:title |
|
43 |
media:keywords |
|
44 |
""" |
|
45 |
def rss_attributes(self): |
|
46 |
attrs = super(MediaRSSFeed, self).rss_attributes() |
|
47 |
attrs['xmlns:media'] = 'http://search.yahoo.com/mrss/' |
|
48 |
attrs['xmlns:atom'] = 'http://www.w3.org/2005/Atom' |
|
49 |
return attrs |
|
50 |
||
51 |
def add_item_elements(self, handler, item): |
|
52 |
"""Callback to add elements to each item (item/entry) element.""" |
|
53 |
super(MediaRSSFeed, self).add_item_elements(handler, item) |
|
54 |
||
55 |
if 'media:title' in item: |
|
56 |
handler.addQuickElement(u"media:title", item['title']) |
|
57 |
if 'media:description' in item: |
|
58 |
handler.addQuickElement(u"media:description", item['description']) |
|
59 |
||
60 |
if 'content_url' in item: |
|
61 |
content = dict(url=item['content_url']) |
|
62 |
if 'content_width' in item: |
|
63 |
content['width'] = str(item['content_width']) |
|
64 |
if 'content_height' in item: |
|
65 |
content['height'] = str(item['content_height']) |
|
66 |
handler.addQuickElement(u"media:content", '', content) |
|
67 |
||
68 |
if 'thumbnail_url' in item: |
|
69 |
thumbnail = dict(url=item['thumbnail_url']) |
|
70 |
if 'thumbnail_width' in item: |
|
71 |
thumbnail['width'] = str(item['thumbnail_width']) |
|
72 |
if 'thumbnail_height' in item: |
|
73 |
thumbnail['height'] = str(item['thumbnail_height']) |
|
74 |
handler.addQuickElement(u"media:thumbnail", '', thumbnail) |
|
75 |
||
76 |
if 'keywords' in item: |
|
77 |
handler.addQuickElement(u"media:keywords", item['keywords']) |
|
78 |
||
79 |
||
80 |
class PhotologueFeed(Feed): |
|
81 |
"""Basic Feed implementation for generating a MediaRSS feed for photologue galleries |
|
82 |
To customize, subclass and override these attributes: |
|
83 |
title |
|
84 |
description |
|
85 |
title_template |
|
86 |
description_template |
|
87 |
item_limit |
|
88 |
""" |
|
89 |
feed_type = MediaRSSFeed |
|
90 |
||
91 |
sitename = Site.objects.get_current().name |
|
92 |
||
93 |
title = '%s Gallery' % (sitename,) |
|
94 |
description = '%s Photo Gallery' % (sitename,) |
|
95 |
title_template = 'gallery_feed_title.html' |
|
96 |
description_template = 'gallery_feed_description.html' |
|
97 |
item_limit = 10 |
|
98 |
||
99 |
def get_object(self, bits): |
|
100 |
""" |
|
101 |
Returns objects based on slug fed through URL |
|
102 |
e.g. |
|
103 |
<url-slug>/gallery-title-slug/ |
|
104 |
returns photos in gallery-title-slug |
|
105 |
||
106 |
<url-slug>/ |
|
107 |
returns latest 10 galleries with sample photos. |
|
108 |
links are to gallery feeds |
|
109 |
""" |
|
110 |
||
111 |
if len(bits) == 0: |
|
112 |
return None |
|
113 |
elif len(bits) > 1: |
|
114 |
return ObjectDoesNotExist |
|
115 |
else: |
|
116 |
return Gallery.objects.get(title_slug__exact=bits[0]) |
|
117 |
||
118 |
def link(self, gallery): |
|
119 |
"""Returns link to either the archive list URL or specific gallery URL""" |
|
120 |
if gallery is None: |
|
121 |
return reverse('pl-gallery-archive') |
|
122 |
else: |
|
123 |
return gallery.get_absolute_url() |
|
124 |
||
125 |
def items(self, gallery): |
|
126 |
"""Returns up to 'item_limit' public Gallery items or 'item_limit' public photos in a specified Gallery (default=10) |
|
127 |
""" |
|
128 |
if gallery is None: |
|
129 |
return Gallery.objects.filter(is_public=True)[:self.item_limit] |
|
130 |
else: |
|
131 |
return gallery.public()[:self.item_limit] |
|
132 |
||
133 |
def item_pubdate(self, obj): |
|
134 |
return obj.date_added |
|
135 |
||
136 |
def item_extra_kwargs(self, obj): |
|
137 |
"""Return a dictionary to the feedgenerator for each item to be added to the feed. |
|
138 |
If the object is a Gallery, uses a random sample image for use as the feed Item |
|
139 |
""" |
|
140 |
if isinstance(obj, Gallery): |
|
141 |
photo = obj.photos.all().reverse()[0] |
|
142 |
photo.caption = obj.description |
|
143 |
else: |
|
144 |
photo = obj |
|
145 |
||
146 |
item = {'media:title': photo.title, |
|
147 |
'media:description': photo.caption, |
|
148 |
'content_url': photo.display.url, |
|
149 |
'content_width': photo.display.width, |
|
150 |
'content_height': photo.display.height, |
|
151 |
'thumbnail_url': photo.thumbnail.url, |
|
152 |
'thumbnail_width': photo.thumbnail.width, |
|
153 |
'thumbnail_height': photo.thumbnail.height, |
|
154 |
} |
|
155 |
||
156 |
return item |
