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
e1a641f3
Commit
e1a641f3
authored
Aug 21, 2008
by
willmcgugan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added thread syncronisation to filesystem objects
parent
53b69ae5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
193 additions
and
80 deletions
+193
-80
fs/fs.py
+23
-1
fs/memoryfs.py
+0
-0
fs/mountfs.py
+0
-0
fs/multifs.py
+141
-74
fs/osfs.py
+1
-0
fs/path.py
+28
-5
No files found.
fs/fs.py
View file @
e1a641f3
...
...
@@ -5,7 +5,10 @@ import os.path
import
fnmatch
from
itertools
import
chain
import
datetime
try
:
import
threading
except
ImportError
:
import
dummy_threading
as
threadding
error_msgs
=
{
...
...
@@ -303,6 +306,18 @@ def print_fs(fs, path="/", max_levels=None, indent=' '*2):
print_dir
(
fs
,
path
,
0
)
def
_synchronize
(
func
):
def
acquire_lock
(
self
,
*
args
,
**
kwargs
):
self
.
_lock
.
acquire
()
try
:
return
func
(
self
,
*
args
,
**
kwargs
)
finally
:
self
.
_lock
.
release
()
acquire_lock
.
__doc__
=
func
.
__doc__
return
acquire_lock
class
FS
(
object
):
"""The base class for Filesystem objects. An instance of a class derived from FS is an abstraction
...
...
@@ -310,6 +325,13 @@ class FS(object):
"""
def
__init__
(
self
,
thread_syncronize
=
False
):
if
thread_syncronize
:
self
.
_lock
=
threading
.
RLock
()
else
:
self
.
_lock
=
None
def
_resolve
(
self
,
pathname
):
resolved_path
=
resolvepath
(
pathname
)
return
resolved_path
...
...
fs/memoryfs.py
View file @
e1a641f3
This diff is collapsed.
Click to expand it.
fs/mountfs.py
View file @
e1a641f3
This diff is collapsed.
Click to expand it.
fs/multifs.py
View file @
e1a641f3
...
...
@@ -5,7 +5,7 @@ from fs import FS, FSError
class
MultiFS
(
FS
):
def
__init__
(
self
):
FS
.
__init__
(
self
)
FS
.
__init__
(
self
,
thread_syncronize
=
True
)
self
.
fs_sequence
=
[]
self
.
fs_lookup
=
{}
...
...
@@ -14,23 +14,39 @@ class MultiFS(FS):
return
"<MultiFS:
%
s>"
%
", "
.
join
(
str
(
fs
)
for
fs
in
self
.
fs_sequence
)
def
addfs
(
self
,
name
,
fs
):
if
name
in
self
.
fs_lookup
:
raise
ValueError
(
"Name already exists."
)
self
.
_lock
.
acquire
()
try
:
if
name
in
self
.
fs_lookup
:
raise
ValueError
(
"Name already exists."
)
self
.
fs_sequence
.
append
(
fs
)
self
.
fs_lookup
[
name
]
=
fs
self
.
fs_sequence
.
append
(
fs
)
self
.
fs_lookup
[
name
]
=
fs
finally
:
self
.
_lock
.
release
()
def
removefs
(
self
,
name
):
fs
=
self
.
fs_lookup
[
name
]
self
.
fs_sequence
.
remove
(
fs
)
del
self
.
fs_lookup
[
name
]
self
.
_lock
.
acquire
()
try
:
fs
=
self
.
fs_lookup
[
name
]
self
.
fs_sequence
.
remove
(
fs
)
del
self
.
fs_lookup
[
name
]
finally
:
self
.
_lock
.
release
()
def
__getitem__
(
self
,
name
):
return
self
.
fs_lookup
[
name
]
self
.
_lock
.
acquire
()
try
:
return
self
.
fs_lookup
[
name
]
finally
:
self
.
_lock
.
release
()
def
__iter__
(
self
):
return
iter
(
self
.
fs_sequence
)
self
.
_lock
.
acquire
()
try
:
return
iter
(
self
.
fs_sequence
[:])
finally
:
self
.
_lock
.
release
()
def
_delegate_search
(
self
,
path
):
for
fs
in
self
:
...
...
@@ -39,97 +55,148 @@ class MultiFS(FS):
return
None
def
which
(
self
,
path
):
for
fs
in
self
:
if
fs
.
exists
(
path
):
for
fs_name
,
fs_object
in
self
.
fs_lookup
.
iteritems
():
if
fs
is
fs_object
:
return
fs_name
,
fs
return
None
,
None
self
.
_lock
.
acquire
()
try
:
for
fs
in
self
:
if
fs
.
exists
(
path
):
for
fs_name
,
fs_object
in
self
.
fs_lookup
.
iteritems
():
if
fs
is
fs_object
:
return
fs_name
,
fs
return
None
,
None
finally
:
self
.
_lock
.
release
()
def
getsyspath
(
self
,
path
):
fs
=
self
.
_delegate_search
(
path
)
if
fs
is
not
None
:
return
fs
.
getsyspath
(
path
)
self
.
_lock
.
acquire
()
try
:
fs
=
self
.
_delegate_search
(
path
)
if
fs
is
not
None
:
return
fs
.
getsyspath
(
path
)
raise
ResourceNotFoundError
(
"NO_FILE"
,
path
)
raise
ResourceNotFoundError
(
"NO_FILE"
,
path
)
finally
:
self
.
_lock
.
release
()
def
desc
(
self
,
path
):
if
not
self
.
exists
(
path
):
raise
FSError
(
"NO_RESOURCE"
,
path
)
name
,
fs
=
self
.
which
(
path
)
if
name
is
None
:
return
""
return
"
%
s, on
%
s (
%
s)"
%
(
fs
.
desc
(
path
),
name
,
fs
)
self
.
_lock
.
acquire
()
try
:
if
not
self
.
exists
(
path
):
raise
FSError
(
"NO_RESOURCE"
,
path
)
name
,
fs
=
self
.
which
(
path
)
if
name
is
None
:
return
""
return
"
%
s, on
%
s (
%
s)"
%
(
fs
.
desc
(
path
),
name
,
fs
)
finally
:
self
.
_lock
.
release
()
def
open
(
self
,
path
,
mode
=
"r"
,
buffering
=-
1
,
**
kwargs
):
for
fs
in
self
:
if
fs
.
exists
(
path
):
fs_file
=
fs
.
open
(
path
,
mode
,
buffering
,
**
kwargs
)
return
fs_file
self
.
_lock
.
acquire
()
try
:
for
fs
in
self
:
if
fs
.
exists
(
path
):
fs_file
=
fs
.
open
(
path
,
mode
,
buffering
,
**
kwargs
)
return
fs_file
raise
ResourceNotFoundError
(
"NO_FILE"
,
path
)
raise
ResourceNotFoundError
(
"NO_FILE"
,
path
)
finally
:
self
.
_lock
.
release
()
def
exists
(
self
,
path
):
return
self
.
_delegate_search
(
path
)
is
not
None
self
.
_lock
.
acquire
()
try
:
return
self
.
_delegate_search
(
path
)
is
not
None
finally
:
self
.
_lock
.
release
()
def
isdir
(
self
,
path
):
fs
=
self
.
_delegate_search
(
path
)
if
fs
is
not
None
:
return
fs
.
isdir
(
path
)
return
False
self
.
_lock
.
acquire
()
try
:
fs
=
self
.
_delegate_search
(
path
)
if
fs
is
not
None
:
return
fs
.
isdir
(
path
)
return
False
finally
:
self
.
_lock
.
release
()
def
isfile
(
self
,
path
):
fs
=
self
.
_delegate_search
(
path
)
if
fs
is
not
None
:
return
fs
.
isfile
(
path
)
return
False
self
.
_lock
.
acquire
()
try
:
fs
=
self
.
_delegate_search
(
path
)
if
fs
is
not
None
:
return
fs
.
isfile
(
path
)
return
False
finally
:
self
.
_lock
.
release
()
def
ishidden
(
self
,
path
):
fs
=
self
.
_delegate_search
(
path
)
if
fs
is
not
None
:
return
fs
.
isfile
(
path
)
return
False
self
.
_lock
.
acquire
()
try
:
fs
=
self
.
_delegate_search
(
path
)
if
fs
is
not
None
:
return
fs
.
isfile
(
path
)
return
False
finally
:
self
.
_lock
.
release
()
def
listdir
(
self
,
path
=
"./"
,
*
args
,
**
kwargs
):
paths
=
[]
for
fs
in
self
:
try
:
paths
+=
fs
.
listdir
(
path
,
*
args
,
**
kwargs
)
except
FSError
,
e
:
pass
return
list
(
set
(
paths
))
self
.
_lock
.
acquire
()
try
:
paths
=
[]
for
fs
in
self
:
try
:
paths
+=
fs
.
listdir
(
path
,
*
args
,
**
kwargs
)
except
FSError
,
e
:
pass
return
list
(
set
(
paths
))
finally
:
self
.
_lock
.
release
()
def
remove
(
self
,
path
):
for
fs
in
self
:
if
fs
.
exists
(
path
):
fs
.
remove
(
path
)
return
raise
ResourceNotFoundError
(
"NO_FILE"
,
path
)
self
.
_lock
.
acquire
()
try
:
for
fs
in
self
:
if
fs
.
exists
(
path
):
fs
.
remove
(
path
)
return
raise
ResourceNotFoundError
(
"NO_FILE"
,
path
)
finally
:
self
.
_lock
.
release
()
def
removedir
(
self
,
path
,
recursive
=
False
):
for
fs
in
self
:
if
fs
.
isdir
(
path
):
fs
.
removedir
(
path
,
recursive
)
return
raise
ResourceNotFoundError
(
"NO_DIR"
,
path
)
self
.
_lock
.
acquire
()
try
:
for
fs
in
self
:
if
fs
.
isdir
(
path
):
fs
.
removedir
(
path
,
recursive
)
return
raise
ResourceNotFoundError
(
"NO_DIR"
,
path
)
finally
:
self
.
_lock
.
release
()
def
rename
(
self
,
src
,
dst
):
for
fs
in
self
:
if
fs
.
exists
(
src
):
fs
.
rename
(
src
,
dst
)
return
raise
FSError
(
"NO_RESOURCE"
,
path
)
self
.
_lock
.
acquire
()
try
:
for
fs
in
self
:
if
fs
.
exists
(
src
):
fs
.
rename
(
src
,
dst
)
return
raise
FSError
(
"NO_RESOURCE"
,
path
)
finally
:
self
.
_lock
.
release
()
def
getinfo
(
self
,
path
):
for
fs
in
self
:
if
fs
.
exists
(
path
):
return
fs
.
getinfo
(
path
)
raise
ResourceNotFoundError
(
"NO_FILE"
,
path
)
self
.
_lock
.
acquire
()
try
:
for
fs
in
self
:
if
fs
.
exists
(
path
):
return
fs
.
getinfo
(
path
)
raise
ResourceNotFoundError
(
"NO_FILE"
,
path
)
finally
:
self
.
_lock
.
release
()
if
__name__
==
"__main__"
:
...
...
fs/osfs.py
View file @
e1a641f3
...
...
@@ -5,6 +5,7 @@ from fs import *
class
OSFS
(
FS
):
def
__init__
(
self
,
root_path
):
FS
.
__init__
(
self
)
expanded_path
=
normpath
(
os
.
path
.
expanduser
(
os
.
path
.
expandvars
(
root_path
)))
...
...
fs/path.py
View file @
e1a641f3
#!/usr/bin/env python
import
fs
from
os
import
path
class
Path
(
unicode
):
def
__repr__
(
self
):
return
"Path(
%
s)"
%
unicode
.
__repr__
(
self
)
def
__add__
(
self
,
path
):
return
self
.
__class__
(
unicode
.
__add__
(
self
,
path
))
def
__radd__
(
self
,
path
):
return
self
.
__class__
(
path
.
__add__
(
self
))
def
join
(
self
,
*
paths
):
return
Path
(
path
.
join
(
self
,
*
paths
))
return
self
.
__class__
(
fs
.
path
join
(
self
,
*
paths
))
def
_get_ext
(
self
):
return
path
.
splitext
(
self
)[
-
1
]
...
...
@@ -13,24 +22,38 @@ class Path(unicode):
def
_get_head
(
self
):
head
,
tail
=
path
.
split
(
self
)
return
Path
(
head
)
return
self
.
__class__
(
head
)
head
=
property
(
_get_head
,
None
,
"Retrieve the head of the path"
)
def
_get_tail
(
self
):
head
,
tail
=
path
.
split
(
self
)
return
Path
(
tail
)
return
self
.
__class__
(
tail
)
tail
=
property
(
_get_tail
,
None
,
"Retrieve the head of the path"
)
def
splitall
(
self
):
return
[
p
for
p
in
self
.
split
(
'/'
)
if
p
]
def
replace
(
self
,
s1
,
s2
):
return
self
.
__class__
(
unicode
.
replace
(
self
,
s1
,
s2
))
def
__getitem__
(
self
,
slice
):
return
self
.
__class__
(
unicode
.
__getitem__
(
self
,
slice
))
def
__div__
(
self
,
pth
):
return
self
.
join
(
pth
)
__truediv__
=
__div__
if
__name__
==
"__main__"
:
p1
=
Path
(
"a/b"
)
p2
=
p1
.
join
(
"c/d.txt"
)
print
repr
(
p1
.
replace
(
'a'
,
'HAI!'
))
print
repr
(
p1
[
0
])
print
repr
(
p1
+
p2
)
print
p1
/
"d/e/f"
print
p2
print
p2
.
ext
print
p2
.
head
print
p2
.
tail
print
p2
print
p2
.
splitall
()
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