root/trunk/plugins/views.py

Revision 79, 8.3 kB (checked in by nobu, 5 months ago)

fixed recent entries

Line 
1 # vim: encoding=utf-8
2
3 import datetime
4 import math
5
6 from django.conf import settings
7 from django.core import exceptions
8 from django.core.urlresolvers import reverse
9 from django.db import connection
10 from django.template import loader, Context
11 from django.utils.translation import ugettext_lazy as _
12
13 from blog.models import Entry, Comment, TrackBack
14
15
16 class ContentsNotUsed(Exception):
17     pass
18
19
20 class ContentsManager(object):
21     """
22     """
23     def __init__(self, keyword):
24         self._contents = []
25         try:
26             assigned_contents = getattr(settings, keyword)
27         except AttributeError:
28             raise exceptions.ImproperlyConfigured('settings does not define a "%s" attribute' % keyword)
29         for contents_path in assigned_contents:
30             try:
31                 dot_index = contents_path.rindex('.')
32             except ValueError:
33                 raise exceptions.ImproperlyConfigured('%s isn\'t a contents module' % contents_path)
34             c_module, c_classname = contents_path[:dot_index], contents_path[dot_index+1:]
35             try:
36                 mod = __import__(c_module, {}, {}, [''])
37             except ImportError, e:
38                 raise exceptions.ImproperlyConfigured('Error importing contents %s: "%s"' % (c_module, e))
39             try:
40                 c_class = getattr(mod, c_classname)
41             except AttributeError:
42                 raise exceptions.ImproperlyConfigured('Contents module "%s" does not define a "%s" class' % (c_module, c_classname))
43             try:
44                 c_instance = c_class()
45             except ContentsNotUsed:
46                 continue
47             self._contents.append(c_instance)
48
49     def __str__(self):
50         return self.render()
51
52     def __unicode__(self):
53         return unicode(self.render(), 'utf-8')
54
55     def render(self):
56         results = []
57         for contents in self._contents:
58             rendered = contents.render()
59             if rendered is None:
60                 continue
61             results.append(rendered)
62         return '\n'.join(results)
63
64
65 class Content(object):
66     """
67     """
68     def __init__(self):
69         pass
70
71     def __str__(self):
72         return self.render()
73
74     def __unicode__(self):
75         return unicode(self.render(), 'utf-8')
76
77     def render(self):
78         raise NotImplementedError
79
80
81 class ArchiveLink(object):
82     """
83     Create Archive Link.
84     """
85     def __init__(self, date, count):
86         self.date = date
87         self.count = count
88    
89     def __str__(self):
90         return self.date.strftime('%b %Y').lower()
91    
92     def get_absolute_url(self):
93         date = self.date.strftime('%Y,%m').split(',')
94         return reverse('blog_archive_month', args=date)
95
96
97 class ArchiveContent(Content):
98     def render(self):
99         cursor = connection.cursor()
100         qn = connection.ops.quote_name
101         sql = """
102         SELECT
103             COUNT(e.%(id)s) as cnt,
104             EXTRACT(YEAR FROM e.%(published_at)s) as year,
105             EXTRACT(MONTH FROM e.%(published_at)s) as month
106         FROM %(blog_entry)s e
107         WHERE
108             e.%(is_published)s = True
109         AND
110             e.%(is_active)s = True
111         GROUP BY
112             year DESC,
113             month DESC
114         """ % {
115             'id': qn('id'),
116             'published_at': qn('published_at'),
117             'blog_entry': qn('blog_entry'),
118             'is_published': qn('is_published'),
119             'is_active': qn('is_active'),
120         }
121         cursor.execute(sql)
122         obj_list = []
123         for count, year, month in cursor.fetchall():
124             if not bool(year) or not bool(month):
125                 continue
126             obj_list.append(ArchiveLink(date=datetime.date(year, month, 1),
127                                         count=count))
128         c = Context({
129             'MEDIA_URL': settings.MEDIA_URL,
130             'DESIGN_THEME': settings.DESIGN_THEME,
131             'id': u'archive-list',
132             'obj_list': obj_list,
133             'title': u'Archives',
134         })
135         t = loader.get_template('blog/_links.html')
136         return t.render(c)
137
138
139 class TagLink(object):
140     """
141     Create tag link.
142     """
143     def __init__(self, label, count, current=None):
144         self.label = label
145         self.count = count
146         self.current = current or False
147    
148     def __unicode__(self):
149         return self.label
150    
151     def get_absolute_url(self):
152         kwargs = {
153             'label': self.label.lower(),
154         }
155         return reverse('blog_entry_tag', args=[self.label.lower()])
156
157
158 class TagCloud(object):
159     """
160     TagLink's container.
161     """
162     def __init__(self):
163         self._clouds = []
164
165     def __len__(self):
166         return len(self._clouds)
167
168     def __iter__(self):
169         return self
170
171     def next(self):
172         if hasattr(self, '_index'):
173             self._index += 1
174         else:
175             self._index = 0
176         try:
177             e = self._clouds[self._index]
178             e.rank = int((math.sqrt(e.count) - self._min) * self._base)
179             return e
180         except IndexError:
181             del self._index
182             raise StopIteration
183
184     def append(self, e):
185         if not isinstance(e, TagLink):
186             raise ValueError("%s is not TagLink's instance." % e.__class__.__name__)
187         self._clouds.append(e)
188
189     def set_range(self, _min, _max):
190         self._min = math.sqrt(_min)
191         self._max = math.sqrt(_max)
192         if self._min != self._max:
193             self._base = float(24) / (self._max - self._min)
194         else:
195             self._base = 1
196
197
198 class TagCloudContent(Content):
199     """
200     """
201     def render(self):
202         cursor = connection.cursor()
203         qn = connection.ops.quote_name
204         sql = """
205         SELECT
206             t.%(label)s,
207             COUNT(t.%(label)s) as cnt
208         FROM %(blog_tag)s t, %(blog_entry_tags)s b, %(blog_entry)s e
209         WHERE
210             t.%(id)s = b.%(tag_id)s
211         AND
212             b.%(entry_id)s = e.%(id)s
213         AND
214             e.%(is_active)s = True
215         GROUP BY
216             t.%(label)s ASC
217         """ % {
218             'id': qn('id'),
219             'tag_id': qn('tag_id'),
220             'entry_id': qn('entry_id'),
221             'label': qn('label'),
222             'is_active': qn('is_active'),
223             'blog_tag': qn('blog_tag'),
224             'blog_entry_tags': qn('blog_entry_tags'),
225             'blog_entry': qn('blog_entry'),
226         }
227         cursor.execute(sql)
228
229         # TODO: check current tags.
230 #        if isinstance(currents, QuerySet):
231 #            currents = [t.label for t in currents]
232 #        elif isinstance(currents, Tag):
233 #            currents = [currents.label]
234 #        else:
235 #            currents = []
236         counts = []
237         obj_list = TagCloud()
238         for label, cnt in cursor.fetchall():
239             counts.append(cnt)
240 #            current = label in currents
241 #            obj_list.append(TagLink(label=label, count=cnt, current=current))
242             obj_list.append(TagLink(label=label, count=cnt))
243         counts.sort()
244         try:
245             obj_list.set_range(counts[0], counts[-1])
246         except IndexError:
247             obj_list = []
248         c = Context({
249             'MEDIA_URL': settings.MEDIA_URL,
250             'DESIGN_THEME': settings.DESIGN_THEME,
251             'id': u'tag-list',
252             'obj_list': obj_list,
253             'title': _(u'Categories'),
254         })
255         t = loader.get_template('blog/_tag_cloud.html')
256         return t.render(c)
257
258
259 class RecentEntriesContent(Content):
260     """
261     """
262     def render(self):
263         # TODO: accessible this point.
264         obj_list = Entry.objects.filter(is_published__exact=True)\
265                                 .filter(is_active__exact=True)[0:10]
266         c = Context({
267             'MEDIA_URL': settings.MEDIA_URL,
268             'DESIGN_THEME': settings.DESIGN_THEME,
269             'id': u'comment-list',
270             'obj_list': obj_list,
271             'title': _(u'Recent Entries'),
272         })
273         t = loader.get_template('blog/_links.html')
274         return t.render(c)
275
276
277 class RecentCommentsContent(Content):
278     """
279     """
280     def render(self):
281         # TODO: accessible this point.
282         obj_list = Comment.objects.all().order_by('-created_at')[0:10]
283         c = Context({
284             'MEDIA_URL': settings.MEDIA_URL,
285             'DESIGN_THEME': settings.DESIGN_THEME,
286             'id': u'comment-list',
287             'obj_list': obj_list,
288             'title': _(u'Recent Comments'),
289         })
290         t = loader.get_template('blog/_links.html')
291         return t.render(c)
Note: See TracBrowser for help on using the browser.