mirror of
https://github.com/Kozea/Radicale.git
synced 2025-09-15 20:36:55 +00:00
Refactor multifilesystem
This commit is contained in:
parent
f2d63ad7f7
commit
35484c9b79
16 changed files with 1163 additions and 840 deletions
83
radicale/storage/multifilesystem/discover.py
Normal file
83
radicale/storage/multifilesystem/discover.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
# This file is part of Radicale Server - Calendar Server
|
||||
# Copyright © 2014 Jean-Marc Martins
|
||||
# Copyright © 2012-2017 Guillaume Ayoub
|
||||
# Copyright © 2017-2018 Unrud<unrud@outlook.com>
|
||||
#
|
||||
# This library is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Radicale. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
import posixpath
|
||||
|
||||
from radicale import pathutils
|
||||
from radicale.log import logger
|
||||
|
||||
|
||||
class CollectionDiscoverMixin:
|
||||
@classmethod
|
||||
def discover(cls, path, depth="0", child_context_manager=(
|
||||
lambda path, href=None: contextlib.ExitStack())):
|
||||
# Path should already be sanitized
|
||||
sane_path = pathutils.strip_path(path)
|
||||
attributes = sane_path.split("/") if sane_path else []
|
||||
|
||||
folder = cls._get_collection_root_folder()
|
||||
# Create the root collection
|
||||
cls._makedirs_synced(folder)
|
||||
try:
|
||||
filesystem_path = pathutils.path_to_filesystem(folder, sane_path)
|
||||
except ValueError as e:
|
||||
# Path is unsafe
|
||||
logger.debug("Unsafe path %r requested from storage: %s",
|
||||
sane_path, e, exc_info=True)
|
||||
return
|
||||
|
||||
# Check if the path exists and if it leads to a collection or an item
|
||||
if not os.path.isdir(filesystem_path):
|
||||
if attributes and os.path.isfile(filesystem_path):
|
||||
href = attributes.pop()
|
||||
else:
|
||||
return
|
||||
else:
|
||||
href = None
|
||||
|
||||
sane_path = "/".join(attributes)
|
||||
collection = cls(pathutils.unstrip_path(sane_path, True))
|
||||
|
||||
if href:
|
||||
yield collection._get(href)
|
||||
return
|
||||
|
||||
yield collection
|
||||
|
||||
if depth == "0":
|
||||
return
|
||||
|
||||
for href in collection._list():
|
||||
with child_context_manager(sane_path, href):
|
||||
yield collection._get(href)
|
||||
|
||||
for entry in os.scandir(filesystem_path):
|
||||
if not entry.is_dir():
|
||||
continue
|
||||
href = entry.name
|
||||
if not pathutils.is_safe_filesystem_path_component(href):
|
||||
if not href.startswith(".Radicale"):
|
||||
logger.debug("Skipping collection %r in %r",
|
||||
href, sane_path)
|
||||
continue
|
||||
sane_child_path = posixpath.join(sane_path, href)
|
||||
child_path = pathutils.unstrip_path(sane_child_path, True)
|
||||
with child_context_manager(sane_child_path):
|
||||
yield cls(child_path)
|
Loading…
Add table
Add a link
Reference in a new issue