X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=osm_common%2Ffsmongo.py;h=740d54032c9237986a989c7753820088b36db75b;hb=refs%2Fchanges%2F70%2F9370%2F1;hp=6a96d4478b14602cf55a3941823d59eea39835d7;hpb=8ab6cc621e77323982e19eaf4f4e1d8ddcd356df;p=osm%2Fcommon.git diff --git a/osm_common/fsmongo.py b/osm_common/fsmongo.py index 6a96d44..740d540 100644 --- a/osm_common/fsmongo.py +++ b/osm_common/fsmongo.py @@ -16,13 +16,16 @@ # contact: eduardo.sousa@canonical.com ## +import errno +from http import HTTPStatus from io import BytesIO, StringIO -from pymongo import MongoClient -from gridfs import GridFSBucket, errors import logging -from http import HTTPStatus import os + +from gridfs import GridFSBucket, errors from osm_common.fsbase import FsBase, FsException +from pymongo import MongoClient + __author__ = "Eduardo Sousa " @@ -195,15 +198,19 @@ class FsMongo(FsBase): self.client = None self.fs = None - def __update_local_fs(self): + def __update_local_fs(self, from_path=None): dir_cursor = self.fs.find({"metadata.type": "dir"}, no_cursor_timeout=True) for directory in dir_cursor: + if from_path and not directory.filename.startswith(from_path): + continue os.makedirs(self.path + directory.filename, exist_ok=True) file_cursor = self.fs.find({"metadata.type": {"$in": ["file", "sym"]}}, no_cursor_timeout=True) for writing_file in file_cursor: + if from_path and not writing_file.filename.startswith(from_path): + continue file_path = self.path + writing_file.filename if writing_file.metadata["type"] == "sym": @@ -211,6 +218,13 @@ class FsMongo(FsBase): self.fs.download_to_stream(writing_file._id, b) b.seek(0) link = b.read().decode("utf-8") + + try: + os.remove(file_path) + except OSError as e: + if e.errno != errno.ENOENT: + # This is probably permission denied or worse + raise os.symlink(link, file_path) else: with open(file_path, 'wb+') as file_stream: @@ -313,7 +327,7 @@ class FsMongo(FsBase): if requested_file.metadata["type"] == mode: return True - + if requested_file.metadata["type"] == "sym" and mode == "file": return True @@ -448,12 +462,14 @@ class FsMongo(FsBase): else: self.fs.delete(requested_file._id) if not found and not ignore_non_exist: - raise FsException("File {} does not exist".format(storage), http_code=HTTPStatus.NOT_FOUND) + raise FsException("File {} does not exist".format(storage), http_code=HTTPStatus.NOT_FOUND) except IOError as e: raise FsException("File {} cannot be deleted: {}".format(f, e), http_code=HTTPStatus.INTERNAL_SERVER_ERROR) - def sync(self): + def sync(self, from_path=None): """ Sync from FSMongo to local storage + :param from_path: if supplied, only copy content from this path, not all + :return: None """ - self.__update_local_fs() + self.__update_local_fs(from_path=from_path)