david / biologeek (http://biologeek.com/)

Source code of biologeek.com weblog under WTFPL.

Clone this repository (size: 252.8 KB): HTTPS / SSH
$ hg clone http://code.welldev.org/biologeek/

Changed (Δ6.1 KB):

raw changeset »

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