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 @@ -1,9 +1,9 @@ import re -import urllib.parse -import httplib2 import xml.etree.ElementTree as ET +import httplib2 from django.core.management import BaseCommand + from boards.models import GlobalId from boards.models.post.sync import SyncManager @@ -14,12 +14,12 @@ REGEX_GLOBAL_ID = re.compile(r'(\w+)::([ class Command(BaseCommand): - help = 'Send a sync or get request to the server.' + \ - 'sync_with_server [post_global_id]' + help = 'Send a sync or get request to the server.' def add_arguments(self, parser): parser.add_argument('url', type=str) - parser.add_argument('global_id', type=str) + parser.add_argument('--global_id', type=str, default='', + help='Post global ID') def handle(self, *args, **options): url = options.get('url') @@ -44,7 +44,8 @@ class Command(BaseCommand): raise Exception('Invalid global ID') else: h = httplib2.Http() - response, content = h.request(url, method="POST") + xml = GlobalId.objects.generate_request_pull() + response, content = h.request(url, method="POST", body=xml) print(content) @@ -53,7 +54,6 @@ class Command(BaseCommand): if status == 'success': models = root.findall('models')[0] for model in models: - model_content = model[0] - print(model_content.findall('text')[0].text) + print(ET.tostring(model)) else: raise Exception('Invalid response status') 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 @@ -150,6 +150,21 @@ class SyncManager: pass @staticmethod + def generate_response_pull(): + response = et.Element(TAG_RESPONSE) + + status = et.SubElement(response, TAG_STATUS) + status.text = STATUS_SUCCESS + + models = et.SubElement(response, TAG_MODELS) + + for post in Post.objects.all(): + tag_id = et.SubElement(models, TAG_ID) + post.global_id.to_xml_element(tag_id) + + return et.tostring(response, ENCODING_UNICODE) + + @staticmethod def _verify_model(tag_content, tag_model): """ Verifies all signatures for a single model. diff --git a/boards/models/signature.py b/boards/models/signature.py --- a/boards/models/signature.py +++ b/boards/models/signature.py @@ -7,6 +7,7 @@ TAG_REQUEST = 'request' TAG_ID = 'id' TYPE_GET = 'get' +TYPE_PULL = 'pull' ATTR_VERSION = 'version' ATTR_TYPE = 'type' @@ -37,6 +38,21 @@ class GlobalIdManager(models.Manager): return et.tostring(request, 'unicode') + def generate_request_pull(self): + """ + Form a pull request from a list of ModelId objects. + """ + + request = et.Element(TAG_REQUEST) + request.set(ATTR_TYPE, TYPE_PULL) + request.set(ATTR_VERSION, '1.0') + + model = et.SubElement(request, TAG_MODEL) + model.set(ATTR_VERSION, '1.0') + model.set(ATTR_NAME, 'post') + + return et.tostring(request, 'unicode') + def global_id_exists(self, global_id): """ Checks if the same global id already exists in the system. diff --git a/boards/urls.py b/boards/urls.py --- a/boards/urls.py +++ b/boards/urls.py @@ -10,7 +10,7 @@ from boards.views.notifications import N from boards.views.search import BoardSearchView from boards.views.static import StaticPageView from boards.views.preview import PostPreviewView -from boards.views.sync import get_post_sync_data, response_get +from boards.views.sync import get_post_sync_data, response_get, response_pull from boards.views.random import RandomImageView @@ -72,7 +72,7 @@ urlpatterns = patterns('', url(r'^api/preview/$', api.api_get_preview, name='preview'), # Sync protocol API - url(r'^api/sync/pull/$', api.sync_pull, name='api_sync_pull'), + url(r'^api/sync/pull/$', response_pull, name='api_sync_pull'), url(r'^api/sync/get/$', response_get, name='api_sync_pull'), # TODO 'get' request diff --git a/boards/views/api.py b/boards/views/api.py --- a/boards/views/api.py +++ b/boards/views/api.py @@ -241,18 +241,3 @@ def api_get_preview(request): parser = Parser() return HttpResponse(content=parser.parse(parser.preparse(raw_text))) - - -# TODO Make a separate module for sync API methods -def sync_pull(request): - """ - Return 'pull' request response for all posts. - """ - request_xml = request.get('xml') - if request_xml is None: - posts = Post.objects.all() - else: - pass # TODO Parse the XML and get filters from it - - xml = SyncManager.generate_response_get(posts) - return HttpResponse(content=xml) diff --git a/boards/views/sync.py b/boards/views/sync.py --- a/boards/views/sync.py +++ b/boards/views/sync.py @@ -5,7 +5,14 @@ from boards.models.post.sync import Sync def response_pull(request): - pass + request_xml = request.body + + if request_xml is None: + return HttpResponse(content='Use the API') + + response_xml = SyncManager.generate_response_pull() + + return HttpResponse(content=response_xml) def response_get(request):