Example #1
0
def _normpath(path):
    """
    Replace all symlink in path with real path and return its absolute path
    For example, if given path is "local/bin/python" and "local" is a symbolic link to "/usr/local",
    returned path will be "/usr/local/bin/python"
    """
    if hasattr(os, 'readlink'):
        parts = Path(path).splitall()
        _path = Path('')
        for p in parts:
            _path = _path / p
            if _path.islink():
                # readlink return an absolute path or relative path depending on symlink.
                # If symlink is a relative link, parent path is used to generate an absolute path
                # Default path behaviour when concatenating two absolute paths is to keep only second one:
                # path('/a/1')/path('/b/2') -> path('/b/2')
                # So, if symlink is absolute, all is ok
                _path = _path.parent / _path.readlink()
        return _path.abspath()
    else:
        return path.abspath()
Example #2
0
def _normpath(path):
    """
    Replace all symlink in path with real path and return its absolute path
    For example, if given path is "local/bin/python" and "local" is a symbolic link to "/usr/local",
    returned path will be "/usr/local/bin/python"
    """
    if hasattr(os, 'readlink'):
        parts = Path(path).splitall()
        _path = Path('')
        for p in parts:
            _path = _path / p
            if _path.islink():
                # readlink return an absolute path or relative path depending on symlink.
                # If symlink is a relative link, parent path is used to generate an absolute path
                # Default path behaviour when concatenating two absolute paths is to keep only second one:
                # path('/a/1')/path('/b/2') -> path('/b/2')
                # So, if symlink is absolute, all is ok
                _path = _path.parent / _path.readlink()
        return _path.abspath()
    else:
        return path.abspath()
Example #3
0
    def _add_item(self, category, obj=None, **kwargs):
        mode = kwargs.pop('mode', self.MODE_COPY)
        if obj and isinstance(obj, Data):
            # TODO: Check obj follow Data or Model interface ??
            new_path = self.path / category / obj.path.name
            if obj.path != new_path and mode == self.MODE_COPY:
                # TODO: use Data.copy instead
                return self._add_item(category, path=obj.path, **kwargs)

            category_dict = getattr(self, category)
            if obj.filename not in category_dict:
                category_dict[str(obj.filename)] = obj
            else:
                raise ValueError("data '%s' already exists in project '%s'" %
                                 (obj.filename, self.alias))
        elif obj:
            category_dict = getattr(self, category)
            if obj.name not in category_dict:
                category_dict[str(obj.name)] = obj
            else:
                raise ValueError("data '%s' already exists in project '%s'" %
                                 (obj.name, self.alias))
        else:
            filename = Path(
                kwargs.pop('filename')) if 'filename' in kwargs else None
            content = kwargs.pop('content', None)
            dtype = kwargs.pop('dtype', None)
            mimetype = kwargs.pop('mimetype', None)
            path = Path(kwargs.pop('path')) if 'path' in kwargs else None
            # If project path exists, ie project exists on disk,
            # Create category dir if necessary
            category_path = self.path / category
            if self.path.exists() and not category_path.exists():
                category_path.makedirs()

            if filename:
                new_path = self.path / category / filename.name
            elif path:
                if not path.exists():
                    raise ErrorInvalidItem("path '%s' doesn't exists" % path)
                filename = path.name
                new_path = self.path / category / filename
            else:
                raise ValueError("path or filename required")

            if path is None:
                path = new_path

            # If data was outside project, we try to fix it.
            # If mode is "prefer copy", we try to copy file inside project
            # If copy fails, we get original content and pass it to new data
            # If mode is "prefer link", we just keep original path (keep outside project)
            # TODO: Move to Data.copy
            data_obj = None
            if new_path.abspath() != path.abspath() and mode == self.MODE_COPY:
                try:
                    path.copyfile(new_path)
                except IOError:
                    data_obj = DataFactory(path,
                                           mimetype,
                                           dtype=dtype,
                                           default_content=content)
                    content = data_obj.read()
                else:
                    content = None
            elif new_path.abspath() != path.abspath(
            ) and mode == self.MODE_LINK:
                new_path = path
            else:
                pass
                # Nothing to do, data is yet in the right place

            data_obj = DataFactory(new_path,
                                   mimetype,
                                   dtype=dtype,
                                   default_content=content)
            obj = self._add_item(category, data_obj, **kwargs)

        obj.package = self
        return obj
Example #4
0
    def _add_item(self, category, obj=None, **kwargs):
        mode = kwargs.pop('mode', self.MODE_COPY)
        if obj and isinstance(obj, Data):
            # TODO: Check obj follow Data or Model interface ??
            new_path = self.path / category / obj.path.name
            if obj.path != new_path and mode == self.MODE_COPY:
                # TODO: use Data.copy instead
                return self._add_item(category, path=obj.path, **kwargs)

            category_dict = getattr(self, category)
            if obj.filename not in category_dict:
                category_dict[str(obj.filename)] = obj
            else:
                raise ValueError("data '%s' already exists in project '%s'" % (obj.filename, self.alias))
        elif obj:
            category_dict = getattr(self, category)
            if obj.name not in category_dict:
                category_dict[str(obj.name)] = obj
            else:
                raise ValueError("data '%s' already exists in project '%s'" % (obj.name, self.alias))
        else:
            filename = Path(kwargs.pop('filename')) if 'filename' in kwargs else None
            content = kwargs.pop('content', None)
            dtype = kwargs.pop('dtype', None)
            mimetype = kwargs.pop('mimetype', None)
            path = Path(kwargs.pop('path')) if 'path' in kwargs else None
            # If project path exists, ie project exists on disk,
            # Create category dir if necessary
            category_path = self.path / category
            if self.path.exists() and not category_path.exists():
                category_path.makedirs()

            if filename:
                new_path = self.path / category / filename.name
            elif path:
                if not path.exists():
                    raise ErrorInvalidItem("path '%s' doesn't exists" % path)
                filename = path.name
                new_path = self.path / category / filename
            else:
                raise ValueError("path or filename required")

            if path is None:
                path = new_path

            # If data was outside project, we try to fix it.
            # If mode is "prefer copy", we try to copy file inside project
            # If copy fails, we get original content and pass it to new data
            # If mode is "prefer link", we just keep original path (keep outside project)
            # TODO: Move to Data.copy
            data_obj = None
            if new_path.abspath() != path.abspath() and mode == self.MODE_COPY:
                try:
                    path.copyfile(new_path)
                except IOError:
                    data_obj = DataFactory(path, mimetype, dtype=dtype, default_content=content)
                    content = data_obj.read()
                else:
                    content = None
            elif new_path.abspath() != path.abspath() and mode == self.MODE_LINK:
                new_path = path
            else:
                pass
                # Nothing to do, data is yet in the right place

            data_obj = DataFactory(new_path, mimetype, dtype=dtype, default_content=content)
            obj = self._add_item(category, data_obj, **kwargs)

        obj.package = self
        return obj