Commit 1e032bdc by rfkelly0

small doc tweaks

parent 72df6519
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
* New FS implementations (under fs.contrib): * New FS implementations (under fs.contrib):
* BigFS: read contents of a BIG file (C&C game file format) * BigFS: read contents of a BIG file (C&C game file format)
* DAVFS: access remote files stored on a WebDAV server * DAVFS: access remote files stored on a WebDAV server
* TahoeFS: access files stored in a Tahoe-LAFS grid * TahoeLAFS: access files stored in a Tahoe-LAFS grid
* New fs.expose implementations: * New fs.expose implementations:
* dokan: mount an FS object as a drive using Dokan (win32-only) * dokan: mount an FS object as a drive using Dokan (win32-only)
* importhook: import modules from files in an FS object * importhook: import modules from files in an FS object
......
...@@ -12,7 +12,7 @@ An interface to WebDAV file servers. See :mod:`fs.contrib.davfs` ...@@ -12,7 +12,7 @@ An interface to WebDAV file servers. See :mod:`fs.contrib.davfs`
Tahoe LAFS Tahoe LAFS
---------- ----------
An interface to Tahoe Least-Authority File System. See :mod:`fs.contrib.tahoefs` An interface to Tahoe Least-Authority File System. See :mod:`fs.contrib.tahoelafs`
BIG (BIG Archive File Format) BIG (BIG Archive File Format)
......
...@@ -7,6 +7,6 @@ The ``fs.contrib`` module contains a number of filesystem implementations provid ...@@ -7,6 +7,6 @@ The ``fs.contrib`` module contains a number of filesystem implementations provid
:maxdepth: 3 :maxdepth: 3
davfs.rst davfs.rst
tahoefs.rst tahoelafs.rst
bigfs.rst bigfs.rst
.. automodule:: fs.contrib.tahoefs .. automodule:: fs.contrib.tahoelafs
:members: :members:
...@@ -37,10 +37,10 @@ but there is nothing preventing you from implementing them -- just be careful to ...@@ -37,10 +37,10 @@ but there is nothing preventing you from implementing them -- just be careful to
Filesystem Errors Filesystem Errors
----------------- -----------------
With the exception of the constuctor, FS methods should throw :class:`fs.errors.FSError` exceptions in preference to any specific exception classes, With the exception of the constuctor, FS methods should throw :class:`fs.errors.FSError` exceptions in preference to any implementation-specific exception classes,
so that generic exception handling can be written. so that generic exception handling can be written.
The constructor *may* throw a non-FSError exception, if no appropriate FSError exists. The constructor *may* throw a non-FSError exception, if no appropriate FSError exists.
The rational for this is that creating an FS interface may require specific knowledge, The rationale for this is that creating an FS interface may require specific knowledge,
but this shouldn't prevent it from working with more generic code. but this shouldn't prevent it from working with more generic code.
If specific exceptions need to be translated in to an equivalent FSError, If specific exceptions need to be translated in to an equivalent FSError,
......
...@@ -3,7 +3,7 @@ Introduction ...@@ -3,7 +3,7 @@ Introduction
PyFilesystem is a Python module that provides a common interface to any filesystem. PyFilesystem is a Python module that provides a common interface to any filesystem.
Think of PyFilesystem (FS) objects as the next logical step to Python's ``file`` class. Just as *file-like* objects abstract a single file, FS objects abstract the whole filesystem by providing a common interface to operations such as reading directories, getting file information, opening/copying/deleting files etc. Think of PyFilesystem ``FS`` objects as the next logical step to Python's ``file`` class. Just as *file-like* objects abstract a single file, FS objects abstract the whole filesystem by providing a common interface to operations such as reading directories, getting file information, opening/copying/deleting files etc.
Even if you only want to work with the local filesystem, PyFilesystem simplifies a number of common operations and reduces the chance of error. Even if you only want to work with the local filesystem, PyFilesystem simplifies a number of common operations and reduces the chance of error.
......
...@@ -2,13 +2,21 @@ ...@@ -2,13 +2,21 @@
fs.contrib.tahoelafs fs.contrib.tahoelafs
==================== ====================
Example (it will use publicly available, but slow-as-hell Tahoe-LAFS cloud):: This modules provides a PyFilesystem interface to the Tahoe Least Authority
File System. Tahoe-LAFS is a distributed, encrypted, fault-tolerant storage
system:
http://tahoe-lafs.org/
You will need access to a Tahoe-LAFS "web api" service.
Example (it will use publicly available (but slow) Tahoe-LAFS cloud)::
from fs.contrib.tahoelafs import TahoeLAFS, Connection from fs.contrib.tahoelafs import TahoeLAFS, Connection
dircap = TahoeLAFS.createdircap(webapi='http://pubgrid.tahoe-lafs.org') dircap = TahoeLAFS.createdircap(webapi='http://insecure.tahoe-lafs.org')
print "Your dircap (unique key to your storage directory) is", dircap print "Your dircap (unique key to your storage directory) is", dircap
print "Keep it safe!" print "Keep it safe!"
fs = TahoeLAFS(dircap, autorun=False, timeout=300, webapi='http://pubgrid.tahoe-lafs.org') fs = TahoeLAFS(dircap, autorun=False, webapi='http://insecure.tahoe-lafs.org')
f = fs.open("foo.txt", "a") f = fs.open("foo.txt", "a")
f.write('bar!') f.write('bar!')
f.close() f.close()
...@@ -296,7 +304,7 @@ class _TahoeLAFS(FS): ...@@ -296,7 +304,7 @@ class _TahoeLAFS(FS):
self.tahoeutil.mkdir(self.dircap, path) self.tahoeutil.mkdir(self.dircap, path)
def movedir(self, src, dst, overwrite=False): def movedir(self, src, dst, overwrite=False):
self.move(src, dst, overwrite) self.move(src, dst, overwrite=overwrite)
def move(self, src, dst, overwrite=False): def move(self, src, dst, overwrite=False):
self._log(INFO, "Moving file from %s to %s" % (src, dst)) self._log(INFO, "Moving file from %s to %s" % (src, dst))
......
...@@ -17,16 +17,19 @@ from fs.contrib.tahoelafs import TahoeLAFS, Connection ...@@ -17,16 +17,19 @@ from fs.contrib.tahoelafs import TahoeLAFS, Connection
logging.getLogger().setLevel(logging.DEBUG) logging.getLogger().setLevel(logging.DEBUG)
logging.getLogger('fs.tahoelafs').addHandler(logging.StreamHandler(sys.stdout)) logging.getLogger('fs.tahoelafs').addHandler(logging.StreamHandler(sys.stdout))
WEBAPI = 'http://pubgrid.tahoe-lafs.org' WEBAPI = 'http://insecure.tahoe-lafs.org'
class TestTahoeLAFS(unittest.TestCase,FSTestCases,ThreadingTestCases):
# The public grid is too slow for threading testcases, disabling for now...
class TestTahoeLAFS(unittest.TestCase,FSTestCases):#,ThreadingTestCases):
# Disabled by default because it takes a *really* long time. # Disabled by default because it takes a *really* long time.
#__test__ = False __test__ = False
def setUp(self): def setUp(self):
self.dircap = TahoeLAFS.createdircap(WEBAPI) self.dircap = TahoeLAFS.createdircap(WEBAPI)
self.fs = TahoeLAFS(self.dircap, timeout=0, webapi=WEBAPI) print TahoeLAFS.__mro__
self.fs = TahoeLAFS(self.dircap, cache_timeout=0, webapi=WEBAPI)
def tearDown(self): def tearDown(self):
self.fs.close() self.fs.close()
......
...@@ -201,7 +201,7 @@ _TIMEOUT_PROTECT_QUEUE = Queue.Queue() ...@@ -201,7 +201,7 @@ _TIMEOUT_PROTECT_QUEUE = Queue.Queue()
_TIMEOUT_PROTECT_WAIT_TIME = 4 * 60 _TIMEOUT_PROTECT_WAIT_TIME = 4 * 60
_TIMEOUT_PROTECT_RESET_TIME = 5 * 60 * 1000 _TIMEOUT_PROTECT_RESET_TIME = 5 * 60 * 1000
def start_timeout_protect_thread(): def _start_timeout_protect_thread():
"""Start the background thread used to protect dokan from timeouts. """Start the background thread used to protect dokan from timeouts.
This function starts the background thread that monitors calls into the This function starts the background thread that monitors calls into the
...@@ -235,7 +235,7 @@ def timeout_protect(func): ...@@ -235,7 +235,7 @@ def timeout_protect(func):
@wraps(func) @wraps(func)
def wrapper(self,*args): def wrapper(self,*args):
if _TIMEOUT_PROTECT_THREAD is None: if _TIMEOUT_PROTECT_THREAD is None:
start_timeout_protect_thread() _start_timeout_protect_thread()
info = args[-1] info = args[-1]
finished = [] finished = []
try: try:
......
...@@ -27,7 +27,7 @@ import stat as statinfo ...@@ -27,7 +27,7 @@ import stat as statinfo
from errno import EINVAL from errno import EINVAL
import fs.utils import fs.utils
from fs.base import threading from fs.base import threading, FS
from fs.wrapfs import WrapFS, wrap_fs_methods from fs.wrapfs import WrapFS, wrap_fs_methods
from fs.wrapfs.lazyfs import LazyFS from fs.wrapfs.lazyfs import LazyFS
from fs.path import * from fs.path import *
...@@ -424,7 +424,7 @@ class CachedInfo(object): ...@@ -424,7 +424,7 @@ class CachedInfo(object):
return cls(info,has_full_info=False) return cls(info,has_full_info=False)
class CacheFSMixin(WrapFS): class CacheFSMixin(FS):
"""Simple FS mixin to cache meta-data of a remote filesystems. """Simple FS mixin to cache meta-data of a remote filesystems.
This FS mixin implements a simplistic cache that can help speed up This FS mixin implements a simplistic cache that can help speed up
...@@ -473,11 +473,15 @@ class CacheFSMixin(WrapFS): ...@@ -473,11 +473,15 @@ class CacheFSMixin(WrapFS):
def __getstate__(self): def __getstate__(self):
state = super(CacheFSMixin,self).__getstate__() state = super(CacheFSMixin,self).__getstate__()
state.pop("_CacheFSMixin__cache",None)
state.pop("_CacheFSMixin__cache_size",None)
state.pop("_CacheFSMixin__cache_lock",None) state.pop("_CacheFSMixin__cache_lock",None)
return state return state
def __setstate__(self,state): def __setstate__(self,state):
super(CacheFSMixin,self).__setstate__(state) super(CacheFSMixin,self).__setstate__(state)
self.__cache = PathMap()
self.__cache_size = 0
self.__cache_lock = threading.RLock() self.__cache_lock = threading.RLock()
def __get_cached_info(self,path,default=_SENTINAL): def __get_cached_info(self,path,default=_SENTINAL):
......
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