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

Source code of biologeek.com weblog under WTFPL.

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

Changed (Δ1.2 KB):

raw changeset »

biologeek/templates/photologue/gallery_detail.html (1 lines added, 1 lines removed)

biologeek/templates/photologue/gallery_list.html (1 lines added, 1 lines removed)

photologue/feeds.py (57 lines added, 36 lines removed)

photologue/models.py (16 lines added, 0 lines removed)

Up to file-list biologeek/templates/photologue/gallery_detail.html:

5
5
6
6
{% block extra_head %}
7
7
  {{ block.super }}
8
  <link rel="alternate" href="/data/media/{{ gallery.title_slug }}/" 
8
  <link rel="alternate" href="{{ gallery.get_feed_url }}" 
9
9
    type="application/rss+xml" title="Photos de la gallerie {{ gallery.title }}" id="gallery" />
10
10
{% endblock %}
11
11

Up to file-list biologeek/templates/photologue/gallery_list.html:

4
4
5
5
{% block extra_head %}
6
6
  {{ block.super }}
7
  <link rel="alternate" href="/data/media/" 
7
  <link rel="alternate" href="{% url feeds "media" %}" 
8
8
    type="application/rss+xml" title="Photos de biologeek.com" id="gallery" />
9
9
{% endblock %}
10
10

Up to file-list photologue/feeds.py:

1
1
"""Comes from http://www.djangosnippets.org/snippets/1648/
2
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
3
Provides basic Feed implementation for generating a MediaRSS feed 
4
for photologue galleries.
23
5
"""
6
from django.conf import settings
24
7
from django.core.urlresolvers import reverse
25
8
from django.contrib.syndication.feeds import Feed
26
9
from django.contrib.sites.models import Site
@@ -41,6 +24,11 @@ class MediaRSSFeed(Rss201rev2Feed):
41
24
    media:description
42
25
    media:title
43
26
    media:keywords
27
    
28
    And those ones in the Channel part:
29
    atom:icon
30
    atom:link
31
        previous, next
44
32
    """
45
33
    def rss_attributes(self):
46
34
        attrs = super(MediaRSSFeed, self).rss_attributes()
@@ -76,9 +64,30 @@ class MediaRSSFeed(Rss201rev2Feed):
76
64
        if 'keywords' in item:
77
65
            handler.addQuickElement(u"media:keywords", item['keywords'])
78
66
                                
67
    def add_root_elements(self, handler):
68
        """
69
        See documentation from http://developer.cooliris.com/?p=full
70
        """
71
        icon_url = '%scss/images/logo_biologeek.png' % settings.MEDIA_URL
72
        handler.addQuickElement(u"atom:icon", icon_url)
73
        if 'previous' in self.feed and self.feed['previous'] is not None:
74
            handler.addQuickElement(u"atom:link", '', {
75
                'rel': 'previous', 
76
                'href': self.feed['previous'].get_feed_url(),
77
            })
78
        if 'next' in self.feed and self.feed['next'] is not None:
79
            handler.addQuickElement(u"atom:link", '', {
80
                'rel': 'next', 
81
                'href': self.feed['next'].get_feed_url(),
82
            })
83
        super(MediaRSSFeed, self).add_root_elements(handler)
84
79
85
80
86
class PhotologueFeed(Feed):
81
    """Basic Feed implementation for generating a MediaRSS feed for photologue galleries
87
    """
88
    Basic Feed implementation for generating a MediaRSS feed 
89
    for photologue galleries.
90
    
82
91
    To customize, subclass and override these attributes:
83
92
        title
84
93
        description
@@ -115,15 +124,27 @@ class PhotologueFeed(Feed):
115
124
        else:
116
125
            return Gallery.objects.get(title_slug__exact=bits[0])
117
126
127
    def feed_extra_kwargs(self, obj):
128
        """
129
        Useful to set previous and next galleries (cooliris handle this).
130
        """
131
        if obj is None:
132
            obj = Gallery.objects.latest()
133
        return { 'previous': obj.get_previous(), 'next': obj.get_next()}
134
        
118
135
    def link(self, gallery):
119
        """Returns link to either the archive list URL or specific gallery URL"""
136
        """
137
        Returns link to either the archive list URL or specific gallery URL.
138
        """
120
139
        if gallery is None:
121
140
            return reverse('pl-gallery-archive')
122
141
        else:
123
142
            return gallery.get_absolute_url()
124
143
125
144
    def items(self, gallery):
126
        """Returns up to 'item_limit' public Gallery items or 'item_limit' public photos in a specified Gallery (default=10)
145
        """
146
        Returns up to 'item_limit' public Gallery items or 'item_limit' 
147
        public photos in a specified Gallery (default=10).
127
148
        """
128
149
        if gallery is None:
129
150
            return Gallery.objects.filter(is_public=True)[:self.item_limit]
@@ -134,8 +155,9 @@ class PhotologueFeed(Feed):
134
155
        return obj.date_added
135
156
136
157
    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
158
        """Return a dictionary to the feedgenerator for each item to be added 
159
        to the feed. If the object is a Gallery, uses a random sample image 
160
        for use as the feed Item.
139
161
        """
140
162
        if isinstance(obj, Gallery):
141
163
            photo = obj.photos.all().reverse()[0]
@@ -143,14 +165,13 @@ class PhotologueFeed(Feed):
143
165
        else:
144
166
            photo = obj
145
167
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
168
        return {
169
            'media:title': photo.title,
170
            'media:description': photo.caption,
171
            'content_url': photo.display.url,
172
            'content_width': photo.display.width,
173
            'content_height': photo.display.height,
174
            'thumbnail_url': photo.thumbnail.url,
175
            'thumbnail_width': photo.thumbnail.width,
176
            'thumbnail_height': photo.thumbnail.height,
177
        }

Up to file-list photologue/models.py:

@@ -31,6 +31,7 @@ class GalleryManager(models.Manager):
31
31
                                          .filter(title_slug__in=group_names)\
32
32
                                          .order_by('-id').distinct()
33
33
34
34
35
class Gallery(models.Model):
35
36
    date_added = models.DateTimeField(_('date published'), default=datetime.now)
36
37
    title = models.CharField(_('title'), max_length=100, unique=True)
@@ -60,6 +61,9 @@ class Gallery(models.Model):
60
61
    def get_absolute_url(self):
61
62
        return reverse('pl-gallery', args=[self.title_slug])
62
63
64
    def get_feed_url(self):
65
        return reverse('feeds', kwargs={'url':'media/%s' % self.title_slug})
66
63
67
    def latest(self, limit=0, public=True):
64
68
        if limit == 0:
65
69
            limit = self.photo_count()
@@ -86,6 +90,18 @@ class Gallery(models.Model):
86
90
87
91
    def public(self):
88
92
        return self.photos.filter(is_public=True)
93
    
94
    def get_previous(self):
95
        try:
96
            return self.get_previous_by_date_added(is_public=True)
97
        except Gallery.DoesNotExist:
98
            return None
99
100
    def get_next(self):
101
        try:
102
            return self.get_next_by_date_added(is_public=True)
103
        except Gallery.DoesNotExist:
104
            return None
89
105
        
90
106
91
107
class GalleryUpload(models.Model):