~widelands-dev/widelands-website/django_staticfiles

22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
1
from datetime import datetime
274 by Holger Rapp
Disable wikiwords in the forums
2
from mainpage.templatetags.wl_markdown import do_wl_markdown
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
3
import os.path
254 by Holger Rapp
Fixed a few deprecation warnings and reparied cross site scripting fixes for AJAX requests
4
import hashlib
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
5
6
from django.db import models
7
from django.contrib.auth.models import User
489.1.13 by franku
django.conf.urlresolvers -> django.urls
8
from django.urls import reverse
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
9
from django.utils.html import strip_tags
10
from django.utils.translation import ugettext_lazy as _
11
from django.conf import settings
12
192 by Holger Rapp
Trying to fix 338756
13
from pybb.markups import mypostmarkup
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
14
from pybb.util import urlize, memoize_method, unescape
15
from pybb import settings as pybb_settings
90 by Holger Rapp
Sphinx must now be enabled in local_settings.py, otherwise it won't work
16
17
from django.conf import settings
427.1.8 by franku
moved unhide_post to pybb.models
18
from notification.models import send
19
from django.contrib.auth.models import User
504.2.9 by franku
some refactoring
20
from check_input.models import SuspiciousInput
21
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
22
209.1.21 by Timo Wingender
Add notifications to forum
23
try:
24
    from notification import models as notification
25
    from django.db.models import signals
26
except ImportError:
27
    notification = None
28
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
29
MARKUP_CHOICES = (
30
    ('markdown', 'markdown'),
209.1.68 by Timo Wingender
add field to choose between markdown and bbcode as markup
31
    ('bbcode', 'bbcode'),
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
32
)
33
34
35
class Category(models.Model):
36
    name = models.CharField(_('Name'), max_length=80)
37
    position = models.IntegerField(_('Position'), blank=True, default=0)
38
39
    class Meta:
40
        ordering = ['position']
41
        verbose_name = _('Category')
42
        verbose_name_plural = _('Categories')
43
44
    def __unicode__(self):
45
        return self.name
46
47
    def forum_count(self):
48
        return self.forums.all().count()
49
50
    def get_absolute_url(self):
51
        return reverse('pybb_category', args=[self.id])
52
53
    @property
54
    def topics(self):
55
        return Topic.objects.filter(forum__category=self).select_related()
192 by Holger Rapp
Trying to fix 338756
56
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
57
    @property
58
    def posts(self):
59
        return Post.objects.filter(topic__forum__category=self).select_related()
60
61
62
class Forum(models.Model):
438.1.6 by franku
run the script
63
    category = models.ForeignKey(
64
        Category, related_name='forums', verbose_name=_('Category'))
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
65
    name = models.CharField(_('Name'), max_length=80)
66
    position = models.IntegerField(_('Position'), blank=True, default=0)
67
    description = models.TextField(_('Description'), blank=True, default='')
438.1.6 by franku
run the script
68
    moderators = models.ManyToManyField(
69
        User, blank=True, verbose_name=_('Moderators'))
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
70
    updated = models.DateTimeField(_('Updated'), null=True)
71
72
    class Meta:
73
        ordering = ['position']
74
        verbose_name = _('Forum')
75
        verbose_name_plural = _('Forums')
76
77
    def __unicode__(self):
78
        return self.name
79
80
    def topic_count(self):
81
        return self.topics.all().count()
82
83
    def get_absolute_url(self):
84
        return reverse('pybb_forum', args=[self.id])
192 by Holger Rapp
Trying to fix 338756
85
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
86
    @property
87
    def posts(self):
504.2.8 by franku
try to increase performance; removed unused template contexts
88
        return Post.objects.filter(topic__forum=self).exclude(hidden=True).select_related()
89
90
    @property
91
    def post_count(self):
92
        return Post.objects.filter(topic__forum=self).exclude(hidden=True).count()
93
94
    @property
95
    def last_post(self):
504.2.13 by franku
addressed code review
96
        # This has better performance than using the posts manager hidden_topics
504.2.12 by franku
performance boost
97
        # We search only for the last 10 topics
98
        topics = self.topics.order_by('-updated')[:10]
99
        for topic in topics:
100
            if topic.is_hidden:
101
                continue
102
            posts = topic.posts.exclude(hidden=True).order_by(
438.1.6 by franku
run the script
103
            '-created').select_related()
504.2.12 by franku
performance boost
104
            break
105
422.1.1 by franku
add hided field to topic and post; hide topics; added akisemt python library
106
        try:
107
            return posts[0]
108
        except IndexError:
109
            return None
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
110
438.1.6 by franku
run the script
111
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
112
class Topic(models.Model):
438.1.6 by franku
run the script
113
    forum = models.ForeignKey(
114
        Forum, related_name='topics', verbose_name=_('Forum'))
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
115
    name = models.CharField(_('Subject'), max_length=255)
116
    created = models.DateTimeField(_('Created'), null=True)
117
    updated = models.DateTimeField(_('Updated'), null=True)
118
    user = models.ForeignKey(User, verbose_name=_('User'))
119
    views = models.IntegerField(_('Views count'), blank=True, default=0)
120
    sticky = models.BooleanField(_('Sticky'), blank=True, default=False)
121
    closed = models.BooleanField(_('Closed'), blank=True, default=False)
438.1.6 by franku
run the script
122
    subscribers = models.ManyToManyField(
123
        User, related_name='subscriptions', verbose_name=_('Subscribers'), blank=True)
192 by Holger Rapp
Trying to fix 338756
124
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
125
    class Meta:
192 by Holger Rapp
Trying to fix 338756
126
        ordering = ['-updated']
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
127
        verbose_name = _('Topic')
128
        verbose_name_plural = _('Topics')
129
130
    def __unicode__(self):
131
        return self.name
192 by Holger Rapp
Trying to fix 338756
132
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
133
    @property
134
    def head(self):
504.2.11 by franku
prevent errors for admin page pybb topics if there is a topic without a post
135
        try:
136
            return self.posts.all().order_by('created').select_related()[0]
137
        except:
138
            return None
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
139
140
    @property
141
    def last_post(self):
504.2.8 by franku
try to increase performance; removed unused template contexts
142
        return self.posts.exclude(hidden=True).order_by('-created').select_related()[0]
422.1.9 by Holger Rapp
Minor nits.
143
422.1.5 by franku
completed hiding of spam to normal users
144
    @property
422.1.8 by GunChleoc
Proofreading.
145
    def is_hidden(self):
504.2.11 by franku
prevent errors for admin page pybb topics if there is a topic without a post
146
        # If the first post of this topic is hidden, the topic is hidden
147
        try:
148
            return self.posts.first().hidden
149
        except:
150
            return False
422.1.9 by Holger Rapp
Minor nits.
151
422.1.5 by franku
completed hiding of spam to normal users
152
    @property
323 by Holger Rapp
Let post count be calculated automatically instead of keeping track of it manually. Let's see how this affects performance
153
    def post_count(self):
429.1.2 by franku
reverted changes to pybb views; instead provide only non hidden adat for them; added django command
154
        return Post.objects.filter(topic=self).exclude(hidden=True).count()
323 by Holger Rapp
Let post count be calculated automatically instead of keeping track of it manually. Let's see how this affects performance
155
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
156
    def get_absolute_url(self):
157
        return reverse('pybb_topic', args=[self.id])
158
159
    def save(self, *args, **kwargs):
209.1.21 by Timo Wingender
Add notifications to forum
160
        new = self.id is None
161
        if new:
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
162
            self.created = datetime.now()
163
        super(Topic, self).save(*args, **kwargs)
164
165
    def update_read(self, user):
166
        read, new = Read.objects.get_or_create(user=user, topic=self)
167
        if not new:
168
            read.time = datetime.now()
169
            read.save()
170
438.1.6 by franku
run the script
171
    # def has_unreads(self, user):
172
        # try:
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
173
            #read = Read.objects.get(user=user, topic=self)
438.1.6 by franku
run the script
174
        # except Read.DoesNotExist:
175
            # return True
176
        # else:
177
            # return self.updated > read.time
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
178
179
180
class RenderableItem(models.Model):
438.1.6 by franku
run the script
181
    """Base class for models that has markup, body, body_text and body_html
182
    fields."""
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
183
184
    class Meta:
185
        abstract = True
186
187
    def render(self):
188
        if self.markup == 'bbcode':
189
            self.body_html = mypostmarkup.markup(self.body, auto_urls=False)
190
        elif self.markup == 'markdown':
438.1.6 by franku
run the script
191
            self.body_html = unicode(do_wl_markdown(
449.2.4 by franku
adjusted backlinks; cleanup
192
                self.body, 'bleachit'))
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
193
        else:
194
            raise Exception('Invalid markup property: %s' % self.markup)
195
196
        # Remove tags which was generated with the markup processor
197
        text = strip_tags(self.body_html)
198
199
        # Unescape entities which was generated with the markup processor
200
        self.body_text = unescape(text)
201
202
        self.body_html = urlize(self.body_html)
203
438.1.6 by franku
run the script
204
504.2.4 by franku
Do not show hidden topics in feeds
205
class HiddenTopicsManager(models.Manager):
206
    """Find all hidden topics by posts.
207
208
    A whole topic is hidden, if the first post is hidden.
209
    This manager returns the hidden topics and can be used to filter them out
210
    like so:
211
504.2.9 by franku
some refactoring
212
    Post.objects.exclude(topic__in=Post.hidden_topics.all()).filter(...)
504.2.5 by franku
implement hide/unhide toggling of topics
213
504.2.13 by franku
addressed code review
214
    Use this with caution, because it affects performance, see:
504.2.8 by franku
try to increase performance; removed unused template contexts
215
    https://docs.djangoproject.com/en/dev/ref/models/querysets/#in
504.2.4 by franku
Do not show hidden topics in feeds
216
    """
217
218
    def get_queryset(self, *args, **kwargs):
219
        qs = super(HiddenTopicsManager,
220
                   self).get_queryset().filter(hidden=True)
221
504.2.5 by franku
implement hide/unhide toggling of topics
222
        hidden_topics = []
514 by franku
fixed issues if the website get set up from scratch
223
        try:
224
            for post in qs:
225
                if post.topic.is_hidden:
226
                    hidden_topics.append(post.topic)
227
            return hidden_topics
228
        except:
229
            return []
504.2.4 by franku
Do not show hidden topics in feeds
230
231
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
232
class Post(RenderableItem):
438.1.6 by franku
run the script
233
    topic = models.ForeignKey(
234
        Topic, related_name='posts', verbose_name=_('Topic'))
235
    user = models.ForeignKey(
236
        User, related_name='posts', verbose_name=_('User'))
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
237
    created = models.DateTimeField(_('Created'), blank=True)
238
    updated = models.DateTimeField(_('Updated'), blank=True, null=True)
438.1.6 by franku
run the script
239
    markup = models.CharField(_('Markup'), max_length=15,
240
                              default=pybb_settings.DEFAULT_MARKUP, choices=MARKUP_CHOICES)
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
241
    body = models.TextField(_('Message'))
242
    body_html = models.TextField(_('HTML version'))
243
    body_text = models.TextField(_('Text version'))
422.1.8 by GunChleoc
Proofreading.
244
    hidden = models.BooleanField(_('Hidden'), blank=True, default=False)
192 by Holger Rapp
Trying to fix 338756
245
504.2.4 by franku
Do not show hidden topics in feeds
246
    objects = models.Manager() # Normal manager 
247
    hidden_topics = HiddenTopicsManager() # Custom manager
248
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
249
    class Meta:
250
        ordering = ['created']
251
        verbose_name = _('Post')
252
        verbose_name_plural = _('Posts')
253
254
    def summary(self):
255
        LIMIT = 50
192 by Holger Rapp
Trying to fix 338756
256
        tail = len(self.body) > LIMIT and '...' or ''
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
257
        return self.body[:LIMIT] + tail
258
259
    __unicode__ = summary
260
261
    def save(self, *args, **kwargs):
262
        if self.created is None:
263
            self.created = datetime.now()
209.1.21 by Timo Wingender
Add notifications to forum
264
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
265
        self.render()
266
267
        new = self.id is None
268
269
        if new:
270
            self.topic.updated = datetime.now()
271
            self.topic.save()
272
            self.topic.forum.updated = self.topic.updated
273
            self.topic.forum.save()
274
275
        super(Post, self).save(*args, **kwargs)
276
277
    def get_absolute_url(self):
278
        return reverse('pybb_post', args=[self.id])
279
427.1.8 by franku
moved unhide_post to pybb.models
280
    def unhide_post(self):
438.1.6 by franku
run the script
281
        """Unhide post(s) and inform subscribers."""
427.1.8 by franku
moved unhide_post to pybb.models
282
        self.hidden = False
283
        self.save()
284
        if self.topic.post_count == 1:
285
            # The topic is new
438.1.6 by franku
run the script
286
            send(User.objects.all(), 'forum_new_topic',
287
                 {'topic': self.topic, 'post': self, 'user': self.topic.user})
427.1.8 by franku
moved unhide_post to pybb.models
288
        else:
289
            # Inform topic subscribers
438.1.6 by franku
run the script
290
            send(self.topic.subscribers.all(), 'forum_new_post',
291
                 {'post': self, 'topic': self.topic, 'user': self.user})
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
292
293
    def delete(self, *args, **kwargs):
294
        self_id = self.id
295
        head_post_id = self.topic.posts.order_by('created')[0].id
296
        super(Post, self).delete(*args, **kwargs)
297
298
        self.topic.save()
299
        self.topic.forum.save()
300
301
        if self_id == head_post_id:
302
            self.topic.delete()
303
504.2.9 by franku
some refactoring
304
    def is_spam(self):
305
        try:
306
            SuspiciousInput.objects.get(object_id = self.pk)
307
            return True
308
        except:
309
            pass
310
        return False
311
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
312
313
class Read(models.Model):
438.1.6 by franku
run the script
314
    """For each topic that user has entered the time is logged to this
315
    model."""
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
316
317
    user = models.ForeignKey(User, verbose_name=_('User'))
318
    topic = models.ForeignKey(Topic, verbose_name=_('Topic'))
319
    time = models.DateTimeField(_('Time'), blank=True)
320
321
    class Meta:
322
        unique_together = ['user', 'topic']
323
        verbose_name = _('Read')
324
        verbose_name_plural = _('Reads')
325
326
    def save(self, *args, **kwargs):
327
        if self.time is None:
328
            self.time = datetime.now()
329
        super(Read, self).save(*args, **kwargs)
330
331
    def __unicode__(self):
332
        return u'T[%d], U[%d]: %s' % (self.topic.id, self.user.id, unicode(self.time))
333
334
335
class PrivateMessage(RenderableItem):
336
438.1.6 by franku
run the script
337
    dst_user = models.ForeignKey(User, verbose_name=_(
338
        'Recipient'), related_name='dst_users')
339
    src_user = models.ForeignKey(User, verbose_name=_(
340
        'Author'), related_name='src_users')
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
341
    read = models.BooleanField(_('Read'), blank=True, default=False)
342
    created = models.DateTimeField(_('Created'), blank=True)
438.1.6 by franku
run the script
343
    markup = models.CharField(_('Markup'), max_length=15,
344
                              default=pybb_settings.DEFAULT_MARKUP, choices=MARKUP_CHOICES)
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
345
    subject = models.CharField(_('Subject'), max_length=255)
346
    body = models.TextField(_('Message'))
347
    body_html = models.TextField(_('HTML version'))
348
    body_text = models.TextField(_('Text version'))
349
350
    class Meta:
351
        ordering = ['-created']
352
        verbose_name = _('Private message')
353
        verbose_name_plural = _('Private messages')
354
355
    # TODO: summary and part of the save method is the same as in the Post model
356
    # move to common functions
357
    def summary(self):
358
        LIMIT = 50
192 by Holger Rapp
Trying to fix 338756
359
        tail = len(self.body) > LIMIT and '...' or ''
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
360
        return self.body[:LIMIT] + tail
361
362
    def __unicode__(self):
363
        return self.subject
364
365
    def save(self, *args, **kwargs):
366
        if self.created is None:
367
            self.created = datetime.now()
368
        self.render()
369
370
        new = self.id is None
371
        super(PrivateMessage, self).save(*args, **kwargs)
372
373
    def get_absolute_url(self):
438.1.6 by franku
run the script
374
        return reverse('pybb_show_pm', args=[self.id])
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
375
376
377
class Attachment(models.Model):
438.1.6 by franku
run the script
378
    post = models.ForeignKey(Post, verbose_name=_(
379
        'Post'), related_name='attachments')
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
380
    size = models.IntegerField(_('Size'))
381
    content_type = models.CharField(_('Content type'), max_length=255)
382
    path = models.CharField(_('Path'), max_length=255)
383
    name = models.TextField(_('Name'))
438.1.6 by franku
run the script
384
    hash = models.CharField(_('Hash'), max_length=40,
385
                            blank=True, default='', db_index=True)
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
386
387
    def save(self, *args, **kwargs):
388
        super(Attachment, self).save(*args, **kwargs)
389
        if not self.hash:
438.1.6 by franku
run the script
390
            self.hash = hashlib.sha1(
391
                str(self.id) + settings.SECRET_KEY).hexdigest()
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
392
        super(Attachment, self).save(*args, **kwargs)
393
394
    def __unicode__(self):
395
        return self.name
396
397
    def get_absolute_url(self):
398
        return reverse('pybb_attachment', args=[self.hash])
399
400
    def size_display(self):
401
        size = self.size
402
        if size < 1024:
403
            return '%b' % size
404
        elif size < 1024 * 1024:
405
            return '%dKb' % int(size / 1024)
406
        else:
407
            return '%.2fMb' % (size / float(1024 * 1024))
408
409
    def get_absolute_path(self):
410
        return os.path.join(settings.MEDIA_ROOT, pybb_settings.ATTACHMENT_UPLOAD_TO,
411
                            self.path)
412
413
404.2.25 by franku
added old notification app to widelands; deactivated notification feed
414
if notification is not None:
415
    signals.post_save.connect(notification.handle_observations, sender=Post)
209.1.21 by Timo Wingender
Add notifications to forum
416
22 by Holger Rapp
- Added my hacked version of pybb. Remerging new versions is very difficult at this point :(
417
from pybb import signals
418
signals.setup_signals()