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
1865b55d
Commit
1865b55d
authored
Sep 05, 2008
by
willmcgugan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added depth first search for the walk method, added a number of docstrings.
parent
a797dfb3
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
131 additions
and
38 deletions
+131
-38
fs/fs.py
+119
-29
fs/memoryfs.py
+1
-1
fs/mountfs.py
+1
-1
fs/multifs.py
+4
-5
fs/osfs.py
+6
-2
No files found.
fs/fs.py
View file @
1865b55d
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
import
os
import
os
import
os.path
import
os.path
import
shutil
import
fnmatch
import
fnmatch
from
itertools
import
chain
from
itertools
import
chain
import
datetime
import
datetime
...
@@ -26,6 +27,7 @@ error_msgs = {
...
@@ -26,6 +27,7 @@ error_msgs = {
"REMOVE_FAILED"
:
"Unable to remove file:
%(path)
s"
,
"REMOVE_FAILED"
:
"Unable to remove file:
%(path)
s"
,
"REMOVEDIR_FAILED"
:
"Unable to remove dir:
%(path)
s"
,
"REMOVEDIR_FAILED"
:
"Unable to remove dir:
%(path)
s"
,
"GETSIZE_FAILED"
:
"Unable to retrieve size of resource:
%(path)
s"
,
"GETSIZE_FAILED"
:
"Unable to retrieve size of resource:
%(path)
s"
,
"COPYFILE_FAILED"
:
"Unable to copy file:
%(path)
s"
,
# NoSysPathError
# NoSysPathError
"NO_SYS_PATH"
:
"No mapping to OS filesytem:
%(path)
s,"
,
"NO_SYS_PATH"
:
"No mapping to OS filesytem:
%(path)
s,"
,
...
@@ -55,7 +57,7 @@ class FSError(Exception):
...
@@ -55,7 +57,7 @@ class FSError(Exception):
"""A catch all exception for FS objects."""
"""A catch all exception for FS objects."""
def
__init__
(
self
,
code
,
path
=
None
,
msg
=
None
,
details
=
None
):
def
__init__
(
self
,
code
,
path
=
None
,
path2
=
None
,
msg
=
None
,
details
=
None
):
"""
"""
code -- A short identifier for the error
code -- A short identifier for the error
...
@@ -335,18 +337,17 @@ class FS(object):
...
@@ -335,18 +337,17 @@ class FS(object):
return
pathjoin
(
'/'
,
pathname
)
return
pathjoin
(
'/'
,
pathname
)
return
pathname
return
pathname
def
getsyspath
(
self
,
path
,
default
=
Non
e
):
def
getsyspath
(
self
,
path
,
allow_none
=
Fals
e
):
"""Returns the system path (a path recognised by the operating system) if present.
"""Returns the system path (a path recognised by the operating system) if present.
If the path does not map to a system path, then either the default is returned (if given),
If the path does not map to a system path (and allow_none is False) then a NoSysPathError exception is thrown.
or a NoSysPathError exception is thrown.
path -- A path within the filesystem
path -- A path within the filesystem
default -- A default value to return if there is no mapping to an operating
system path
allow_none -- If True, this method can return None if there is no
system path
"""
"""
if
default
is
N
one
:
if
not
allow_n
one
:
raise
NoSysPathError
(
"NO_SYS_PATH"
,
path
)
raise
NoSysPathError
(
"NO_SYS_PATH"
,
path
)
return
default
return
None
def
open
(
self
,
path
,
mode
=
"r"
,
buffering
=-
1
,
**
kwargs
):
def
open
(
self
,
path
,
mode
=
"r"
,
buffering
=-
1
,
**
kwargs
):
raise
UnsupportedError
(
"UNSUPPORTED"
)
raise
UnsupportedError
(
"UNSUPPORTED"
)
...
@@ -368,15 +369,36 @@ class FS(object):
...
@@ -368,15 +369,36 @@ class FS(object):
raise
UnsupportedError
(
"UNSUPPORTED"
)
raise
UnsupportedError
(
"UNSUPPORTED"
)
def
isdir
(
self
,
path
):
def
isdir
(
self
,
path
):
"""Returns True if a given path references a directory."""
raise
UnsupportedError
(
"UNSUPPORTED"
)
raise
UnsupportedError
(
"UNSUPPORTED"
)
def
isfile
(
self
,
path
):
def
isfile
(
self
,
path
):
"""Returns True if a given path references a file."""
raise
UnsupportedError
(
"UNSUPPORTED"
)
raise
UnsupportedError
(
"UNSUPPORTED"
)
def
ishidden
(
self
,
path
):
def
ishidden
(
self
,
path
):
"""Returns True if the given path is hidden."""
return
path
.
startswith
(
'.'
)
return
path
.
startswith
(
'.'
)
def
listdir
(
self
,
path
=
"./"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
hidden
=
False
,
dirs_only
=
False
,
files_only
=
False
):
def
listdir
(
self
,
path
=
"./"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
hidden
=
True
,
dirs_only
=
False
,
files_only
=
False
):
"""Lists all the files and directories in a path. Returns a list of paths.
path -- Root of the path to list
wildcard -- Only returns paths that match this wildcard, default does no matching
full -- Returns a full path
absolute -- Returns an absolute path
hidden -- If True, return hidden files
dirs_only -- If True, only return directories
files_only -- If True, only return files
"""
raise
UnsupportedError
(
"UNSUPPORTED"
)
raise
UnsupportedError
(
"UNSUPPORTED"
)
def
makedir
(
self
,
path
,
mode
=
0777
,
recursive
=
False
):
def
makedir
(
self
,
path
,
mode
=
0777
,
recursive
=
False
):
...
@@ -434,7 +456,7 @@ class FS(object):
...
@@ -434,7 +456,7 @@ class FS(object):
if
wildcard
is
not
None
:
if
wildcard
is
not
None
:
match
=
fnmatch
.
fnmatch
match
=
fnmatch
.
fnmatch
paths
=
[
p
for
p
in
path
if
match
(
p
,
wildcard
)]
paths
=
[
p
for
p
in
path
s
if
match
(
p
,
wildcard
)]
if
not
hidden
:
if
not
hidden
:
paths
=
[
p
for
p
in
paths
if
not
self
.
ishidden
(
p
)]
paths
=
[
p
for
p
in
paths
if
not
self
.
ishidden
(
p
)]
...
@@ -452,29 +474,38 @@ class FS(object):
...
@@ -452,29 +474,38 @@ class FS(object):
return
paths
return
paths
def
walkfiles
(
self
,
path
=
"/"
,
wildcard
=
None
,
dir_wildcard
=
None
):
def
walkfiles
(
self
,
path
=
"/"
,
wildcard
=
None
,
dir_wildcard
=
None
,
search
=
"breadth"
):
dirs
=
[
path
]
files
=
[]
while
dirs
:
"""Like the 'walk' method, but just yields files.
current_path
=
dirs
.
pop
()
path -- Root path to start walking
wildcard -- If given, only return files that match this wildcard
dir_wildcard -- If given, only walk in to directories that match this wildcard
search -- A string that identifies the method used to walk the directories,
can be 'breadth' for a breadth first search, or 'depth' for a depth first
search. Use 'depth' if you plan to create / delete files as you go.
for
path
in
self
.
listdir
(
current_path
,
full
=
True
):
"""
if
self
.
isdir
(
path
):
if
dir_wildcard
is
not
None
:
for
path
,
files
in
self
.
walk
(
path
,
wildcard
,
dir_wildcard
,
search
):
if
fnmatch
.
fnmatch
(
path
,
dir_wilcard
):
for
f
in
files
:
dirs
.
append
(
path
)
yield
f
else
:
dirs
.
append
(
path
)
else
:
def
walk
(
self
,
path
=
"/"
,
wildcard
=
None
,
dir_wildcard
=
None
,
search
=
"breadth"
):
if
wildcard
is
not
None
:
"""Walks a directory tree and yields the root path and contents.
if
fnmatch
.
fnmatch
(
path
,
wildcard
):
Yields a tuple of the path of each directory and a list of its file contents.
yield
path
else
:
path -- Root path to start walking
yield
path
wildcard -- If given, only return files that match this wildcard
dir_wildcard -- If given, only walk in to directories that match this wildcard
search -- A string that identifies the method used to walk the directories,
can be 'breadth' for a breadth first search, or 'depth' for a depth first
search. Use 'depth' if you plan to create / delete files as you go.
def
walk
(
self
,
path
=
"/"
,
wildcard
=
None
,
dir_wildcard
=
None
):
"""
if
search
==
"breadth"
:
dirs
=
[
path
]
dirs
=
[
path
]
while
dirs
:
while
dirs
:
current_path
=
dirs
.
pop
()
current_path
=
dirs
.
pop
()
...
@@ -496,6 +527,19 @@ class FS(object):
...
@@ -496,6 +527,19 @@ class FS(object):
paths
.
append
(
path
)
paths
.
append
(
path
)
yield
(
current_path
,
paths
)
yield
(
current_path
,
paths
)
elif
search
==
"depth"
:
def
recurse
(
recurse_path
):
for
path
in
self
.
listdir
(
recurse_path
,
wildcard
=
dir_wildcard
,
full
=
True
,
dirs_only
=
True
):
for
p
in
recurse
(
path
):
yield
p
yield
(
recurse_path
,
self
.
listdir
(
recurse_path
,
wildcard
=
wildcard
,
full
=
True
,
files_only
=
True
))
for
p
in
recurse
(
path
):
yield
p
else
:
raise
ValueError
(
"Search should be 'breadth' or 'depth'"
)
def
getsize
(
self
,
path
):
def
getsize
(
self
,
path
):
"""Returns the size (in bytes) of a resource.
"""Returns the size (in bytes) of a resource.
...
@@ -509,6 +553,52 @@ class FS(object):
...
@@ -509,6 +553,52 @@ class FS(object):
raise
OperationFailedError
(
"GETSIZE_FAILED"
,
path
)
raise
OperationFailedError
(
"GETSIZE_FAILED"
,
path
)
return
size
return
size
def
copyfile
(
self
,
src
,
dst
,
overwrite
=
False
,
chunk_size
=
1024
*
16384
):
src_syspath
=
self
.
getsyspath
(
src
,
allow_none
=
True
)
dst_syspath
=
self
.
getsyspath
(
dst
,
allow_none
=
True
)
if
not
self
.
isdir
(
src
):
raise
ResourceInvalid
(
"WRONG_TYPE"
,
src
,
msg
=
"Source is not a file:
%(path)
s"
)
if
not
self
.
isdir
(
dst
):
raise
ResourceInvalid
(
"WRONG_TYPE"
,
dst
,
msg
=
"Source is not a file:
%(path)
s"
)
if
src_syspath
is
not
None
and
dst_syspath
is
not
None
:
shutil
.
copyfile
(
src_syspath
,
dst_syspath
)
else
:
src_file
,
dst_file
=
None
,
None
try
:
src_file
=
self
.
open
(
src
,
"rb"
)
if
not
overwrite
:
if
self
.
exists
(
dst
):
raise
OperationFailedError
(
"COPYFILE_FAILED"
,
src
,
dst
,
msg
=
"Destination file exists:
%(path2)
s"
)
dst_file
=
self
.
open
(
src
,
"wb"
)
while
True
:
chunk
=
src_file
.
read
(
chunk_size
)
dst_file
.
write
(
chunk
)
if
len
(
chunk
)
!=
chunk_size
:
break
finally
:
if
src_file
is
not
None
:
src_file
.
close
()
if
dst_file
is
not
None
:
dst_file
.
close
()
def
movefile
(
self
,
src
,
dst
):
src_syspath
=
self
.
getsyspath
(
src
,
allow_none
=
True
)
dst_syspath
=
self
.
getsyspath
(
dst
,
allow_none
=
True
)
if
src_syspath
is
not
None
and
dst_syspath
is
not
None
:
if
not
self
.
isdir
(
src
):
raise
ResourceInvalid
(
"WRONG_TYPE"
,
src
,
msg
=
"Source is not a file:
%(path)
s"
)
if
not
self
.
isdir
(
dst
):
raise
ResourceInvalid
(
"WRONG_TYPE"
,
dst
,
msg
=
"Source is not a file:
%(path)
s"
)
shutil
.
move
(
src_syspath
,
dst_syspath
)
else
:
self
.
copyfile
(
src
,
dst
)
self
.
remove
(
src
)
class
SubFS
(
FS
):
class
SubFS
(
FS
):
...
@@ -561,7 +651,7 @@ class SubFS(FS):
...
@@ -561,7 +651,7 @@ class SubFS(FS):
def
ishidden
(
self
,
path
):
def
ishidden
(
self
,
path
):
return
self
.
parent
.
ishidden
(
self
.
_delegate
(
path
))
return
self
.
parent
.
ishidden
(
self
.
_delegate
(
path
))
def
listdir
(
self
,
path
=
"./"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
hidden
=
Fals
e
,
dirs_only
=
False
,
files_only
=
False
):
def
listdir
(
self
,
path
=
"./"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
hidden
=
Tru
e
,
dirs_only
=
False
,
files_only
=
False
):
paths
=
self
.
parent
.
listdir
(
self
.
_delegate
(
path
),
paths
=
self
.
parent
.
listdir
(
self
.
_delegate
(
path
),
wildcard
,
wildcard
,
False
,
False
,
...
...
fs/memoryfs.py
View file @
1865b55d
...
@@ -405,7 +405,7 @@ class MemoryFS(FS):
...
@@ -405,7 +405,7 @@ class MemoryFS(FS):
finally
:
finally
:
self
.
_lock
.
release
()
self
.
_lock
.
release
()
def
listdir
(
self
,
path
=
"/"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
hidden
=
Fals
e
,
dirs_only
=
False
,
files_only
=
False
):
def
listdir
(
self
,
path
=
"/"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
hidden
=
Tru
e
,
dirs_only
=
False
,
files_only
=
False
):
self
.
_lock
.
acquire
()
self
.
_lock
.
acquire
()
try
:
try
:
dir_entry
=
self
.
_get_dir_entry
(
path
)
dir_entry
=
self
.
_get_dir_entry
(
path
)
...
...
fs/mountfs.py
View file @
1865b55d
...
@@ -82,7 +82,7 @@ class MountFS(FS):
...
@@ -82,7 +82,7 @@ class MountFS(FS):
finally
:
finally
:
self
.
_lock
.
release
()
self
.
_lock
.
release
()
def
listdir
(
self
,
path
=
"/"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
hidden
=
Fals
e
,
dirs_only
=
False
,
files_only
=
False
):
def
listdir
(
self
,
path
=
"/"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
hidden
=
Tru
e
,
dirs_only
=
False
,
files_only
=
False
):
self
.
_lock
.
acquire
()
self
.
_lock
.
acquire
()
try
:
try
:
...
...
fs/multifs.py
View file @
1865b55d
...
@@ -96,14 +96,13 @@ class MultiFS(FS):
...
@@ -96,14 +96,13 @@ class MultiFS(FS):
finally
:
finally
:
self
.
_lock
.
release
()
self
.
_lock
.
release
()
def
getsyspath
(
self
,
path
):
def
getsyspath
(
self
,
path
,
allow_none
=
False
):
self
.
_lock
.
acquire
()
self
.
_lock
.
acquire
()
try
:
try
:
fs
=
self
.
_delegate_search
(
path
)
fs
=
self
.
_delegate_search
(
path
)
if
fs
is
not
None
:
if
fs
is
not
None
:
return
fs
.
getsyspath
(
path
)
return
fs
.
getsyspath
(
path
,
allow_none
)
raise
ResourceNotFoundError
(
"NO_RESOURCE"
,
path
)
raise
ResourceNotFoundError
(
"NO_FILE"
,
path
)
finally
:
finally
:
self
.
_lock
.
release
()
self
.
_lock
.
release
()
...
@@ -111,7 +110,7 @@ class MultiFS(FS):
...
@@ -111,7 +110,7 @@ class MultiFS(FS):
self
.
_lock
.
acquire
()
self
.
_lock
.
acquire
()
try
:
try
:
if
not
self
.
exists
(
path
):
if
not
self
.
exists
(
path
):
raise
FS
Error
(
"NO_RESOURCE"
,
path
)
raise
ResourceNotFound
Error
(
"NO_RESOURCE"
,
path
)
name
,
fs
=
self
.
which
(
path
)
name
,
fs
=
self
.
which
(
path
)
if
name
is
None
:
if
name
is
None
:
...
...
fs/osfs.py
View file @
1865b55d
...
@@ -19,7 +19,7 @@ class OSFS(FS):
...
@@ -19,7 +19,7 @@ class OSFS(FS):
def
__str__
(
self
):
def
__str__
(
self
):
return
"<OSFS
\"
%
s
\"
>"
%
self
.
root_path
return
"<OSFS
\"
%
s
\"
>"
%
self
.
root_path
def
getsyspath
(
self
,
path
,
default
=
Non
e
):
def
getsyspath
(
self
,
path
,
allow_none
=
Fals
e
):
sys_path
=
os
.
path
.
join
(
self
.
root_path
,
makerelative
(
self
.
_resolve
(
path
)))
sys_path
=
os
.
path
.
join
(
self
.
root_path
,
makerelative
(
self
.
_resolve
(
path
)))
return
sys_path
return
sys_path
...
@@ -127,7 +127,6 @@ class OSFS(FS):
...
@@ -127,7 +127,6 @@ class OSFS(FS):
def
getsize
(
self
,
path
):
def
getsize
(
self
,
path
):
sys_path
=
self
.
getsyspath
(
path
)
sys_path
=
self
.
getsyspath
(
path
)
try
:
try
:
stats
=
os
.
stat
(
sys_path
)
stats
=
os
.
stat
(
sys_path
)
except
OSError
,
e
:
except
OSError
,
e
:
...
@@ -140,6 +139,11 @@ class OSFS(FS):
...
@@ -140,6 +139,11 @@ class OSFS(FS):
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
osfs
=
OSFS
(
"~/projects"
)
osfs
=
OSFS
(
"~/projects"
)
for
p
in
osfs
.
walk
(
"tagging-trunk"
,
search
=
'depth'
):
print
p
import
browsewin
import
browsewin
browsewin
.
browse
(
osfs
)
browsewin
.
browse
(
osfs
)
...
...
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