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
56227fb8
Commit
56227fb8
authored
Feb 10, 2013
by
willmcgugan@gmail.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix for xmlrpc
parent
2c113c7f
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
184 additions
and
168 deletions
+184
-168
fs/expose/xmlrpc.py
+12
-8
fs/mountfs.py
+19
-19
fs/rpcfs.py
+41
-37
fs/tests/test_archivefs.py
+9
-1
fs/tests/test_expose.py
+3
-103
fs/tests/test_rpcfs.py
+100
-0
No files found.
fs/expose/xmlrpc.py
View file @
56227fb8
...
@@ -41,23 +41,27 @@ class RPCFSInterface(object):
...
@@ -41,23 +41,27 @@ class RPCFSInterface(object):
is base64-encoded UTF-8.
is base64-encoded UTF-8.
"""
"""
if
PY3
:
if
PY3
:
return
path
return
path
return
path
.
encode
(
"utf8"
)
.
encode
(
"base64"
)
return
path
.
encode
(
"utf8"
)
.
encode
(
"base64"
)
def
decode_path
(
self
,
path
):
def
decode_path
(
self
,
path
):
"""Decode paths arriving over the wire."""
"""Decode paths arriving over the wire."""
if
PY3
:
if
PY3
:
return
path
return
path
return
path
.
decode
(
"base64"
)
.
decode
(
"utf8"
)
return
path
.
decode
(
"base64"
)
.
decode
(
"utf8"
)
def
getmeta
(
self
,
meta_name
):
def
getmeta
(
self
,
meta_name
):
meta
=
self
.
fs
.
getmeta
(
meta_name
)
meta
=
self
.
fs
.
getmeta
(
meta_name
)
if
isinstance
(
meta
,
basestring
):
meta
=
meta
.
decode
(
'base64'
)
return
meta
return
meta
def
getmeta_default
(
self
,
meta_name
,
default
):
def
getmeta_default
(
self
,
meta_name
,
default
):
meta
=
self
.
fs
.
getmeta
(
meta_name
,
default
)
meta
=
self
.
fs
.
getmeta
(
meta_name
,
default
)
if
isinstance
(
meta
,
basestring
):
meta
=
meta
.
decode
(
'base64'
)
return
meta
return
meta
def
hasmeta
(
self
,
meta_name
):
def
hasmeta
(
self
,
meta_name
):
return
self
.
fs
.
hasmeta
(
meta_name
)
return
self
.
fs
.
hasmeta
(
meta_name
)
...
@@ -98,7 +102,7 @@ class RPCFSInterface(object):
...
@@ -98,7 +102,7 @@ class RPCFSInterface(object):
def
removedir
(
self
,
path
,
recursive
=
False
,
force
=
False
):
def
removedir
(
self
,
path
,
recursive
=
False
,
force
=
False
):
path
=
self
.
decode_path
(
path
)
path
=
self
.
decode_path
(
path
)
return
self
.
fs
.
removedir
(
path
,
recursive
,
force
)
return
self
.
fs
.
removedir
(
path
,
recursive
,
force
)
def
rename
(
self
,
src
,
dst
):
def
rename
(
self
,
src
,
dst
):
src
=
self
.
decode_path
(
src
)
src
=
self
.
decode_path
(
src
)
dst
=
self
.
decode_path
(
dst
)
dst
=
self
.
decode_path
(
dst
)
...
@@ -109,12 +113,12 @@ class RPCFSInterface(object):
...
@@ -109,12 +113,12 @@ class RPCFSInterface(object):
if
isinstance
(
accessed_time
,
xmlrpclib
.
DateTime
):
if
isinstance
(
accessed_time
,
xmlrpclib
.
DateTime
):
accessed_time
=
datetime
.
strptime
(
accessed_time
.
value
,
"
%
Y
%
m
%
dT
%
H:
%
M:
%
S"
)
accessed_time
=
datetime
.
strptime
(
accessed_time
.
value
,
"
%
Y
%
m
%
dT
%
H:
%
M:
%
S"
)
if
isinstance
(
modified_time
,
xmlrpclib
.
DateTime
):
if
isinstance
(
modified_time
,
xmlrpclib
.
DateTime
):
modified_time
=
datetime
.
strptime
(
modified_time
.
value
,
"
%
Y
%
m
%
dT
%
H:
%
M:
%
S"
)
modified_time
=
datetime
.
strptime
(
modified_time
.
value
,
"
%
Y
%
m
%
dT
%
H:
%
M:
%
S"
)
return
self
.
fs
.
settimes
(
path
,
accessed_time
,
modified_time
)
return
self
.
fs
.
settimes
(
path
,
accessed_time
,
modified_time
)
def
getinfo
(
self
,
path
):
def
getinfo
(
self
,
path
):
path
=
self
.
decode_path
(
path
)
path
=
self
.
decode_path
(
path
)
info
=
self
.
fs
.
getinfo
(
path
)
info
=
self
.
fs
.
getinfo
(
path
)
return
info
return
info
def
desc
(
self
,
path
):
def
desc
(
self
,
path
):
...
...
fs/mountfs.py
View file @
56227fb8
...
@@ -8,12 +8,12 @@ For example, lets say we have two filesystems containing config files and resour
...
@@ -8,12 +8,12 @@ For example, lets say we have two filesystems containing config files and resour
[config_fs]
[config_fs]
|-- config.cfg
|-- config.cfg
`-- defaults.cfg
`-- defaults.cfg
[resources_fs]
[resources_fs]
|-- images
|-- images
| |-- logo.jpg
| |-- logo.jpg
| `-- photo.jpg
| `-- photo.jpg
`-- data.dat
`-- data.dat
We can combine these filesystems in to a single filesystem with the following code::
We can combine these filesystems in to a single filesystem with the following code::
...
@@ -31,7 +31,7 @@ This will create a single filesystem where paths under `config` map to `config_f
...
@@ -31,7 +31,7 @@ This will create a single filesystem where paths under `config` map to `config_f
| `-- defaults.cfg
| `-- defaults.cfg
`-- resources
`-- resources
|-- images
|-- images
| |-- logo.jpg
| |-- logo.jpg
| `-- photo.jpg
| `-- photo.jpg
`-- data.dat
`-- data.dat
...
@@ -39,7 +39,7 @@ Now both filesystems can be accessed with the same path structure::
...
@@ -39,7 +39,7 @@ Now both filesystems can be accessed with the same path structure::
print combined_fs.getcontents('/config/defaults.cfg')
print combined_fs.getcontents('/config/defaults.cfg')
read_jpg(combined_fs.open('/resources/images/logo.jpg')
read_jpg(combined_fs.open('/resources/images/logo.jpg')
"""
"""
from
fs.base
import
*
from
fs.base
import
*
...
@@ -51,14 +51,14 @@ from fs import _thread_synchronize_default
...
@@ -51,14 +51,14 @@ from fs import _thread_synchronize_default
class
DirMount
(
object
):
class
DirMount
(
object
):
def
__init__
(
self
,
path
,
fs
):
def
__init__
(
self
,
path
,
fs
):
self
.
path
=
path
self
.
path
=
path
self
.
fs
=
fs
self
.
fs
=
fs
def
__str__
(
self
):
def
__str__
(
self
):
return
"<DirMount
%
s,
%
s>"
%
(
self
.
path
,
self
.
fs
)
return
"<DirMount
%
s,
%
s>"
%
(
self
.
path
,
self
.
fs
)
def
__repr__
(
self
):
def
__repr__
(
self
):
return
"<DirMount
%
s,
%
s>"
%
(
self
.
path
,
self
.
fs
)
return
"<DirMount
%
s,
%
s>"
%
(
self
.
path
,
self
.
fs
)
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
u"<DirMount
%
s,
%
s>"
%
(
self
.
path
,
self
.
fs
)
return
u"<DirMount
%
s,
%
s>"
%
(
self
.
path
,
self
.
fs
)
...
@@ -77,7 +77,7 @@ class MountFS(FS):
...
@@ -77,7 +77,7 @@ class MountFS(FS):
_meta
=
{
'virtual'
:
True
,
_meta
=
{
'virtual'
:
True
,
'read_only'
:
False
,
'read_only'
:
False
,
'unicode_paths'
:
True
,
'unicode_paths'
:
True
,
'case_insensitive_paths'
:
False
,
'case_insensitive_paths'
:
False
,
}
}
DirMount
=
DirMount
DirMount
=
DirMount
...
@@ -86,7 +86,7 @@ class MountFS(FS):
...
@@ -86,7 +86,7 @@ class MountFS(FS):
def
__init__
(
self
,
auto_close
=
True
,
thread_synchronize
=
_thread_synchronize_default
):
def
__init__
(
self
,
auto_close
=
True
,
thread_synchronize
=
_thread_synchronize_default
):
self
.
auto_close
=
auto_close
self
.
auto_close
=
auto_close
super
(
MountFS
,
self
)
.
__init__
(
thread_synchronize
=
thread_synchronize
)
super
(
MountFS
,
self
)
.
__init__
(
thread_synchronize
=
thread_synchronize
)
self
.
mount_tree
=
PathMap
()
self
.
mount_tree
=
PathMap
()
def
__str__
(
self
):
def
__str__
(
self
):
return
"<
%
s [
%
s]>"
%
(
self
.
__class__
.
__name__
,
self
.
mount_tree
.
items
(),)
return
"<
%
s [
%
s]>"
%
(
self
.
__class__
.
__name__
,
self
.
mount_tree
.
items
(),)
...
@@ -128,11 +128,11 @@ class MountFS(FS):
...
@@ -128,11 +128,11 @@ class MountFS(FS):
def
close
(
self
):
def
close
(
self
):
# Explicitly closes children if requested
# Explicitly closes children if requested
if
self
.
auto_close
:
if
self
.
auto_close
:
for
mount
in
self
.
mount_tree
.
itervalues
():
for
mount
in
self
.
mount_tree
.
itervalues
():
mount
.
fs
.
close
()
mount
.
fs
.
close
()
# Free references (which may incidently call the close method of the child filesystems)
# Free references (which may incidently call the close method of the child filesystems)
self
.
mount_tree
.
clear
()
self
.
mount_tree
.
clear
()
super
(
MountFS
,
self
)
.
close
()
super
(
MountFS
,
self
)
.
close
()
def
getsyspath
(
self
,
path
,
allow_none
=
False
):
def
getsyspath
(
self
,
path
,
allow_none
=
False
):
fs
,
_mount_path
,
delegate_path
=
self
.
_delegate
(
path
)
fs
,
_mount_path
,
delegate_path
=
self
.
_delegate
(
path
)
...
@@ -142,7 +142,7 @@ class MountFS(FS):
...
@@ -142,7 +142,7 @@ class MountFS(FS):
else
:
else
:
raise
NoSysPathError
(
path
=
path
)
raise
NoSysPathError
(
path
=
path
)
return
fs
.
getsyspath
(
delegate_path
,
allow_none
=
allow_none
)
return
fs
.
getsyspath
(
delegate_path
,
allow_none
=
allow_none
)
def
getpathurl
(
self
,
path
,
allow_none
=
False
):
def
getpathurl
(
self
,
path
,
allow_none
=
False
):
fs
,
_mount_path
,
delegate_path
=
self
.
_delegate
(
path
)
fs
,
_mount_path
,
delegate_path
=
self
.
_delegate
(
path
)
if
fs
is
self
or
fs
is
None
:
if
fs
is
self
or
fs
is
None
:
...
@@ -160,7 +160,7 @@ class MountFS(FS):
...
@@ -160,7 +160,7 @@ class MountFS(FS):
return
"Mount dir"
return
"Mount dir"
else
:
else
:
return
"Mounted file"
return
"Mounted file"
return
"Mounted dir, maps to path
%
s on
%
s"
%
(
delegate_path
,
str
(
fs
))
return
"Mounted dir, maps to path
%
s on
%
s"
%
(
delegate_path
or
'/'
,
str
(
fs
))
@synchronize
@synchronize
def
isdir
(
self
,
path
):
def
isdir
(
self
,
path
):
...
@@ -283,7 +283,7 @@ class MountFS(FS):
...
@@ -283,7 +283,7 @@ class MountFS(FS):
if
not
delegate_path
:
if
not
delegate_path
:
if
allow_recreate
:
if
allow_recreate
:
return
return
else
:
else
:
raise
DestinationExistsError
(
path
,
msg
=
"Can not create a directory that already exists (try allow_recreate=True):
%(path)
s"
)
raise
DestinationExistsError
(
path
,
msg
=
"Can not create a directory that already exists (try allow_recreate=True):
%(path)
s"
)
return
fs
.
makedir
(
delegate_path
,
recursive
=
recursive
,
allow_recreate
=
allow_recreate
)
return
fs
.
makedir
(
delegate_path
,
recursive
=
recursive
,
allow_recreate
=
allow_recreate
)
...
@@ -396,9 +396,9 @@ class MountFS(FS):
...
@@ -396,9 +396,9 @@ class MountFS(FS):
@synchronize
@synchronize
def
mountdir
(
self
,
path
,
fs
):
def
mountdir
(
self
,
path
,
fs
):
"""Mounts a host FS object on a given path.
"""Mounts a host FS object on a given path.
:param path: A path within the MountFS
:param path: A path within the MountFS
:param fs: A filesystem object to mount
:param fs: A filesystem object to mount
"""
"""
path
=
abspath
(
normpath
(
path
))
path
=
abspath
(
normpath
(
path
))
...
@@ -408,11 +408,11 @@ class MountFS(FS):
...
@@ -408,11 +408,11 @@ class MountFS(FS):
@synchronize
@synchronize
def
mountfile
(
self
,
path
,
open_callable
=
None
,
info_callable
=
None
):
def
mountfile
(
self
,
path
,
open_callable
=
None
,
info_callable
=
None
):
"""Mounts a single file path.
"""Mounts a single file path.
:param path: A path within the MountFS
:param path: A path within the MountFS
:param open_callable: A callable that returns a file-like object
:param open_callable: A callable that returns a file-like object
:param info_callable: A callable that returns a dictionary with information regarding the file-like object
:param info_callable: A callable that returns a dictionary with information regarding the file-like object
"""
"""
self
.
mount_tree
[
path
]
=
MountFS
.
FileMount
(
path
,
callable
,
info_callable
)
self
.
mount_tree
[
path
]
=
MountFS
.
FileMount
(
path
,
callable
,
info_callable
)
...
...
fs/rpcfs.py
View file @
56227fb8
...
@@ -23,22 +23,22 @@ from six import PY3, b
...
@@ -23,22 +23,22 @@ from six import PY3, b
def
re_raise_faults
(
func
):
def
re_raise_faults
(
func
):
"""Decorator to re-raise XML-RPC faults as proper exceptions."""
"""Decorator to re-raise XML-RPC faults as proper exceptions."""
def
wrapper
(
*
args
,
**
kwds
):
def
wrapper
(
*
args
,
**
kwds
):
try
:
try
:
return
func
(
*
args
,
**
kwds
)
return
func
(
*
args
,
**
kwds
)
except
xmlrpclib
.
Fault
,
f
:
except
(
xmlrpclib
.
Fault
)
,
f
:
# Make sure it's in a form we can handle
# Make sure it's in a form we can handle
bits
=
f
.
faultString
.
split
(
" "
)
bits
=
f
.
faultString
.
split
(
" "
)
if
bits
[
0
]
not
in
[
"<type"
,
"<class"
]:
if
bits
[
0
]
not
in
[
"<type"
,
"<class"
]:
raise
f
raise
f
# Find the class/type object
# Find the class/type object
bits
=
" "
.
join
(
bits
[
1
:])
.
split
(
">:"
)
bits
=
" "
.
join
(
bits
[
1
:])
.
split
(
">:"
)
cls
=
bits
[
0
]
cls
=
bits
[
0
]
msg
=
">:"
.
join
(
bits
[
1
:])
msg
=
">:"
.
join
(
bits
[
1
:])
cls
=
cls
.
strip
(
'
\'
'
)
cls
=
cls
.
strip
(
'
\'
'
)
cls
=
_object_by_name
(
cls
)
cls
=
_object_by_name
(
cls
)
# Re-raise using the remainder of the fault code as message
# Re-raise using the remainder of the fault code as message
if
cls
:
if
cls
:
if
issubclass
(
cls
,
FSError
):
if
issubclass
(
cls
,
FSError
):
raise
cls
(
''
,
msg
=
msg
)
raise
cls
(
''
,
msg
=
msg
)
else
:
else
:
...
@@ -66,7 +66,7 @@ def _object_by_name(name,root=None):
...
@@ -66,7 +66,7 @@ def _object_by_name(name,root=None):
return
_object_by_name
(
"."
.
join
(
bits
[
1
:]),
obj
)
return
_object_by_name
(
"."
.
join
(
bits
[
1
:]),
obj
)
else
:
else
:
return
obj
return
obj
class
ReRaiseFaults
:
class
ReRaiseFaults
:
"""XML-RPC proxy wrapper that re-raises Faults as proper Exceptions."""
"""XML-RPC proxy wrapper that re-raises Faults as proper Exceptions."""
...
@@ -94,9 +94,9 @@ class RPCFS(FS):
...
@@ -94,9 +94,9 @@ class RPCFS(FS):
"""
"""
_meta
=
{
'thread_safe'
:
True
,
_meta
=
{
'thread_safe'
:
True
,
'virtual'
:
False
,
'virtual'
:
False
,
'network'
:
True
,
'network'
:
True
,
}
}
def
__init__
(
self
,
uri
,
transport
=
None
):
def
__init__
(
self
,
uri
,
transport
=
None
):
...
@@ -105,30 +105,30 @@ class RPCFS(FS):
...
@@ -105,30 +105,30 @@ class RPCFS(FS):
The only required argument is the URI of the server to connect
The only required argument is the URI of the server to connect
to. This will be passed to the underlying XML-RPC server proxy
to. This will be passed to the underlying XML-RPC server proxy
object, along with the 'transport' argument if it is provided.
object, along with the 'transport' argument if it is provided.
:param uri: address of the server
:param uri: address of the server
"""
"""
super
(
RPCFS
,
self
)
.
__init__
(
thread_synchronize
=
True
)
super
(
RPCFS
,
self
)
.
__init__
(
thread_synchronize
=
True
)
self
.
uri
=
uri
self
.
uri
=
uri
self
.
_transport
=
transport
self
.
_transport
=
transport
self
.
proxy
=
self
.
_make_proxy
()
self
.
proxy
=
self
.
_make_proxy
()
self
.
isdir
(
'/'
)
self
.
isdir
(
'/'
)
@synchronize
@synchronize
def
_make_proxy
(
self
):
def
_make_proxy
(
self
):
kwds
=
dict
(
allow_none
=
True
,
use_datetime
=
True
)
kwds
=
dict
(
allow_none
=
True
,
use_datetime
=
True
)
if
self
.
_transport
is
not
None
:
if
self
.
_transport
is
not
None
:
proxy
=
xmlrpclib
.
ServerProxy
(
self
.
uri
,
self
.
_transport
,
**
kwds
)
proxy
=
xmlrpclib
.
ServerProxy
(
self
.
uri
,
self
.
_transport
,
**
kwds
)
else
:
else
:
proxy
=
xmlrpclib
.
ServerProxy
(
self
.
uri
,
**
kwds
)
proxy
=
xmlrpclib
.
ServerProxy
(
self
.
uri
,
**
kwds
)
return
ReRaiseFaults
(
proxy
)
return
ReRaiseFaults
(
proxy
)
def
__str__
(
self
):
def
__str__
(
self
):
return
'<RPCFS:
%
s>'
%
(
self
.
uri
,)
return
'<RPCFS:
%
s>'
%
(
self
.
uri
,)
def
__repr__
(
self
):
def
__repr__
(
self
):
return
'<RPCFS:
%
s>'
%
(
self
.
uri
,)
return
'<RPCFS:
%
s>'
%
(
self
.
uri
,)
...
@@ -140,10 +140,10 @@ class RPCFS(FS):
...
@@ -140,10 +140,10 @@ class RPCFS(FS):
except
KeyError
:
except
KeyError
:
pass
pass
return
state
return
state
def
__setstate__
(
self
,
state
):
def
__setstate__
(
self
,
state
):
super
(
RPCFS
,
self
)
.
__setstate__
(
state
)
super
(
RPCFS
,
self
)
.
__setstate__
(
state
)
self
.
proxy
=
self
.
_make_proxy
()
self
.
proxy
=
self
.
_make_proxy
()
def
encode_path
(
self
,
path
):
def
encode_path
(
self
,
path
):
"""Encode a filesystem path for sending over the wire.
"""Encode a filesystem path for sending over the wire.
...
@@ -154,23 +154,27 @@ class RPCFS(FS):
...
@@ -154,23 +154,27 @@ class RPCFS(FS):
"""
"""
if
PY3
:
if
PY3
:
return
path
return
path
return
path
.
encode
(
"utf8"
)
.
encode
(
"base64"
)
return
path
.
encode
(
"utf8"
)
.
encode
(
"base64"
)
def
decode_path
(
self
,
path
):
def
decode_path
(
self
,
path
):
"""Decode paths arriving over the wire."""
"""Decode paths arriving over the wire."""
if
PY3
:
if
PY3
:
return
path
return
path
return
path
.
decode
(
"base64"
)
.
decode
(
"utf8"
)
return
path
.
decode
(
"base64"
)
.
decode
(
"utf8"
)
@synchronize
@synchronize
def
getmeta
(
self
,
meta_name
,
default
=
NoDefaultMeta
):
def
getmeta
(
self
,
meta_name
,
default
=
NoDefaultMeta
):
if
default
is
NoDefaultMeta
:
if
default
is
NoDefaultMeta
:
return
self
.
proxy
.
getmeta
(
meta_name
)
meta
=
self
.
proxy
.
getmeta
(
meta_name
)
else
:
else
:
return
self
.
proxy
.
getmeta_default
(
meta_name
,
default
)
meta
=
self
.
proxy
.
getmeta_default
(
meta_name
,
default
)
if
isinstance
(
meta
,
basestring
):
@synchronize
# To allow transport of meta with invalid xml chars (like null)
def
hasmeta
(
self
,
meta_name
):
meta
=
meta
.
encode
(
'base64'
)
return
meta
@synchronize
def
hasmeta
(
self
,
meta_name
):
return
self
.
proxy
.
hasmeta
(
meta_name
)
return
self
.
proxy
.
hasmeta
(
meta_name
)
@synchronize
@synchronize
...
@@ -197,7 +201,7 @@ class RPCFS(FS):
...
@@ -197,7 +201,7 @@ class RPCFS(FS):
f
.
seek
(
0
,
2
)
f
.
seek
(
0
,
2
)
oldflush
=
f
.
flush
oldflush
=
f
.
flush
oldclose
=
f
.
close
oldclose
=
f
.
close
oldtruncate
=
f
.
truncate
oldtruncate
=
f
.
truncate
def
newflush
():
def
newflush
():
self
.
_lock
.
acquire
()
self
.
_lock
.
acquire
()
try
:
try
:
...
@@ -219,7 +223,7 @@ class RPCFS(FS):
...
@@ -219,7 +223,7 @@ class RPCFS(FS):
f
.
flush
()
f
.
flush
()
finally
:
finally
:
self
.
_lock
.
release
()
self
.
_lock
.
release
()
f
.
flush
=
newflush
f
.
flush
=
newflush
f
.
close
=
newclose
f
.
close
=
newclose
f
.
truncate
=
newtruncate
f
.
truncate
=
newtruncate
...
@@ -241,7 +245,7 @@ class RPCFS(FS):
...
@@ -241,7 +245,7 @@ class RPCFS(FS):
return
self
.
proxy
.
isfile
(
path
)
return
self
.
proxy
.
isfile
(
path
)
@synchronize
@synchronize
def
listdir
(
self
,
path
=
"./"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
dirs_only
=
False
,
files_only
=
False
):
def
listdir
(
self
,
path
=
"./"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
dirs_only
=
False
,
files_only
=
False
):
enc_path
=
self
.
encode_path
(
path
)
enc_path
=
self
.
encode_path
(
path
)
if
not
callable
(
wildcard
):
if
not
callable
(
wildcard
):
entries
=
self
.
proxy
.
listdir
(
enc_path
,
wildcard
,
full
,
absolute
,
entries
=
self
.
proxy
.
listdir
(
enc_path
,
wildcard
,
full
,
absolute
,
...
@@ -272,7 +276,7 @@ class RPCFS(FS):
...
@@ -272,7 +276,7 @@ class RPCFS(FS):
def
removedir
(
self
,
path
,
recursive
=
False
,
force
=
False
):
def
removedir
(
self
,
path
,
recursive
=
False
,
force
=
False
):
path
=
self
.
encode_path
(
path
)
path
=
self
.
encode_path
(
path
)
return
self
.
proxy
.
removedir
(
path
,
recursive
,
force
)
return
self
.
proxy
.
removedir
(
path
,
recursive
,
force
)
@synchronize
@synchronize
def
rename
(
self
,
src
,
dst
):
def
rename
(
self
,
src
,
dst
):
src
=
self
.
encode_path
(
src
)
src
=
self
.
encode_path
(
src
)
...
@@ -286,7 +290,7 @@ class RPCFS(FS):
...
@@ -286,7 +290,7 @@ class RPCFS(FS):
@synchronize
@synchronize
def
getinfo
(
self
,
path
):
def
getinfo
(
self
,
path
):
path
=
self
.
encode_path
(
path
)
path
=
self
.
encode_path
(
path
)
return
self
.
proxy
.
getinfo
(
path
)
return
self
.
proxy
.
getinfo
(
path
)
@synchronize
@synchronize
...
...
fs/tests/test_archivefs.py
View file @
56227fb8
...
@@ -13,12 +13,20 @@ import shutil
...
@@ -13,12 +13,20 @@ import shutil
import
fs.tests
import
fs.tests
from
fs.path
import
*
from
fs.path
import
*
from
fs.contrib
import
archivefs
try
:
from
fs.contrib
import
archivefs
except
ImportError
:
libarchive_available
=
False
else
:
libarchive_available
=
True
from
six
import
PY3
,
b
from
six
import
PY3
,
b
class
TestReadArchiveFS
(
unittest
.
TestCase
):
class
TestReadArchiveFS
(
unittest
.
TestCase
):
__test__
=
libarchive_available
def
setUp
(
self
):
def
setUp
(
self
):
self
.
temp_filename
=
""
.
join
(
random
.
choice
(
"abcdefghijklmnopqrstuvwxyz"
)
for
_
in
range
(
6
))
+
".zip"
self
.
temp_filename
=
""
.
join
(
random
.
choice
(
"abcdefghijklmnopqrstuvwxyz"
)
for
_
in
range
(
6
))
+
".zip"
self
.
temp_filename
=
os
.
path
.
join
(
tempfile
.
gettempdir
(),
self
.
temp_filename
)
self
.
temp_filename
=
os
.
path
.
join
(
tempfile
.
gettempdir
(),
self
.
temp_filename
)
...
...
fs/tests/test_expose.py
View file @
56227fb8
...
@@ -24,99 +24,7 @@ from fs.expose.xmlrpc import RPCFSServer
...
@@ -24,99 +24,7 @@ from fs.expose.xmlrpc import RPCFSServer
import
six
import
six
from
six
import
PY3
,
b
from
six
import
PY3
,
b
class
TestRPCFS
(
unittest
.
TestCase
,
FSTestCases
,
ThreadingTestCases
):
from
fs.tests.test_rpcfs
import
TestRPCFS
def
makeServer
(
self
,
fs
,
addr
):
return
RPCFSServer
(
fs
,
addr
,
logRequests
=
False
)
def
startServer
(
self
):
port
=
3000
self
.
temp_fs
=
TempFS
()
self
.
server
=
None
self
.
serve_more_requests
=
True
self
.
server_thread
=
threading
.
Thread
(
target
=
self
.
runServer
)
self
.
server_thread
.
setDaemon
(
True
)
self
.
start_event
=
threading
.
Event
()
self
.
end_event
=
threading
.
Event
()
self
.
server_thread
.
start
()
self
.
start_event
.
wait
()
def
runServer
(
self
):
"""Run the server, swallowing shutdown-related execptions."""
port
=
3000
while
not
self
.
server
:
try
:
self
.
server
=
self
.
makeServer
(
self
.
temp_fs
,(
"127.0.0.1"
,
port
))
except
socket
.
error
,
e
:
if
e
.
args
[
1
]
==
"Address already in use"
:
port
+=
1
else
:
raise
self
.
server_addr
=
(
"127.0.0.1"
,
port
)
self
.
server
.
socket
.
setsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_REUSEADDR
,
1
)
# if sys.platform != "win32":
# try:
# self.server.socket.settimeout(1)
# except socket.error:
# pass
#
self
.
start_event
.
set
()
try
:
#self.server.serve_forever()
while
self
.
serve_more_requests
:
self
.
server
.
handle_request
()
except
Exception
,
e
:
pass
self
.
end_event
.
set
()
def
setUp
(
self
):
self
.
startServer
()
self
.
fs
=
rpcfs
.
RPCFS
(
"http://
%
s:
%
d"
%
self
.
server_addr
)
def
tearDown
(
self
):
self
.
serve_more_requests
=
False
#self.server.socket.close()
# self.server.socket.shutdown(socket.SHUT_RDWR)
# self.server.socket.close()
# self.temp_fs.close()
#self.server_thread.join()
#self.end_event.wait()
#return
try
:
self
.
bump
()
self
.
server
.
server_close
()
except
Exception
:
pass
#self.server_thread.join()
self
.
temp_fs
.
close
()
def
bump
(
self
):
host
,
port
=
self
.
server_addr
for
res
in
socket
.
getaddrinfo
(
host
,
port
,
0
,
socket
.
SOCK_STREAM
):
af
,
socktype
,
proto
,
cn
,
sa
=
res
sock
=
None
try
:
sock
=
socket
.
socket
(
af
,
socktype
,
proto
)
sock
.
settimeout
(
.
1
)
sock
.
connect
(
sa
)
sock
.
send
(
b
(
"
\n
"
))
except
socket
.
error
,
e
:
pass
finally
:
if
sock
is
not
None
:
sock
.
close
()
try
:
try
:
from
fs
import
sftpfs
from
fs
import
sftpfs
...
@@ -125,7 +33,7 @@ except ImportError:
...
@@ -125,7 +33,7 @@ except ImportError:
if
not
PY3
:
if
not
PY3
:
raise
raise
class
TestSFTPFS
(
TestRPCFS
):
class
TestSFTPFS
(
TestRPCFS
):
__test__
=
not
PY3
__test__
=
not
PY3
def
makeServer
(
self
,
fs
,
addr
):
def
makeServer
(
self
,
fs
,
addr
):
...
@@ -134,14 +42,6 @@ class TestSFTPFS(TestRPCFS):
...
@@ -134,14 +42,6 @@ class TestSFTPFS(TestRPCFS):
def
setUp
(
self
):
def
setUp
(
self
):
self
.
startServer
()
self
.
startServer
()
self
.
fs
=
sftpfs
.
SFTPFS
(
self
.
server_addr
,
no_auth
=
True
)
self
.
fs
=
sftpfs
.
SFTPFS
(
self
.
server_addr
,
no_auth
=
True
)
#def runServer(self):
# self.server.serve_forever()
#
#def tearDown(self):
# self.server.shutdown()
# self.server_thread.join()
# self.temp_fs.close()
def
bump
(
self
):
def
bump
(
self
):
# paramiko doesn't like being bumped, just wait for it to timeout.
# paramiko doesn't like being bumped, just wait for it to timeout.
...
@@ -158,7 +58,7 @@ else:
...
@@ -158,7 +58,7 @@ else:
class
TestFUSE
(
unittest
.
TestCase
,
FSTestCases
,
ThreadingTestCases
):
class
TestFUSE
(
unittest
.
TestCase
,
FSTestCases
,
ThreadingTestCases
):
def
setUp
(
self
):
def
setUp
(
self
):
self
.
temp_fs
=
TempFS
()
self
.
temp_fs
=
TempFS
()
self
.
temp_fs
.
makedir
(
"root"
)
self
.
temp_fs
.
makedir
(
"root"
)
self
.
temp_fs
.
makedir
(
"mount"
)
self
.
temp_fs
.
makedir
(
"mount"
)
self
.
mounted_fs
=
self
.
temp_fs
.
opendir
(
"root"
)
self
.
mounted_fs
=
self
.
temp_fs
.
opendir
(
"root"
)
...
...
fs/tests/test_rpcfs.py
0 → 100644
View file @
56227fb8
import
unittest
import
sys
import
os
,
os
.
path
import
socket
import
threading
import
time
from
fs.tests
import
FSTestCases
,
ThreadingTestCases
from
fs.tempfs
import
TempFS
from
fs.osfs
import
OSFS
from
fs.memoryfs
import
MemoryFS
from
fs.path
import
*
from
fs.errors
import
*
from
fs
import
rpcfs
from
fs.expose.xmlrpc
import
RPCFSServer
import
six
from
six
import
PY3
,
b
class
TestRPCFS
(
unittest
.
TestCase
,
FSTestCases
,
ThreadingTestCases
):
def
makeServer
(
self
,
fs
,
addr
):
return
RPCFSServer
(
fs
,
addr
,
logRequests
=
False
)
def
startServer
(
self
):
port
=
3000
self
.
temp_fs
=
TempFS
()
self
.
server
=
None
self
.
serve_more_requests
=
True
self
.
server_thread
=
threading
.
Thread
(
target
=
self
.
runServer
)
self
.
server_thread
.
setDaemon
(
True
)
self
.
start_event
=
threading
.
Event
()
self
.
end_event
=
threading
.
Event
()
self
.
server_thread
.
start
()
self
.
start_event
.
wait
()
def
runServer
(
self
):
"""Run the server, swallowing shutdown-related execptions."""
port
=
3000
while
not
self
.
server
:
try
:
self
.
server
=
self
.
makeServer
(
self
.
temp_fs
,(
"127.0.0.1"
,
port
))
except
socket
.
error
,
e
:
if
e
.
args
[
1
]
==
"Address already in use"
:
port
+=
1
else
:
raise
self
.
server_addr
=
(
"127.0.0.1"
,
port
)
self
.
server
.
socket
.
setsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_REUSEADDR
,
1
)
self
.
start_event
.
set
()
try
:
#self.server.serve_forever()
while
self
.
serve_more_requests
:
self
.
server
.
handle_request
()
except
Exception
,
e
:
pass
self
.
end_event
.
set
()
def
setUp
(
self
):
self
.
startServer
()
self
.
fs
=
rpcfs
.
RPCFS
(
"http://
%
s:
%
d"
%
self
.
server_addr
)
def
tearDown
(
self
):
self
.
serve_more_requests
=
False
try
:
self
.
bump
()
self
.
server
.
server_close
()
except
Exception
:
pass
#self.server_thread.join()
self
.
temp_fs
.
close
()
def
bump
(
self
):
host
,
port
=
self
.
server_addr
for
res
in
socket
.
getaddrinfo
(
host
,
port
,
0
,
socket
.
SOCK_STREAM
):
af
,
socktype
,
proto
,
cn
,
sa
=
res
sock
=
None
try
:
sock
=
socket
.
socket
(
af
,
socktype
,
proto
)
sock
.
settimeout
(
.
1
)
sock
.
connect
(
sa
)
sock
.
send
(
b
(
"
\n
"
))
except
socket
.
error
,
e
:
pass
finally
:
if
sock
is
not
None
:
sock
.
close
()
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