Commit 079fa398 by willmcgugan

Lots of docs, some cosmetic changes

parent a9aecf14
fs.contrib fs.contrib
========= ==========
The ``fs.contrib`` module contains a number of filesystem implementations provided by third parties. The ``fs.contrib`` module contains a number of filesystem implementations provided by third parties.
......
...@@ -17,11 +17,13 @@ Guide ...@@ -17,11 +17,13 @@ Guide
introduction.rst introduction.rst
getting_started.rst getting_started.rst
concepts.rst concepts.rst
opening.rst
interface.rst interface.rst
filesystems.rst filesystems.rst
contrib.rst contrib.rst
expose.rst expose.rst
utilities.rst utilities.rst
commands.rst
Code Documentation Code Documentation
------------------ ------------------
......
...@@ -3,11 +3,11 @@ Filesystem Interface ...@@ -3,11 +3,11 @@ Filesystem Interface
It requires a relatively small number of methods to implement a working FS object. It requires a relatively small number of methods to implement a working FS object.
If you are looking to implement a working FS object, derive a class from fs.base.FS and implement the essential methods (below). Be sure to convert all exceptions to instances of :class:`fs.errors.FSError`. If you are looking to implement a working FS object, derive a class from :py:class:`fs.base.FS` and implement the essential methods (below). Be sure to convert all exceptions to instances of :class:`fs.errors.FSError`.
It may also be worthwhile implementing some of the non-essential methods, as the default implementations may not be optimal. For example, the method :meth:`fs.base.FS.move` is implemeneted as a file copy followed by a delete, but many filesystems can move a file without copying data. It may also be worthwhile implementing some of the non-essential methods, as the default implementations may not be optimal. For example, the method :meth:`fs.base.FS.move` is implemented as a file copy followed by a delete, but many filesystems can move a file without copying data.
If the filesystem you are implementing maps paths to the native filesystem, be sure to implement `getsyspath`. Doing so will improve performance, especialy when copying / moving files between FS objects. If the filesystem you are implementing maps paths to the native filesystem, be sure to implement :py:meth:`~fs.base.FS.getsyspath`. Doing so will improve performance, especially when copying / moving files between FS objects.
Essential Methods Essential Methods
----------------- -----------------
...@@ -28,7 +28,7 @@ The following methods are required for a minimal Filesystem interface: ...@@ -28,7 +28,7 @@ The following methods are required for a minimal Filesystem interface:
Non - Essential Methods Non - Essential Methods
----------------------- -----------------------
The following methods have default implementations in fs.base.FS and aren't required for a functional FS interface. They may be overriden if an alternative implementation can be supplied: The following methods have default implementations in :py:class:`fs.base.FS` and aren't required for a functional FS interface. They may be overriden if an alternative implementation can be supplied:
* :meth:`~fs.base.FS.copy` Copy a file to a new location * :meth:`~fs.base.FS.copy` Copy a file to a new location
* :meth:`~fs.base.FS.copydir` Recursively copy a directory to a new location * :meth:`~fs.base.FS.copydir` Recursively copy a directory to a new location
...@@ -53,7 +53,7 @@ The following methods have default implementations in fs.base.FS and aren't requ ...@@ -53,7 +53,7 @@ The following methods have default implementations in fs.base.FS and aren't requ
Utility Methods Utility Methods
--------------- ---------------
The following members have implementations in fs.base.FS and will probably never require a non-default implementation, although there is nothing to prevent a derived class from implementing these: The following members have implementations in :py:class:`fs.base.FS` and will probably never require a non-default implementation, although there is nothing to prevent a derived class from implementing these:
* :meth:`~fs.base.FS.createfile` Create a file with data * :meth:`~fs.base.FS.createfile` Create a file with data
* :meth:`~fs.base.FS.getcontents` Returns the contents of a file as a string * :meth:`~fs.base.FS.getcontents` Returns the contents of a file as a string
......
.. automodule:: fs.opener .. automodule:: fs.opener
:members: :members:
\ No newline at end of file
Opening Filesystems
===================
Generally, when you want to work with the files and directories of any of the supported filesytems,
you create an instance of the appropriate class. For example, the following opens the directory /foo/bar::
from fs.osfs import OSFS
my_fs = OSFS('/foo/bar')
This is fine if you know beforehand where the directory you want to work with is located, and on what medium.
However, there are occasions where the location of the files may change at runtime or should be specified in a config file or from the command line.
In these situations you can use an _opener_ which is a generic way of specifying a filesystem. For example, the following is equivalent to the code above::
from fs.opener import fsopen
my_fs = fsopen('/foo/bar')
The `fsopen` method takes a string that identifies the filesystem, but if called with a regular path, it will return an OSFS instance.
To open a different kind of filesystem, you specify it with a URI like syntax. The following code opens an ftp filesystem rather than a directory on your harddrive::
from fs.opener import fsopen
my_fs = fsopen('ftp://example.org/foo/bar')
For further information regarding filesystem openers see :doc:`opener`.
\ No newline at end of file
...@@ -5,14 +5,14 @@ fs.opener ...@@ -5,14 +5,14 @@ fs.opener
Open filesystems via a URI. Open filesystems via a URI.
There are occasions when you want to specify a filesytem from the command line or in a config file. There are occasions when you want to specify a filesytem from the command line or in a config file.
This module enables that functionality, and can return a FS object given a URI like syntax (http://commons.apache.org/vfs/filesystems.html). This module enables that functionality, and can return an FS object given a URI like syntax (http://commons.apache.org/vfs/filesystems.html).
The `OpenerRegistry` class maps the protocol (file, ftp etc.) on to an Opener object, which returns an appropriate filesystem object and path. The `OpenerRegistry` class maps the protocol (file, ftp etc.) on to an Opener object, which returns an appropriate filesystem object and path.
You can create a custom opener registry that opens just the filesystems you require, or use the opener registry defined here (also called `opener`) that can open any supported filesystem. You can create a custom opener registry that opens just the filesystems you require, or use the opener registry defined here (also called `opener`) that can open any supported filesystem.
The `parse` method of an `OpenerRegsitry` object returns a tuple of an FS object a path. Here's an example of how to use the default opener registry:: The `parse` method of an `OpenerRegsitry` object returns a tuple of an FS object a path. Here's an example of how to use the default opener registry::
>>> from fs.opener import opener >>> from fs.opener import opener
>>> opener.parse('ftp://ftp.mozilla.org') >>> opener.parse('ftp://ftp.mozilla.org/pub')
(<fs.ftpfs.FTPFS object at 0x96e66ec>, u'pub') (<fs.ftpfs.FTPFS object at 0x96e66ec>, u'pub')
You can use use the `opendir` method, which just returns an FS object. In the example above, `opendir` will return a FS object for the directory `pub`:: You can use use the `opendir` method, which just returns an FS object. In the example above, `opendir` will return a FS object for the directory `pub`::
...@@ -26,12 +26,11 @@ If you are just interested in a single file, use the `open` method of a registry ...@@ -26,12 +26,11 @@ If you are just interested in a single file, use the `open` method of a registry
<fs.ftpfs._FTPFile object at 0x973764c> <fs.ftpfs._FTPFile object at 0x973764c>
The `opendir` and `open` methods can also be imported from the top-level of this module for sake of convenience. The `opendir` and `open` methods can also be imported from the top-level of this module for sake of convenience.
To avoid shadowing the builtin `open` methd, they are named `fsopendir` and `fsopen`. Here's how you might import them:: To avoid shadowing the builtin `open` method, they are named `fsopendir` and `fsopen`. Here's how you might import them::
from fs.opener import fsopendir, fsopen from fs.opener import fsopendir, fsopen
""" """
__all__ = ['OpenerError', __all__ = ['OpenerError',
...@@ -55,10 +54,7 @@ __all__ = ['OpenerError', ...@@ -55,10 +54,7 @@ __all__ = ['OpenerError',
'DavOpener', 'DavOpener',
'HTTPOpener'] 'HTTPOpener']
import sys from fs.path import pathsplit, join, iswildcard, normpath
from fs.osfs import OSFS
from fs.path import pathsplit, basename, join, iswildcard, normpath
import os
import os.path import os.path
import re import re
from urlparse import urlparse from urlparse import urlparse
...@@ -104,7 +100,7 @@ def _parse_name(fs_name): ...@@ -104,7 +100,7 @@ def _parse_name(fs_name):
def _split_url_path(url): def _split_url_path(url):
if '://' not in url: if '://' not in url:
url = 'http://' + url url = 'http://' + url
scheme, netloc, path, params, query, fragment = urlparse(url) scheme, netloc, path, _params, _query, _fragment = urlparse(url)
url = '%s://%s' % (scheme, netloc) url = '%s://%s' % (scheme, netloc)
return url, path return url, path
...@@ -172,7 +168,7 @@ class OpenerRegistry(object): ...@@ -172,7 +168,7 @@ class OpenerRegistry(object):
:param fs_url: an FS url :param fs_url: an FS url
:param default_fs_name: the default FS to use if none is indicated (defaults is OSFS) :param default_fs_name: the default FS to use if none is indicated (defaults is OSFS)
:param writeable: if True, a writeable FS will be returned :param writeable: if True, a writeable FS will be returned
:oaram create_dir: if True, then the directory in the FS will be created :param create_dir: if True, then the directory in the FS will be created
""" """
...@@ -343,8 +339,6 @@ class ZipOpener(Opener): ...@@ -343,8 +339,6 @@ class ZipOpener(Opener):
@classmethod @classmethod
def get_fs(cls, registry, fs_name, fs_name_params, fs_path, writeable, create_dir): def get_fs(cls, registry, fs_name, fs_name_params, fs_path, writeable, create_dir):
append_zip = fs_name_params == 'add'
zip_fs, zip_path = registry.parse(fs_path) zip_fs, zip_path = registry.parse(fs_path)
if zip_path is None: if zip_path is None:
raise OpenerError('File required for zip opener') raise OpenerError('File required for zip opener')
...@@ -357,7 +351,7 @@ class ZipOpener(Opener): ...@@ -357,7 +351,7 @@ class ZipOpener(Opener):
open_mode = 'w+' open_mode = 'w+'
zip_file = zip_fs.open(zip_path, mode=open_mode) zip_file = zip_fs.open(zip_path, mode=open_mode)
username, password, fs_path = _parse_credentials(fs_path) _username, _password, fs_path = _parse_credentials(fs_path)
from fs.zipfs import ZipFS from fs.zipfs import ZipFS
if zip_file is None: if zip_file is None:
...@@ -384,11 +378,11 @@ rpc://www.example.org (opens an RPC server on www.example.org, default port 80)" ...@@ -384,11 +378,11 @@ rpc://www.example.org (opens an RPC server on www.example.org, default port 80)"
@classmethod @classmethod
def get_fs(cls, registry, fs_name, fs_name_params, fs_path, writeable, create_dir): def get_fs(cls, registry, fs_name, fs_name_params, fs_path, writeable, create_dir):
from fs.rpcfs import RPCFS from fs.rpcfs import RPCFS
username, password, fs_path = _parse_credentials(fs_path) _username, _password, fs_path = _parse_credentials(fs_path)
if '://' not in fs_path: if '://' not in fs_path:
fs_path = 'http://' + fs_path fs_path = 'http://' + fs_path
scheme, netloc, path, params, query, fragment = urlparse(fs_path) scheme, netloc, path, _params, _query, _fragment = urlparse(fs_path)
rpcfs = RPCFS('%s://%s' % (scheme, netloc)) rpcfs = RPCFS('%s://%s' % (scheme, netloc))
...@@ -411,10 +405,10 @@ examples: ...@@ -411,10 +405,10 @@ examples:
from fs.ftpfs import FTPFS from fs.ftpfs import FTPFS
username, password, fs_path = _parse_credentials(fs_path) username, password, fs_path = _parse_credentials(fs_path)
scheme, netloc, path, params, query, fragment = urlparse(fs_path) scheme, _netloc, _path, _params, _query, _fragment = urlparse(fs_path)
if not scheme: if not scheme:
fs_path = 'ftp://' + fs_path fs_path = 'ftp://' + fs_path
scheme, netloc, path, params, query, fragment = urlparse(fs_path) scheme, netloc, path, _params, _query, _fragment = urlparse(fs_path)
dirpath, resourcepath = pathsplit(path) dirpath, resourcepath = pathsplit(path)
url = netloc url = netloc
...@@ -519,7 +513,7 @@ example: ...@@ -519,7 +513,7 @@ example:
def get_fs(cls, registry, fs_name, fs_name_params, fs_path, writeable, create_dir): def get_fs(cls, registry, fs_name, fs_name_params, fs_path, writeable, create_dir):
from fs.wrapfs.debugfs import DebugFS from fs.wrapfs.debugfs import DebugFS
if fs_path: if fs_path:
fs, path = registry.parse(fs_path, writeable=writeable, create_dir=create_dir) fs, _path = registry.parse(fs_path, writeable=writeable, create_dir=create_dir)
return DebugFS(fs, verbose=False), None return DebugFS(fs, verbose=False), None
if fs_name_params == 'ram': if fs_name_params == 'ram':
from fs.memoryfs import MemoryFS from fs.memoryfs import MemoryFS
...@@ -590,8 +584,8 @@ class TahoeOpener(Opener): ...@@ -590,8 +584,8 @@ class TahoeOpener(Opener):
fs = TahoeFS(dircap, webapi=url) fs = TahoeFS(dircap, webapi=url)
if '/' in path: if '/' in path:
dirname, resourcename = pathsplit(path) dirname, _resourcename = pathsplit(path)
if createdir: if create_dir:
fs = fs.makeopendir(dirname) fs = fs.makeopendir(dirname)
else: else:
fs = fs.opendir(dirname) fs = fs.opendir(dirname)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment