def do_DELETE(self):
"""Manage DELETE request."""
item = self._calendar.get_item(xmlutils.name_from_path(self.path))
- if item and self.headers.get("If-Match", item.etag) == item.etag:
+
+ if item and self.headers.get("If-Match", item.etag) == '"' + item.etag + '"':
+ print "item matches"
# No ETag precondition or precondition verified, delete item
self._answer = xmlutils.delete(self.path, self._calendar)
self.end_headers()
self.wfile.write(self._answer)
else:
+ print "no item or etag"
# No item or ETag precondition not verified, do not delete item
self.send_response(client.PRECONDITION_FAILED)
self._answer = xmlutils.propfind(
self.path, xml_request, self._calendar,
self.headers.get("depth", "infinity"))
+# print "PROPFIND %s\n%s" % (xml_request, self._answer)
self.send_response(client.MULTI_STATUS)
self.send_header("DAV", "1, calendar-access")
self.send_response(client.CREATED)
self.send_header("ETag", etag)
self.end_headers()
-
+ else:
# PUT rejected in all other cases
self.send_response(client.PRECONDITION_FAILED)
def do_REPORT(self):
"""Manage REPORT request."""
xml_request = self.rfile.read(int(self.headers["Content-Length"]))
+# print "REPORT %s" % xml_request
self._answer = xmlutils.report(self.path, xml_request, self._calendar)
+# print "ANSWER %s" % self._answer
self.send_response(client.MULTI_STATUS)
self.send_header("Content-Length", len(self._answer))
self.end_headers()
import glob
import tempfile
import vobject
+import string
+import re
from calypso import config
-# This function overrides the builtin ``open`` function for this module
-# pylint: disable=W0622
-def open(path, mode="r"):
- """Open file at ``path`` with ``mode``, automagically managing encoding."""
- return codecs.open(path, mode, config.get("encoding", "stock"))
-# pylint: enable=W0622
-
-
#
# Recursive search for 'name' within 'vobject'
#
def __init__(self, text, name=None, path=None):
"""Initialize object from ``text`` and different ``kwargs``."""
- text = text.encode(encoding='UTF-8', errors='replace')
+ try:
+ text = text.encode('utf8')
+ except UnicodeDecodeError:
+ text = text.decode('latin1').encode('utf-8')
+
+ # Strip out control characters
+
+ text = re.sub(r"[\x01-\x09\x0b-\x1F\x7F]","",text)
try:
self.object = vobject.readOne(text)
Text is the serialized form of the item.
"""
- try:
- return self.object.serialize()
- except UnicodeDecodeError, ue:
- print "Unicode decode error in %s" % self.path
- raise ue
+ return self.object.serialize().decode('utf-8')
@property
def length(self):
def insert_file(self, path):
try:
- text = open(path).read()
+ text = open(path,"rb").read()
item = Item(text, None, path)
if item:
self.my_items.append(item)
for file in self.files:
if not file in files:
self.remove_file(file)
+ h = hashlib.sha1()
+ for item in self.my_items:
+ h.update(item.etag)
+ self._ctag = '%d-' % self.mtime + h.hexdigest()
self.files = files
def __init__(self, path):
self.files = []
self.my_items = []
self.mtime = 0
+ self._ctag = ''
+ self.etag = hashlib.sha1(self.path).hexdigest()
self.scan_dir()
self.tag = "Collection"
def write_file(self, item):
fd, path = tempfile.mkstemp(suffix=".ics", prefix="cal", dir=self.path)
- file = os.fdopen(fd, 'w')
+ file = os.fdopen(fd, 'wb')
file.write(item.text)
file.close()
return path
new_item = Item(text, name, None)
if not new_item:
+ print "Cannot create new item"
return False
if new_item.name not in (item.name for item in self.my_items):
- self.create_file(new_item)
- return True
+ print "New item %s" % new_item.name
+ self.create_file(new_item)
+ return True
+ print "Item %s already present %s" % (new_item.name, self.get_item(new_item.name).path)
return False
def append_file(self, path):
"""
try:
- text = open(path).read()
+ text = open(path,"rb").read()
if not self.append(None, text):
print "Already in calendar: %s" % path
return True
except Exception, ex:
print "Failed to import: %s: %s" % (ex, path)
return False
- print "Imported: %s" % arg
+ print "Imported: %s" % path
return True
def remove(self, name):
"""Remove object named ``name`` from calendar."""
+ print "Remove object %s" % name
for old_item in self.my_items:
if old_item.name == name:
self.destroy_file(old_item)
# os.makedirs(os.path.dirname(self.path))
#text = serialize(headers=headers, items=items)
- #return open(self.path, "w").write(text)
+ #return open(self.path, "wb").write(text)
return True
@property
- def etag(self):
- """Etag from calendar."""
- h = hashlib.sha1()
- for item in self.my_items:
- h.update(item.etag)
- return h.hexdigest()
+ def ctag(self):
+ self.scan_dir()
+ """Ctag from calendar."""
+ return self._ctag
@property
def name(self):
"""
# Reading request
+ print "delete name %s" % name_from_path(path)
calendar.remove(name_from_path(path))
# Writing answer
status.text = _response(200)
response.append(status)
+ print "Deleted\n"
return ET.tostring(multistatus, config.get("encoding", "request"))
for tag in props:
element = ET.Element(tag)
- if tag == _tag("D", "resourcetype") and is_calendar:
+ if tag == _tag("D", "resourcetype"):
tag = ET.Element(_tag("C", "calendar"))
element.append(tag)
tag = ET.Element(_tag("D", "collection"))
else:
element.text = "text/calendar"
elif tag == _tag("CS", "getctag") and is_calendar:
- element.text = item.etag
+ element.text = item.ctag
elif tag == _tag("D", "getetag"):
element.text = item.etag
- elif tag == _tag("D", "displayname") and is_calendar:
+ elif tag == _tag("D", "displayname"):
element.text = calendar.name
elif tag == _tag("D", "principal-URL"):
# TODO: use a real principal URL, read rfc3744-4.2 for info
if tag == _tag("D", "getetag"):
element.text = item.etag
elif tag == _tag("C", "calendar-data"):
- element.text = item.text.decode('utf-8', errors='replace')
+ element.text = item.text
prop.append(element)
status = ET.Element(_tag("D", "status"))