##// END OF EJS Templates
Show raw post text in the log when created post
neko259 -
r2006:127660f1 default
parent child Browse files
Show More
@@ -1,291 +1,291
1 1 import logging
2 2 import re
3 3 from datetime import datetime, timedelta, date
4 4 from datetime import time as dtime
5 5
6 6 from django.core.exceptions import PermissionDenied
7 7 from django.db import models, transaction
8 8 from django.dispatch import Signal
9 9 from django.shortcuts import redirect
10 10 from django.utils import timezone
11 11
12 12 import boards
13 13 from boards import utils
14 14 from boards.abstracts.exceptions import ArchiveException
15 15 from boards.abstracts.constants import REGEX_TAGS, REGEX_REPLY
16 16 from boards.mdx_neboard import Parser
17 17 from boards.models import Attachment
18 18 from boards.models.attachment import StickerPack, AttachmentSticker
19 19 from boards.models.user import Ban
20 20
21 21 __author__ = 'neko259'
22 22
23 23 POSTS_PER_DAY_RANGE = 7
24 24 NO_IP = '0.0.0.0'
25 25
26 26
27 27 post_import_deps = Signal()
28 28
29 29 FORM_TEXT = 'text'
30 30 FORM_TAGS = 'tags'
31 31
32 32 REFLINK_PREFIX = '>>'
33 33
34 34
35 35 class PostManager(models.Manager):
36 36 @transaction.atomic
37 37 def create_post(self, title: str, text: str, files=[], thread=None,
38 38 ip=NO_IP, tags: list=None,
39 39 tripcode='', monochrome=False, images=[],
40 40 file_urls=[], stickerpack=False):
41 41 """
42 42 Creates new post
43 43 """
44 44
45 45 if thread is not None and thread.is_archived():
46 46 raise ArchiveException('Cannot post into an archived thread')
47 47
48 48 if not utils.is_anonymous_mode():
49 49 is_banned = Ban.objects.filter(ip=ip).exists()
50 50 else:
51 51 is_banned = False
52 52
53 53 if is_banned:
54 54 raise PermissionDenied()
55 55
56 56 if not tags:
57 57 tags = []
58 58
59 59 posting_time = timezone.now()
60 60 new_thread = False
61 61 if not thread:
62 62 thread = boards.models.thread.Thread.objects.create(
63 63 bump_time=posting_time, last_edit_time=posting_time,
64 64 monochrome=monochrome, stickerpack=stickerpack)
65 65 list(map(thread.tags.add, tags))
66 66 new_thread = True
67 67
68 68 pre_text = Parser().preparse(text)
69 69
70 70 post = self.create(title=title,
71 71 text=pre_text,
72 72 pub_time=posting_time,
73 73 poster_ip=ip,
74 74 thread=thread,
75 75 last_edit_time=posting_time,
76 76 tripcode=tripcode,
77 77 opening=new_thread)
78 78
79 79 logger = logging.getLogger('boards.post.create')
80 80
81 81 logger.info('Created post [{}] with text [{}] by {}'.format(post,
82 post.get_text(),post.poster_ip))
82 post.get_raw_text(), post.poster_ip))
83 83
84 84 for file in files:
85 85 self._add_file_to_post(file, post)
86 86 for image in images:
87 87 post.attachments.add(image)
88 88 for file_url in file_urls:
89 89 post.attachments.add(Attachment.objects.create_from_url(file_url))
90 90
91 91 post.set_global_id()
92 92
93 93 # Thread needs to be bumped only when the post is already created
94 94 if not new_thread:
95 95 thread.last_edit_time = posting_time
96 96 thread.bump()
97 97 thread.save()
98 98
99 99 self._create_stickers(post)
100 100
101 101 return post
102 102
103 103 def delete_posts_by_ip(self, ip):
104 104 """
105 105 Deletes all posts of the author with same IP
106 106 """
107 107
108 108 posts = self.filter(poster_ip=ip)
109 109 for post in posts:
110 110 post.delete()
111 111
112 112 @utils.cached_result()
113 113 def get_posts_per_day(self) -> float:
114 114 """
115 115 Gets average count of posts per day for the last 7 days
116 116 """
117 117
118 118 day_end = date.today()
119 119 day_start = day_end - timedelta(POSTS_PER_DAY_RANGE)
120 120
121 121 day_time_start = timezone.make_aware(datetime.combine(
122 122 day_start, dtime()), timezone.get_current_timezone())
123 123 day_time_end = timezone.make_aware(datetime.combine(
124 124 day_end, dtime()), timezone.get_current_timezone())
125 125
126 126 posts_per_period = float(self.filter(
127 127 pub_time__lte=day_time_end,
128 128 pub_time__gte=day_time_start).count())
129 129
130 130 ppd = posts_per_period / POSTS_PER_DAY_RANGE
131 131
132 132 return ppd
133 133
134 134 def get_post_per_days(self, days) -> int:
135 135 day_end = date.today() + timedelta(1)
136 136 day_start = day_end - timedelta(days)
137 137
138 138 day_time_start = timezone.make_aware(datetime.combine(
139 139 day_start, dtime()), timezone.get_current_timezone())
140 140 day_time_end = timezone.make_aware(datetime.combine(
141 141 day_end, dtime()), timezone.get_current_timezone())
142 142
143 143 return self.filter(
144 144 pub_time__lte=day_time_end,
145 145 pub_time__gte=day_time_start).count()
146 146
147 147 @transaction.atomic
148 148 def import_post(self, title: str, text: str, pub_time: str, global_id,
149 149 opening_post=None, tags=list(), files=list(),
150 150 file_urls=list(), tripcode=None, last_edit_time=None):
151 151 is_opening = opening_post is None
152 152 if is_opening:
153 153 thread = boards.models.thread.Thread.objects.create(
154 154 bump_time=pub_time, last_edit_time=pub_time)
155 155 list(map(thread.tags.add, tags))
156 156 else:
157 157 thread = opening_post.get_thread()
158 158
159 159 post = self.create(title=title,
160 160 text=text,
161 161 pub_time=pub_time,
162 162 poster_ip=NO_IP,
163 163 last_edit_time=last_edit_time or pub_time,
164 164 global_id=global_id,
165 165 opening=is_opening,
166 166 thread=thread,
167 167 tripcode=tripcode)
168 168
169 169 for file in files:
170 170 self._add_file_to_post(file, post)
171 171 for file_url in file_urls:
172 172 post.attachments.add(Attachment.objects.create_from_url(file_url))
173 173
174 174 url_to_post = '[post]{}[/post]'.format(str(global_id))
175 175 replies = self.filter(text__contains=url_to_post)
176 176 for reply in replies:
177 177 post_import_deps.send(reply)
178 178
179 179 @transaction.atomic
180 180 def update_post(self, post, title: str, text: str, pub_time: str,
181 181 tags=list(), files=list(), file_urls=list(), tripcode=None):
182 182 post.title = title
183 183 post.text = text
184 184 post.pub_time = pub_time
185 185 post.tripcode = tripcode
186 186 post.save()
187 187
188 188 post.clear_cache()
189 189
190 190 post.attachments.clear()
191 191 for file in files:
192 192 self._add_file_to_post(file, post)
193 193 for file_url in file_urls:
194 194 post.attachments.add(Attachment.objects.create_from_url(file_url))
195 195
196 196 thread = post.get_thread()
197 197 thread.tags.clear()
198 198 list(map(thread.tags.add, tags))
199 199
200 200 def create_from_form(self, request, form, opening_post, html_response=True):
201 201 ip = utils.get_client_ip(request)
202 202
203 203 data = form.cleaned_data
204 204
205 205 title = form.get_title()
206 206 text = data[FORM_TEXT]
207 207 files = form.get_files()
208 208 file_urls = form.get_file_urls()
209 209 images = form.get_images()
210 210
211 211 text = self._remove_invalid_links(text)
212 212
213 213 if opening_post:
214 214 post_thread = opening_post.get_thread()
215 215 monochrome = False
216 216 stickerpack = False
217 217 tags = []
218 218 else:
219 219 tags = data[FORM_TAGS]
220 220 monochrome = form.is_monochrome()
221 221 stickerpack = form.is_stickerpack()
222 222 post_thread = None
223 223
224 224 post = self.create_post(title=title, text=text, files=files,
225 225 thread=post_thread, ip=ip,
226 226 tripcode=form.get_tripcode(),
227 227 images=images, file_urls=file_urls,
228 228 monochrome=monochrome,
229 229 stickerpack=stickerpack, tags=tags)
230 230
231 231 if form.is_subscribe():
232 232 from boards.abstracts.settingsmanager import get_settings_manager
233 233 settings_manager = get_settings_manager(request)
234 234 settings_manager.add_or_read_fav_thread(
235 235 post_thread.get_opening_post())
236 236
237 237 if html_response:
238 238 return redirect(post.get_absolute_url())
239 239 else:
240 240 return post
241 241
242 242 def _add_file_to_post(self, file, post):
243 243 post.attachments.add(Attachment.objects.create_with_hash(file))
244 244
245 245 def _create_stickers(self, post):
246 246 thread = post.get_thread()
247 247 stickerpack_thread = thread.is_stickerpack()
248 248 if stickerpack_thread:
249 249 logger = logging.getLogger('boards.stickers')
250 250 if not post.is_opening():
251 251 has_title = len(post.title) > 0
252 252 has_one_attachment = post.attachments.count() == 1
253 253 opening_post = thread.get_opening_post()
254 254 valid_name = REGEX_TAGS.match(post.title)
255 255 if has_title and has_one_attachment and valid_name:
256 256 existing_sticker = AttachmentSticker.objects.filter(
257 257 name=post.get_title()).first()
258 258 attachment = post.attachments.first()
259 259 if existing_sticker:
260 260 existing_sticker.attachment = attachment
261 261 existing_sticker.save()
262 262 logger.info('Updated sticker {} with new attachment'.format(existing_sticker))
263 263 else:
264 264 try:
265 265 stickerpack = StickerPack.objects.get(
266 266 name=opening_post.get_title(), tripcode=post.tripcode)
267 267 sticker = AttachmentSticker.objects.create(
268 268 stickerpack=stickerpack, name=post.get_title(),
269 269 attachment=attachment)
270 270 logger.info('Created sticker {}'.format(sticker))
271 271 except StickerPack.DoesNotExist:
272 272 pass
273 273 else:
274 274 stickerpack, created = StickerPack.objects.get_or_create(
275 275 name=post.get_title(), tripcode=post.tripcode)
276 276 if created:
277 277 logger.info('Created stickerpack {}'.format(stickerpack))
278 278
279 279 def _remove_invalid_links(self, text):
280 280 """
281 281 Replace invalid links in posts so that they won't be parsed.
282 282 Invalid links are links to non-existent posts
283 283 """
284 284
285 285 for reply_number in re.finditer(REGEX_REPLY, text):
286 286 post_id = reply_number.group(1)
287 287 post = self.filter(id=post_id)
288 288 if not post.exists():
289 289 text = text.replace(REFLINK_PREFIX + post_id, post_id)
290 290
291 291 return text
General Comments 0
You need to be logged in to leave comments. Login now