root/trunk/blog/templatetags/blogutils.py

Revision 57, 5.3 kB (checked in by nobu, 10 months ago)
  • テンプレートタグを修正
Line 
1 # vim: encoding=utf-8 :
2
3 import datetime
4 import math
5 import os
6 import re
7 import time
8
9 from django.conf import settings
10 from django.db import connection
11 from django.db.models.query import QuerySet
12 from django.core.urlresolvers import reverse
13 from django.template import Library
14
15 from blog.models import Tag
16
17 EMOTICON_PATTERNS = (
18     (re.compile(r'(\s+)(:\)|:-\))(\s*)'), u'emoticon_smile'),
19     (re.compile(r'(\s+)(:D|:-D)(\s*)'), u'emoticon_grin'),
20     (re.compile(r'(\s+)(:p|:P|:-p|:-P)(\s*)'), u'emoticon_tongue'),
21     (re.compile(r'(\s+)(;\)|;-\))(\s*)'), u'emoticon_wink'),
22     (re.compile(r'(\s+)(:\(|:-\()(\s*)'), u'emoticon_unhappy'),
23     (re.compile(r'(\s+)(:o|:O|:-o|:-O)(\s*)'), u'emoticon_surprised'),
24     (re.compile(r'(\s+)(:3|:-3)(\s*)'), u'emoticon_waii'),
25     (re.compile(r'(\s+)(:lol:)(\s*)'), u'emoticon_happy'),
26     (re.compile(r'(\s+)(:evil:)(\s*)'), u'emoticon_evilgrin'),
27 )
28
29
30 register = Library()
31
32 class ArchiveLink(object):
33     """
34     Create Archive Link.
35     """
36     def __init__(self, date, count):
37         self.date = date
38         self.count = count
39    
40     def __str__(self):
41         return self.date.strftime('%b %Y').lower()
42    
43     def get_absolute_url(self):
44         date = self.date.strftime('%Y,%m').split(',')
45         return reverse('blog_archive_month', args=date)
46
47
48 class TagLink(object):
49     """
50     Create tag link.
51     """
52     def __init__(self, label, count, current=None):
53         self.label = label
54         self.count = count
55         self.current = current or False
56    
57     def __unicode__(self):
58         return self.label
59    
60     def get_absolute_url(self):
61         kwargs = {
62             'label': self.label.lower(),
63         }
64         return reverse('blog_entry_tag', args=[self.label.lower()])
65
66
67 class TagCloud(object):
68     """
69     TagLink's container.
70     """
71     def __init__(self):
72         self._clouds = []
73
74     def __len__(self):
75         return len(self._clouds)
76
77     def __iter__(self):
78         return self
79
80     def next(self):
81         if hasattr(self, '_index'):
82             self._index += 1
83         else:
84             self._index = 0
85         try:
86             e = self._clouds[self._index]
87             e.rank = int((math.sqrt(e.count) - self._min) * self._base)
88             return e
89         except IndexError:
90             del self._index
91             raise StopIteration
92
93     def append(self, e):
94         if not isinstance(e, TagLink):
95             raise ValueError("%s is not TagLink's instance." % e.__class__.__name__)
96         self._clouds.append(e)
97
98     def set_range(self, _min, _max):
99         self._min = math.sqrt(_min)
100         self._max = math.sqrt(_max)
101         if self._min != self._max:
102             self._base = float(24) / (self._max - self._min)
103         else:
104             self._base = 1
105
106
107 @register.inclusion_tag('blog/_links.html')
108 def archive_links():
109     sql = """
110     SELECT
111         COUNT(id) as cnt,
112         EXTRACT(YEAR FROM created_at) as year,
113         EXTRACT(MONTH FROM created_at) as month
114     FROM
115         blog_entry
116     WHERE
117         is_active = True
118     GROUP BY
119         year DESC,
120         month DESC
121     """.splitlines()
122     sql = ' '.join(map(lambda l: l.strip(), sql))
123     cursor = connection.cursor()
124     cursor.execute(sql)
125     obj_list = []
126     for count, year, month in cursor.fetchall():
127         obj_list.append(ArchiveLink(date=datetime.date(year, month, 1),
128                                     count=count))
129     return {
130         'MEDIA_URL': settings.MEDIA_URL,
131         'DESIGN_THEME': settings.DESIGN_THEME,
132         'id': u'archive-list',
133         'obj_list': obj_list,
134         'title': u'Archives',
135     }
136
137
138 @register.inclusion_tag('blog/_tag_cloud.html')
139 def tag_links(currents=None):
140     sql = """
141     SELECT
142         T.label,
143         COUNT(T.label) as cnt
144     FROM
145         blog_tag AS T
146     JOIN
147         blog_entry_tags AS B
148     ON
149         T.id = B.tag_id
150     JOIN
151         blog_entry AS E
152     ON
153         B.entry_id = E.id AND E.is_active = True
154     GROUP BY
155         T.label ASC
156     """.splitlines()
157     sql = ' '.join(map(lambda l: l.strip(), sql))
158     cursor = connection.cursor()
159     cursor.execute(sql)
160    
161     if isinstance(currents, QuerySet):
162         currents = [t.label for t in currents]
163     elif isinstance(currents, Tag):
164         currents = [currents.label]
165     else:
166         currents = []
167     counts = []
168     obj_list = TagCloud()
169     for label, cnt in cursor.fetchall():
170         counts.append(cnt)
171         current = label in currents
172         obj_list.append(TagLink(label=label, count=cnt, current=current))
173     counts.sort()
174     try:
175         obj_list.set_range(counts[0], counts[-1])
176     except IndexError:
177         obj_list = []
178     return {
179         'MEDIA_URL': settings.MEDIA_URL,
180         'DESIGN_THEME': settings.DESIGN_THEME,
181         'id': u'tag-list',
182         'obj_list': obj_list,
183         'title': u'Categories',
184     }
185
186
187 @register.filter
188 def to_oneline(value):
189     return value.replace('\r\n', '\n').replace('\r', '\n').replace('\n', '')
190
191
192 @register.filter
193 def emoticon(value):
194     """
195     replace keyword to emoticon
196     """
197     file_path = os.path.join(settings.MEDIA_URL, 'themes', settings.DESIGN_THEME)
198     for pattern, file_name in EMOTICON_PATTERNS:
199         needle = r'\1<img src="%(file_path)s/images/icons/%(file_name)s.png" alt="\2" />\3' % {
200             'file_path': file_path,
201             'file_name': file_name,
202         }
203         value = pattern.sub(needle, value)
204     return value
205 emoticon.is_safe = True
Note: See TracBrowser for help on using the browser.