class Folder(object): def __init__(self, obj=None): if obj is None: self._folder = None elif type(obj) is str: self._folder = File(obj) elif isinstance(obj, File): self._folder = obj else: raise ValueError, 'unexpected obj "%s"' % obj ############################ # Private API ############################ def _get_g_file(self, uri): if type(uri) is not str: raise TypeError, 'unexpected "%s"' % repr(uri) # Resolve or not ? # Your folder is None => new File if self._folder is None: g_file = File(uri) else: # Split the uri scheme, authority, path, query, fragment = urlsplit(uri) # A scheme or an authority => new File # XXX This is not truly exact: # we can have a scheme and a relative path. if scheme or authority: g_file = File(uri) else: # Else we resolve the path g_file = self._folder.resolve_relative_path(uri) # Automount a ftp server ? if g_file.get_uri_scheme () == 'ftp': # Mount the server AnonymousConnection(g_file) return g_file def _get_xtime(self, uri, attribut): g_file = self._get_g_file(uri) info = g_file.query_info(attribut) uint64 = info.get_attribute_uint64(attribut) return datetime.fromtimestamp(uint64) def _can_x(self, uri, attribut): g_file = self._get_g_file(uri) info = g_file.query_info(attribut) return info.get_attribute_boolean(attribut) ############################ # Public API ############################ def exists(self, uri): g_file = self._get_g_file(uri) return g_file.query_exists() def is_file(self, uri): g_file = self._get_g_file(uri) return _is_file(g_file) def is_folder(self, uri): g_file = self._get_g_file(uri) return _is_folder(g_file) def can_read(self, uri): return self._can_x(uri, FILE_ATTRIBUTE_ACCESS_CAN_READ) def can_write(self, uri): return self._can_x(uri, FILE_ATTRIBUTE_ACCESS_CAN_WRITE) def make_file(self, uri): g_file = self._get_g_file(uri) # Make the parent's directory _make_directory_with_parents(g_file.get_parent()) return g_file.create() def make_folder(self, uri): g_file = self._get_g_file(uri) # XXX g_file_make_directory_with_parents is not yet implemented!! _make_directory_with_parents(g_file) def get_ctime(self, uri): return self._get_xtime(uri, FILE_ATTRIBUTE_TIME_CHANGED) def get_mtime(self, uri): return self._get_xtime(uri, FILE_ATTRIBUTE_TIME_MODIFIED) def get_atime(self, uri): return self._get_xtime(uri, FILE_ATTRIBUTE_TIME_ACCESS) def get_mimetype(self, uri): g_file = self._get_g_file(uri) info = g_file.query_info(FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE) content_type = info.get_attribute_as_string( FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE) return content_type_get_mime_type(content_type) def get_size(self, uri): g_file = self._get_g_file(uri) info = g_file.query_info(FILE_ATTRIBUTE_STANDARD_SIZE) return info.get_attribute_uint64(FILE_ATTRIBUTE_STANDARD_SIZE) def open(self, uri, mode=READ): g_file = self._get_g_file(uri) # A directory => a new Folder ? if g_file.query_exists() and _is_folder(g_file): return Folder(g_file) # Get the Stream if mode is READ: # XXX can we find a better implementation ? # The problem is that a GFileInputStream object # doesn't implement all the usual functions of "file" # by example, there is no get_lines member. return StringIO(g_file.read().read()) elif mode is WRITE: return g_file.replace('', False) elif mode is APPEND: return g_file.append_to() # XXX Finish me elif mode is READ_WRITE: raise NotImplementedError def remove(self, uri): g_file = self._get_g_file(uri) _remove(g_file) def copy(self, source, target): source = self._get_g_file(source) target = self._get_g_file(target) # Make the target's parent directory _make_directory_with_parents(target.get_parent()) _copy(source, target) def move(self, source, target): source = self._get_g_file(source) target = self._get_g_file(target) # Make the target's parent directory _make_directory_with_parents(target.get_parent()) source.move(target) def get_names(self, uri='.'): g_file = self._get_g_file(uri) return _get_names(g_file) def traverse(self, uri): g_file = self._get_g_file(uri) return _traverse(g_file) def get_uri(self, reference='.'): g_file = self._get_g_file(reference) return g_file.get_uri() def get_relative_path(self, uri): g_file = self._get_g_file(uri) if self._folder is None: return g_file.get_path() return self._folder.get_relative_path(g_file)
class Folder(object): def __init__(self, obj=None): if obj is None: self._folder = None elif type(obj) is str: self._folder = File(obj) elif isinstance(obj, File): self._folder = obj else: raise ValueError, 'unexpected obj "%s"' % obj ############################ # Private API ############################ def _get_g_file(self, uri): if type(uri) is not str: raise TypeError, 'unexpected "%s"' % repr(uri) # Your folder is None => new File if self._folder is None: return File(uri) # Your folder is not None, we must resolve the uri scheme, authority, path, query, fragment = urlsplit(uri) # A scheme or an authority => new File # XXX This is not truly exact: # we can have a scheme and a relative path. if scheme or authority: return File(uri) # Else we resolve the path return self._folder.resolve_relative_path(uri) def _get_xtime(self, uri, attribut): g_file = self._get_g_file(uri) info = g_file.query_info(attribut) uint64 = info.get_attribute_uint64(attribut) return datetime.fromtimestamp(uint64) def _can_x(self, uri, attribut): g_file = self._get_g_file(uri) info = g_file.query_info(attribut) return info.get_attribute_boolean(attribut) ####################################################################### # Public API ####################################################################### def exists(self, uri): g_file = self._get_g_file(uri) return g_file.query_exists() def is_file(self, uri): g_file = self._get_g_file(uri) return _is_file(g_file) def is_folder(self, uri): g_file = self._get_g_file(uri) return _is_folder(g_file) def can_read(self, uri): return self._can_x(uri, FILE_ATTRIBUTE_ACCESS_CAN_READ) def can_write(self, uri): return self._can_x(uri, FILE_ATTRIBUTE_ACCESS_CAN_WRITE) def make_file(self, uri): g_file = self._get_g_file(uri) # Make the parent's directory _make_directory_with_parents(g_file.get_parent()) return g_file.create() def make_folder(self, uri): g_file = self._get_g_file(uri) _make_directory_with_parents(g_file) def get_ctime(self, uri): return self._get_xtime(uri, FILE_ATTRIBUTE_TIME_CHANGED) def get_mtime(self, uri): return self._get_xtime(uri, FILE_ATTRIBUTE_TIME_MODIFIED) def get_atime(self, uri): return self._get_xtime(uri, FILE_ATTRIBUTE_TIME_ACCESS) def get_mimetype(self, uri): """Try to guess the mimetype for a resource, given the resource itself and its name. See `itools.fs.base.get_mimetype` for complete description. """ g_file = self._get_g_file(uri) # TODO Use magic numbers too (like file -i). # Not a file ? if not _is_file(g_file): return 'application/x-not-regular-file' # Find out the filename extension scheme, authority, path, query, fragment = urlsplit(uri) path = unquote(path) name = basename(path) return get_mimetype(name) def get_size(self, uri): g_file = self._get_g_file(uri) info = g_file.query_info(FILE_ATTRIBUTE_STANDARD_SIZE) return info.get_attribute_uint64(FILE_ATTRIBUTE_STANDARD_SIZE) def open(self, uri, mode=READ): g_file = self._get_g_file(uri) # A directory => a new Folder ? if g_file.query_exists() and _is_folder(g_file): return Folder(g_file) # Get the Stream if mode is READ: # XXX can we find a better implementation ? # The problem is that a GFileInputStream object # doesn't implement all the usual functions of "file" # by example, there is no get_lines member. return StringIO(g_file.read().read()) elif mode is WRITE: return g_file.replace('', False) elif mode is APPEND: return g_file.append_to() # XXX Finish me elif mode is READ_WRITE: raise NotImplementedError def remove(self, uri): g_file = self._get_g_file(uri) _remove(g_file) def copy(self, source, target): source = self._get_g_file(source) target = self._get_g_file(target) # Make the target's parent directory _make_directory_with_parents(target.get_parent()) _copy(source, target) def move(self, source, target): source = self._get_g_file(source) target = self._get_g_file(target) # Make the target's parent directory _make_directory_with_parents(target.get_parent()) source.move(target) def get_names(self, uri='.'): g_file = self._get_g_file(uri) return _get_names(g_file) def traverse(self, uri): g_file = self._get_g_file(uri) return _traverse(g_file) def mount_archive(self, uri): g_file = self._get_g_file(uri) return Archive(g_file) def get_uri(self, reference='.'): g_file = self._get_g_file(reference) return g_file.get_uri() def get_relative_path(self, uri): g_file = self._get_g_file(uri) if self._folder is None: return g_file.get_path() return self._folder.get_relative_path(g_file) ####################################################################### # Used by itools.handlers ####################################################################### @staticmethod def get_basename(reference): return get_uri_name(reference) @staticmethod def get_path(reference): return get_uri_path(reference) @staticmethod def resolve(base, reference): return resolve_uri(base, reference) @staticmethod def resolve2(base, reference): return resolve_uri2(base, reference) # Resolution method for handler database keys normalize_key = get_uri