##// END OF EJS Templates
Sort threads by name. Previous commit: added navigation panel, added tag manager to get active tags.
neko259 -
r34:8db8d0b7 default
parent child Browse files
Show More
@@ -1,208 +1,208 b''
1 1 import os
2 2 import re
3 3 from django.db import models
4 4 from django.utils import timezone
5 5 import time
6 6
7 7 from neboard import settings
8 8
9 9 import thumbs
10 10
11 11 NO_PARENT = -1
12 12 NO_IP = '0.0.0.0'
13 13 UNKNOWN_UA = ''
14 14
15 15
16 16 def update_image_filename(instance, filename):
17 17 """Get unique image filename"""
18 18
19 19 path = 'images/'
20 20 new_name = str(int(time.mktime(time.gmtime()))) + '_' + filename
21 21 return os.path.join(path, new_name)
22 22
23 23
24 24 class PostManager(models.Manager):
25 25 def create_post(self, title, text, image=None, parent_id=NO_PARENT,
26 26 ip=NO_IP, tags=None):
27 27 post = self.create(title=title,
28 28 text=text,
29 29 pub_time=timezone.now(),
30 30 parent=parent_id,
31 31 image=image,
32 32 poster_ip=ip,
33 33 poster_user_agent=UNKNOWN_UA,
34 34 last_edit_time=timezone.now())
35 35
36 36 if tags:
37 37 for tag in tags:
38 38 post.tags.add(tag)
39 39
40 40 if parent_id != NO_PARENT:
41 41 parent = self.get(id=parent_id)
42 42 parent.last_edit_time=timezone.now()
43 43 parent.save()
44 44 else:
45 45 self._delete_old_threads()
46 46
47 47 return post
48 48
49 49 def delete_post(self, post):
50 50 children = self.filter(parent=post.id)
51 51 for child in children:
52 52 self.delete_post(child)
53 53 post.delete()
54 54
55 55 def delete_posts_by_ip(self, ip):
56 56 posts = self.filter(poster_ip=ip)
57 57 for post in posts:
58 58 self.delete_post(post)
59 59
60 60 def get_threads(self, tag=None):
61 61 if tag:
62 62 threads = self.filter(parent=NO_PARENT, tags=tag)
63 63 else:
64 64 threads = self.filter(parent=NO_PARENT)
65 65 threads = list(threads.order_by('-last_edit_time'))
66 66
67 67 return threads
68 68
69 69 def get_thread(self, opening_post_id):
70 70 opening_post = self.get(id=opening_post_id)
71 71
72 72 if opening_post.parent == NO_PARENT:
73 73 replies = self.filter(parent=opening_post_id)
74 74
75 75 thread = [opening_post]
76 76 thread.extend(replies)
77 77
78 78 return thread
79 79
80 80 def exists(self, post_id):
81 81 posts = self.filter(id=post_id)
82 82
83 83 return len(posts) > 0
84 84
85 85 def _delete_old_threads(self):
86 86 """
87 87 Preserves maximum thread count. If there are too many threads,
88 88 delete the old ones.
89 89 """
90 90
91 91 # TODO Try to find a better way to get the active thread count.
92 92
93 93 # TODO Move old threads to the archive instead of deleting them.
94 94 # Maybe make some 'old' field in the model to indicate the thread
95 95 # must not be shown and be able for replying.
96 96
97 97 threads = self.get_threads()
98 98 thread_count = len(threads)
99 99
100 100 if thread_count > settings.MAX_THREAD_COUNT:
101 101 num_threads_to_delete = thread_count - settings.MAX_THREAD_COUNT
102 102 old_threads = threads[-num_threads_to_delete:]
103 103
104 104 for thread in old_threads:
105 105 self.delete_post(thread)
106 106
107 107
108 108 class TagManager(models.Manager):
109 109 def get_not_empty_tags(self):
110 all_tags = self.all()
110 all_tags = self.all().order_by('name')
111 111 tags = []
112 112 for tag in all_tags:
113 113 if not tag.is_empty():
114 114 tags.append(tag)
115 115
116 116 return tags
117 117
118 118
119 119 class Tag(models.Model):
120 120 """
121 121 A tag is a text node assigned to the post. The tag serves as a board
122 122 section. There can be multiple tags for each message
123 123 """
124 124
125 125 objects = TagManager()
126 126
127 127 name = models.CharField(max_length=100)
128 128 # TODO Connect the tag to its posts to check the number of threads for
129 129 # the tag.
130 130
131 131 def __unicode__(self):
132 132 return self.name
133 133
134 134 def is_empty(self):
135 135 return self.get_post_count() == 0
136 136
137 137 def get_post_count(self):
138 138 posts_with_tag = Post.objects.get_threads(tag=self)
139 139 return len(posts_with_tag)
140 140
141 141
142 142 class Post(models.Model):
143 143 """A post is a message."""
144 144
145 145 objects = PostManager()
146 146
147 147 title = models.CharField(max_length=50)
148 148 pub_time = models.DateTimeField()
149 149 text = models.TextField()
150 150 image = thumbs.ImageWithThumbsField(upload_to=update_image_filename,
151 151 blank=True, sizes=((200, 150),))
152 152 poster_ip = models.IPAddressField()
153 153 poster_user_agent = models.TextField()
154 154 parent = models.BigIntegerField()
155 155 tags = models.ManyToManyField(Tag)
156 156 last_edit_time = models.DateTimeField()
157 157
158 158 def __unicode__(self):
159 159 return self.title + ' (' + self.text + ')'
160 160
161 161 def _get_replies(self):
162 162 return Post.objects.filter(parent=self.id)
163 163
164 164 def get_reply_count(self):
165 165 return len(self._get_replies())
166 166
167 167 def get_images_count(self):
168 168 images_count = 1 if self.image else 0
169 169 for reply in self._get_replies():
170 170 if reply.image:
171 171 images_count += 1
172 172
173 173 return images_count
174 174
175 175 def get_gets_count(self):
176 176 gets_count = 1 if self.is_get() else 0
177 177 for reply in self._get_replies():
178 178 if reply.is_get():
179 179 gets_count += 1
180 180
181 181 return gets_count
182 182
183 183 def is_get(self):
184 184 """If the post has pretty id (1, 1000, 77777), than it is called GET"""
185 185
186 186 # TODO Make a better algorithm for describing gets
187 187 return self.id == 1 or self.id % 10 == 0
188 188
189 189 def get_parsed_text(self):
190 190 text = self.text
191 191
192 192 # TODO Implement parsing
193 193 # Make //text colored
194 194 # Make >>12 links to posts
195 195
196 196 return text
197 197
198 198
199 199 class Admin(models.Model):
200 200 """
201 201 Model for admin users
202 202 """
203 203 name = models.CharField(max_length=100)
204 204 password = models.CharField(max_length=100)
205 205
206 206 def __unicode__(self):
207 207 return self.name + '/' + '*' * len(self.password)
208 208
General Comments 0
You need to be logged in to leave comments. Login now