Cache item name and component_name

This commit is contained in:
Unrud 2017-08-29 20:08:28 +02:00
parent f37b22b682
commit 642b4236fe
2 changed files with 33 additions and 15 deletions

View File

@ -334,7 +334,8 @@ class ComponentNotFoundError(ValueError):
class Item: class Item:
def __init__(self, collection, item=None, href=None, last_modified=None, def __init__(self, collection, item=None, href=None, last_modified=None,
text=None, etag=None, uid=None): text=None, etag=None, uid=None, name=None,
component_name=None):
"""Initialize an item. """Initialize an item.
``collection`` the parent collection. ``collection`` the parent collection.
@ -362,6 +363,8 @@ class Item:
self._item = item self._item = item
self._etag = etag self._etag = etag
self._uid = uid self._uid = uid
self._name = name
self._component_name = component_name
def __getattr__(self, attr): def __getattr__(self, attr):
return getattr(self.item, attr) return getattr(self.item, attr)
@ -398,6 +401,18 @@ class Item:
self._uid = get_uid_from_object(self.item) self._uid = get_uid_from_object(self.item)
return self._uid return self._uid
@property
def name(self):
if self._name is not None:
return self._name
return self.item.name
@property
def component_name(self):
if self._component_name is not None:
return self._component_name
return xmlutils.find_tag(self.item)
class BaseCollection: class BaseCollection:
@ -985,7 +1000,7 @@ class Collection(BaseCollection):
raise UnsafePathError(href) raise UnsafePathError(href)
try: try:
cache_content = self._item_cache_content(href, vobject_item) cache_content = self._item_cache_content(href, vobject_item)
_, _, _, text, _, _, _ = cache_content _, _, _, text, _, _, _, _ = cache_content
except Exception as e: except Exception as e:
raise ValueError( raise ValueError(
"Failed to store item %r in temporary collection %r: %s" % "Failed to store item %r in temporary collection %r: %s" %
@ -1235,8 +1250,9 @@ class Collection(BaseCollection):
cache_hash = self._item_cache_hash(text.encode(self._encoding)) cache_hash = self._item_cache_hash(text.encode(self._encoding))
etag = get_etag(text) etag = get_etag(text)
uid = get_uid_from_object(vobject_item) uid = get_uid_from_object(vobject_item)
name = vobject_item.name
tag, start, end = xmlutils.find_tag_and_time_range(vobject_item) tag, start, end = xmlutils.find_tag_and_time_range(vobject_item)
return cache_hash, uid, etag, text, tag, start, end return cache_hash, uid, etag, text, name, tag, start, end
def _store_item_cache(self, href, vobject_item, cache_hash=None): def _store_item_cache(self, href, vobject_item, cache_hash=None):
cache_folder = os.path.join(self._filesystem_path, ".Radicale.cache", cache_folder = os.path.join(self._filesystem_path, ".Radicale.cache",
@ -1288,17 +1304,18 @@ class Collection(BaseCollection):
def _load_item_cache(self, href): def _load_item_cache(self, href):
cache_folder = os.path.join(self._filesystem_path, ".Radicale.cache", cache_folder = os.path.join(self._filesystem_path, ".Radicale.cache",
"item") "item")
cache_hash = uid = etag = text = tag = start = end = None cache_hash = uid = etag = text = name = tag = start = end = None
try: try:
with open(os.path.join(cache_folder, href), "rb") as f: with open(os.path.join(cache_folder, href), "rb") as f:
cache_hash, uid, etag, text, tag, start, end = pickle.load(f) cache_hash, uid, etag, text, name, tag, start, end = \
pickle.load(f)
except FileNotFoundError as e: except FileNotFoundError as e:
pass pass
except (pickle.UnpicklingError, ValueError) as e: except (pickle.UnpicklingError, ValueError) as e:
self.logger.warning( self.logger.warning(
"Failed to load item cache entry %r in %r: %s", "Failed to load item cache entry %r in %r: %s",
href, self.path, e, exc_info=True) href, self.path, e, exc_info=True)
return cache_hash, uid, etag, text, tag, start, end return cache_hash, uid, etag, text, name, tag, start, end
def _clean_item_cache(self): def _clean_item_cache(self):
cache_folder = os.path.join(self._filesystem_path, ".Radicale.cache", cache_folder = os.path.join(self._filesystem_path, ".Radicale.cache",
@ -1331,8 +1348,8 @@ class Collection(BaseCollection):
# The hash of the component in the file system. This is used to check, # The hash of the component in the file system. This is used to check,
# if the entry in the cache is still valid. # if the entry in the cache is still valid.
input_hash = self._item_cache_hash(raw_text) input_hash = self._item_cache_hash(raw_text)
cache_hash, uid, etag, text, tag, start, end = self._load_item_cache( cache_hash, uid, etag, text, name, tag, start, end = \
href) self._load_item_cache(href)
vobject_item = None vobject_item = None
if input_hash != cache_hash: if input_hash != cache_hash:
with contextlib.ExitStack() as lock_stack: with contextlib.ExitStack() as lock_stack:
@ -1342,7 +1359,7 @@ class Collection(BaseCollection):
if self._lock.locked() == "r": if self._lock.locked() == "r":
lock_stack.enter_context(self._acquire_cache_lock("item")) lock_stack.enter_context(self._acquire_cache_lock("item"))
# Check if another process created the file in the meantime # Check if another process created the file in the meantime
cache_hash, uid, etag, text, tag, start, end = \ cache_hash, uid, etag, text, name, tag, start, end = \
self._load_item_cache(href) self._load_item_cache(href)
if input_hash != cache_hash: if input_hash != cache_hash:
try: try:
@ -1354,7 +1371,7 @@ class Collection(BaseCollection):
vobject_item = vobject_items[0] vobject_item = vobject_items[0]
check_and_sanitize_item(vobject_item, uid=uid, check_and_sanitize_item(vobject_item, uid=uid,
tag=self.get_meta("tag")) tag=self.get_meta("tag"))
cache_hash, uid, etag, text, tag, start, end = \ cache_hash, uid, etag, text, name, tag, start, end = \
self._store_item_cache( self._store_item_cache(
href, vobject_item, input_hash) href, vobject_item, input_hash)
except Exception as e: except Exception as e:
@ -1370,7 +1387,8 @@ class Collection(BaseCollection):
time.gmtime(os.path.getmtime(path))) time.gmtime(os.path.getmtime(path)))
return Item( return Item(
self, href=href, last_modified=last_modified, etag=etag, self, href=href, last_modified=last_modified, etag=etag,
text=text, item=vobject_item, uid=uid), (tag, start, end) text=text, item=vobject_item, uid=uid, name=name,
component_name=tag), (tag, start, end)
def get_multi2(self, hrefs): def get_multi2(self, hrefs):
# It's faster to check for file name collissions here, because # It's faster to check for file name collissions here, because
@ -1411,8 +1429,8 @@ class Collection(BaseCollection):
if not is_safe_filesystem_path_component(href): if not is_safe_filesystem_path_component(href):
raise UnsafePathError(href) raise UnsafePathError(href)
try: try:
cache_hash, uid, etag, text, _, _, _ = self._store_item_cache( cache_hash, uid, etag, text, name, tag, _, _ = \
href, vobject_item) self._store_item_cache(href, vobject_item)
except Exception as e: except Exception as e:
raise ValueError("Failed to store item %r in collection %r: %s" % raise ValueError("Failed to store item %r in collection %r: %s" %
(href, self.path, e)) from e (href, self.path, e)) from e
@ -1423,7 +1441,7 @@ class Collection(BaseCollection):
# will be removed again. # will be removed again.
self._clean_item_cache() self._clean_item_cache()
item = Item(self, href=href, etag=etag, text=text, item=vobject_item, item = Item(self, href=href, etag=etag, text=text, item=vobject_item,
uid=uid) uid=uid, name=name, component_name=tag)
# Track the change # Track the change
self._update_history_etag(href, item) self._update_history_etag(href, item)
self._clean_history_cache() self._clean_history_cache()

View File

@ -607,7 +607,7 @@ def get_content_type(item):
""" """
mimetype = OBJECT_MIMETYPES[item.name] mimetype = OBJECT_MIMETYPES[item.name]
encoding = item.collection.configuration.get("encoding", "request") encoding = item.collection.configuration.get("encoding", "request")
tag = find_tag(item) tag = item.component_name
content_type = "%s;charset=%s" % (mimetype, encoding) content_type = "%s;charset=%s" % (mimetype, encoding)
if tag: if tag:
content_type += ";component=%s" % tag content_type += ";component=%s" % tag