diff --git a/tests/storage/test_http.py b/tests/storage/test_http.py new file mode 100644 index 0000000..aa6e60f --- /dev/null +++ b/tests/storage/test_http.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +''' + vdirsyncer.tests.storage.test_http + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + :copyright: (c) 2014 Markus Unterwaditzer + :license: MIT, see LICENSE for more details. +''' + +from unittest import TestCase +from .. import assert_item_equals +from textwrap import dedent +from vdirsyncer.storage.http import HttpStorage, Item, split_collection + + +class HttpStorageTests(TestCase): + + def _get_storage(self, **kwargs): + return HttpStorage(**kwargs) + + def test_split_collection(self): + (item,) = list(split_collection( + dedent(u''' + BEGIN:VCALENDAR + VERSION:2.0 + PRODID:http://www.example.com/calendarapplication/ + METHOD:PUBLISH + BEGIN:VEVENT + UID:461092315540@example.com + ORGANIZER;CN="Alice Balder, Example Inc.":MAILTO:alice@example.com + LOCATION:Somewhere + SUMMARY:Eine Kurzinfo + DESCRIPTION:Beschreibung des Termines + CLASS:PUBLIC + DTSTART:20060910T220000Z + DTEND:20060919T215900Z + DTSTAMP:20060812T125900Z + END:VEVENT + END:VCALENDAR + ''') + )) + assert_item_equals(item, Item(dedent(u''' + BEGIN:VEVENT + UID:461092315540@example.com + ORGANIZER;CN="Alice Balder, Example Inc.":MAILTO:alice@example.com + LOCATION:Somewhere + SUMMARY:Eine Kurzinfo + DESCRIPTION:Beschreibung des Termines + CLASS:PUBLIC + DTSTART:20060910T220000Z + DTEND:20060919T215900Z + DTSTAMP:20060812T125900Z + END:VEVENT + ''').strip())) diff --git a/vdirsyncer/storage/__init__.py b/vdirsyncer/storage/__init__.py index 8b09d39..9f6c3a8 100644 --- a/vdirsyncer/storage/__init__.py +++ b/vdirsyncer/storage/__init__.py @@ -15,9 +15,11 @@ from .dav.caldav import CaldavStorage from .dav.carddav import CarddavStorage from .filesystem import FilesystemStorage +from .http import HttpStorage storage_names = { 'caldav': CaldavStorage, 'carddav': CarddavStorage, - 'filesystem': FilesystemStorage + 'filesystem': FilesystemStorage, + 'http': HttpStorage } diff --git a/vdirsyncer/storage/http.py b/vdirsyncer/storage/http.py new file mode 100644 index 0000000..d4e9c4a --- /dev/null +++ b/vdirsyncer/storage/http.py @@ -0,0 +1,76 @@ + +# -*- coding: utf-8 -*- +''' + vdirsyncer.storage.http + ~~~~~~~~~~~~~~~~~~~~~~~ + + :copyright: (c) 2014 Markus Unterwaditzer + :license: MIT, see LICENSE for more details. +''' + +import requests +import hashlib +from .base import Storage, Item + + +def split_collection(text): + item = [] + collection_type = None + item_type = None + for line in text.splitlines(): + if not line.strip(): + continue + key, value = (x.strip() for x in line.split(u':', 1)) + if key == u'BEGIN': + if collection_type is None: + collection_type = value + elif item_type is None: + item_type = value + item.append(line) + elif key == u'END': + if value == collection_type: + break + elif value == item_type: + item.append(line) + yield Item(u'\n'.join(item)) + item = [] + else: + item.append(line) + else: + if item_type is not None: + item.append(line) + + +class HttpStorage(Storage): + _repr_attributes = ('url',) + _items = None + + def __init__(self, url, **kwargs): + super(HttpStorage, self).__init__(**kwargs) + self.url = url + + def list(self): + if self._items is None: + r = requests.get(self.url) + r.raise_on_status() + self._items = {} + for item in split_collection(r.text): + self._items[item.uid] = item + + for uid in self._items.keys(): + yield uid, hashlib.sha256(item.raw) + + def get(self, href): + ((actual_href, obj, etag),) = self.get_multi([href]) + assert href == actual_href + return obj, etag + + def get_multi(self, hrefs): + pass + + def has(self, href): + ''' + check if item exists by href + :returns: True or False + ''' + raise NotImplementedError()