| 1 |
from datetime import datetime, timedelta |
|---|
| 2 |
|
|---|
| 3 |
from django import template |
|---|
| 4 |
from django.core.urlresolvers import reverse |
|---|
| 5 |
from django.utils.safestring import mark_safe |
|---|
| 6 |
from django.template import RequestContext |
|---|
| 7 |
from django.utils.encoding import smart_unicode |
|---|
| 8 |
from django.db import settings |
|---|
| 9 |
from django.utils.html import escape |
|---|
| 10 |
from django.utils.translation import ugettext as _ |
|---|
| 11 |
from django.utils import dateformat |
|---|
| 12 |
|
|---|
| 13 |
from pybb.models import Forum, Topic, Read |
|---|
| 14 |
from pybb.unread import cache_unreads |
|---|
| 15 |
|
|---|
| 16 |
register = template.Library() |
|---|
| 17 |
|
|---|
| 18 |
@register.filter |
|---|
| 19 |
def pybb_profile_link(user): |
|---|
| 20 |
data = u'<a href="%s">%s</a>' % (\ |
|---|
| 21 |
reverse('pybb_profile', args=[user.username]), user.username) |
|---|
| 22 |
return mark_safe(data) |
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
@register.tag |
|---|
| 26 |
def pybb_time(parser, token): |
|---|
| 27 |
try: |
|---|
| 28 |
tag, time = token.split_contents() |
|---|
| 29 |
except ValueError: |
|---|
| 30 |
raise template.TemplateSyntaxError('pybb_time requires single argument') |
|---|
| 31 |
else: |
|---|
| 32 |
return PybbTimeNode(time) |
|---|
| 33 |
|
|---|
| 34 |
|
|---|
| 35 |
class PybbTimeNode(template.Node): |
|---|
| 36 |
def __init__(self, time): |
|---|
| 37 |
self.time = template.Variable(time) |
|---|
| 38 |
|
|---|
| 39 |
def render(self, context): |
|---|
| 40 |
time = self.time.resolve(context) |
|---|
| 41 |
|
|---|
| 42 |
delta = datetime.now() - time |
|---|
| 43 |
today = datetime.now().replace(hour=0, minute=0, second=0) |
|---|
| 44 |
yesterday = today - timedelta(days=1) |
|---|
| 45 |
|
|---|
| 46 |
if delta.days == 0: |
|---|
| 47 |
if delta.seconds < 60: |
|---|
| 48 |
if context['LANGUAGE_CODE'].startswith('ru'): |
|---|
| 49 |
msg = _('seconds ago,seconds ago,seconds ago') |
|---|
| 50 |
import pytils |
|---|
| 51 |
msg = pytils.numeral.choose_plural(delta.seconds, msg) |
|---|
| 52 |
else: |
|---|
| 53 |
msg = _('seconds ago') |
|---|
| 54 |
return u'%d %s' % (delta.seconds, msg) |
|---|
| 55 |
|
|---|
| 56 |
elif delta.seconds < 3600: |
|---|
| 57 |
minutes = int(delta.seconds / 60) |
|---|
| 58 |
if context['LANGUAGE_CODE'].startswith('ru'): |
|---|
| 59 |
msg = _('minutes ago,minutes ago,minutes ago') |
|---|
| 60 |
import pytils |
|---|
| 61 |
msg = pytils.numeral.choose_plural(minutes, msg) |
|---|
| 62 |
else: |
|---|
| 63 |
msg = _('minutes ago') |
|---|
| 64 |
return u'%d %s' % (minutes, msg) |
|---|
| 65 |
if time > today: |
|---|
| 66 |
return _('today, %s') % time.strftime('%H:%M') |
|---|
| 67 |
elif time > yesterday: |
|---|
| 68 |
return _('yesterday, %s') % time.strftime('%H:%M') |
|---|
| 69 |
else: |
|---|
| 70 |
return dateformat.format(time, 'd M, Y H:i') |
|---|
| 71 |
|
|---|
| 72 |
|
|---|
| 73 |
|
|---|
| 74 |
@register.inclusion_tag('pybb/pagination.html',takes_context=True) |
|---|
| 75 |
def pybb_pagination(context, adjacent_pages=5): |
|---|
| 76 |
""" |
|---|
| 77 |
Return the list of A tags with links to pages. |
|---|
| 78 |
""" |
|---|
| 79 |
|
|---|
| 80 |
page_list = range( |
|---|
| 81 |
max(1,context['page'] - adjacent_pages), |
|---|
| 82 |
min(context['pages'],context['page'] + adjacent_pages) + 1) |
|---|
| 83 |
lower_page = None |
|---|
| 84 |
higher_page = None |
|---|
| 85 |
|
|---|
| 86 |
if not 1 == context['page']: |
|---|
| 87 |
lower_page = context['page'] - 1 |
|---|
| 88 |
|
|---|
| 89 |
if not 1 in page_list: |
|---|
| 90 |
page_list.insert(0,1) |
|---|
| 91 |
if not 2 in page_list: |
|---|
| 92 |
page_list.insert(1,'.') |
|---|
| 93 |
|
|---|
| 94 |
if not context['pages'] == context['page']: |
|---|
| 95 |
higher_page = context['page'] + 1 |
|---|
| 96 |
|
|---|
| 97 |
if not context['pages'] in page_list: |
|---|
| 98 |
if not context['pages'] - 1 in page_list: |
|---|
| 99 |
page_list.append('.') |
|---|
| 100 |
page_list.append(context['pages']) |
|---|
| 101 |
get_params = '&'.join(['%s=%s' % (x[0],','.join(x[1])) for x in |
|---|
| 102 |
context['request'].GET.iteritems() if (not x[0] == 'page' and not x[0] == 'per_page')]) |
|---|
| 103 |
if get_params: |
|---|
| 104 |
get_params = '?%s&' % get_params |
|---|
| 105 |
else: |
|---|
| 106 |
get_params = '?' |
|---|
| 107 |
|
|---|
| 108 |
return { |
|---|
| 109 |
'get_params': get_params, |
|---|
| 110 |
'lower_page': lower_page, |
|---|
| 111 |
'higher_page': higher_page, |
|---|
| 112 |
'page': context['page'], |
|---|
| 113 |
'pages': context['pages'], |
|---|
| 114 |
'page_list': page_list, |
|---|
| 115 |
'per_page': context['per_page'], |
|---|
| 116 |
} |
|---|
| 117 |
|
|---|
| 118 |
|
|---|
| 119 |
@register.simple_tag |
|---|
| 120 |
def pybb_link(object, anchor=u''): |
|---|
| 121 |
""" |
|---|
| 122 |
Return A tag with link to object. |
|---|
| 123 |
""" |
|---|
| 124 |
|
|---|
| 125 |
url = hasattr(object,'get_absolute_url') and object.get_absolute_url() or None |
|---|
| 126 |
anchor = anchor or smart_unicode(object) |
|---|
| 127 |
return mark_safe('<a href="%s">%s</a>' % (url, escape(anchor))) |
|---|
| 128 |
|
|---|
| 129 |
|
|---|
| 130 |
@register.filter |
|---|
| 131 |
def pybb_has_unreads(topic, user): |
|---|
| 132 |
""" |
|---|
| 133 |
Check if topic has messages which user didn't read. |
|---|
| 134 |
""" |
|---|
| 135 |
|
|---|
| 136 |
now = datetime.now() |
|---|
| 137 |
delta = timedelta(seconds=settings.PYBB_READ_TIMEOUT) |
|---|
| 138 |
|
|---|
| 139 |
if not user.is_authenticated(): |
|---|
| 140 |
return False |
|---|
| 141 |
else: |
|---|
| 142 |
if isinstance(topic, Topic): |
|---|
| 143 |
if (now - delta > topic.updated): |
|---|
| 144 |
return False |
|---|
| 145 |
else: |
|---|
| 146 |
if hasattr(topic, '_read'): |
|---|
| 147 |
read = topic._read |
|---|
| 148 |
else: |
|---|
| 149 |
try: |
|---|
| 150 |
read = Read.objects.get(user=user, topic=topic) |
|---|
| 151 |
except Read.DoesNotExist: |
|---|
| 152 |
read = None |
|---|
| 153 |
|
|---|
| 154 |
if read is None: |
|---|
| 155 |
return True |
|---|
| 156 |
else: |
|---|
| 157 |
return topic.updated > read.time |
|---|
| 158 |
else: |
|---|
| 159 |
raise Exception('Object should be a topic') |
|---|
| 160 |
|
|---|
| 161 |
|
|---|
| 162 |
@register.filter |
|---|
| 163 |
def pybb_setting(name): |
|---|
| 164 |
return mark_safe(getattr(settings, name, 'NOT DEFINED')) |
|---|
| 165 |
|
|---|
| 166 |
|
|---|
| 167 |
@register.filter |
|---|
| 168 |
def pybb_moderated_by(topic, user): |
|---|
| 169 |
""" |
|---|
| 170 |
Check if user is moderator of topic's forum. |
|---|
| 171 |
""" |
|---|
| 172 |
|
|---|
| 173 |
return user.is_superuser or user in topic.forum.moderators.all() |
|---|
| 174 |
|
|---|
| 175 |
|
|---|
| 176 |
@register.filter |
|---|
| 177 |
def pybb_editable_by(post, user): |
|---|
| 178 |
""" |
|---|
| 179 |
Check if the post could be edited by the user. |
|---|
| 180 |
""" |
|---|
| 181 |
|
|---|
| 182 |
if user.is_superuser: |
|---|
| 183 |
return True |
|---|
| 184 |
if post.user == user: |
|---|
| 185 |
return True |
|---|
| 186 |
if user in post.topic.forum.moderators.all(): |
|---|
| 187 |
return True |
|---|
| 188 |
return False |
|---|
| 189 |
|
|---|
| 190 |
|
|---|
| 191 |
@register.filter |
|---|
| 192 |
def pybb_posted_by(post, user): |
|---|
| 193 |
""" |
|---|
| 194 |
Check if the post is writed by the user. |
|---|
| 195 |
""" |
|---|
| 196 |
|
|---|
| 197 |
return post.user == user |
|---|
| 198 |
|
|---|
| 199 |
|
|---|
| 200 |
@register.filter |
|---|
| 201 |
def pybb_equal_to(obj1, obj2): |
|---|
| 202 |
""" |
|---|
| 203 |
Check if objects are equal. |
|---|
| 204 |
""" |
|---|
| 205 |
|
|---|
| 206 |
return obj1 == obj2 |
|---|
| 207 |
|
|---|
| 208 |
|
|---|
| 209 |
@register.filter |
|---|
| 210 |
def pybb_unreads(qs, user): |
|---|
| 211 |
return cache_unreads(qs, user) |
|---|