Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pyfs
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
pyfs
Commits
fb95d7be
Commit
fb95d7be
authored
Jul 10, 2010
by
willmcgugan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added better zip exceptions, and added __all__ to core classes
parent
8a504419
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
117 additions
and
36 deletions
+117
-36
fs/base.py
+11
-7
fs/errors.py
+28
-5
fs/expose/fuse/__init__.py
+1
-0
fs/expose/sftp.py
+1
-3
fs/ftpfs.py
+3
-5
fs/memoryfs.py
+3
-4
fs/mountfs.py
+2
-0
fs/multifs.py
+1
-0
fs/osfs/__init__.py
+2
-0
fs/path.py
+1
-0
fs/remote.py
+1
-0
fs/rpcfs.py
+2
-0
fs/s3fs.py
+2
-0
fs/sftpfs.py
+4
-1
fs/tempfs.py
+1
-0
fs/tests/__init__.py
+2
-0
fs/tests/test_path.py
+8
-8
fs/tests/test_remote.py
+2
-0
fs/utils.py
+9
-0
fs/wrapfs/__init__.py
+2
-0
fs/wrapfs/hidedotfilesfs.py
+1
-0
fs/wrapfs/lazyfs.py
+1
-0
fs/wrapfs/limitsizefs.py
+1
-0
fs/zipfs.py
+28
-3
No files found.
fs/base.py
View file @
fb95d7be
...
@@ -10,6 +10,13 @@ start by sublcassing the base FS class.
...
@@ -10,6 +10,13 @@ start by sublcassing the base FS class.
"""
"""
__all__
=
[
'DummyLock'
,
'silence_fserrors'
,
'NullFile'
,
'synchronize'
,
'FS'
,
'flags_to_mode'
]
import
os
,
os
.
path
import
os
,
os
.
path
import
sys
import
sys
import
shutil
import
shutil
...
@@ -23,9 +30,10 @@ except ImportError:
...
@@ -23,9 +30,10 @@ except ImportError:
from
fs.path
import
*
from
fs.path
import
*
from
fs.errors
import
*
from
fs.errors
import
*
from
fs.functools
import
wraps
class
DummyLock
:
class
DummyLock
(
object
)
:
"""A dummy lock object that doesn't do anything.
"""A dummy lock object that doesn't do anything.
This is used as a placeholder when locking is disabled. We can't
This is used as a placeholder when locking is disabled. We can't
...
@@ -102,11 +110,6 @@ class NullFile(object):
...
@@ -102,11 +110,6 @@ class NullFile(object):
def
writelines
(
self
,
*
args
,
**
kwargs
):
def
writelines
(
self
,
*
args
,
**
kwargs
):
pass
pass
try
:
from
functools
import
wraps
except
ImportError
:
wraps
=
lambda
f
:
lambda
f
:
f
def
synchronize
(
func
):
def
synchronize
(
func
):
"""Decorator to synchronize a method on self._lock."""
"""Decorator to synchronize a method on self._lock."""
...
@@ -119,6 +122,7 @@ def synchronize(func):
...
@@ -119,6 +122,7 @@ def synchronize(func):
self
.
_lock
.
release
()
self
.
_lock
.
release
()
return
acquire_lock
return
acquire_lock
class
FS
(
object
):
class
FS
(
object
):
"""The base class for Filesystem abstraction objects.
"""The base class for Filesystem abstraction objects.
...
@@ -489,7 +493,7 @@ class FS(object):
...
@@ -489,7 +493,7 @@ class FS(object):
f
=
None
f
=
None
try
:
try
:
f
=
self
.
open
(
path
,
'wb'
)
f
=
self
.
open
(
path
,
'wb'
)
if
hasattr
(
data
,
"read"
):
if
hasattr
(
data
,
"read"
):
chunk
=
data
.
read
(
1024
*
512
)
chunk
=
data
.
read
(
1024
*
512
)
while
chunk
:
while
chunk
:
f
.
write
(
chunk
)
f
.
write
(
chunk
)
...
...
fs/errors.py
View file @
fb95d7be
...
@@ -5,15 +5,33 @@ All Exception classes are derived from `FSError` which can be used as a catch-al
...
@@ -5,15 +5,33 @@ All Exception classes are derived from `FSError` which can be used as a catch-al
"""
"""
__all__
=
[
'FSError'
,
'CreateFailedError'
,
'PathError'
,
'OperationFailedError'
,
'UnsupportedError'
,
'RemoteConnectionError'
,
'StorageSpaceError'
,
'PermissionDeniedError'
,
'FSClosedError'
,
'OperationTimeoutError'
,
'ResourceError'
,
'NoSysPathError'
,
'ResourceNotFoundError'
,
'ResourceInvalidError'
,
'DestinationExistsError'
,
'DirectoryNotEmptyError'
,
'ParentDirectoryMissingError'
,
'ResourceLockedError'
,
'convert_fs_errors'
,
'convert_os_errors'
]
import
sys
import
sys
import
errno
import
errno
from
fs.path
import
*
from
fs.path
import
*
from
fs.functools
import
wraps
try
:
from
functools
import
wraps
except
ImportError
:
wraps
=
lambda
f
:
lambda
f
:
f
class
FSError
(
Exception
):
class
FSError
(
Exception
):
...
@@ -41,6 +59,11 @@ class FSError(Exception):
...
@@ -41,6 +59,11 @@ class FSError(Exception):
return
self
.
__dict__
.
copy
()
return
self
.
__dict__
.
copy
()
class
CreateFailedError
(
FSError
):
"""An exception thrown when a FS could not be created"""
default_message
=
"Unable to create filesystem"
class
PathError
(
FSError
):
class
PathError
(
FSError
):
"""Exception for errors to do with a path string.
"""Exception for errors to do with a path string.
"""
"""
...
...
fs/expose/fuse/__init__.py
View file @
fb95d7be
...
@@ -58,6 +58,7 @@ import pickle
...
@@ -58,6 +58,7 @@ import pickle
from
fs.base
import
flags_to_mode
,
threading
from
fs.base
import
flags_to_mode
,
threading
from
fs.errors
import
*
from
fs.errors
import
*
from
fs.path
import
*
from
fs.path
import
*
from
fs.functools
import
wraps
try
:
try
:
import
fuse_ctypes
as
fuse
import
fuse_ctypes
as
fuse
...
...
fs/expose/sftp.py
View file @
fb95d7be
...
@@ -36,9 +36,7 @@ import paramiko
...
@@ -36,9 +36,7 @@ import paramiko
from
fs.base
import
flags_to_mode
from
fs.base
import
flags_to_mode
from
fs.path
import
*
from
fs.path
import
*
from
fs.errors
import
*
from
fs.errors
import
*
from
fs.functools
import
wraps
from
fs.errors
import
wraps
# Default host key used by BaseSFTPServer
# Default host key used by BaseSFTPServer
...
...
fs/ftpfs.py
View file @
fb95d7be
...
@@ -10,7 +10,8 @@ __all__ = ['FTPFS']
...
@@ -10,7 +10,8 @@ __all__ = ['FTPFS']
import
fs
import
fs
from
fs.base
import
*
from
fs.base
import
*
from
fs.path
import
pathsplit
from
fs.errors
import
*
from
fs.path
import
pathsplit
,
abspath
,
dirname
,
recursepath
,
normpath
from
ftplib
import
FTP
,
error_perm
,
error_temp
,
error_proto
,
error_reply
from
ftplib
import
FTP
,
error_perm
,
error_temp
,
error_proto
,
error_reply
...
@@ -26,10 +27,7 @@ from time import sleep
...
@@ -26,10 +27,7 @@ from time import sleep
import
datetime
import
datetime
import
re
import
re
from
socket
import
error
as
socket_error
from
socket
import
error
as
socket_error
try
:
from
fs.functools
import
wraps
from
functools
import
wraps
except
ImportError
:
wraps
=
lambda
f
:
lambda
f
:
f
try
:
try
:
from
cStringIO
import
StringIO
from
cStringIO
import
StringIO
...
...
fs/memoryfs.py
View file @
fb95d7be
...
@@ -11,8 +11,9 @@ If you open a file from a `memoryfs` you will get back a StringIO object from th
...
@@ -11,8 +11,9 @@ If you open a file from a `memoryfs` you will get back a StringIO object from th
"""
"""
import
datetime
import
datetime
from
fs.path
import
iteratepath
from
fs.path
import
iteratepath
,
pathsplit
,
normpath
from
fs.base
import
*
from
fs.base
import
*
from
fs.errors
import
*
from
fs
import
_thread_synchronize_default
from
fs
import
_thread_synchronize_default
try
:
try
:
...
@@ -131,7 +132,6 @@ class MemoryFile(object):
...
@@ -131,7 +132,6 @@ class MemoryFile(object):
return
False
return
False
class
DirEntry
(
object
):
class
DirEntry
(
object
):
def
__init__
(
self
,
type
,
name
,
contents
=
None
):
def
__init__
(
self
,
type
,
name
,
contents
=
None
):
...
@@ -507,8 +507,7 @@ class MemoryFS(FS):
...
@@ -507,8 +507,7 @@ class MemoryFS(FS):
info
[
'size'
]
=
len
(
dir_entry
.
data
or
''
)
info
[
'size'
]
=
len
(
dir_entry
.
data
or
''
)
info
[
'st_mode'
]
=
0666
info
[
'st_mode'
]
=
0666
return
info
return
info
@synchronize
@synchronize
def
copydir
(
self
,
src
,
dst
,
overwrite
=
False
,
ignore_errors
=
False
,
chunk_size
=
16384
):
def
copydir
(
self
,
src
,
dst
,
overwrite
=
False
,
ignore_errors
=
False
,
chunk_size
=
16384
):
...
...
fs/mountfs.py
View file @
fb95d7be
...
@@ -43,6 +43,8 @@ Now both filesystems can be accessed with the same path structure::
...
@@ -43,6 +43,8 @@ Now both filesystems can be accessed with the same path structure::
"""
"""
from
fs.base
import
*
from
fs.base
import
*
from
fs.errors
import
*
from
fs.path
import
*
from
fs.objecttree
import
ObjectTree
from
fs.objecttree
import
ObjectTree
from
fs
import
_thread_synchronize_default
from
fs
import
_thread_synchronize_default
...
...
fs/multifs.py
View file @
fb95d7be
...
@@ -54,6 +54,7 @@ directories::
...
@@ -54,6 +54,7 @@ directories::
from
fs.base
import
FS
,
FSError
,
synchronize
from
fs.base
import
FS
,
FSError
,
synchronize
from
fs.path
import
*
from
fs.path
import
*
from
fs.errors
import
*
from
fs
import
_thread_synchronize_default
from
fs
import
_thread_synchronize_default
from
fs.errors
import
ResourceNotFoundError
from
fs.errors
import
ResourceNotFoundError
...
...
fs/osfs/__init__.py
View file @
fb95d7be
...
@@ -16,8 +16,10 @@ For example, to print all the files and directories in the OS root::
...
@@ -16,8 +16,10 @@ For example, to print all the files and directories in the OS root::
import
os
import
os
import
sys
import
sys
import
errno
import
errno
import
datetime
from
fs.base
import
*
from
fs.base
import
*
from
fs.errors
import
*
from
fs.path
import
*
from
fs.path
import
*
from
fs
import
_thread_synchronize_default
from
fs
import
_thread_synchronize_default
...
...
fs/path.py
View file @
fb95d7be
...
@@ -269,6 +269,7 @@ def forcedir(path):
...
@@ -269,6 +269,7 @@ def forcedir(path):
return
path
+
'/'
return
path
+
'/'
return
path
return
path
def
frombase
(
path1
,
path2
):
def
frombase
(
path1
,
path2
):
if
not
isprefix
(
path1
,
path2
):
if
not
isprefix
(
path1
,
path2
):
raise
ValueError
(
"path1 must be a prefix of path2"
)
raise
ValueError
(
"path1 must be a prefix of path2"
)
...
...
fs/remote.py
View file @
fb95d7be
...
@@ -29,6 +29,7 @@ from fs.wrapfs import WrapFS, wrap_fs_methods
...
@@ -29,6 +29,7 @@ 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
*
from
fs.errors
import
*
from
fs.errors
import
*
from
fs.functools
import
wraps
try
:
try
:
from
tempfile
import
SpooledTemporaryFile
from
tempfile
import
SpooledTemporaryFile
...
...
fs/rpcfs.py
View file @
fb95d7be
...
@@ -11,6 +11,8 @@ class from the :mod:`fs.expose.xmlrpc` module.
...
@@ -11,6 +11,8 @@ class from the :mod:`fs.expose.xmlrpc` module.
import
xmlrpclib
import
xmlrpclib
from
fs.base
import
*
from
fs.base
import
*
from
fs.errors
import
*
from
fs.path
import
*
from
StringIO
import
StringIO
from
StringIO
import
StringIO
if
hasattr
(
StringIO
,
"__exit__"
):
if
hasattr
(
StringIO
,
"__exit__"
):
...
...
fs/s3fs.py
View file @
fb95d7be
...
@@ -19,6 +19,8 @@ from boto.s3.prefix import Prefix
...
@@ -19,6 +19,8 @@ from boto.s3.prefix import Prefix
from
boto.exception
import
S3ResponseError
from
boto.exception
import
S3ResponseError
from
fs.base
import
*
from
fs.base
import
*
from
fs.path
import
*
from
fs.errors
import
*
from
fs.remote
import
*
from
fs.remote
import
*
...
...
fs/sftpfs.py
View file @
fb95d7be
...
@@ -8,13 +8,16 @@ Filesystem accessing an SFTP server (via paramiko)
...
@@ -8,13 +8,16 @@ Filesystem accessing an SFTP server (via paramiko)
import
datetime
import
datetime
import
stat
as
statinfo
import
stat
as
statinfo
import
threading
import
paramiko
import
paramiko
from
fs.base
import
*
from
fs.base
import
*
from
fs.path
import
*
from
fs.errors
import
*
# SFTPClient appears to not be thread-safe, so we use an instance per thread
# SFTPClient appears to not be thread-safe, so we use an instance per thread
if
hasattr
(
threading
,
"local"
):
if
hasattr
(
threading
,
"local"
):
thread_local
=
threading
.
local
thread_local
=
threading
.
local
else
:
else
:
class
thread_local
(
object
):
class
thread_local
(
object
):
...
...
fs/tempfs.py
View file @
fb95d7be
...
@@ -12,6 +12,7 @@ import tempfile
...
@@ -12,6 +12,7 @@ import tempfile
from
fs.osfs
import
OSFS
from
fs.osfs
import
OSFS
from
fs.errors
import
*
from
fs.errors
import
*
from
fs
import
_thread_synchronize_default
from
fs
import
_thread_synchronize_default
class
TempFS
(
OSFS
):
class
TempFS
(
OSFS
):
...
...
fs/tests/__init__.py
View file @
fb95d7be
...
@@ -12,6 +12,8 @@ import logging
...
@@ -12,6 +12,8 @@ import logging
logging
.
basicConfig
(
level
=
logging
.
ERROR
,
stream
=
sys
.
stdout
)
logging
.
basicConfig
(
level
=
logging
.
ERROR
,
stream
=
sys
.
stdout
)
from
fs.base
import
*
from
fs.base
import
*
from
fs.path
import
*
from
fs.errors
import
*
import
datetime
import
datetime
import
unittest
import
unittest
...
...
fs/tests/test_path.py
View file @
fb95d7be
...
@@ -46,12 +46,12 @@ class TestPathFunctions(unittest.TestCase):
...
@@ -46,12 +46,12 @@ class TestPathFunctions(unittest.TestCase):
for
testpaths
in
tests
:
for
testpaths
in
tests
:
paths
=
testpaths
[:
-
1
]
paths
=
testpaths
[:
-
1
]
result
=
testpaths
[
-
1
]
result
=
testpaths
[
-
1
]
self
.
assertEqual
(
fs
.
pathjoin
(
*
paths
),
result
)
self
.
assertEqual
(
pathjoin
(
*
paths
),
result
)
self
.
assertRaises
(
ValueError
,
fs
.
pathjoin
,
"../"
)
self
.
assertRaises
(
ValueError
,
pathjoin
,
"../"
)
self
.
assertRaises
(
ValueError
,
fs
.
pathjoin
,
"./../"
)
self
.
assertRaises
(
ValueError
,
pathjoin
,
"./../"
)
self
.
assertRaises
(
ValueError
,
fs
.
pathjoin
,
"a/b"
,
"../../.."
)
self
.
assertRaises
(
ValueError
,
pathjoin
,
"a/b"
,
"../../.."
)
self
.
assertRaises
(
ValueError
,
fs
.
pathjoin
,
"a/b/../../../d"
)
self
.
assertRaises
(
ValueError
,
pathjoin
,
"a/b/../../../d"
)
def
test_relpath
(
self
):
def
test_relpath
(
self
):
tests
=
[
(
"/a/b"
,
"a/b"
),
tests
=
[
(
"/a/b"
,
"a/b"
),
...
@@ -59,7 +59,7 @@ class TestPathFunctions(unittest.TestCase):
...
@@ -59,7 +59,7 @@ class TestPathFunctions(unittest.TestCase):
(
"/"
,
""
)
]
(
"/"
,
""
)
]
for
path
,
result
in
tests
:
for
path
,
result
in
tests
:
self
.
assertEqual
(
fs
.
relpath
(
path
),
result
)
self
.
assertEqual
(
relpath
(
path
),
result
)
def
test_abspath
(
self
):
def
test_abspath
(
self
):
tests
=
[
(
"/a/b"
,
"/a/b"
),
tests
=
[
(
"/a/b"
,
"/a/b"
),
...
@@ -67,7 +67,7 @@ class TestPathFunctions(unittest.TestCase):
...
@@ -67,7 +67,7 @@ class TestPathFunctions(unittest.TestCase):
(
"/"
,
"/"
)
]
(
"/"
,
"/"
)
]
for
path
,
result
in
tests
:
for
path
,
result
in
tests
:
self
.
assertEqual
(
fs
.
abspath
(
path
),
result
)
self
.
assertEqual
(
abspath
(
path
),
result
)
def
test_iteratepath
(
self
):
def
test_iteratepath
(
self
):
tests
=
[
(
"a/b"
,
[
"a"
,
"b"
]),
tests
=
[
(
"a/b"
,
[
"a"
,
"b"
]),
...
@@ -92,7 +92,7 @@ class TestPathFunctions(unittest.TestCase):
...
@@ -92,7 +92,7 @@ class TestPathFunctions(unittest.TestCase):
(
"foo/bar/baz"
,
(
"foo/bar"
,
"baz"
)),
(
"foo/bar/baz"
,
(
"foo/bar"
,
"baz"
)),
]
]
for
path
,
result
in
tests
:
for
path
,
result
in
tests
:
self
.
assertEqual
(
fs
.
pathsplit
(
path
),
result
)
self
.
assertEqual
(
pathsplit
(
path
),
result
)
def
test_recursepath
(
self
):
def
test_recursepath
(
self
):
self
.
assertEquals
(
recursepath
(
"/"
),[
"/"
])
self
.
assertEquals
(
recursepath
(
"/"
),[
"/"
])
...
...
fs/tests/test_remote.py
View file @
fb95d7be
...
@@ -10,12 +10,14 @@ import unittest
...
@@ -10,12 +10,14 @@ import unittest
import
threading
import
threading
import
random
import
random
import
time
import
time
import
sys
from
fs.remote
import
*
from
fs.remote
import
*
from
fs.wrapfs
import
WrapFS
,
wrap_fs_methods
from
fs.wrapfs
import
WrapFS
,
wrap_fs_methods
from
fs.tempfs
import
TempFS
from
fs.tempfs
import
TempFS
from
fs.path
import
*
from
fs.path
import
*
from
fs.functools
import
wraps
class
TestCacheFS
(
unittest
.
TestCase
,
FSTestCases
,
ThreadingTestCases
):
class
TestCacheFS
(
unittest
.
TestCase
,
FSTestCases
,
ThreadingTestCases
):
...
...
fs/utils.py
View file @
fb95d7be
...
@@ -4,6 +4,14 @@ The `utils` module provides a number of utility functions that don't belong in t
...
@@ -4,6 +4,14 @@ The `utils` module provides a number of utility functions that don't belong in t
"""
"""
__all__
=
[
'copyfile'
,
'movefile'
,
'movedir'
,
'copydir'
,
'countbytes'
,
'find_duplicates'
,
'print_fs'
]
import
shutil
import
shutil
import
os
import
os
import
sys
import
sys
...
@@ -12,6 +20,7 @@ from fs.path import pathjoin, pathsplit
...
@@ -12,6 +20,7 @@ from fs.path import pathjoin, pathsplit
from
fs.errors
import
DestinationExistsError
from
fs.errors
import
DestinationExistsError
def
copyfile
(
src_fs
,
src_path
,
dst_fs
,
dst_path
,
overwrite
=
True
,
chunk_size
=
16384
):
def
copyfile
(
src_fs
,
src_path
,
dst_fs
,
dst_path
,
overwrite
=
True
,
chunk_size
=
16384
):
"""Copy a file from one filesystem to another. Will use system copyfile, if both files have a syspath.
"""Copy a file from one filesystem to another. Will use system copyfile, if both files have a syspath.
Otherwise file will be copied a chunk at a time.
Otherwise file will be copied a chunk at a time.
...
...
fs/wrapfs/__init__.py
View file @
fb95d7be
...
@@ -20,6 +20,8 @@ from fnmatch import fnmatch
...
@@ -20,6 +20,8 @@ from fnmatch import fnmatch
from
fs.base
import
FS
,
threading
,
synchronize
from
fs.base
import
FS
,
threading
,
synchronize
from
fs.errors
import
*
from
fs.errors
import
*
from
fs.functools
import
wraps
def
rewrite_errors
(
func
):
def
rewrite_errors
(
func
):
"""Re-write paths in errors raised by wrapped FS objects."""
"""Re-write paths in errors raised by wrapped FS objects."""
...
...
fs/wrapfs/hidedotfilesfs.py
View file @
fb95d7be
...
@@ -7,6 +7,7 @@ An FS wrapper class for hiding dot-files in directory listings.
...
@@ -7,6 +7,7 @@ An FS wrapper class for hiding dot-files in directory listings.
"""
"""
from
fs.wrapfs
import
WrapFS
from
fs.wrapfs
import
WrapFS
from
fs.path
import
*
class
HideDotFilesFS
(
WrapFS
):
class
HideDotFilesFS
(
WrapFS
):
...
...
fs/wrapfs/lazyfs.py
View file @
fb95d7be
...
@@ -16,6 +16,7 @@ except ImportError:
...
@@ -16,6 +16,7 @@ except ImportError:
from
fs.base
import
FS
from
fs.base
import
FS
from
fs.wrapfs
import
WrapFS
from
fs.wrapfs
import
WrapFS
from
fs.path
import
*
class
LazyFS
(
WrapFS
):
class
LazyFS
(
WrapFS
):
...
...
fs/wrapfs/limitsizefs.py
View file @
fb95d7be
...
@@ -11,6 +11,7 @@ total size of files stored in the wrapped FS.
...
@@ -11,6 +11,7 @@ total size of files stored in the wrapped FS.
# for Python2.5 compatibility
# for Python2.5 compatibility
from
__future__
import
with_statement
from
__future__
import
with_statement
from
fs.errors
import
*
from
fs.errors
import
*
from
fs.path
import
*
from
fs.base
import
FS
,
threading
,
synchronize
from
fs.base
import
FS
,
threading
,
synchronize
from
fs.wrapfs
import
WrapFS
from
fs.wrapfs
import
WrapFS
...
...
fs/zipfs.py
View file @
fb95d7be
...
@@ -7,8 +7,10 @@ A FS object that represents the contents of a Zip file
...
@@ -7,8 +7,10 @@ A FS object that represents the contents of a Zip file
"""
"""
from
fs.base
import
*
from
fs.base
import
*
from
fs.path
import
*
from
fs.errors
import
*
from
zipfile
import
ZipFile
,
ZIP_DEFLATED
,
ZIP_STORED
from
zipfile
import
ZipFile
,
ZIP_DEFLATED
,
ZIP_STORED
,
BadZipfile
,
LargeZipFile
from
memoryfs
import
MemoryFS
from
memoryfs
import
MemoryFS
try
:
try
:
...
@@ -18,6 +20,17 @@ except ImportError:
...
@@ -18,6 +20,17 @@ except ImportError:
import
tempfs
import
tempfs
class
ZipOpenError
(
CreateFailedError
):
"""Thrown when the zip file could not be opened"""
pass
class
ZipMissingError
(
CreateFailedError
):
"""Thrown when the requested zip file does not exist"""
pass
class
_TempWriteFile
(
object
):
class
_TempWriteFile
(
object
):
"""Proxies a file object and calls a callback when the file is closed."""
"""Proxies a file object and calls a callback when the file is closed."""
...
@@ -38,6 +51,7 @@ class _TempWriteFile(object):
...
@@ -38,6 +51,7 @@ class _TempWriteFile(object):
self
.
_file
.
close
()
self
.
_file
.
close
()
self
.
close_callback
(
self
.
filename
)
self
.
close_callback
(
self
.
filename
)
class
_ExceptionProxy
(
object
):
class
_ExceptionProxy
(
object
):
"""A placeholder for an object that may no longer be used."""
"""A placeholder for an object that may no longer be used."""
...
@@ -51,6 +65,7 @@ class _ExceptionProxy(object):
...
@@ -51,6 +65,7 @@ class _ExceptionProxy(object):
def
__nonzero__
(
self
):
def
__nonzero__
(
self
):
return
False
return
False
class
ZipFS
(
FS
):
class
ZipFS
(
FS
):
"""A FileSystem that represents a zip file."""
"""A FileSystem that represents a zip file."""
...
@@ -64,6 +79,8 @@ class ZipFS(FS):
...
@@ -64,6 +79,8 @@ class ZipFS(FS):
:param allow_zip_64: -- Set to True to use zip files greater than 2 GB, default is False
:param allow_zip_64: -- Set to True to use zip files greater than 2 GB, default is False
:param encoding: -- The encoding to use for unicode filenames
:param encoding: -- The encoding to use for unicode filenames
:param thread_synchronize: -- Set to True (default) to enable thread-safety
:param thread_synchronize: -- Set to True (default) to enable thread-safety
:raises ZipOpenError: Thrown when the zip file could not be opened
:raises ZipMissingError: Thrown when the zip file does not exist (derived from ZipOpenError)
"""
"""
super
(
ZipFS
,
self
)
.
__init__
(
thread_synchronize
=
thread_synchronize
)
super
(
ZipFS
,
self
)
.
__init__
(
thread_synchronize
=
thread_synchronize
)
...
@@ -81,8 +98,16 @@ class ZipFS(FS):
...
@@ -81,8 +98,16 @@ class ZipFS(FS):
self
.
encoding
=
encoding
self
.
encoding
=
encoding
try
:
try
:
self
.
zf
=
ZipFile
(
zip_file
,
mode
,
compression_type
,
allow_zip_64
)
self
.
zf
=
ZipFile
(
zip_file
,
mode
,
compression_type
,
allow_zip_64
)
except
IOError
:
except
BadZipfile
,
bzf
:
raise
ResourceNotFoundError
(
str
(
zip_file
),
msg
=
"Zip file does not exist:
%(path)
s"
)
raise
ZipOpenError
(
"Not a zip file or corrupt (
%
s)"
%
str
(
zip_file
),
details
=
bzf
)
except
IOError
,
ioe
:
if
str
(
ioe
)
.
startswith
(
'[Errno 22] Invalid argument'
):
raise
ZipOpenError
(
"Not a zip file or corrupt (
%
s)"
%
str
(
zip_file
),
details
=
bzf
)
raise
ZipMissingError
(
"Zip file not found (
%
s)"
%
str
(
zip_file
),
details
=
ioe
)
self
.
zip_path
=
str
(
zip_file
)
self
.
zip_path
=
str
(
zip_file
)
self
.
temp_fs
=
None
self
.
temp_fs
=
None
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment