##// END OF EJS Templates
Allow syncing posts from timestamp
neko259 -
r1846:3bc31272 default
parent child Browse files
Show More
@@ -5,6 +5,7 b' from boards.models import Post, Tag'
5 TAG_THREAD = 'thread'
5 TAG_THREAD = 'thread'
6 TAG_TAGS = 'tags'
6 TAG_TAGS = 'tags'
7 TAG_TAG = 'tag'
7 TAG_TAG = 'tag'
8 TAG_TIME_FROM = 'timestamp_from'
8
9
9
10
10 class PostFilter:
11 class PostFilter:
@@ -53,3 +54,13 b' class TagsFilter(PostFilter):'
53 tag_tag = et.SubElement(tags_tag, TAG_TAG)
54 tag_tag = et.SubElement(tags_tag, TAG_TAG)
54 tag_tag.text = tag_name
55 tag_tag.text = tag_name
55
56
57
58 class TimestampFromFilter(PostFilter):
59 def filter(self, posts):
60 from_time = self.content.text
61 return posts.filter(pub_time__gt=from_time)
62
63 def add_filter(self, model_tag, value):
64 tags_from_time = et.SubElement(model_tag, TAG_TIME_FROM)
65 tags_from_time.text = value
66
@@ -28,6 +28,8 b' class Command(BaseCommand):'
28 help='Get posts of one specific thread')
28 help='Get posts of one specific thread')
29 parser.add_argument('--tags', type=str,
29 parser.add_argument('--tags', type=str,
30 help='Get posts of the tags, comma-separated')
30 help='Get posts of the tags, comma-separated')
31 parser.add_argument('--time-from', type=str,
32 help='Get posts from the given timestamp')
31
33
32 def handle(self, *args, **options):
34 def handle(self, *args, **options):
33 logger = logging.getLogger('boards.sync')
35 logger = logging.getLogger('boards.sync')
@@ -66,7 +68,8 b' class Command(BaseCommand):'
66 tags = tags_str.split(',')
68 tags = tags_str.split(',')
67
69
68 xml = SyncManager.generate_request_list(
70 xml = SyncManager.generate_request_list(
69 opening_post=options.get('thread'), tags=tags).encode()
71 opening_post=options.get('thread'), tags=tags,
72 timestamp_from=options.get('time_from')).encode()
70 response, content = h.request(list_url, method="POST", body=xml)
73 response, content = h.request(list_url, method="POST", body=xml)
71 if response.status != 200:
74 if response.status != 200:
72 raise Exception('Server returned error {}'.format(response.status))
75 raise Exception('Server returned error {}'.format(response.status))
@@ -3,7 +3,8 b' import logging'
3 from xml.etree import ElementTree
3 from xml.etree import ElementTree
4
4
5 from boards.abstracts.exceptions import SyncException
5 from boards.abstracts.exceptions import SyncException
6 from boards.abstracts.sync_filters import ThreadFilter, TagsFilter
6 from boards.abstracts.sync_filters import ThreadFilter, TagsFilter,\
7 TimestampFromFilter
7 from boards.models import KeyPair, GlobalId, Signature, Post, Tag
8 from boards.models import KeyPair, GlobalId, Signature, Post, Tag
8 from boards.models.attachment.downloaders import download
9 from boards.models.attachment.downloaders import download
9 from boards.models.signature import TAG_REQUEST, ATTR_TYPE, TYPE_GET, \
10 from boards.models.signature import TAG_REQUEST, ATTR_TYPE, TYPE_GET, \
@@ -360,7 +361,8 b' class SyncManager:'
360 return et.tostring(request, 'unicode')
361 return et.tostring(request, 'unicode')
361
362
362 @staticmethod
363 @staticmethod
363 def generate_request_list(opening_post=None, tags=list()):
364 def generate_request_list(opening_post=None, tags=list(),
365 timestamp_from=None):
364 """
366 """
365 Form a pull request from a list of ModelId objects.
367 Form a pull request from a list of ModelId objects.
366 """
368 """
@@ -377,5 +379,7 b' class SyncManager:'
377 ThreadFilter().add_filter(model, opening_post)
379 ThreadFilter().add_filter(model, opening_post)
378 if tags:
380 if tags:
379 TagsFilter().add_filter(model, tags)
381 TagsFilter().add_filter(model, tags)
382 if timestamp_from:
383 TimestampFromFilter().add_filter(model, timestamp_from)
380
384
381 return et.tostring(request, 'unicode')
385 return et.tostring(request, 'unicode')
@@ -212,3 +212,42 b' class SyncTest(TestCase):'
212 in response_thread,
212 in response_thread,
213 'Wrong response generated for the LIST request for posts of '
213 'Wrong response generated for the LIST request for posts of '
214 'non-existing thread.')
214 'non-existing thread.')
215
216 def test_list_pub_time(self):
217 key = KeyPair.objects.generate_key(primary=True)
218 tag = Tag.objects.create(name='tag1')
219 post = Post.objects.create_post(title='test_title',
220 text='test_text\rline two',
221 tags=[tag])
222 post2 = Post.objects.create_post(title='test title 2',
223 text='test text 2',
224 tags=[tag])
225
226 request_thread = MockRequest()
227 request_thread.body = (
228 '<request type="list" version="1.0">'
229 '<model name="post" version="1.0">'
230 '<timestamp_from>{}</timestamp_from>'
231 '</model>'
232 '</request>'.format(
233 post.pub_time,
234 )
235 )
236
237 response_thread = response_list(request_thread).content.decode()
238 self.assertTrue(
239 '<status>success</status>'
240 '<models>'
241 '<model>'
242 '<id key="{}" local-id="{}" type="{}" />'
243 '<version>{}</version>'
244 '</model>'
245 '</models>'.format(
246 post2.global_id.key,
247 post2.global_id.local_id,
248 post2.global_id.key_type,
249 post2.version,
250 ) in response_thread,
251 'Wrong response generated for the LIST request for posts of '
252 'existing thread.')
253
@@ -5,7 +5,8 b' import xml.etree.ElementTree as et'
5 from django.http import HttpResponse, Http404
5 from django.http import HttpResponse, Http404
6
6
7 from boards.abstracts.sync_filters import ThreadFilter, TagsFilter,\
7 from boards.abstracts.sync_filters import ThreadFilter, TagsFilter,\
8 TAG_THREAD, TAG_TAGS
8 TimestampFromFilter,\
9 TAG_THREAD, TAG_TAGS, TAG_TIME_FROM
9 from boards.models import GlobalId, Post
10 from boards.models import GlobalId, Post
10 from boards.models.post.sync import SyncManager
11 from boards.models.post.sync import SyncManager
11
12
@@ -16,6 +17,7 b" logger = logging.getLogger('boards.sync'"
16 FILTERS = {
17 FILTERS = {
17 TAG_THREAD: ThreadFilter,
18 TAG_THREAD: ThreadFilter,
18 TAG_TAGS: TagsFilter,
19 TAG_TAGS: TagsFilter,
20 TAG_TIME_FROM: TimestampFromFilter,
19 }
21 }
20
22
21
23
General Comments 0
You need to be logged in to leave comments. Login now