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
7f1e44a3
Commit
7f1e44a3
authored
Dec 12, 2010
by
willmcgugan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added fsmount command, made memroyfs work with threads
parent
91093534
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
279 additions
and
136 deletions
+279
-136
ChangeLog
+4
-0
fs/base.py
+6
-3
fs/commands/fsmount
+6
-0
fs/commands/fsmount.py
+82
-0
fs/expose/fuse/__init__.py
+7
-4
fs/ftpfs.py
+3
-5
fs/memoryfs.py
+147
-121
fs/opener.py
+1
-1
fs/osfs/__init__.py
+20
-0
fs/rpcfs.py
+1
-1
setup.py
+2
-1
No files found.
ChangeLog
View file @
7f1e44a3
...
@@ -63,4 +63,8 @@
...
@@ -63,4 +63,8 @@
* Separated behaviour of setcontents and createfile
* Separated behaviour of setcontents and createfile
* Added a getmmap to base
* Added a getmmap to base
* Added command line scripts fsls, fstree, fscat, fscp, fsmv
* Added command line scripts fsls, fstree, fscat, fscp, fsmv
* Added command line scripts fsmkdir, fsmount
* Made automatically pick up keys if no other authentication is available
* Optimized listdir and listdirinfo in SFTPFS
* Made memoryfs work with threads
fs/base.py
View file @
7f1e44a3
...
@@ -149,9 +149,11 @@ class FS(object):
...
@@ -149,9 +149,11 @@ class FS(object):
:param thread_synconize: If True, a lock object will be created for the object, otherwise a dummy lock will be used.
:param thread_synconize: If True, a lock object will be created for the object, otherwise a dummy lock will be used.
:type thread_synchronize: bool
:type thread_synchronize: bool
"""
"""
super
(
FS
,
self
)
.
__init__
()
super
(
FS
,
self
)
.
__init__
()
self
.
closed
=
False
self
.
closed
=
False
self
.
thread_synchronize
=
thread_synchronize
if
thread_synchronize
:
if
thread_synchronize
:
self
.
_lock
=
threading
.
RLock
()
self
.
_lock
=
threading
.
RLock
()
else
:
else
:
...
@@ -188,9 +190,10 @@ class FS(object):
...
@@ -188,9 +190,10 @@ class FS(object):
return
state
return
state
def
__setstate__
(
self
,
state
):
def
__setstate__
(
self
,
state
):
for
(
k
,
v
)
in
state
.
iteritems
():
self
.
__dict__
.
update
(
state
)
self
.
__dict__
[
k
]
=
v
#for (k,v) in state.iteritems():
lock
=
state
.
get
(
"_lock"
,
None
)
# self.__dict__[k] = v
lock
=
state
.
get
(
"_lock"
)
if
lock
is
not
None
:
if
lock
is
not
None
:
if
lock
:
if
lock
:
self
.
_lock
=
threading
.
RLock
()
self
.
_lock
=
threading
.
RLock
()
...
...
fs/commands/fsmount
0 → 100644
View file @
7f1e44a3
#!/usr/bin/env python
import
sys
from
fs.commands.fsmount
import
run
sys
.
exit
(
run
())
fs/commands/fsmount.py
0 → 100644
View file @
7f1e44a3
#!/usr/bin/env python
from
fs.opener
import
opener
from
fs.commands.runner
import
Command
import
sys
import
platform
import
os
import
os.path
import
time
class
FSMount
(
Command
):
usage
=
"""fsmount [SYSTEM PATH] [FS]
or fsmount -u [SYSTEM PATH]
Mounts a file system on a system path"""
version
=
"1.0"
def
get_optparse
(
self
):
optparse
=
super
(
FSMount
,
self
)
.
get_optparse
()
optparse
.
add_option
(
'-f'
,
'--foreground'
,
dest
=
'foreground'
,
action
=
"store_true"
,
default
=
False
,
help
=
"run the mount process in the foreground"
,
metavar
=
"FOREGROUND"
)
optparse
.
add_option
(
'-u'
,
'--unmount'
,
dest
=
'unmount'
,
action
=
"store_true"
,
default
=
False
,
help
=
"unmount path"
,
metavar
=
"UNMOUNT"
)
return
optparse
def
do_run
(
self
,
options
,
args
):
if
options
.
unmount
:
try
:
mount_path
=
args
[
0
]
except
IndexError
:
self
.
error
(
'Mount path required
\n
'
)
return
1
from
fs.expose
import
fuse
fuse
.
unmount
(
mount_path
)
return
try
:
mount_path
=
args
[
0
]
except
IndexError
:
self
.
error
(
'Mount path required
\n
'
)
return
1
try
:
fs_url
=
args
[
1
]
except
IndexError
:
self
.
error
(
'FS required
\n
'
)
return
1
if
platform
.
system
()
==
'Windows'
:
pass
else
:
fs
,
path
=
self
.
open_fs
(
fs_url
,
create
=
True
)
if
path
:
if
not
fs
.
isdir
(
path
):
self
.
error
(
'
%
s is not a directory on
%
s'
%
(
fs_url
.
fs
))
return
1
fs
=
fs
.
opendir
(
path
)
path
=
'/'
if
not
os
.
path
.
exists
(
mount_path
):
os
.
makedirs
(
mount_path
)
from
fs.expose
import
fuse
if
options
.
foreground
:
fuse_process
=
fuse
.
mount
(
fs
,
mount_path
,
foreground
=
True
)
else
:
mp
=
fuse
.
mount
(
fs
,
mount_path
,
foreground
=
False
)
def
run
():
return
FSMount
()
.
run
()
if
__name__
==
"__main__"
:
sys
.
exit
(
run
())
\ No newline at end of file
fs/expose/fuse/__init__.py
View file @
7f1e44a3
...
@@ -245,11 +245,14 @@ class FSOperations(Operations):
...
@@ -245,11 +245,14 @@ class FSOperations(Operations):
@handle_fs_errors
@handle_fs_errors
def
readdir
(
self
,
path
,
fh
=
None
):
def
readdir
(
self
,
path
,
fh
=
None
):
path
=
path
.
decode
(
NATIVE_ENCODING
)
path
=
path
.
decode
(
NATIVE_ENCODING
)
entries
=
[]
entries
=
[
'.'
,
'..'
]
#print
#print self.fs
for
(
nm
,
info
)
in
self
.
fs
.
listdirinfo
(
path
):
for
(
nm
,
info
)
in
self
.
fs
.
listdirinfo
(
path
):
#print "*", repr(nm), info
self
.
_fill_stat_dict
(
pathjoin
(
path
,
nm
),
info
)
self
.
_fill_stat_dict
(
pathjoin
(
path
,
nm
),
info
)
entries
.
append
((
nm
.
encode
(
NATIVE_ENCODING
),
info
,
0
))
entries
.
append
((
nm
.
encode
(
NATIVE_ENCODING
),
info
,
0
))
entries
=
[
"."
,
".."
]
+
entries
#print
return
entries
return
entries
@handle_fs_errors
@handle_fs_errors
...
@@ -472,7 +475,7 @@ def unmount(path):
...
@@ -472,7 +475,7 @@ def unmount(path):
return
return
if
"not found"
in
stderr
:
if
"not found"
in
stderr
:
return
return
raise
OSError
(
"filesystem could not be unmounted:
%
s (
%
s) "
%
(
path
,
stderr
,))
raise
OSError
(
"filesystem could not be unmounted:
%
s (
%
s) "
%
(
path
,
str
(
stderr
)
.
rstrip
()
,))
class
MountProcess
(
subprocess
.
Popen
):
class
MountProcess
(
subprocess
.
Popen
):
...
...
fs/ftpfs.py
View file @
7f1e44a3
...
@@ -17,11 +17,9 @@ from fs.remote import RemoteFileBuffer
...
@@ -17,11 +17,9 @@ from fs.remote import RemoteFileBuffer
from
ftplib
import
FTP
,
error_perm
,
error_temp
,
error_proto
,
error_reply
from
ftplib
import
FTP
,
error_perm
,
error_temp
,
error_proto
,
error_reply
try
:
try
:
from
ftplib
import
_GLOBAL_DEFAULT_TIMEOUT
from
ftplib
import
_GLOBAL_DEFAULT_TIMEOUT
_FTPLIB_TIMEOUT
=
True
except
ImportError
:
except
ImportError
:
_GLOBAL_DEFAULT_TIMEOUT
=
None
_GLOBAL_DEFAULT_TIMEOUT
=
object
()
_FTPLIB_TIMEOUT
=
False
import
threading
import
threading
from
time
import
sleep
from
time
import
sleep
...
@@ -934,7 +932,7 @@ class FTPFS(FS):
...
@@ -934,7 +932,7 @@ class FTPFS(FS):
def
_open_ftp
(
self
):
def
_open_ftp
(
self
):
try
:
try
:
ftp
=
FTP
()
ftp
=
FTP
()
if
_FTPLIB
_TIMEOUT
:
if
self
.
timeout
is
not
_GLOBAL_DEFAULT
_TIMEOUT
:
ftp
.
connect
(
self
.
host
,
self
.
port
,
self
.
timeout
)
ftp
.
connect
(
self
.
host
,
self
.
port
,
self
.
timeout
)
else
:
else
:
ftp
.
connect
(
self
.
host
,
self
.
port
)
ftp
.
connect
(
self
.
host
,
self
.
port
)
...
...
fs/memoryfs.py
View file @
7f1e44a3
...
@@ -17,6 +17,8 @@ from fs.base import *
...
@@ -17,6 +17,8 @@ from fs.base import *
from
fs.errors
import
*
from
fs.errors
import
*
from
fs
import
_thread_synchronize_default
from
fs
import
_thread_synchronize_default
from
fs.filelike
import
StringIO
from
fs.filelike
import
StringIO
from
os
import
SEEK_END
import
threading
def
_check_mode
(
mode
,
mode_chars
):
def
_check_mode
(
mode
,
mode_chars
):
...
@@ -25,47 +27,46 @@ def _check_mode(mode, mode_chars):
...
@@ -25,47 +27,46 @@ def _check_mode(mode, mode_chars):
return
False
return
False
return
True
return
True
class
MemoryFile
(
object
):
class
MemoryFile
(
object
):
def
__init__
(
self
,
path
,
memory_fs
,
value
,
mode
):
def
seek_and_lock
(
f
):
def
deco
(
self
,
*
args
,
**
kwargs
):
try
:
self
.
lock
.
acquire
()
self
.
mem_file
.
seek
(
self
.
pos
)
ret
=
f
(
self
,
*
args
,
**
kwargs
)
self
.
pos
=
self
.
mem_file
.
tell
()
return
ret
finally
:
self
.
lock
.
release
()
return
deco
def
__init__
(
self
,
path
,
memory_fs
,
mem_file
,
mode
,
lock
):
self
.
closed
=
False
self
.
closed
=
False
self
.
path
=
path
self
.
path
=
path
self
.
memory_fs
=
memory_fs
self
.
memory_fs
=
memory_fs
self
.
mode
=
mode
self
.
mem_file
=
mem_file
value
=
value
or
''
self
.
mode
=
mode
self
.
lock
=
lock
self
.
mem_file
=
None
self
.
pos
=
0
if
'+'
in
mode
:
self
.
mem_file
=
StringIO
()
if
_check_mode
(
mode
,
'a'
):
self
.
mem_file
.
write
(
value
)
lock
.
acquire
()
self
.
mem_file
.
seek
(
0
)
try
:
self
.
mem_file
.
seek
(
0
,
SEEK_END
)
elif
_check_mode
(
mode
,
'wa'
):
self
.
pos
=
self
.
mem_file
.
tell
()
self
.
mem_file
=
StringIO
()
finally
:
self
.
mem_file
.
write
(
value
)
lock
.
release
()
elif
_check_mode
(
mode
,
'w'
):
if
_check_mode
(
mode
,
'w'
):
self
.
mem_file
=
StringIO
()
lock
.
acquire
()
try
:
elif
_check_mode
(
mode
,
'ra'
):
self
.
mem_file
.
seek
(
0
)
self
.
mem_file
=
StringIO
()
self
.
mem_file
.
truncate
()
self
.
mem_file
.
write
(
value
)
finally
:
lock
.
release
()
elif
_check_mode
(
mode
,
'r'
):
self
.
mem_file
=
StringIO
(
value
)
self
.
mem_file
.
seek
(
0
)
elif
_check_mode
(
mode
,
"a"
):
self
.
mem_file
=
StringIO
()
self
.
mem_file
.
write
(
value
)
else
:
if
value
:
self
.
mem_file
=
StringIO
(
value
)
else
:
self
.
mem_file
=
StringIO
()
assert
self
.
mem_file
is
not
None
,
"self.mem_file should have a value"
assert
self
.
mem_file
is
not
None
,
"self.mem_file should have a value"
...
@@ -82,44 +83,57 @@ class MemoryFile(object):
...
@@ -82,44 +83,57 @@ class MemoryFile(object):
self
.
close
()
self
.
close
()
def
flush
(
self
):
def
flush
(
self
):
value
=
self
.
mem_file
.
getvalue
()
pass
self
.
memory_fs
.
_on_flush_memory_file
(
self
.
path
,
value
)
def
__iter__
(
self
):
def
__iter__
(
self
):
return
iter
(
self
.
mem_file
)
return
self
def
next
(
self
):
@seek_and_lock
def
next
(
self
):
return
self
.
mem_file
.
next
()
return
self
.
mem_file
.
next
()
@seek_and_lock
def
readline
(
self
,
*
args
,
**
kwargs
):
def
readline
(
self
,
*
args
,
**
kwargs
):
return
self
.
mem_file
.
readline
(
*
args
,
**
kwargs
)
return
self
.
mem_file
.
readline
(
*
args
,
**
kwargs
)
#@seek_and_lock
def
close
(
self
):
def
close
(
self
):
if
not
self
.
closed
and
self
.
mem_file
is
not
None
:
if
not
self
.
closed
and
self
.
mem_file
is
not
None
:
value
=
self
.
mem_file
.
getvalue
()
self
.
memory_fs
.
_on_close_memory_file
(
self
,
self
.
path
)
self
.
memory_fs
.
_on_close_memory_file
(
self
,
self
.
path
,
value
)
self
.
closed
=
True
self
.
mem_file
.
close
()
self
.
closed
=
True
@seek_and_lock
def
read
(
self
,
size
=
None
):
def
read
(
self
,
size
=
None
):
if
size
is
None
:
if
size
is
None
:
size
=
-
1
size
=
-
1
return
self
.
mem_file
.
read
(
size
)
return
self
.
mem_file
.
read
(
size
)
def
seek
(
self
,
*
args
,
**
kwargs
):
@seek_and_lock
def
seek
(
self
,
*
args
,
**
kwargs
):
return
self
.
mem_file
.
seek
(
*
args
,
**
kwargs
)
return
self
.
mem_file
.
seek
(
*
args
,
**
kwargs
)
@seek_and_lock
def
tell
(
self
):
def
tell
(
self
):
return
self
.
mem_file
.
tell
()
return
self
.
pos
@seek_and_lock
def
truncate
(
self
,
*
args
,
**
kwargs
):
def
truncate
(
self
,
*
args
,
**
kwargs
):
return
self
.
mem_file
.
truncate
(
*
args
,
**
kwargs
)
return
self
.
mem_file
.
truncate
(
*
args
,
**
kwargs
)
def
write
(
self
,
data
):
#@seek_and_lock
def
write
(
self
,
data
):
self
.
memory_fs
.
_on_modify_memory_file
(
self
.
path
)
self
.
memory_fs
.
_on_modify_memory_file
(
self
.
path
)
return
self
.
mem_file
.
write
(
data
)
self
.
lock
.
acquire
()
try
:
def
writelines
(
self
,
*
args
,
**
kwargs
):
self
.
mem_file
.
seek
(
self
.
pos
)
self
.
mem_file
.
write
(
data
)
self
.
pos
=
self
.
mem_file
.
tell
()
finally
:
self
.
lock
.
release
()
@seek_and_lock
def
writelines
(
self
,
*
args
,
**
kwargs
):
return
self
.
mem_file
.
writelines
(
*
args
,
**
kwargs
)
return
self
.
mem_file
.
writelines
(
*
args
,
**
kwargs
)
def
__enter__
(
self
):
def
__enter__
(
self
):
...
@@ -132,6 +146,18 @@ class MemoryFile(object):
...
@@ -132,6 +146,18 @@ class MemoryFile(object):
class
DirEntry
(
object
):
class
DirEntry
(
object
):
def
sync
(
f
):
def
deco
(
self
,
*
args
,
**
kwargs
):
if
self
.
lock
is
not
None
:
try
:
self
.
lock
.
acquire
()
return
f
(
self
,
*
args
,
**
kwargs
)
finally
:
self
.
lock
.
release
()
else
:
return
f
(
self
,
*
args
,
**
kwargs
)
return
deco
def
__init__
(
self
,
type
,
name
,
contents
=
None
):
def
__init__
(
self
,
type
,
name
,
contents
=
None
):
assert
type
in
(
"dir"
,
"file"
),
"Type must be dir or file!"
assert
type
in
(
"dir"
,
"file"
),
"Type must be dir or file!"
...
@@ -143,27 +169,32 @@ class DirEntry(object):
...
@@ -143,27 +169,32 @@ class DirEntry(object):
contents
=
{}
contents
=
{}
self
.
open_files
=
[]
self
.
open_files
=
[]
self
.
contents
=
contents
self
.
contents
=
contents
self
.
data
=
None
self
.
mem_file
=
None
self
.
locks
=
0
self
.
created_time
=
datetime
.
datetime
.
now
()
self
.
created_time
=
datetime
.
datetime
.
now
()
self
.
modified_time
=
self
.
created_time
self
.
modified_time
=
self
.
created_time
self
.
accessed_time
=
self
.
created_time
self
.
accessed_time
=
self
.
created_time
self
.
xattrs
=
{}
self
.
xattrs
=
{}
def
lock
(
self
):
self
.
lock
=
None
self
.
locks
+=
1
if
self
.
type
==
'file'
:
self
.
mem_file
=
StringIO
()
def
unlock
(
self
):
self
.
lock
=
threading
.
RLock
()
self
.
locks
-=
1
assert
self
.
locks
>=
0
,
"Lock / Unlock mismatch!"
def
get_value
(
self
):
self
.
lock
.
acquire
()
try
:
return
self
.
mem_file
.
getvalue
()
finally
:
self
.
lock
.
release
()
data
=
property
(
get_value
)
def
desc_contents
(
self
):
def
desc_contents
(
self
):
if
self
.
isfile
():
if
self
.
isfile
():
return
"<file
%
s>"
%
self
.
name
return
"<file
%
s>"
%
self
.
name
elif
self
.
isdir
():
elif
self
.
isdir
():
return
"<dir
%
s>"
%
""
.
join
(
"
%
s:
%
s"
%
(
k
,
v
.
desc_contents
())
for
k
,
v
in
self
.
contents
.
iteritems
())
return
"<dir
%
s>"
%
""
.
join
(
"
%
s:
%
s"
%
(
k
,
v
.
desc_contents
())
for
k
,
v
in
self
.
contents
.
iteritems
())
def
isdir
(
self
):
def
isdir
(
self
):
return
self
.
type
==
"dir"
return
self
.
type
==
"dir"
...
@@ -171,12 +202,27 @@ class DirEntry(object):
...
@@ -171,12 +202,27 @@ class DirEntry(object):
def
isfile
(
self
):
def
isfile
(
self
):
return
self
.
type
==
"file"
return
self
.
type
==
"file"
def
islocked
(
self
):
return
self
.
locks
>
0
def
__str__
(
self
):
def
__str__
(
self
):
return
"
%
s:
%
s"
%
(
self
.
name
,
self
.
desc_contents
())
return
"
%
s:
%
s"
%
(
self
.
name
,
self
.
desc_contents
())
@sync
def
__getstate__
(
self
):
state
=
self
.
__dict__
.
copy
()
state
.
pop
(
'lock'
)
if
self
.
mem_file
is
not
None
:
state
[
'mem_file'
]
=
self
.
data
return
state
def
__setstate__
(
self
,
state
):
self
.
__dict__
.
update
(
state
)
if
self
.
type
==
'file'
:
self
.
lock
=
threading
.
RLock
()
else
:
self
.
lock
=
None
if
self
.
mem_file
is
not
None
:
data
=
self
.
mem_file
self
.
mem_file
=
StringIO
()
self
.
mem_file
.
write
(
data
)
class
MemoryFS
(
FS
):
class
MemoryFS
(
FS
):
...
@@ -207,7 +253,7 @@ class MemoryFS(FS):
...
@@ -207,7 +253,7 @@ class MemoryFS(FS):
if
not
callable
(
self
.
file_factory
):
if
not
callable
(
self
.
file_factory
):
raise
ValueError
(
"file_factory should be callable"
)
raise
ValueError
(
"file_factory should be callable"
)
self
.
root
=
self
.
_make_dir_entry
(
'dir'
,
'root'
)
self
.
root
=
self
.
_make_dir_entry
(
'dir'
,
'root'
)
def
__str__
(
self
):
def
__str__
(
self
):
return
"<MemoryFS>"
return
"<MemoryFS>"
...
@@ -219,6 +265,7 @@ class MemoryFS(FS):
...
@@ -219,6 +265,7 @@ class MemoryFS(FS):
@synchronize
@synchronize
def
_get_dir_entry
(
self
,
dirpath
):
def
_get_dir_entry
(
self
,
dirpath
):
dirpath
=
normpath
(
dirpath
)
current_dir
=
self
.
root
current_dir
=
self
.
root
for
path_component
in
iteratepath
(
dirpath
):
for
path_component
in
iteratepath
(
dirpath
):
if
current_dir
.
contents
is
None
:
if
current_dir
.
contents
is
None
:
...
@@ -247,27 +294,40 @@ class MemoryFS(FS):
...
@@ -247,27 +294,40 @@ class MemoryFS(FS):
@synchronize
@synchronize
def
isdir
(
self
,
path
):
def
isdir
(
self
,
path
):
dir_item
=
self
.
_get_dir_entry
(
normpath
(
path
))
path
=
normpath
(
path
)
if
path
in
(
''
,
'/'
):
return
True
dir_item
=
self
.
_get_dir_entry
(
path
)
if
dir_item
is
None
:
if
dir_item
is
None
:
return
False
return
False
return
dir_item
.
isdir
()
return
dir_item
.
isdir
()
@synchronize
@synchronize
def
isfile
(
self
,
path
):
def
isfile
(
self
,
path
):
dir_item
=
self
.
_get_dir_entry
(
normpath
(
path
))
path
=
normpath
(
path
)
if
path
in
(
''
,
'/'
):
return
False
dir_item
=
self
.
_get_dir_entry
(
path
)
if
dir_item
is
None
:
if
dir_item
is
None
:
return
False
return
False
return
dir_item
.
isfile
()
return
dir_item
.
isfile
()
@synchronize
@synchronize
def
exists
(
self
,
path
):
def
exists
(
self
,
path
):
path
=
normpath
(
path
)
if
path
in
(
''
,
'/'
):
return
True
return
self
.
_get_dir_entry
(
path
)
is
not
None
return
self
.
_get_dir_entry
(
path
)
is
not
None
@synchronize
@synchronize
def
makedir
(
self
,
dirname
,
recursive
=
False
,
allow_recreate
=
False
):
def
makedir
(
self
,
dirname
,
recursive
=
False
,
allow_recreate
=
False
):
if
not
dirname
and
not
allow_recreate
:
if
not
dirname
and
not
allow_recreate
:
raise
PathError
(
dirname
)
raise
PathError
(
dirname
)
fullpath
=
dirname
fullpath
=
normpath
(
dirname
)
if
fullpath
in
(
''
,
'/'
):
if
allow_recreate
:
return
raise
DestinationExistsError
(
dirname
)
dirpath
,
dirname
=
pathsplit
(
dirname
)
dirpath
,
dirname
=
pathsplit
(
dirname
)
if
recursive
:
if
recursive
:
...
@@ -318,25 +378,10 @@ class MemoryFS(FS):
...
@@ -318,25 +378,10 @@ class MemoryFS(FS):
parent_dir
.
contents
[
dirname
]
=
self
.
_make_dir_entry
(
"dir"
,
dirname
)
parent_dir
.
contents
[
dirname
]
=
self
.
_make_dir_entry
(
"dir"
,
dirname
)
@synchronize
#@synchronize
def
_orphan_files
(
self
,
file_dir_entry
):
#def _orphan_files(self, file_dir_entry):
for
f
in
file_dir_entry
.
open_files
[:]:
# for f in file_dir_entry.open_files[:]:
f
.
close
()
# f.close()
@synchronize
def
_lock_dir_entry
(
self
,
path
):
dir_entry
=
self
.
_get_dir_entry
(
path
)
dir_entry
.
lock
()
@synchronize
def
_unlock_dir_entry
(
self
,
path
):
dir_entry
=
self
.
_get_dir_entry
(
path
)
dir_entry
.
unlock
()
@synchronize
def
_is_dir_locked
(
self
,
path
):
dir_entry
=
self
.
_get_dir_entry
(
path
)
return
dir_entry
.
islocked
()
@synchronize
@synchronize
def
open
(
self
,
path
,
mode
=
"r"
,
**
kwargs
):
def
open
(
self
,
path
,
mode
=
"r"
,
**
kwargs
):
...
@@ -353,14 +398,10 @@ class MemoryFS(FS):
...
@@ -353,14 +398,10 @@ class MemoryFS(FS):
file_dir_entry
=
parent_dir_entry
.
contents
[
filename
]
file_dir_entry
=
parent_dir_entry
.
contents
[
filename
]
if
file_dir_entry
.
isdir
():
if
file_dir_entry
.
isdir
():
raise
ResourceInvalidError
(
path
)
raise
ResourceInvalidError
(
path
)
if
'a'
in
mode
:
if
file_dir_entry
.
islocked
():
raise
ResourceLockedError
(
path
)
file_dir_entry
.
accessed_time
=
datetime
.
datetime
.
now
()
file_dir_entry
.
accessed_time
=
datetime
.
datetime
.
now
()
self
.
_lock_dir_entry
(
path
)
mem_file
=
self
.
file_factory
(
path
,
self
,
file_dir_entry
.
mem_file
,
mode
,
file_dir_entry
.
lock
)
mem_file
=
self
.
file_factory
(
path
,
self
,
file_dir_entry
.
data
,
mode
)
file_dir_entry
.
open_files
.
append
(
mem_file
)
file_dir_entry
.
open_files
.
append
(
mem_file
)
return
mem_file
return
mem_file
...
@@ -371,13 +412,9 @@ class MemoryFS(FS):
...
@@ -371,13 +412,9 @@ class MemoryFS(FS):
else
:
else
:
file_dir_entry
=
parent_dir_entry
.
contents
[
filename
]
file_dir_entry
=
parent_dir_entry
.
contents
[
filename
]
if
file_dir_entry
.
islocked
():
raise
ResourceLockedError
(
path
)
file_dir_entry
.
accessed_time
=
datetime
.
datetime
.
now
()
file_dir_entry
.
accessed_time
=
datetime
.
datetime
.
now
()
self
.
_lock_dir_entry
(
path
)
mem_file
=
self
.
file_factory
(
path
,
self
,
file_dir_entry
.
mem_file
,
mode
,
file_dir_entry
.
lock
)
mem_file
=
self
.
file_factory
(
path
,
self
,
None
,
mode
)
file_dir_entry
.
open_files
.
append
(
mem_file
)
file_dir_entry
.
open_files
.
append
(
mem_file
)
return
mem_file
return
mem_file
...
@@ -391,10 +428,6 @@ class MemoryFS(FS):
...
@@ -391,10 +428,6 @@ class MemoryFS(FS):
if
dir_entry
is
None
:
if
dir_entry
is
None
:
raise
ResourceNotFoundError
(
path
)
raise
ResourceNotFoundError
(
path
)
if
dir_entry
.
islocked
():
self
.
_orphan_files
(
dir_entry
)
#raise ResourceLockedError(path)
if
dir_entry
.
isdir
():
if
dir_entry
.
isdir
():
raise
ResourceInvalidError
(
path
,
msg
=
"That's a directory, not a file:
%(path)
s"
)
raise
ResourceInvalidError
(
path
,
msg
=
"That's a directory, not a file:
%(path)
s"
)
...
@@ -410,8 +443,6 @@ class MemoryFS(FS):
...
@@ -410,8 +443,6 @@ class MemoryFS(FS):
if
dir_entry
is
None
:
if
dir_entry
is
None
:
raise
ResourceNotFoundError
(
path
)
raise
ResourceNotFoundError
(
path
)
if
dir_entry
.
islocked
():
raise
ResourceLockedError
(
path
)
if
not
dir_entry
.
isdir
():
if
not
dir_entry
.
isdir
():
raise
ResourceInvalidError
(
path
,
msg
=
"Can't remove resource, its not a directory:
%(path)
s"
)
raise
ResourceInvalidError
(
path
,
msg
=
"Can't remove resource, its not a directory:
%(path)
s"
)
...
@@ -471,17 +502,10 @@ class MemoryFS(FS):
...
@@ -471,17 +502,10 @@ class MemoryFS(FS):
return
False
return
False
@synchronize
@synchronize
def
_on_close_memory_file
(
self
,
open_file
,
path
,
value
):
def
_on_close_memory_file
(
self
,
open_file
,
path
):
dir_entry
=
self
.
_get_dir_entry
(
path
)
dir_entry
=
self
.
_get_dir_entry
(
path
)
if
dir_entry
is
not
None
and
value
is
not
None
:
dir_entry
.
open_files
.
remove
(
open_file
)
dir_entry
.
data
=
value
dir_entry
.
open_files
.
remove
(
open_file
)
self
.
_unlock_dir_entry
(
path
)
@synchronize
def
_on_flush_memory_file
(
self
,
path
,
value
):
dir_entry
=
self
.
_get_dir_entry
(
path
)
dir_entry
.
data
=
value
@synchronize
@synchronize
def
_on_modify_memory_file
(
self
,
path
):
def
_on_modify_memory_file
(
self
,
path
):
...
@@ -571,7 +595,7 @@ class MemoryFS(FS):
...
@@ -571,7 +595,7 @@ class MemoryFS(FS):
if
dir_entry
is
None
:
if
dir_entry
is
None
:
raise
ResourceNotFoundError
(
path
)
raise
ResourceNotFoundError
(
path
)
if
not
dir_entry
.
isfile
():
if
not
dir_entry
.
isfile
():
raise
ResourceInvalidError
(
path
,
msg
=
"not a
directory
:
%(path)
s"
)
raise
ResourceInvalidError
(
path
,
msg
=
"not a
file
:
%(path)
s"
)
return
dir_entry
.
data
or
''
return
dir_entry
.
data
or
''
@synchronize
@synchronize
...
@@ -584,7 +608,9 @@ class MemoryFS(FS):
...
@@ -584,7 +608,9 @@ class MemoryFS(FS):
dir_entry
=
self
.
_get_dir_entry
(
path
)
dir_entry
=
self
.
_get_dir_entry
(
path
)
if
not
dir_entry
.
isfile
():
if
not
dir_entry
.
isfile
():
raise
ResourceInvalidError
(
'Not a directory
%(path)
s'
,
path
)
raise
ResourceInvalidError
(
'Not a directory
%(path)
s'
,
path
)
dir_entry
.
data
=
data
new_mem_file
=
StringIO
()
new_mem_file
.
write
(
data
)
dir_entry
.
mem_file
=
new_mem_file
@synchronize
@synchronize
def
setxattr
(
self
,
path
,
key
,
value
):
def
setxattr
(
self
,
path
,
key
,
value
):
...
...
fs/opener.py
View file @
7f1e44a3
...
@@ -365,7 +365,7 @@ class TempOpener(Opener):
...
@@ -365,7 +365,7 @@ class TempOpener(Opener):
@classmethod
@classmethod
def
get_fs
(
cls
,
registry
,
fs_name
,
fs_name_params
,
fs_path
,
writeable
,
create
):
def
get_fs
(
cls
,
registry
,
fs_name
,
fs_name_params
,
fs_path
,
writeable
,
create
):
from
fs.tempfs
import
TempFS
from
fs.tempfs
import
TempFS
return
TempFS
(
identifier
=
fs_name_params
,
temp_dir
=
fs_path
,
create
=
create
),
None
return
TempFS
(
identifier
=
fs_name_params
,
temp_dir
=
fs_path
),
None
opener
=
OpenerRegistry
([
OSFSOpener
,
opener
=
OpenerRegistry
([
OSFSOpener
,
...
...
fs/osfs/__init__.py
View file @
7f1e44a3
...
@@ -98,6 +98,7 @@ class OSFS(OSFSXAttrMixin, OSFSWatchMixin, FS):
...
@@ -98,6 +98,7 @@ class OSFS(OSFSXAttrMixin, OSFSWatchMixin, FS):
super
(
OSFS
,
self
)
.
__init__
(
thread_synchronize
=
thread_synchronize
)
super
(
OSFS
,
self
)
.
__init__
(
thread_synchronize
=
thread_synchronize
)
self
.
encoding
=
encoding
or
sys
.
getfilesystemencoding
()
self
.
encoding
=
encoding
or
sys
.
getfilesystemencoding
()
self
.
dir_mode
=
dir_mode
root_path
=
os
.
path
.
expanduser
(
os
.
path
.
expandvars
(
root_path
))
root_path
=
os
.
path
.
expanduser
(
os
.
path
.
expandvars
(
root_path
))
root_path
=
os
.
path
.
normpath
(
os
.
path
.
abspath
(
root_path
))
root_path
=
os
.
path
.
normpath
(
os
.
path
.
abspath
(
root_path
))
# Enable long pathnames on win32
# Enable long pathnames on win32
...
@@ -319,4 +320,23 @@ class OSFS(OSFSXAttrMixin, OSFSWatchMixin, FS):
...
@@ -319,4 +320,23 @@ class OSFS(OSFSXAttrMixin, OSFSWatchMixin, FS):
def
getsize
(
self
,
path
):
def
getsize
(
self
,
path
):
return
self
.
_stat
(
path
)
.
st_size
return
self
.
_stat
(
path
)
.
st_size
@convert_os_errors
def
opendir
(
self
,
path
):
"""A specialised opendir that returns another OSFS rather than a SubDir
This is more optimal than a SubDir because no path delegation is required.
"""
if
path
in
(
''
,
'/'
):
return
self
path
=
normpath
(
path
)
if
not
self
.
exists
(
path
):
raise
ResourceNotFoundError
(
path
)
sub_path
=
pathjoin
(
self
.
root_path
,
path
)
return
OSFS
(
sub_path
,
thread_synchronize
=
self
.
thread_synchronize
,
encoding
=
self
.
encoding
,
create
=
False
,
dir_mode
=
self
.
dir_mode
)
fs/rpcfs.py
View file @
7f1e44a3
...
@@ -38,7 +38,7 @@ def re_raise_faults(func):
...
@@ -38,7 +38,7 @@ def re_raise_faults(func):
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
:
raise
cls
(
msg
=
msg
)
raise
cls
(
''
,
msg
=
msg
)
raise
f
raise
f
except
socket
.
error
,
e
:
except
socket
.
error
,
e
:
raise
RemoteConnectionError
(
str
(
e
),
details
=
e
)
raise
RemoteConnectionError
(
str
(
e
),
details
=
e
)
...
...
setup.py
View file @
7f1e44a3
...
@@ -12,7 +12,8 @@ COMMANDS = ['fscat',
...
@@ -12,7 +12,8 @@ COMMANDS = ['fscat',
'fsrm'
,
'fsrm'
,
'fsserve'
,
'fsserve'
,
'fstree'
,
'fstree'
,
'fsmkdir'
]
'fsmkdir'
,
'fsmount'
]
classifiers
=
[
classifiers
=
[
...
...
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