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 |
|
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