# HG changeset patch
# User neko259
# Date 2017-09-29 08:36:17
# Node ID f370237893b4d0cebe8a125e31b6bb76ab892e09
# Parent 75d347ed0ea16ca111e7ef94c76e39bc09ffb8fc
Use update-time of a post instead of version
diff --git a/boards/admin.py b/boards/admin.py
--- a/boards/admin.py
+++ b/boards/admin.py
@@ -16,7 +16,7 @@ class PostAdmin(admin.ModelAdmin):
exclude = ('referenced_posts', 'refmap', 'images', 'global_id')
readonly_fields = ('poster_ip', 'thread', 'linked_images',
'attachments', 'uid', 'url', 'pub_time', 'opening', 'linked_global_id',
- 'version', 'foreign', 'tags')
+ 'foreign', 'tags')
def ban_poster(self, request, queryset):
bans = 0
@@ -63,7 +63,6 @@ class PostAdmin(admin.ModelAdmin):
return ', '.join([tag.get_name() for tag in obj.get_tags()])
def save_model(self, request, obj, form, change):
- obj.increment_version()
obj.save()
obj.clear_cache()
@@ -127,8 +126,6 @@ class ThreadAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
op = obj.get_opening_post()
- op.increment_version()
- op.save(update_fields=['version'])
obj.save()
op.clear_cache()
diff --git a/boards/management/commands/sync_with_server.py b/boards/management/commands/sync_with_server.py
--- a/boards/management/commands/sync_with_server.py
+++ b/boards/management/commands/sync_with_server.py
@@ -4,9 +4,10 @@ import xml.etree.ElementTree as ET
import httplib2
from django.core.management import BaseCommand
+from django.utils.dateparse import parse_datetime
from boards.models import GlobalId
-from boards.models.post.sync import SyncManager, TAG_ID, TAG_VERSION
+from boards.models.post.sync import SyncManager, TAG_ID, TAG_UPDATE_TIME
__author__ = 'neko259'
@@ -85,12 +86,12 @@ class Command(BaseCommand):
for model in models:
tag_id = model.find(TAG_ID)
global_id, exists = GlobalId.from_xml_element(tag_id)
- tag_version = model.find(TAG_VERSION)
- if tag_version is not None:
- version = int(tag_version.text) or 1
+ tag_update_time = model.find(TAG_UPDATE_TIME)
+ if tag_update_time:
+ update_time = tag_update_time.text
else:
- version = 1
- if not exists or global_id.post.version < version:
+ update_time = None
+ if not exists or update_time is None or global_id.post.last_edit_time < parse_datetime(update_time):
logger.debug('Processed (+) post {}'.format(global_id))
ids_to_sync.append(global_id)
else:
diff --git a/boards/migrations/0064_remove_post_version.py b/boards/migrations/0064_remove_post_version.py
new file mode 100644
--- /dev/null
+++ b/boards/migrations/0064_remove_post_version.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2017-09-27 12:38
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('boards', '0063_auto_20170301_1058'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='post',
+ name='version',
+ ),
+ ]
diff --git a/boards/models/post/__init__.py b/boards/models/post/__init__.py
--- a/boards/models/post/__init__.py
+++ b/boards/models/post/__init__.py
@@ -100,7 +100,6 @@ class Post(models.Model, Viewable):
tripcode = models.CharField(max_length=50, blank=True, default='')
opening = models.BooleanField(db_index=True)
hidden = models.BooleanField(default=False)
- version = models.IntegerField(default=1)
def __str__(self):
return 'P#{}/{}'.format(self.id, self.get_title())
@@ -341,9 +340,6 @@ class Post(models.Model, Viewable):
def set_hidden(self, hidden):
self.hidden = hidden
- def increment_version(self):
- self.version = F('version') + 1
-
def clear_cache(self):
"""
Clears sync data (content cache, signatures etc).
diff --git a/boards/models/post/manager.py b/boards/models/post/manager.py
--- a/boards/models/post/manager.py
+++ b/boards/models/post/manager.py
@@ -138,7 +138,7 @@ class PostManager(models.Manager):
@transaction.atomic
def import_post(self, title: str, text: str, pub_time: str, global_id,
opening_post=None, tags=list(), files=list(),
- file_urls=list(), tripcode=None, version=1):
+ file_urls=list(), tripcode=None, last_edit_time=None):
is_opening = opening_post is None
if is_opening:
thread = boards.models.thread.Thread.objects.create(
@@ -151,12 +151,11 @@ class PostManager(models.Manager):
text=text,
pub_time=pub_time,
poster_ip=NO_IP,
- last_edit_time=pub_time,
+ last_edit_time=last_edit_time or pub_time,
global_id=global_id,
opening=is_opening,
thread=thread,
- tripcode=tripcode,
- version=version)
+ tripcode=tripcode)
for file in files:
self._add_file_to_post(file, post)
@@ -170,12 +169,11 @@ class PostManager(models.Manager):
@transaction.atomic
def update_post(self, post, title: str, text: str, pub_time: str,
- tags=list(), files=list(), file_urls=list(), tripcode=None, version=1):
+ tags=list(), files=list(), file_urls=list(), tripcode=None):
post.title = title
post.text = text
post.pub_time = pub_time
post.tripcode = tripcode
- post.version = version
post.save()
post.clear_cache()
diff --git a/boards/models/post/sync.py b/boards/models/post/sync.py
--- a/boards/models/post/sync.py
+++ b/boards/models/post/sync.py
@@ -1,16 +1,17 @@
+import logging
import xml.etree.ElementTree as et
-import logging
-from xml.etree import ElementTree
+
+from django.db import transaction
+from django.utils.dateparse import parse_datetime
from boards.abstracts.exceptions import SyncException
-from boards.abstracts.sync_filters import ThreadFilter, TagsFilter,\
- TimestampFromFilter
+from boards.abstracts.sync_filters import ThreadFilter, TagsFilter, \
+ TimestampFromFilter
from boards.models import KeyPair, GlobalId, Signature, Post, Tag
from boards.models.attachment.downloaders import download
from boards.models.signature import TAG_REQUEST, ATTR_TYPE, TYPE_GET, \
ATTR_VERSION, TAG_MODEL, ATTR_NAME, TAG_ID, TYPE_LIST
from boards.utils import get_file_mimetype, get_file_hash
-from django.db import transaction
EXCEPTION_NODE = 'Sync node returned an error: {}.'
EXCEPTION_DOWNLOAD = 'File was not downloaded.'
@@ -30,6 +31,7 @@ TAG_TITLE = 'title'
TAG_TEXT = 'text'
TAG_THREAD = 'thread'
TAG_PUB_TIME = 'pub-time'
+TAG_UPDATE_TIME = 'update-time'
TAG_SIGNATURES = 'signatures'
TAG_SIGNATURE = 'signature'
TAG_CONTENT = 'content'
@@ -59,6 +61,8 @@ ID_TYPE_URL = 'url'
STATUS_SUCCESS = 'success'
+CURRENT_MODEL_VERSION = '1.1'
+
logger = logging.getLogger('boards.sync')
@@ -120,6 +124,9 @@ class SyncManager:
pub_time = et.SubElement(content_tag, TAG_PUB_TIME)
pub_time.text = str(post.get_pub_time_str())
+ update_time = et.SubElement(content_tag, TAG_UPDATE_TIME)
+ update_time.text = str(post.last_edit_time)
+
if post.tripcode:
tripcode = et.SubElement(content_tag, TAG_TRIPCODE)
tripcode.text = post.tripcode
@@ -141,8 +148,6 @@ class SyncManager:
for file in attachments:
SyncManager._attachment_to_xml(
attachments_tag, attachment_refs, file)
- version_tag = et.SubElement(content_tag, TAG_VERSION)
- version_tag.text = str(post.version)
global_id.content = et.tostring(content_tag, ENCODING_UNICODE)
global_id.save()
@@ -191,8 +196,8 @@ class SyncManager:
global_id, exists = GlobalId.from_xml_element(tag_id)
signatures = SyncManager._verify_model(global_id, content_str, tag_model)
- version = int(tag_content.find(TAG_VERSION).text)
- is_old = exists and global_id.post.version < version
+ update_time = tag_content.find(TAG_UPDATE_TIME).text
+ is_old = exists and global_id.post.last_edit_time < parse_datetime(update_time)
if exists and not is_old:
logger.debug('Post {} exists and is up to date.'.format(global_id))
else:
@@ -204,13 +209,13 @@ class SyncManager:
title = tag_content.find(TAG_TITLE).text or ''
text = tag_content.find(TAG_TEXT).text or ''
- pub_time = tag_content.find(TAG_PUB_TIME).text
tripcode_tag = tag_content.find(TAG_TRIPCODE)
if tripcode_tag is not None:
tripcode = tripcode_tag.text or ''
else:
tripcode = ''
+ pub_time = tag_content.find(TAG_PUB_TIME).text
thread = tag_content.find(TAG_THREAD)
tags = []
if thread:
@@ -257,15 +262,14 @@ class SyncManager:
Post.objects.update_post(
post, title=title, text=text, pub_time=pub_time,
tags=tags, files=files, file_urls=urls,
- tripcode=tripcode, version=version)
+ tripcode=tripcode, version=version, last_edit_time=update_time)
logger.debug('Parsed updated post {}'.format(global_id))
else:
Post.objects.import_post(
title=title, text=text, pub_time=pub_time,
opening_post=opening_post, tags=tags,
global_id=global_id, files=files,
- file_urls=urls, tripcode=tripcode,
- version=version)
+ file_urls=urls, tripcode=tripcode, last_edit_time=update_time)
logger.debug('Parsed new post {}'.format(global_id))
@staticmethod
@@ -285,8 +289,8 @@ class SyncManager:
tag_model = et.SubElement(models, TAG_MODEL)
tag_id = et.SubElement(tag_model, TAG_ID)
post.global_id.to_xml_element(tag_id)
- tag_version = et.SubElement(tag_model, TAG_VERSION)
- tag_version.text = str(post.version)
+ update_time = et.SubElement(tag_model, TAG_UPDATE_TIME)
+ update_time.text = str(post.last_edit_time)
return et.tostring(response, ENCODING_UNICODE)
@@ -372,7 +376,7 @@ class SyncManager:
request.set(ATTR_VERSION, '1.0')
model = et.SubElement(request, TAG_MODEL)
- model.set(ATTR_VERSION, '1.0')
+ model.set(ATTR_VERSION, CURRENT_MODEL_VERSION)
model.set(ATTR_NAME, 'post')
if opening_post:
diff --git a/boards/models/thread.py b/boards/models/thread.py
--- a/boards/models/thread.py
+++ b/boards/models/thread.py
@@ -186,7 +186,7 @@ class Thread(models.Model):
"""
Gets replies with only fields that are used for viewing.
"""
- return self.get_replies().defer('text', 'last_edit_time', 'version')
+ return self.get_replies().defer('text', 'last_edit_time')
def get_top_level_replies(self) -> QuerySet:
return self.get_replies().exclude(refposts__threads__in=[self])
diff --git a/boards/templates/boards/all_threads.html b/boards/templates/boards/all_threads.html
--- a/boards/templates/boards/all_threads.html
+++ b/boards/templates/boards/all_threads.html
@@ -64,6 +64,7 @@
{% endif %}
+ •
+ •
{% trans 'Gallery' %}
{% if tag.get_description %}
diff --git a/boards/tests/test_keys.py b/boards/tests/test_keys.py
--- a/boards/tests/test_keys.py
+++ b/boards/tests/test_keys.py
@@ -65,22 +65,22 @@ class KeyTest(TestCase):
''
''
''
- ''
+ ''
'test_title'
- '[post]%s[/post]'
- ''
- '%s'
- '%s'
- '' % (
+ '[post]{}[/post]'
+ ''
+ '{}'
+ '{}'
+ ''.format(
key.public_key,
reply_post.id,
key.key_type,
- str(post.global_id),
+ post.global_id,
key.public_key,
post.id,
key.key_type,
- str(reply_post.get_pub_time_str()),
- post.version,
+ reply_post.get_pub_time_str(),
+ reply_post.last_edit_time,
) in response,
'Wrong XML generated for the GET response.')
diff --git a/boards/tests/test_sync.py b/boards/tests/test_sync.py
--- a/boards/tests/test_sync.py
+++ b/boards/tests/test_sync.py
@@ -37,13 +37,13 @@ class SyncTest(TestCase):
''
''
''
- ''
- '%s'
- '%s'
- '%s'
- '%s'
- '%s'
- '' % (
+ ''
+ '{}'
+ '{}'
+ '{}'
+ '{}'
+ '{}'
+ ''.format(
post.global_id.key,
post.global_id.local_id,
post.global_id.key_type,
@@ -51,7 +51,7 @@ class SyncTest(TestCase):
post.get_sync_text(),
post.get_thread().get_tags().first().get_name(),
post.get_pub_time_str(),
- post.version,
+ post.last_edit_time,
) in response,
'Wrong response generated for the GET request.')
@@ -86,13 +86,13 @@ class SyncTest(TestCase):
''
''
''
- ''
- '%s'
- '%s'
- '%s'
- '%s'
- '%s'
- '' % (
+ ''
+ '{}'
+ '{}'
+ '{}'
+ '{}'
+ '{}'
+ ''.format(
post.global_id.key,
post.global_id.local_id,
post.global_id.key_type,
@@ -100,7 +100,6 @@ class SyncTest(TestCase):
post.get_sync_text(),
post.get_thread().get_tags().first().get_name(),
post.get_pub_time_str(),
- post.version,
) in response,
'Wrong response generated for the GET request.')
@@ -128,21 +127,21 @@ class SyncTest(TestCase):
''
''
''
- '{}'
+ '{}'
''
''
''
- '{}'
+ '{}'
''
''.format(
post.global_id.key,
post.global_id.local_id,
post.global_id.key_type,
- post.version,
+ post.last_edit_time,
post2.global_id.key,
post2.global_id.local_id,
post2.global_id.key_type,
- post2.version,
+ post2.last_edit_time,
) in response_all,
'Wrong response generated for the LIST request for all posts.')
@@ -173,13 +172,13 @@ class SyncTest(TestCase):
''
''
''
- '{}'
+ '{}'
''
''.format(
post.global_id.key,
post.global_id.local_id,
post.global_id.key_type,
- post.version,
+ post.last_edit_time,
) in response_thread,
'Wrong response generated for the LIST request for posts of '
'existing thread.')
@@ -240,13 +239,13 @@ class SyncTest(TestCase):
''
''
''
- '{}'
+ '{}'
''
''.format(
post2.global_id.key,
post2.global_id.local_id,
post2.global_id.key_type,
- post2.version,
+ post2.last_edit_time,
) in response_thread,
'Wrong response generated for the LIST request for posts of '
'existing thread.')
diff --git a/docs/dip-1.markdown b/docs/dip-1.markdown
--- a/docs/dip-1.markdown
+++ b/docs/dip-1.markdown
@@ -97,7 +97,7 @@ Sample response:
- 1
+ 2017-01-01 00:00:00
diff --git a/docs/dip-2.markdown b/docs/dip-2.markdown
--- a/docs/dip-2.markdown
+++ b/docs/dip-2.markdown
@@ -1,6 +1,6 @@
# 0 Title #
-"post" model reference
+"post" model reference of version 1.1
# 1 Description #
@@ -13,7 +13,7 @@
* title -- text field.
* text -- text field.
* pub-time -- timestamp (TBD: Define format).
-* version -- when post content changes, version should be incremented.
+* update -- when post content changes, the update time should be incremented.
# 2.2 Optional fields #