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
707f5ba7
Commit
707f5ba7
authored
Nov 29, 2009
by
willmcgugan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Some fixes
parent
f5dfa021
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
115 additions
and
30 deletions
+115
-30
fs/base.py
+35
-12
fs/mountfs.py
+9
-2
fs/path.py
+15
-1
fs/utils.py
+56
-15
No files found.
fs/base.py
View file @
707f5ba7
...
@@ -211,7 +211,7 @@ class FS(object):
...
@@ -211,7 +211,7 @@ class FS(object):
path -- Pach to check
path -- Pach to check
"""
"""
return
self
.
getsyspath
(
path
,
Non
e
)
is
not
None
return
self
.
getsyspath
(
path
,
allow_none
=
Tru
e
)
is
not
None
def
open
(
self
,
path
,
mode
=
"r"
,
**
kwargs
):
def
open
(
self
,
path
,
mode
=
"r"
,
**
kwargs
):
...
@@ -492,11 +492,26 @@ class FS(object):
...
@@ -492,11 +492,26 @@ class FS(object):
depth first search. Use 'depth' if you plan to create or
depth first search. Use 'depth' if you plan to create or
delete files as you go.
delete files as you go.
"""
"""
for
path
,
files
in
self
.
walk
(
path
,
wildcard
,
dir_wildcard
,
search
):
for
path
,
files
in
self
.
walk
(
path
,
wildcard
=
wildcard
,
dir_widlcard
=
dir_wildcard
,
search
=
search
):
for
f
in
files
:
for
f
in
files
:
yield
pathjoin
(
path
,
f
)
yield
pathjoin
(
path
,
f
)
def
walkdirs
(
self
,
path
=
"/"
,
wildcard
=
None
,
search
=
"breadth"
):
""" Like the 'walk' method but yields directories.
path -- Root path to start walking
wildcard -- If given, only return dictories that match this wildcard
search -- A string dentifying 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 or
delete files as you go.
"""
for
p
,
files
in
self
.
walk
(
path
,
wildcard
=
wildcard
,
search
=
search
):
yield
p
def
getsize
(
self
,
path
):
def
getsize
(
self
,
path
):
"""Returns the size (in bytes) of a resource.
"""Returns the size (in bytes) of a resource.
...
@@ -565,7 +580,7 @@ class FS(object):
...
@@ -565,7 +580,7 @@ class FS(object):
src -- Source path
src -- Source path
dst -- Destination path
dst -- Destination path
overwrite -- If True, then an existing file at the destination path
overwrite -- If True, then an existing file at the destination path
will be silently overwritte; if False then an exception
will be silently overwritte
n
; if False then an exception
will be raised in this case.
will be raised in this case.
"""
"""
...
@@ -617,9 +632,9 @@ class FS(object):
...
@@ -617,9 +632,9 @@ class FS(object):
except
OSError
:
except
OSError
:
pass
pass
def
movefile_noerrors
(
src
,
dst
,
overwrite
,
chunk_size
):
def
movefile_noerrors
(
src
,
dst
,
**
kwargs
):
try
:
try
:
return
self
.
move
(
src
,
dst
,
overwrite
,
chunk_size
)
return
self
.
move
(
src
,
dst
,
**
kwargs
)
except
FSError
:
except
FSError
:
return
return
if
ignore_errors
:
if
ignore_errors
:
...
@@ -627,10 +642,15 @@ class FS(object):
...
@@ -627,10 +642,15 @@ class FS(object):
else
:
else
:
movefile
=
self
.
move
movefile
=
self
.
move
src
=
abspath
(
src
)
dst
=
abspath
(
dst
)
if
dst
:
self
.
makedir
(
dst
,
allow_recreate
=
overwrite
)
self
.
makedir
(
dst
,
allow_recreate
=
overwrite
)
for
dirname
,
filenames
in
self
.
walk
(
src
,
search
=
"depth"
):
for
dirname
,
filenames
in
self
.
walk
(
src
,
search
=
"depth"
):
dst_dirname
=
relpath
(
dirname
[
len
(
src
):]
)
dst_dirname
=
relpath
(
frombase
(
src
,
abspath
(
dirname
))
)
dst_dirpath
=
pathjoin
(
dst
,
dst_dirname
)
dst_dirpath
=
pathjoin
(
dst
,
dst_dirname
)
self
.
makedir
(
dst_dirpath
,
allow_recreate
=
True
,
recursive
=
True
)
self
.
makedir
(
dst_dirpath
,
allow_recreate
=
True
,
recursive
=
True
)
...
@@ -657,9 +677,9 @@ class FS(object):
...
@@ -657,9 +677,9 @@ class FS(object):
"""
"""
if
not
self
.
isdir
(
src
):
if
not
self
.
isdir
(
src
):
raise
ResourceInvalidError
(
src
,
msg
=
"Source is not a directory:
%(path)
s"
)
raise
ResourceInvalidError
(
src
,
msg
=
"Source is not a directory:
%(path)
s"
)
def
copyfile_noerrors
(
src
,
dst
,
overwrite
):
def
copyfile_noerrors
(
src
,
dst
,
**
kwargs
):
try
:
try
:
return
self
.
copy
(
src
,
dst
,
overwrite
=
overwrite
)
return
self
.
copy
(
src
,
dst
,
**
kwargs
)
except
FSError
:
except
FSError
:
return
return
if
ignore_errors
:
if
ignore_errors
:
...
@@ -667,14 +687,17 @@ class FS(object):
...
@@ -667,14 +687,17 @@ class FS(object):
else
:
else
:
copyfile
=
self
.
copy
copyfile
=
self
.
copy
copyfile
=
self
.
copy
src
=
abspath
(
src
)
dst
=
abspath
(
dst
)
if
dst
:
if
dst
:
self
.
makedir
(
dst
,
allow_recreate
=
overwrite
)
self
.
makedir
(
dst
,
allow_recreate
=
overwrite
)
for
dirname
,
filenames
in
self
.
walk
(
src
):
for
dirname
,
filenames
in
self
.
walk
(
src
):
dst_dirname
=
relpath
(
dirname
[
len
(
src
):]
)
dst_dirname
=
relpath
(
frombase
(
src
,
abspath
(
dirname
))
)
dst_dirpath
=
pathjoin
(
dst
,
dst_dirname
)
dst_dirpath
=
pathjoin
(
dst
,
dst_dirname
)
self
.
makedir
(
dst_dirpath
,
allow_recreate
=
True
)
self
.
makedir
(
dst_dirpath
,
allow_recreate
=
True
,
recursive
=
True
)
for
filename
in
filenames
:
for
filename
in
filenames
:
...
@@ -724,7 +747,7 @@ class SubFS(FS):
...
@@ -724,7 +747,7 @@ class SubFS(FS):
def
__init__
(
self
,
parent
,
sub_dir
):
def
__init__
(
self
,
parent
,
sub_dir
):
self
.
parent
=
parent
self
.
parent
=
parent
self
.
sub_dir
=
abspath
(
normpath
(
sub_dir
))
self
.
sub_dir
=
abspath
(
normpath
(
sub_dir
))
FS
.
__init__
(
self
,
thread_synchronize
=
False
)
FS
.
__init__
(
self
,
thread_synchronize
=
False
)
def
__str__
(
self
):
def
__str__
(
self
):
return
"<SubFS:
%
s in
%
s>"
%
(
self
.
sub_dir
,
self
.
parent
)
return
"<SubFS:
%
s in
%
s>"
%
(
self
.
sub_dir
,
self
.
parent
)
...
...
fs/mountfs.py
View file @
707f5ba7
...
@@ -52,6 +52,15 @@ class MountFS(FS):
...
@@ -52,6 +52,15 @@ class MountFS(FS):
return
self
,
head_path
,
tail_path
return
self
,
head_path
,
tail_path
def
getsyspath
(
self
,
path
,
allow_none
=
False
):
fs
,
mount_path
,
delegate_path
=
self
.
_delegate
(
path
)
if
fs
is
self
:
if
allow_none
:
return
None
else
:
raise
NoSysPathError
(
path
=
path
)
return
fs
.
getsyspath
(
delegate_path
,
allow_none
=
allow_none
)
@synchronize
@synchronize
def
desc
(
self
,
path
):
def
desc
(
self
,
path
):
fs
,
mount_path
,
delegate_path
=
self
.
_delegate
(
path
)
fs
,
mount_path
,
delegate_path
=
self
.
_delegate
(
path
)
...
@@ -309,5 +318,3 @@ class MountFS(FS):
...
@@ -309,5 +318,3 @@ class MountFS(FS):
if
fs
is
self
:
if
fs
is
self
:
return
[]
return
[]
return
fs
.
listxattrs
(
delegate_path
)
return
fs
.
listxattrs
(
delegate_path
)
fs/path.py
View file @
707f5ba7
...
@@ -178,7 +178,7 @@ def issamedir(path1, path2):
...
@@ -178,7 +178,7 @@ def issamedir(path1, path2):
return
pathsplit
(
normpath
(
path1
))[
0
]
==
pathsplit
(
normpath
(
path2
))[
0
]
return
pathsplit
(
normpath
(
path1
))[
0
]
==
pathsplit
(
normpath
(
path2
))[
0
]
def
isprefix
(
path1
,
path2
):
def
isprefix
(
path1
,
path2
):
"""Return true is path1 is a prefix of path2.
"""Return true is path1 is a prefix of path2.
>>> isprefix("foo/bar", "foo/bar/spam.txt")
>>> isprefix("foo/bar", "foo/bar/spam.txt")
...
@@ -203,6 +203,20 @@ def isprefix(path1,path2):
...
@@ -203,6 +203,20 @@ def isprefix(path1,path2):
return
True
return
True
def
forcedir
(
path
):
def
forcedir
(
path
):
"""Ensure the path ends with a trailing /
>>> forcedir("foo/bar")
'foo/bar/'
>>> forcedir("foo/bar/")
'foo/bar/'
"""
if
not
path
.
endswith
(
'/'
):
if
not
path
.
endswith
(
'/'
):
return
path
+
'/'
return
path
+
'/'
return
path
return
path
def
frombase
(
path1
,
path2
):
if
not
isprefix
(
path1
,
path2
):
raise
ValueError
(
"path1 must be a prefix of path2"
)
return
path2
[
len
(
path1
):]
fs/utils.py
View file @
707f5ba7
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
import
shutil
import
shutil
from
fs.mountfs
import
MountFS
from
fs.mountfs
import
MountFS
from
fs.path
import
pathjoin
def
copyfile
(
src_fs
,
src_path
,
dst_fs
,
dst_path
,
chunk_size
=
16384
):
def
copyfile
(
src_fs
,
src_path
,
dst_fs
,
dst_path
,
chunk_size
=
16384
):
"""Copy a file from one filesystem to another. Will use system copyfile, if both files have a syspath.
"""Copy a file from one filesystem to another. Will use system copyfile, if both files have a syspath.
...
@@ -18,11 +19,11 @@ def copyfile(src_fs, src_path, dst_fs, dst_path, chunk_size=16384):
...
@@ -18,11 +19,11 @@ def copyfile(src_fs, src_path, dst_fs, dst_path, chunk_size=16384):
chunk_size -- Size of chunks to move if system copyfile is not available (default 16K)
chunk_size -- Size of chunks to move if system copyfile is not available (default 16K)
"""
"""
src_syspath
=
src_fs
.
getsyspath
(
src_path
)
or
""
src_syspath
=
src_fs
.
getsyspath
(
src_path
,
allow_none
=
True
)
dst_syspath
=
dst_fs
.
getsyspath
(
dst_path
)
or
""
dst_syspath
=
dst_fs
.
getsyspath
(
dst_path
,
allow_none
=
True
)
# System copy if there are two sys paths
# System copy if there are two sys paths
if
src_syspath
and
dst_syspath
:
if
src_syspath
is
not
None
and
dst_syspath
is
not
None
:
shutil
.
copyfile
(
src_syspath
,
dst_syspath
)
shutil
.
copyfile
(
src_syspath
,
dst_syspath
)
return
return
...
@@ -57,11 +58,11 @@ def movefile(src_fs, src_path, dst_fs, dst_path, chunk_size=16384):
...
@@ -57,11 +58,11 @@ def movefile(src_fs, src_path, dst_fs, dst_path, chunk_size=16384):
chunk_size -- Size of chunks to move if system copyfile is not available (default 16K)
chunk_size -- Size of chunks to move if system copyfile is not available (default 16K)
"""
"""
src_syspath
=
src_fs
.
getsyspath
(
src_path
)
or
""
src_syspath
=
src_fs
.
getsyspath
(
src_path
,
allow_none
=
True
)
dst_syspath
=
dst_fs
.
getsyspath
(
dst_path
)
or
""
dst_syspath
=
dst_fs
.
getsyspath
(
dst_path
,
allow_none
=
True
)
# System copy if there are two sys paths
# System copy if there are two sys paths
if
src_syspath
and
dst_syspath
:
if
src_syspath
is
not
None
and
dst_syspath
is
not
None
:
shutil
.
movefile
(
src_syspath
,
dst_syspath
)
shutil
.
movefile
(
src_syspath
,
dst_syspath
)
return
return
...
@@ -87,7 +88,7 @@ def movefile(src_fs, src_path, dst_fs, dst_path, chunk_size=16384):
...
@@ -87,7 +88,7 @@ def movefile(src_fs, src_path, dst_fs, dst_path, chunk_size=16384):
dst
.
close
()
dst
.
close
()
def
movedir
(
fs1
,
fs2
,
ignore_errors
=
False
,
chunk_size
=
16384
):
def
movedir
(
fs1
,
fs2
,
overwrite
=
False
,
ignore_errors
=
False
,
chunk_size
=
16384
):
"""Moves contents of a directory from one filesystem to another.
"""Moves contents of a directory from one filesystem to another.
fs1 -- Source filesystem, or a tuple of (<filesystem>, <directory path>)
fs1 -- Source filesystem, or a tuple of (<filesystem>, <directory path>)
...
@@ -104,12 +105,16 @@ def movedir(fs1, fs2, ignore_errors=False, chunk_size=16384):
...
@@ -104,12 +105,16 @@ def movedir(fs1, fs2, ignore_errors=False, chunk_size=16384):
fs2
=
fs2
.
opendir
(
dir2
)
fs2
=
fs2
.
opendir
(
dir2
)
mount_fs
=
MountFS
()
mount_fs
=
MountFS
()
mount_fs
.
mount
(
'dir1'
,
fs1
)
mount_fs
.
mount
(
'src'
,
fs1
)
mount_fs
.
mount
(
'dir2'
,
fs2
)
mount_fs
.
mount
(
'dst'
,
fs2
)
mount_fs
.
movedir
(
'dir1'
,
'dir2'
,
ignore_errors
=
ignore_errors
,
chunk_size
=
chunk_size
)
mount_fs
.
movedir
(
'src'
,
'dst'
,
overwrite
=
overwrite
,
ignore_errors
=
ignore_errors
,
chunk_size
=
chunk_size
)
def
copydir
(
fs1
,
fs2
,
ignore_errors
=
False
,
chunk_size
=
16384
):
def
copydir
(
fs1
,
fs2
,
overwrite
=
False
,
ignore_errors
=
False
,
chunk_size
=
16384
):
"""Copies contents of a directory from one filesystem to another.
"""Copies contents of a directory from one filesystem to another.
fs1 -- Source filesystem, or a tuple of (<filesystem>, <directory path>)
fs1 -- Source filesystem, or a tuple of (<filesystem>, <directory path>)
...
@@ -126,9 +131,12 @@ def copydir(fs1, fs2, ignore_errors=False, chunk_size=16384):
...
@@ -126,9 +131,12 @@ def copydir(fs1, fs2, ignore_errors=False, chunk_size=16384):
fs2
=
fs2
.
opendir
(
dir2
)
fs2
=
fs2
.
opendir
(
dir2
)
mount_fs
=
MountFS
()
mount_fs
=
MountFS
()
mount_fs
.
mount
(
'dir1'
,
fs1
)
mount_fs
.
mount
(
'src'
,
fs1
)
mount_fs
.
mount
(
'dir2'
,
fs2
)
mount_fs
.
mount
(
'dst'
,
fs2
)
mount_fs
.
copydir
(
'dir1'
,
'dir2'
,
ignore_errors
=
ignore_errors
,
chunk_size
=
chunk_size
)
mount_fs
.
copydir
(
'src'
,
'dst'
,
overwrite
=
overwrite
,
ignore_errors
=
ignore_errors
,
chunk_size
=
chunk_size
)
def
countbytes
(
fs
):
def
countbytes
(
fs
):
...
@@ -244,6 +252,40 @@ def find_duplicates(fs, compare_paths=None, quick=False, signature_chunk_size=16
...
@@ -244,6 +252,40 @@ def find_duplicates(fs, compare_paths=None, quick=False, signature_chunk_size=16
paths
=
list
(
set
(
paths
)
.
difference
(
dups
))
paths
=
list
(
set
(
paths
)
.
difference
(
dups
))
def
print_fs
(
fs
,
path
=
"/"
,
max_levels
=
5
,
indent
=
' '
*
2
):
"""Prints a filesystem listing to stdout (including sub dirs). Useful as a debugging aid.
Be careful about printing a OSFS, or any other large filesystem.
Without max_levels set, this function will traverse the entire directory tree.
fs -- A filesystem object
path -- Path of root to list (default "/")
max_levels -- Maximum levels of dirs to list (default 5), set to None for no maximum
indent -- String to indent each directory level (default two spaces)
"""
def
print_dir
(
fs
,
path
,
level
):
try
:
dir_listing
=
[(
fs
.
isdir
(
pathjoin
(
path
,
p
)),
p
)
for
p
in
fs
.
listdir
(
path
)]
except
Exception
,
e
:
print
indent
*
level
+
"... unabled to retrieve directory list (reason:
%
s) ..."
%
str
(
e
)
return
dir_listing
.
sort
(
key
=
lambda
(
isdir
,
p
):(
not
isdir
,
p
.
lower
()))
for
is_dir
,
item
in
dir_listing
:
if
is_dir
:
print
indent
*
level
+
'[
%
s]'
%
item
if
max_levels
is
None
or
level
<
max_levels
:
print_dir
(
fs
,
pathjoin
(
path
,
item
),
level
+
1
)
if
max_levels
is
not
None
:
if
level
>=
max_levels
:
print
indent
*
(
level
+
1
)
+
"..."
else
:
print
indent
*
level
+
'
%
s'
%
item
print_dir
(
fs
,
path
,
0
)
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
from
osfs
import
*
from
osfs
import
*
fs
=
OSFS
(
'~/copytest'
)
fs
=
OSFS
(
'~/copytest'
)
...
@@ -256,4 +298,3 @@ if __name__ == "__main__":
...
@@ -256,4 +298,3 @@ if __name__ == "__main__":
from
browsewin
import
browse
from
browsewin
import
browse
browse
(
m
)
browse
(
m
)
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