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
81230f9c
Commit
81230f9c
authored
Dec 27, 2010
by
rfkelly0
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added ilistdir() and ilistdirinfo() methods
parent
df581bd1
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
86 additions
and
28 deletions
+86
-28
ChangeLog
+3
-1
fs/base.py
+41
-7
fs/contrib/davfs/__init__.py
+42
-20
No files found.
ChangeLog
View file @
81230f9c
...
@@ -48,9 +48,9 @@
...
@@ -48,9 +48,9 @@
fs.wrapfs.subfs.
fs.wrapfs.subfs.
* OSFSWatchMixin improvements:
* OSFSWatchMixin improvements:
* watch_inotify: allow more than one watcher on a single path.
* watch_inotify: allow more than one watcher on a single path.
* watch_win32: don't create immortal reference cycles.
* watch_win32: report errors if the filesystem does't support
* watch_win32: report errors if the filesystem does't support
ReadDirectoryChangesW.
ReadDirectoryChangesW.
* watch_win32: don't create immortal reference cycles.
* MountFS: added support for mounting at the root directory, and for
* MountFS: added support for mounting at the root directory, and for
mounting over an existing mount.
mounting over an existing mount.
* Added 'getpathurl' and 'haspathurl' methods.
* Added 'getpathurl' and 'haspathurl' methods.
...
@@ -68,4 +68,6 @@
...
@@ -68,4 +68,6 @@
* Optimized listdir and listdirinfo in SFTPFS
* Optimized listdir and listdirinfo in SFTPFS
* Made memoryfs work with threads
* Made memoryfs work with threads
* Added copyfile_non_atomic and movefile_non_atomic for improved performance of multi-threaded copies
* Added copyfile_non_atomic and movefile_non_atomic for improved performance of multi-threaded copies
* Added ilistdir() and ilistdirinfo() methods, which are generator-based
variants of listdir() and listdirinfo().
fs/base.py
View file @
81230f9c
...
@@ -203,17 +203,17 @@ class FS(object):
...
@@ -203,17 +203,17 @@ class FS(object):
self
.
_lock
=
DummyLock
()
self
.
_lock
=
DummyLock
()
def
getmeta
(
self
,
meta_name
,
default
=
NoDefaultMeta
):
def
getmeta
(
self
,
meta_name
,
default
=
NoDefaultMeta
):
"""Retrieve a meta value associated with an FS object. Meta values are
"""Retrieve a meta value associated with an FS object.
a way for an FS implementation to report potentially useful information
associated with the file system.
Meta values are a way for an FS implementation to report potentially
useful information associated with the file system.
A meta key is a lower case string with no spaces. Meta keys may also
A meta key is a lower case string with no spaces. Meta keys may also
be grouped in namespaces in a dotted notation, e.g. 'atomic.namespaces'.
be grouped in namespaces in a dotted notation, e.g. 'atomic.namespaces'.
FS implementations aren't obliged to return any meta values, but the
FS implementations aren't obliged to return any meta values, but the
following are common:
following are common:
* *read_only* True if the file system can
not be modified
* *read_only* True if the file system cannot be modified
* *network* True if the file system requires network access
* *network* True if the file system requires network access
* *unicode_paths* True if the file system supports unicode paths
* *unicode_paths* True if the file system supports unicode paths
* *case_insensitive_paths* True if the file system ignores the case of paths
* *case_insensitive_paths* True if the file system ignores the case of paths
...
@@ -407,9 +407,14 @@ class FS(object):
...
@@ -407,9 +407,14 @@ class FS(object):
absolute
=
False
,
absolute
=
False
,
dirs_only
=
False
,
dirs_only
=
False
,
files_only
=
False
):
files_only
=
False
):
"""Retrieves a list of paths and path info under a given path.
This method behaves like listdir() but instead of just returning
the name of each item in the directory, it returns a tuple of the
name and the info dict as returned by getinfo.
"""Retrieves an iterable of paths and path info (as returned by getinfo) under
Depending on the filesystem, this may be more efficient than calling
a given path
.
getinfo() on each individual item returned by listdir()
.
:param path: root of the path to list
:param path: root of the path to list
:param wildcard: filter paths that match this wildcard
:param wildcard: filter paths that match this wildcard
...
@@ -474,6 +479,35 @@ class FS(object):
...
@@ -474,6 +479,35 @@ class FS(object):
return
entries
return
entries
def
ilistdir
(
self
,
path
=
"./"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
dirs_only
=
False
,
files_only
=
False
):
"""Generator yielding the files and directories under a given path.
This method behaves identically to listdir() but returns a generator
instead of a list. Depending on the filesystem this may be more
efficient than calling listdir() and iterating over the resulting list.
"""
return
iter
(
self
.
listdir
(
path
,
wildcard
,
full
,
absolute
,
dirs_only
,
files_only
))
def
ilistdirinfo
(
self
,
path
=
"./"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
dirs_only
=
False
,
files_only
=
False
):
"""Generator yielding paths and path info under a given path.
This method behaves identically to listdirinfo() but returns a generator
instead of a list. Depending on the filesystem this may be more
efficient than calling listdirinfo() and iterating over the resulting
list.
"""
return
iter
(
self
.
listdirinfo
(
path
,
wildcard
,
full
,
absolute
,
dirs_only
,
files_only
))
def
makedir
(
self
,
path
,
recursive
=
False
,
allow_recreate
=
False
):
def
makedir
(
self
,
path
,
recursive
=
False
,
allow_recreate
=
False
):
"""Make a directory on the filesystem.
"""Make a directory on the filesystem.
...
...
fs/contrib/davfs/__init__.py
View file @
81230f9c
...
@@ -374,6 +374,9 @@ class DAVFS(FS):
...
@@ -374,6 +374,9 @@ class DAVFS(FS):
response
.
close
()
response
.
close
()
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
):
return
list
(
self
.
ilistdir
(
path
=
path
,
wildcard
=
wildcard
,
full
=
full
,
absolute
=
absolute
,
dirs_only
=
dirs_only
,
files_only
=
files_only
))
def
ilistdir
(
self
,
path
=
"./"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
dirs_only
=
False
,
files_only
=
False
):
pf
=
propfind
(
prop
=
"<prop xmlns='DAV:'><resourcetype /></prop>"
)
pf
=
propfind
(
prop
=
"<prop xmlns='DAV:'><resourcetype /></prop>"
)
response
=
self
.
_request
(
path
,
"PROPFIND"
,
pf
.
render
(),{
"Depth"
:
"1"
})
response
=
self
.
_request
(
path
,
"PROPFIND"
,
pf
.
render
(),{
"Depth"
:
"1"
})
try
:
try
:
...
@@ -381,7 +384,6 @@ class DAVFS(FS):
...
@@ -381,7 +384,6 @@ class DAVFS(FS):
raise
ResourceNotFoundError
(
path
)
raise
ResourceNotFoundError
(
path
)
if
response
.
status
!=
207
:
if
response
.
status
!=
207
:
raise_generic_error
(
response
,
"listdir"
,
path
)
raise_generic_error
(
response
,
"listdir"
,
path
)
entries
=
[]
msres
=
multistatus
.
parse
(
response
.
read
())
msres
=
multistatus
.
parse
(
response
.
read
())
dir_ok
=
False
dir_ok
=
False
for
res
in
msres
.
responses
:
for
res
in
msres
.
responses
:
...
@@ -393,32 +395,44 @@ class DAVFS(FS):
...
@@ -393,32 +395,44 @@ class DAVFS(FS):
break
break
else
:
else
:
nm
=
basename
(
self
.
_url2path
(
res
.
href
))
nm
=
basename
(
self
.
_url2path
(
res
.
href
))
entry_ok
=
False
if
dirs_only
:
if
dirs_only
:
for
ps
in
res
.
propstats
:
for
ps
in
res
.
propstats
:
if
ps
.
props
.
getElementsByTagNameNS
(
"DAV:"
,
"collection"
):
if
ps
.
props
.
getElementsByTagNameNS
(
"DAV:"
,
"collection"
):
entr
ies
.
append
(
nm
)
entr
y_ok
=
True
break
break
elif
files_only
:
elif
files_only
:
for
ps
in
res
.
propstats
:
for
ps
in
res
.
propstats
:
if
ps
.
props
.
getElementsByTagNameNS
(
"DAV:"
,
"collection"
):
if
ps
.
props
.
getElementsByTagNameNS
(
"DAV:"
,
"collection"
):
break
break
else
:
else
:
entr
ies
.
append
(
nm
)
entr
y_ok
=
True
else
:
else
:
entr
ies
.
append
(
nm
)
entr
y_ok
=
True
if
not
dir
_ok
:
if
not
entry
_ok
:
raise
ResourceInvalidError
(
path
)
continue
if
wildcard
is
not
None
:
if
wildcard
is
not
None
:
entries
=
[
e
for
e
in
entries
if
fnmatch
.
fnmatch
(
e
,
wildcard
)]
if
isinstance
(
wildcard
,
basestring
):
if
not
fnmatch
.
fnmatch
(
nm
,
wildcard
):
continue
else
:
if
not
wildcard
(
nm
):
continue
if
full
:
if
full
:
entries
=
[
relpath
(
pathjoin
(
path
,
e
))
for
e
in
entries
]
yield
relpath
(
pathjoin
(
path
,
nm
))
elif
absolute
:
elif
absolute
:
entries
=
[
abspath
(
pathjoin
(
path
,
e
))
for
e
in
entries
]
yield
abspath
(
pathjoin
(
path
,
nm
))
return
entries
else
:
yield
nm
if
not
dir_ok
:
raise
ResourceInvalidError
(
path
)
finally
:
finally
:
response
.
close
()
response
.
close
()
def
listdirinfo
(
self
,
path
=
"./"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
dirs_only
=
False
,
files_only
=
False
):
def
listdirinfo
(
self
,
path
=
"./"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
dirs_only
=
False
,
files_only
=
False
):
return
list
(
self
.
ilistdirinfo
(
path
=
path
,
wildcard
=
wildcard
,
full
=
full
,
absolute
=
absolute
,
dirs_only
=
dirs_only
,
files_only
=
files_only
))
def
ilistdirinfo
(
self
,
path
=
"./"
,
wildcard
=
None
,
full
=
False
,
absolute
=
False
,
dirs_only
=
False
,
files_only
=
False
):
pf
=
propfind
(
prop
=
"<prop xmlns='DAV:'><resourcetype /><getcontentlength /><getlastmodified /><getetag /></prop>"
)
pf
=
propfind
(
prop
=
"<prop xmlns='DAV:'><resourcetype /><getcontentlength /><getlastmodified /><getetag /></prop>"
)
response
=
self
.
_request
(
path
,
"PROPFIND"
,
pf
.
render
(),{
"Depth"
:
"1"
})
response
=
self
.
_request
(
path
,
"PROPFIND"
,
pf
.
render
(),{
"Depth"
:
"1"
})
try
:
try
:
...
@@ -426,7 +440,6 @@ class DAVFS(FS):
...
@@ -426,7 +440,6 @@ class DAVFS(FS):
raise
ResourceNotFoundError
(
path
)
raise
ResourceNotFoundError
(
path
)
if
response
.
status
!=
207
:
if
response
.
status
!=
207
:
raise_generic_error
(
response
,
"listdir"
,
path
)
raise_generic_error
(
response
,
"listdir"
,
path
)
entries
=
[]
msres
=
multistatus
.
parse
(
response
.
read
())
msres
=
multistatus
.
parse
(
response
.
read
())
dir_ok
=
False
dir_ok
=
False
for
res
in
msres
.
responses
:
for
res
in
msres
.
responses
:
...
@@ -441,28 +454,37 @@ class DAVFS(FS):
...
@@ -441,28 +454,37 @@ class DAVFS(FS):
# appropriate type and add to entries list as required.
# appropriate type and add to entries list as required.
info
=
self
.
_info_from_propfind
(
res
)
info
=
self
.
_info_from_propfind
(
res
)
nm
=
basename
(
self
.
_url2path
(
res
.
href
))
nm
=
basename
(
self
.
_url2path
(
res
.
href
))
entry_ok
=
False
if
dirs_only
:
if
dirs_only
:
for
ps
in
res
.
propstats
:
for
ps
in
res
.
propstats
:
if
ps
.
props
.
getElementsByTagNameNS
(
"DAV:"
,
"collection"
):
if
ps
.
props
.
getElementsByTagNameNS
(
"DAV:"
,
"collection"
):
entr
ies
.
append
((
nm
,
info
))
entr
y_ok
=
True
break
break
elif
files_only
:
elif
files_only
:
for
ps
in
res
.
propstats
:
for
ps
in
res
.
propstats
:
if
ps
.
props
.
getElementsByTagNameNS
(
"DAV:"
,
"collection"
):
if
ps
.
props
.
getElementsByTagNameNS
(
"DAV:"
,
"collection"
):
break
break
else
:
else
:
entr
ies
.
append
((
nm
,
info
))
entr
y_ok
=
True
else
:
else
:
entr
ies
.
append
((
nm
,
info
))
entr
y_ok
=
True
if
not
dir
_ok
:
if
not
entry
_ok
:
raise
ResourceInvalidError
(
path
)
continue
if
wildcard
is
not
None
:
if
wildcard
is
not
None
:
entries
=
[(
e
,
info
)
for
(
e
,
info
)
in
entries
if
fnmatch
.
fnmatch
(
e
,
wildcard
)]
if
isinstance
(
wildcard
,
basestring
):
if
not
fnmatch
.
fnmatch
(
nm
,
wildcard
):
continue
else
:
if
not
wildcard
(
nm
):
continue
if
full
:
if
full
:
entries
=
[(
relpath
(
pathjoin
(
path
,
e
)),
info
)
for
(
e
,
info
)
in
entries
]
yield
(
relpath
(
pathjoin
(
path
,
nm
)),
info
)
elif
absolute
:
elif
absolute
:
entries
=
[(
abspath
(
pathjoin
(
path
,
e
)),
info
)
for
(
e
,
info
)
in
entries
]
yield
(
abspath
(
pathjoin
(
path
,
nm
)),
info
)
return
entries
else
:
yield
(
nm
,
info
)
if
not
dir_ok
:
raise
ResourceInvalidError
(
path
)
finally
:
finally
:
response
.
close
()
response
.
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