10
10
from django.utils.translation import ugettext_lazy as _
11
11
from django.conf import settings
13
from pybb.markups import mypostmarkup
13
from pybb.markups import mypostmarkup
14
from pybb.fields import AutoOneToOneField, ExtendedImageField
14
15
from pybb.util import urlize, memoize_method, unescape
15
16
from pybb import settings as pybb_settings
17
from django.conf import settings
18
if settings.USE_SPHINX:
19
from djangosphinx.models import SphinxSearch
22
from notification import models as notification
23
from django.db.models import signals
18
TZ_CHOICES = [(float(x[0]), x[1]) for x in (
19
(-12, '-12'), (-11, '-11'), (-10, '-10'), (-9.5, '-09.5'), (-9, '-09'),
20
(-8.5, '-08.5'), (-8, '-08 PST'), (-7, '-07 MST'), (-6, '-06 CST'),
21
(-5, '-05 EST'), (-4, '-04 AST'), (-3.5, '-03.5'), (-3, '-03 ADT'),
22
(-2, '-02'), (-1, '-01'), (0, '00 GMT'), (1, '+01 CET'), (2, '+02'),
23
(3, '+03'), (3.5, '+03.5'), (4, '+04'), (4.5, '+04.5'), (5, '+05'),
24
(5.5, '+05.5'), (6, '+06'), (6.5, '+06.5'), (7, '+07'), (8, '+08'),
25
(9, '+09'), (9.5, '+09.5'), (10, '+10'), (10.5, '+10.5'), (11, '+11'),
26
(11.5, '+11.5'), (12, '+12'), (13, '+13'), (14, '+14'),
28
31
('markdown', 'markdown'),
64
66
description = models.TextField(_('Description'), blank=True, default='')
65
67
moderators = models.ManyToManyField(User, blank=True, null=True, verbose_name=_('Moderators'))
66
68
updated = models.DateTimeField(_('Updated'), null=True)
69
post_count = models.IntegerField(_('Post count'), blank=True, default=0)
69
72
ordering = ['position']
106
105
sticky = models.BooleanField(_('Sticky'), blank=True, default=False)
107
106
closed = models.BooleanField(_('Closed'), blank=True, default=False)
108
107
subscribers = models.ManyToManyField(User, related_name='subscriptions', verbose_name=_('Subscribers'), blank=True)
111
if settings.USE_SPHINX:
112
search = SphinxSearch(
108
post_count = models.IntegerField(_('Post count'), blank=True, default=0)
119
ordering = ['-updated']
111
ordering = ['-created']
120
112
verbose_name = _('Topic')
121
113
verbose_name_plural = _('Topics')
123
115
def __unicode__(self):
128
120
return self.posts.all().order_by('created').select_related()[0]
131
123
def last_post(self):
132
124
return self.posts.all().order_by('-created').select_related()[0]
135
def post_count(self):
136
return Post.objects.filter(topic=self).count()
138
126
def get_absolute_url(self):
139
127
return reverse('pybb_topic', args=[self.id])
141
129
def save(self, *args, **kwargs):
142
new = self.id is None
144
131
self.created = datetime.now()
145
132
super(Topic, self).save(*args, **kwargs)
171
158
if self.markup == 'bbcode':
172
159
self.body_html = mypostmarkup.markup(self.body, auto_urls=False)
173
160
elif self.markup == 'markdown':
174
self.body_html = unicode(do_wl_markdown(self.body, safe_mode='escape', wikiwords=False))
161
self.body_html = unicode(Markdown(self.body, safe_mode='escape'))
176
163
raise Exception('Invalid markup property: %s' % self.markup)
220
198
def save(self, *args, **kwargs):
221
199
if self.created is None:
222
200
self.created = datetime.now()
226
203
new = self.id is None
229
206
self.topic.updated = datetime.now()
207
self.topic.post_count += 1
230
208
self.topic.save()
231
209
self.topic.forum.updated = self.topic.updated
210
self.topic.forum.post_count += 1
232
211
self.topic.forum.save()
234
213
super(Post, self).save(*args, **kwargs)
243
222
head_post_id = self.topic.posts.order_by('created')[0].id
244
223
super(Post, self).delete(*args, **kwargs)
225
self.topic.post_count -= 1
246
226
self.topic.save()
227
self.topic.forum.post_count -= 1
247
228
self.topic.forum.save()
249
230
if self_id == head_post_id:
250
231
self.topic.delete()
234
class Profile(models.Model):
235
user = AutoOneToOneField(User, related_name='pybb_profile', verbose_name=_('User'))
236
site = models.URLField(_('Site'), verify_exists=False, blank=True, default='')
237
jabber = models.CharField(_('Jabber'), max_length=80, blank=True, default='')
238
icq = models.CharField(_('ICQ'), max_length=12, blank=True, default='')
239
msn = models.CharField(_('MSN'), max_length=80, blank=True, default='')
240
aim = models.CharField(_('AIM'), max_length=80, blank=True, default='')
241
yahoo = models.CharField(_('Yahoo'), max_length=80, blank=True, default='')
242
location = models.CharField(_('Location'), max_length=30, blank=True, default='')
243
signature = models.TextField(_('Signature'), blank=True, default='', max_length=pybb_settings.SIGNATURE_MAX_LENGTH)
244
time_zone = models.FloatField(_('Time zone'), choices=TZ_CHOICES, default=float(pybb_settings.DEFAULT_TIME_ZONE))
245
language = models.CharField(_('Language'), max_length=10, blank=True, default='',
246
choices=settings.LANGUAGES)
247
avatar = ExtendedImageField(_('Avatar'), blank=True, default='', upload_to=pybb_settings.AVATARS_UPLOAD_TO, width=pybb_settings.AVATAR_WIDTH, height=pybb_settings.AVATAR_HEIGHT)
248
show_signatures = models.BooleanField(_('Show signatures'), blank=True, default=True)
249
markup = models.CharField(_('Default markup'), max_length=15, default=pybb_settings.DEFAULT_MARKUP, choices=MARKUP_CHOICES)
252
verbose_name = _('Profile')
253
verbose_name_plural = _('Profiles')
257
def unread_pm_count(self):
258
return PrivateMessage.objects.filter(dst_user=self, read=False).count()
260
def post_count(self):
262
Return the nr of posts the user has. This uses djangos filter feature
263
will therefore hit the database. This should maybe be reworked when the
264
database grows to not be always calculated.
266
return Post.objects.filter(user=self.user).count()
253
268
class Read(models.Model):
255
For each topic that user has entered the time
270
For each topic that user has entered the time
256
271
is logged to this model.
325
340
def save(self, *args, **kwargs):
326
341
super(Attachment, self).save(*args, **kwargs)
327
342
if not self.hash:
328
self.hash = hashlib.sha1(str(self.id) + settings.SECRET_KEY).hexdigest()
343
self.hash = sha.new(str(self.id) + settings.SECRET_KEY).hexdigest()
329
344
super(Attachment, self).save(*args, **kwargs)
331
346
def __unicode__(self):