##// END OF EJS Templates
Added test for reflinks. Added management command to get posts from other node...
Added test for reflinks. Added management command to get posts from other node (incomplete). Added ability to parse global reflinks in the text

File last commit:

r841:c295c39c decentral
r841:c295c39c decentral
Show More
post.py
518 lines | 15.8 KiB | text/x-python | PythonLexer
neko259
Optimized getting current date in PPD calculation
r586 from datetime import datetime, timedelta, date
neko259
Show posts per
r407 from datetime import time as dtime
neko259
Added some logging
r639 import logging
neko259
Split up user models
r386 import re
neko259
Generate GET request and response (not full yet). Add global id to the posts...
r827 import xml.etree.ElementTree as et
neko259
Added image duplicate check
r527
neko259
Use cache for PPD value
r410 from django.core.cache import cache
neko259
Added post url caching to cache post replies and id urls
r589 from django.core.urlresolvers import reverse
neko259
Added post admin page with tags edit capability
r566 from django.db import models, transaction
neko259
Added tag search. Refactored search to show any model results in a list.
r692 from django.template.loader import render_to_string
neko259
Moved models to a separate module folder. Starting to split up models file
r384 from django.utils import timezone
neko259
Generate GET request and response (not full yet). Add global id to the posts...
r827
neko259
Moved models to a separate module folder. Starting to split up models file
r384 from markupfield.fields import MarkupField
neko259
Removed unused imports for post
r723
neko259
Added signatures to the GET response. Added a view to get a full post response for one post. Don't show post key as it is present in the XML post view. Changed key display format
r837 from boards.models import PostImage, KeyPair, GlobalId, Signature
neko259
Added tag search. Refactored search to show any model results in a list.
r692 from boards.models.base import Viewable
neko259
Moved thread model to a separate module
r691 from boards.models.thread import Thread
neko259
Added more parameters to the post xml output
r828 from boards import utils
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Added test for reflinks. Added management command to get posts from other node...
r841 ENCODING_UNICODE = 'unicode'
neko259
Optimized imports and added some docstrings to the post module
r622
neko259
Use cache for PPD value
r410 APP_LABEL_BOARDS = 'boards'
CACHE_KEY_PPD = 'ppd'
neko259
Added post url caching to cache post replies and id urls
r589 CACHE_KEY_POST_URL = 'post_url'
neko259
Use cache for PPD value
r410
neko259
Optimized PPD counter (now it uses a single query instead of one for each day)
r745 POSTS_PER_DAY_RANGE = 7
neko259
Get PPD for the last week
r408
neko259
Moved models to a separate module folder. Starting to split up models file
r384 BAN_REASON_AUTO = 'Auto'
IMAGE_THUMB_SIZE = (200, 150)
neko259
Enlarged title field
r612 TITLE_MAX_LENGTH = 200
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Very alpha bbcode support (markdown removed)
r736 DEFAULT_MARKUP_TYPE = 'bbcode'
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Added TODOs to the bad and deprecated code to be removed
r702 # TODO This should be removed
neko259
Moved models to a separate module folder. Starting to split up models file
r384 NO_IP = '0.0.0.0'
neko259
Added TODOs to the bad and deprecated code to be removed
r702
# TODO Real user agent should be saved instead of this
neko259
Moved models to a separate module folder. Starting to split up models file
r384 UNKNOWN_UA = ''
neko259
Added TODOs to the bad and deprecated code to be removed
r702
neko259
Moving neboard to python3 support (no python2 for now until we figure out how...
r765 REGEX_REPLY = re.compile(r'\[post\](\d+)\[/post\]')
neko259
Added test for reflinks. Added management command to get posts from other node...
r841 REGEX_GLOBAL_REPLY = re.compile(r'\[post\](\w+)::([^:]+)::(\d+)\[/post\]')
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Generate GET request and response (not full yet). Add global id to the posts...
r827 TAG_MODEL = 'model'
TAG_REQUEST = 'request'
TAG_RESPONSE = 'response'
TAG_ID = 'id'
TAG_STATUS = 'status'
TAG_MODELS = 'models'
TAG_TITLE = 'title'
neko259
Moved signatures block to the model block. All the signed content is in the 'content' block now. Removed edit time, previous and next posts links from the XML sync output because they can be computed from the post itself and can be changed locally for foreign posts (which breaks the signature)
r838 TAG_TEXT = 'text'
neko259
Added more parameters to the post xml output
r828 TAG_THREAD = 'thread'
TAG_PUB_TIME = 'pub-time'
neko259
Added signatures to the GET response. Added a view to get a full post response for one post. Don't show post key as it is present in the XML post view. Changed key display format
r837 TAG_SIGNATURES = 'signatures'
TAG_SIGNATURE = 'signature'
neko259
Moved signatures block to the model block. All the signed content is in the 'content' block now. Removed edit time, previous and next posts links from the XML sync output because they can be computed from the post itself and can be changed locally for foreign posts (which breaks the signature)
r838 TAG_CONTENT = 'content'
neko259
Added info about attachments
r840 TAG_ATTACHMENTS = 'attachments'
TAG_ATTACHMENT = 'attachment'
neko259
Generate GET request and response (not full yet). Add global id to the posts...
r827
TYPE_GET = 'get'
ATTR_VERSION = 'version'
ATTR_TYPE = 'type'
ATTR_NAME = 'name'
neko259
Added signatures to the GET response. Added a view to get a full post response for one post. Don't show post key as it is present in the XML post view. Changed key display format
r837 ATTR_VALUE = 'value'
neko259
Added info about attachments
r840 ATTR_MIMETYPE = 'mimetype'
neko259
Generate GET request and response (not full yet). Add global id to the posts...
r827
STATUS_SUCCESS = 'success'
neko259
Added some logging
r639 logger = logging.getLogger(__name__)
neko259
Moved models to a separate module folder. Starting to split up models file
r384
class PostManager(models.Manager):
neko259
Removed user and settings mode. Added settings manager to manage settings and keep them in the session (or any other backend like cookie in the future
r728 def create_post(self, title, text, image=None, thread=None, ip=NO_IP,
tags=None):
neko259
Small changes to the docstrings. Added some TODOs
r418 """
neko259
Optimized imports and added some docstrings to the post module
r622 Creates new post
neko259
Small changes to the docstrings. Added some TODOs
r418 """
neko259
Fixed tag problems with python3 (related to the 'map' function that was...
r766 if not tags:
tags = []
neko259
Moved models to a separate module folder. Starting to split up models file
r384 posting_time = timezone.now()
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 if not thread:
thread = Thread.objects.create(bump_time=posting_time,
last_edit_time=posting_time)
neko259
Delete old threads only on thread creation, not on every added post
r615 new_thread = True
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 else:
thread.bump()
thread.last_edit_time = posting_time
thread.save()
neko259
Delete old threads only on thread creation, not on every added post
r615 new_thread = False
neko259
Moved models to a separate module folder. Starting to split up models file
r384
post = self.create(title=title,
text=text,
pub_time=posting_time,
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 thread_new=thread,
neko259
Moved models to a separate module folder. Starting to split up models file
r384 poster_ip=ip,
neko259
Fixed threads title in the browser title bar. Moving old threads to archive instead of deleting them.
r484 poster_user_agent=UNKNOWN_UA, # TODO Get UA at
# last!
neko259
Removed user and settings mode. Added settings manager to manage settings and keep them in the session (or any other backend like cookie in the future
r728 last_edit_time=posting_time)
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Generate GET request and response (not full yet). Add global id to the posts...
r827 post.set_global_id()
neko259
Moved post image to a separate model. Each post (as of model) can contain multiple images now. The image shown to the user is got with get_first_image method
r693 if image:
post_image = PostImage.objects.create(image=image)
post.images.add(post_image)
logger.info('Created image #%d for post #%d' % (post_image.id,
post.id))
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 thread.replies.add(post)
neko259
Use map() in python3 style
r770 list(map(thread.add_tag, tags))
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Delete old threads only on thread creation, not on every added post
r615 if new_thread:
neko259
Moved imageboard settings to the boards settings module. Added setting to disable archive
r716 Thread.objects.process_oldest_threads()
neko259
Moved models to a separate module folder. Starting to split up models file
r384 self.connect_replies(post)
neko259
Fixed posting without a primary key defined. Use more proper way to assert an exception
r835 logger.info('Created post #%d with title %s'
% (post.id, post.get_title()))
neko259
Added some logging
r639
neko259
Moved models to a separate module folder. Starting to split up models file
r384 return post
def delete_post(self, post):
neko259
Small changes to the docstrings. Added some TODOs
r418 """
neko259
Optimized imports and added some docstrings to the post module
r622 Deletes post and update or delete its thread
neko259
Small changes to the docstrings. Added some TODOs
r418 """
neko259
Moved delete view to class-based views
r552
neko259
Added some logging
r639 post_id = post.id
neko259
Changed thread_new to get_thread() in the post model
r619 thread = post.get_thread()
neko259
Small changes to the docstrings. Added some TODOs
r418
neko259
Moved delete view to class-based views
r552 if post.is_opening():
neko259
Use own search form and view
r718 thread.delete()
neko259
Fixed thread moderation
r456 else:
thread.last_edit_time = timezone.now()
thread.save()
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Fixed deleting old threads when reaching limit
r470 post.delete()
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Added missing migration, changed logs format
r742 logger.info('Deleted post #%d (%s)' % (post_id, post.get_title()))
neko259
Added some logging
r639
neko259
Moved models to a separate module folder. Starting to split up models file
r384 def delete_posts_by_ip(self, ip):
neko259
Small changes to the docstrings. Added some TODOs
r418 """
neko259
Optimized imports and added some docstrings to the post module
r622 Deletes all posts of the author with same IP
neko259
Small changes to the docstrings. Added some TODOs
r418 """
neko259
Moved models to a separate module folder. Starting to split up models file
r384 posts = self.filter(poster_ip=ip)
neko259
Fixed tag problems with python3 (related to the 'map' function that was...
r766 for post in posts:
self.delete_post(post)
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Added test for reflinks. Added management command to get posts from other node...
r841 # TODO This can be moved into a post
neko259
Moved models to a separate module folder. Starting to split up models file
r384 def connect_replies(self, post):
neko259
Small changes to the docstrings. Added some TODOs
r418 """
neko259
Optimized imports and added some docstrings to the post module
r622 Connects replies to a post to show them as a reflink map
neko259
Small changes to the docstrings. Added some TODOs
r418 """
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Added next id list, previous id list and thread to the post XML output
r829 for reply_number in post.get_replied_ids():
ref_post = self.filter(id=reply_number)
neko259
Moved models to a separate module folder. Starting to split up models file
r384 if ref_post.count() > 0:
referenced_post = ref_post[0]
referenced_post.referenced_posts.add(post)
referenced_post.last_edit_time = post.pub_time
neko259
Added refmap cache to speed up work with reference maps
r674 referenced_post.build_refmap()
neko259
Code cleanup. Update only edited fields while performing thread archiving or post editing. Remove image when post is removed
r715 referenced_post.save(update_fields=['refmap', 'last_edit_time'])
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Changed thread_new to get_thread() in the post model
r619 referenced_thread = referenced_post.get_thread()
neko259
Update referenced post's thread last edit time on connecting replies
r535 referenced_thread.last_edit_time = post.pub_time
neko259
Code cleanup. Update only edited fields while performing thread archiving or post editing. Remove image when post is removed
r715 referenced_thread.save(update_fields=['last_edit_time'])
neko259
Update referenced post's thread last edit time on connecting replies
r535
neko259
Show posts per
r407 def get_posts_per_day(self):
neko259
Small changes to the docstrings. Added some TODOs
r418 """
neko259
Optimized imports and added some docstrings to the post module
r622 Gets average count of posts per day for the last 7 days
neko259
Small changes to the docstrings. Added some TODOs
r418 """
neko259
Show posts per
r407
neko259
Optimized PPD counter (now it uses a single query instead of one for each day)
r745 day_end = date.today()
day_start = day_end - timedelta(POSTS_PER_DAY_RANGE)
cache_key = CACHE_KEY_PPD + str(day_end)
ppd = cache.get(cache_key)
neko259
Use cache for PPD value
r410 if ppd:
return ppd
neko259
Optimized PPD counter (now it uses a single query instead of one for each day)
r745 day_time_start = timezone.make_aware(datetime.combine(
day_start, dtime()), timezone.get_current_timezone())
day_time_end = timezone.make_aware(datetime.combine(
day_end, dtime()), timezone.get_current_timezone())
neko259
Fixed PPD counting. Before this it was count from the future week
r413
neko259
Optimized PPD counter (now it uses a single query instead of one for each day)
r745 posts_per_period = float(self.filter(
pub_time__lte=day_time_end,
pub_time__gte=day_time_start).count())
neko259
Get PPD for the last week
r408
neko259
Optimized PPD counter (now it uses a single query instead of one for each day)
r745 ppd = posts_per_period / POSTS_PER_DAY_RANGE
neko259
Get PPD for the last week
r408
neko259
Optimized PPD counter (now it uses a single query instead of one for each day)
r745 cache.set(cache_key, ppd)
neko259
Use cache for PPD value
r410 return ppd
neko259
Show posts per
r407
neko259
Added test for reflinks. Added management command to get posts from other node...
r841 # TODO Make a separate sync facade?
neko259
Generate GET request and response (not full yet). Add global id to the posts...
r827 def generate_response_get(self, model_list: list):
response = et.Element(TAG_RESPONSE)
status = et.SubElement(response, TAG_STATUS)
status.text = STATUS_SUCCESS
models = et.SubElement(response, TAG_MODELS)
for post in model_list:
model = et.SubElement(models, TAG_MODEL)
model.set(ATTR_NAME, 'post')
neko259
Moved signatures block to the model block. All the signed content is in the 'content' block now. Removed edit time, previous and next posts links from the XML sync output because they can be computed from the post itself and can be changed locally for foreign posts (which breaks the signature)
r838 content_tag = et.SubElement(model, TAG_CONTENT)
tag_id = et.SubElement(content_tag, TAG_ID)
neko259
Generate GET request and response (not full yet). Add global id to the posts...
r827 post.global_id.to_xml_element(tag_id)
neko259
Moved signatures block to the model block. All the signed content is in the 'content' block now. Removed edit time, previous and next posts links from the XML sync output because they can be computed from the post itself and can be changed locally for foreign posts (which breaks the signature)
r838 title = et.SubElement(content_tag, TAG_TITLE)
neko259
Generate GET request and response (not full yet). Add global id to the posts...
r827 title.text = post.title
neko259
Moved signatures block to the model block. All the signed content is in the 'content' block now. Removed edit time, previous and next posts links from the XML sync output because they can be computed from the post itself and can be changed locally for foreign posts (which breaks the signature)
r838 text = et.SubElement(content_tag, TAG_TEXT)
neko259
Added test for reflinks. Added management command to get posts from other node...
r841 # TODO Replace local links by global ones in the text
neko259
Added more parameters to the post xml output
r828 text.text = post.text.raw
if not post.is_opening():
neko259
Moved signatures block to the model block. All the signed content is in the 'content' block now. Removed edit time, previous and next posts links from the XML sync output because they can be computed from the post itself and can be changed locally for foreign posts (which breaks the signature)
r838 thread = et.SubElement(content_tag, TAG_THREAD)
neko259
Added next id list, previous id list and thread to the post XML output
r829 thread.text = str(post.get_thread().get_opening_post_id())
neko259
Added info about attachments
r840 else:
# TODO Output tags here
pass
neko259
Added more parameters to the post xml output
r828
neko259
Moved signatures block to the model block. All the signed content is in the 'content' block now. Removed edit time, previous and next posts links from the XML sync output because they can be computed from the post itself and can be changed locally for foreign posts (which breaks the signature)
r838 pub_time = et.SubElement(content_tag, TAG_PUB_TIME)
neko259
Added more parameters to the post xml output
r828 pub_time.text = str(post.get_pub_time_epoch())
neko259
Moved signatures block to the model block. All the signed content is in the 'content' block now. Removed edit time, previous and next posts links from the XML sync output because they can be computed from the post itself and can be changed locally for foreign posts (which breaks the signature)
r838 signatures_tag = et.SubElement(model, TAG_SIGNATURES)
neko259
Added signatures to the GET response. Added a view to get a full post response for one post. Don't show post key as it is present in the XML post view. Changed key display format
r837 post_signatures = post.signature.all()
if post_signatures:
neko259
Moved signatures block to the model block. All the signed content is in the 'content' block now. Removed edit time, previous and next posts links from the XML sync output because they can be computed from the post itself and can be changed locally for foreign posts (which breaks the signature)
r838 signatures = post.signatures
neko259
Added signatures to the GET response. Added a view to get a full post response for one post. Don't show post key as it is present in the XML post view. Changed key display format
r837 else:
# TODO Maybe the signature can be computed only once after
# the post is added? Need to add some on_save signal queue
# and add this there.
key = KeyPair.objects.get(public_key=post.global_id.key)
neko259
Moved signatures block to the model block. All the signed content is in the 'content' block now. Removed edit time, previous and next posts links from the XML sync output because they can be computed from the post itself and can be changed locally for foreign posts (which breaks the signature)
r838 signatures = [Signature(
neko259
Added signatures to the GET response. Added a view to get a full post response for one post. Don't show post key as it is present in the XML post view. Changed key display format
r837 key_type=key.key_type,
key=key.public_key,
neko259
Added test for reflinks. Added management command to get posts from other node...
r841 signature=key.sign(et.tostring(model, ENCODING_UNICODE)),
neko259
Added signatures to the GET response. Added a view to get a full post response for one post. Don't show post key as it is present in the XML post view. Changed key display format
r837 )]
for signature in signatures:
signature_tag = et.SubElement(signatures_tag, TAG_SIGNATURE)
signature_tag.set(ATTR_TYPE, signature.key_type)
signature_tag.set(ATTR_VALUE, signature.signature)
neko259
Added test for reflinks. Added management command to get posts from other node...
r841 return et.tostring(response, ENCODING_UNICODE)
def parse_response_get(self, response_xml):
tag_root = et.fromstring(response_xml)
tag_status = tag_root[0]
if 'success' == tag_status.text:
tag_models = tag_root[1]
for tag_model in tag_models:
tag_content = tag_model[0]
tag_id = tag_content[1]
try:
GlobalId.from_xml_element(tag_id, existing=True)
# If this post already exists, just continue
# TODO Compare post content and update the post if necessary
pass
except GlobalId.DoesNotExist:
global_id = GlobalId.from_xml_element(tag_id)
title = tag_content.find(TAG_TITLE).text
text = tag_content.find(TAG_TEXT).text
# TODO Check that the replied posts are already present
# before adding new ones
# TODO Pub time, thread, tags
post = Post.objects.create(title=title, text=text)
else:
# TODO Throw an exception?
pass
neko259
Generate GET request and response (not full yet). Add global id to the posts...
r827
neko259
Added tag search. Refactored search to show any model results in a list.
r692 class Post(models.Model, Viewable):
neko259
Moved models to a separate module folder. Starting to split up models file
r384 """A post is a message."""
objects = PostManager()
class Meta:
neko259
Use cache for PPD value
r410 app_label = APP_LABEL_BOARDS
neko259
Optimized thread view and threads list
r649 ordering = ('id',)
neko259
Moved models to a separate module folder. Starting to split up models file
r384
title = models.CharField(max_length=TITLE_MAX_LENGTH)
pub_time = models.DateTimeField()
text = MarkupField(default_markup_type=DEFAULT_MARKUP_TYPE,
escape_html=False)
neko259
Moved post image to a separate model. Each post (as of model) can contain multiple images now. The image shown to the user is got with get_first_image method
r693 images = models.ManyToManyField(PostImage, null=True, blank=True,
related_name='ip+', db_index=True)
neko259
Moved models to a separate module folder. Starting to split up models file
r384
poster_ip = models.GenericIPAddressField()
poster_user_agent = models.TextField()
neko259
Query optimizations
r661 thread_new = models.ForeignKey('Thread', null=True, default=None,
neko259
Code cleanup. Update only edited fields while performing thread archiving or post editing. Remove image when post is removed
r715 db_index=True)
neko259
Moved models to a separate module folder. Starting to split up models file
r384 last_edit_time = models.DateTimeField()
neko259
Added KeyPair model for signing and verifying data, that will be user for...
r793 # Replies to the post
neko259
Moved models to a separate module folder. Starting to split up models file
r384 referenced_posts = models.ManyToManyField('Post', symmetrical=False,
null=True,
neko259
Query optimizations
r661 blank=True, related_name='rfp+',
db_index=True)
neko259
Added KeyPair model for signing and verifying data, that will be user for...
r793
# Replies map. This is built from the referenced posts list to speed up
# page loading (no need to get all the referenced posts from the database).
neko259
Added refmap cache to speed up work with reference maps
r674 refmap = models.TextField(null=True, blank=True)
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Added an admin page for keypair. Renamed the public key to global id in the...
r797 # Global ID with author key. If the message was downloaded from another
# server, this indicates the server.
neko259
Added signature model. Use signatures in posts
r820 global_id = models.OneToOneField('GlobalId', null=True, blank=True)
# One post can be signed by many nodes that give their trust to it
signature = models.ManyToManyField('Signature', null=True, blank=True)
neko259
Added KeyPair model for signing and verifying data, that will be user for...
r793
neko259
Moved models to a separate module folder. Starting to split up models file
r384 def __unicode__(self):
return '#' + str(self.id) + ' ' + self.title + ' (' + \
self.text.raw[:50] + ')'
def get_title(self):
neko259
Added test for reflinks. Added management command to get posts from other node...
r841 return self.title
neko259
Moved models to a separate module folder. Starting to split up models file
r384
neko259
Added refmap cache to speed up work with reference maps
r674 def build_refmap(self):
neko259
Removed linked tags. Added changelog for 2.0. Fixed reply connection.
r740 """
Builds a replies map string from replies list. This is a cache to stop
the server from recalculating the map on every post show.
"""
neko259
Added refmap cache to speed up work with reference maps
r674 map_string = ''
first = True
for refpost in self.referenced_posts.all():
if not first:
map_string += ', '
neko259
Removed linked tags. Added changelog for 2.0. Fixed reply connection.
r740 map_string += '<a href="%s">&gt;&gt;%s</a>' % (refpost.get_url(),
refpost.id)
neko259
Added refmap cache to speed up work with reference maps
r674 first = False
self.refmap = map_string
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398 def get_sorted_referenced_posts(self):
neko259
Added refmap cache to speed up work with reference maps
r674 return self.refmap
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398
def is_referenced(self):
neko259
Added refmap cache to speed up work with reference maps
r674 return len(self.refmap) > 0
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
r398
neko259
Fixed some issues with post model migration
r400 def is_opening(self):
neko259
Optimized imports and added some docstrings to the post module
r622 """
Checks if this is an opening post or just a reply.
"""
neko259
Added cache for opening post id
r620 return self.get_thread().get_opening_post_id() == self.id
neko259
Fixed some issues with post model migration
r400
neko259
Added post admin page with tags edit capability
r566 @transaction.atomic
def add_tag(self, tag):
edit_time = timezone.now()
neko259
Changed thread_new to get_thread() in the post model
r619 thread = self.get_thread()
neko259
Added post admin page with tags edit capability
r566 thread.add_tag(tag)
self.last_edit_time = edit_time
neko259
Removed linked tags. Added changelog for 2.0. Fixed reply connection.
r740 self.save(update_fields=['last_edit_time'])
neko259
Added post admin page with tags edit capability
r566
thread.last_edit_time = edit_time
neko259
Removed linked tags. Added changelog for 2.0. Fixed reply connection.
r740 thread.save(update_fields=['last_edit_time'])
neko259
Added post admin page with tags edit capability
r566
@transaction.atomic
def remove_tag(self, tag):
edit_time = timezone.now()
neko259
Changed thread_new to get_thread() in the post model
r619 thread = self.get_thread()
neko259
Fixed tag removal from thread and thread from tag
r576 thread.remove_tag(tag)
neko259
Added post admin page with tags edit capability
r566 self.last_edit_time = edit_time
neko259
Removed linked tags. Added changelog for 2.0. Fixed reply connection.
r740 self.save(update_fields=['last_edit_time'])
neko259
Added post admin page with tags edit capability
r566
thread.last_edit_time = edit_time
neko259
Removed linked tags. Added changelog for 2.0. Fixed reply connection.
r740 thread.save(update_fields=['last_edit_time'])
neko259
Added post admin page with tags edit capability
r566
neko259
Some more speedups to the post view
r625 def get_url(self, thread=None):
neko259
Added post url caching to cache post replies and id urls
r589 """
neko259
Optimized imports and added some docstrings to the post module
r622 Gets full url to the post.
neko259
Added post url caching to cache post replies and id urls
r589 """
cache_key = CACHE_KEY_POST_URL + str(self.id)
link = cache.get(cache_key)
if not link:
neko259
Some more speedups to the post view
r625 if not thread:
thread = self.get_thread()
opening_id = thread.get_opening_post_id()
neko259
Speed up thread loading
r614
if self.id != opening_id:
neko259
Style cleanup
r608 link = reverse('thread', kwargs={
neko259
Speed up thread loading
r614 'post_id': opening_id}) + '#' + str(self.id)
neko259
Added post url caching to cache post replies and id urls
r589 else:
link = reverse('thread', kwargs={'post_id': self.id})
cache.set(cache_key, link)
return link
neko259
Made getting post thread more generic and scalable
r617 def get_thread(self):
neko259
Optimized imports and added some docstrings to the post module
r622 """
Gets post's thread.
"""
neko259
Made getting post thread more generic and scalable
r617 return self.thread_new
neko259
Removed prefetch for referenced posts to speed up thread loading
r660 def get_referenced_posts(self):
neko259
Added tag search. Refactored search to show any model results in a list.
r692 return self.referenced_posts.only('id', 'thread_new')
def get_text(self):
return self.text
def get_view(self, moderator=False, need_open_link=False,
truncated=False, *args, **kwargs):
if 'is_opening' in kwargs:
is_opening = kwargs['is_opening']
else:
is_opening = self.is_opening()
if 'thread' in kwargs:
thread = kwargs['thread']
else:
thread = self.get_thread()
if 'can_bump' in kwargs:
can_bump = kwargs['can_bump']
else:
can_bump = thread.can_bump()
neko259
Use post id in search. Speed up post viewing
r724 if is_opening:
opening_post_id = self.id
else:
opening_post_id = thread.get_opening_post_id()
neko259
Added tag search. Refactored search to show any model results in a list.
r692
return render_to_string('boards/post.html', {
'post': self,
'moderator': moderator,
'is_opening': is_opening,
'thread': thread,
'bumpable': can_bump,
'need_open_link': need_open_link,
'truncated': truncated,
'opening_post_id': opening_post_id,
})
neko259
Moved post image to a separate model. Each post (as of model) can contain multiple images now. The image shown to the user is got with get_first_image method
r693 def get_first_image(self):
return self.images.earliest('id')
neko259
Code cleanup. Update only edited fields while performing thread archiving or post editing. Remove image when post is removed
r715 def delete(self, using=None):
"""
neko259
Removed linked tags. Added changelog for 2.0. Fixed reply connection.
r740 Deletes all post images and the post itself.
neko259
Code cleanup. Update only edited fields while performing thread archiving or post editing. Remove image when post is removed
r715 """
self.images.all().delete()
neko259
Added next id list, previous id list and thread to the post XML output
r829 self.signature.all().delete()
if self.global_id:
self.global_id.delete()
neko259
Code cleanup. Update only edited fields while performing thread archiving or post editing. Remove image when post is removed
r715
neko259
Very alpha bbcode support (markdown removed)
r736 super(Post, self).delete(using)
neko259
Generate GET request and response (not full yet). Add global id to the posts...
r827
def set_global_id(self, key_pair=None):
"""
Sets global id based on the given key pair. If no key pair is given,
default one is used.
"""
if key_pair:
key = key_pair
else:
try:
key = KeyPair.objects.get(primary=True)
except KeyPair.DoesNotExist:
# Do not update the global id because there is no key defined
return
global_id = GlobalId(key_type=key.key_type,
key=key.public_key,
local_id = self.id)
neko259
Added next id list, previous id list and thread to the post XML output
r829 global_id.save()
neko259
Generate GET request and response (not full yet). Add global id to the posts...
r827
self.global_id = global_id
self.save(update_fields=['global_id'])
neko259
Added more parameters to the post xml output
r828
def get_pub_time_epoch(self):
return utils.datetime_to_epoch(self.pub_time)
neko259
Added test for reflinks. Added management command to get posts from other node...
r841 def get_replied_ids(self):
"""
Gets ID list of the posts that this post replies.
"""
neko259
Added next id list, previous id list and thread to the post XML output
r829
neko259
Added test for reflinks. Added management command to get posts from other node...
r841 local_replied = REGEX_REPLY.findall(self.text.raw)
global_replied = []
# TODO Similar code is used in mdx_neboard, maybe it can be extracted
# into a method?
for match in REGEX_GLOBAL_REPLY.findall(self.text.raw):
key_type = match[0]
key = match[1]
local_id = match[2]
try:
global_id = GlobalId.objects.get(key_type=key_type,
key=key, local_id=local_id)
for post in Post.objects.filter(global_id=global_id).only('id'):
global_replied.append(post.id)
except GlobalId.DoesNotExist:
pass
return local_replied + global_replied