diff --git a/boards/abstracts/sync_filters.py b/boards/abstracts/sync_filters.py --- a/boards/abstracts/sync_filters.py +++ b/boards/abstracts/sync_filters.py @@ -1,8 +1,10 @@ import xml.etree.ElementTree as et -from boards.models import Post +from boards.models import Post, Tag TAG_THREAD = 'thread' +TAG_TAGS = 'tags' +TAG_TAG = 'tag' class PostFilter: @@ -29,3 +31,25 @@ class ThreadFilter(PostFilter): def add_filter(self, model_tag, value): thread_tag = et.SubElement(model_tag, TAG_THREAD) thread_tag.text = str(value) + + +class TagsFilter(PostFilter): + def filter(self, posts): + tags = [] + for tag_tag in self.content: + try: + tags.append(Tag.objects.get(name=tag_tag.text)) + except Tag.DoesNotExist: + pass + + if tags: + return posts.filter(thread__tags__in=tags) + else: + return posts.none() + + def add_filter(self, model_tag, value): + tags_tag = et.SubElement(model_tag, TAG_TAGS) + for tag_name in value: + tag_tag = et.SubElement(tags_tag, TAG_TAG) + tag_tag.text = tag_name + 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 @@ -26,6 +26,8 @@ class Command(BaseCommand): ' number of posts in one') parser.add_argument('--thread', type=int, help='Get posts of one specific thread') + parser.add_argument('--tags', type=str, + help='Get posts of the tags, comma-separated') def handle(self, *args, **options): logger = logging.getLogger('boards.sync') @@ -58,8 +60,11 @@ class Command(BaseCommand): logger.info('Running LIST request...') h = httplib2.Http() xml = SyncManager.generate_request_list( - opening_post=options.get('thread')) + opening_post=options.get('thread'), tags=options.get('tags').split(',')).encode() response, content = h.request(list_url, method="POST", body=xml) + if response.status != 200: + raise Exception('Server returned error {}'.format(response.status)) + logger.info('Processing response...') root = ET.fromstring(content) 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 @@ -3,7 +3,7 @@ import logging from xml.etree import ElementTree from boards.abstracts.exceptions import SyncException -from boards.abstracts.sync_filters import ThreadFilter +from boards.abstracts.sync_filters import ThreadFilter, TagsFilter 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, \ @@ -360,7 +360,7 @@ class SyncManager: return et.tostring(request, 'unicode') @staticmethod - def generate_request_list(opening_post=None): + def generate_request_list(opening_post=None, tags=list()): """ Form a pull request from a list of ModelId objects. """ @@ -375,5 +375,7 @@ class SyncManager: if opening_post: ThreadFilter().add_filter(model, opening_post) + if tags: + TagsFilter().add_filter(model, tags) return et.tostring(request, 'unicode') diff --git a/boards/views/sync.py b/boards/views/sync.py --- a/boards/views/sync.py +++ b/boards/views/sync.py @@ -4,7 +4,8 @@ import xml.etree.ElementTree as et from django.http import HttpResponse, Http404 -from boards.abstracts.sync_filters import ThreadFilter, TAG_THREAD +from boards.abstracts.sync_filters import ThreadFilter, TagsFilter,\ + TAG_THREAD, TAG_TAGS from boards.models import GlobalId, Post from boards.models.post.sync import SyncManager @@ -14,6 +15,7 @@ logger = logging.getLogger('boards.sync' FILTERS = { TAG_THREAD: ThreadFilter, + TAG_TAGS: TagsFilter, } @@ -30,10 +32,10 @@ def response_list(request): for tag_filter in model_tag: filter_name = tag_filter.tag - model_filter = FILTERS.get(filter_name)(tag_filter) + model_filter = FILTERS.get(filter_name) if not model_filter: logger.warning('Unavailable filter: {}'.format(filter_name)) - filters.append(model_filter) + filters.append(model_filter(tag_filter)) response_xml = SyncManager.generate_response_list(filters)