diff options
| author | CoprDistGit <infra@openeuler.org> | 2023-04-11 16:39:51 +0000 |
|---|---|---|
| committer | CoprDistGit <infra@openeuler.org> | 2023-04-11 16:39:51 +0000 |
| commit | 3e4e76422c02902c23edb143571b7926f57c21e1 (patch) | |
| tree | 1a435578db51e242a36e0755e71a0f8f3c4722e0 | |
| parent | 11cb65ea43a579cdbca0598759753144a30c17fb (diff) | |
automatic import of python-scantree
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | python-scantree.spec | 507 | ||||
| -rw-r--r-- | sources | 1 |
3 files changed, 509 insertions, 0 deletions
@@ -0,0 +1 @@ +/scantree-0.0.1.tar.gz diff --git a/python-scantree.spec b/python-scantree.spec new file mode 100644 index 0000000..52e7d2e --- /dev/null +++ b/python-scantree.spec @@ -0,0 +1,507 @@ +%global _empty_manifest_terminate_build 0 +Name: python-scantree +Version: 0.0.1 +Release: 1 +Summary: Flexible recursive directory iterator: scandir meets glob("**", recursive=True) +License: MIT +URL: https://github.com/andhus/scantree +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/35/0a/8709b1516110e7b5e1ef796426d8e3fcdb96d83a0cc2639a3d559df1b7c7/scantree-0.0.1.tar.gz +BuildArch: noarch + + +%description +[](https://travis-ci.com/andhus/scantree) +[](https://codecov.io/gh/andhus/scantree) +# scantree +Recursive directory iterator supporting: +- flexible filtering including wildcard path matching +- in memory representation of file-tree (for repeated access) +- efficient access to directory entry properties (`posix.DirEntry` interface) extended with real path and path relative to the recursion root directory +- detection and handling of cyclic symlinks + +## Installation +```commandline +pip install scantree +``` + +## Usage +See source code for full documentation, some generic examples below. + +Get matching file paths: +```python +from scantree import scantree, RecursionFilter + +tree = scantree('/path/to/dir', RecursionFilter(match=['*.txt'])) +print([path.relative for path in tree.filepaths()]) +print([path.real for path in tree.filepaths()]) +``` +``` +['d1/d2/file3.txt', 'd1/file2.txt', 'file1.txt'] +['/path/to/other_dir/file3.txt', '/path/to/dir/d1/file2.txt', '/path/to/dir/file1.txt'] +``` + +Access metadata of directory entries in file tree: +```python +d2 = tree.directories[0].directories[0] +print(type(d2)) +print(d2.path.absolute) +print(d2.path.real) +print(d2.path.is_symlink()) +print(d2.files[0].relative) +``` +``` +scantree._node.DirNode +/path/to/dir/d1/d2 +/path/to/other_dir +True +d1/d2/file3.txt +``` + +Aggregate information by operating on tree: +```python +hello_count = tree.apply( + file_apply=lambda path: sum([ + w.lower() == 'hello' for w in + path.as_pathlib().read_text().split() + ]), + dir_apply=lambda dir_: sum(dir_.entries), +) +print(hello_count) +``` +``` +3 +``` + +```python +hello_count_tree = tree.apply( + file_apply=lambda path: { + 'name': path.name, + 'count': sum([ + w.lower() == 'hello' + for w in path.as_pathlib().read_text().split() + ]) + }, + dir_apply=lambda dir_: { + 'name': dir_.path.name, + 'count': sum(e['count'] for e in dir_.entries), + 'sub_counts': [e for e in dir_.entries] + }, +) +from pprint import pprint +pprint(hello_count_tree) +``` +``` +{'count': 3, + 'name': 'dir', + 'sub_counts': [{'count': 2, 'name': 'file1.txt'}, + {'count': 1, + 'name': 'd1', + 'sub_counts': [{'count': 1, 'name': 'file2.txt'}, + {'count': 0, + 'name': 'd2', + 'sub_counts': [{'count': 0, + 'name': 'file3.txt'}]}]}]} +``` + +Flexible filtering: +```python +without_hidden_files = scantree('.', RecursionFilter(match=['*', '!.*'])) + +without_palindrome_linked_dirs = scantree( + '.', + lambda paths: [ + p for p in paths if not ( + p.is_dir() and + p.is_symlink() and + p.name == p.name[::-1] + ) + ] +) +``` + +Comparison: +```python +tree = scandir('path/to/dir') +# make some operations on filesystem, make sure file tree is the same: +assert tree == scandir('path/to/dir') + +# tree contains absolute/real path info: +import shutil +shutil.copytree('path/to/dir', 'path/to/other_dir') +new_tree = scandir('path/to/other_dir') +assert tree != new_tree +assert ( + [p.relative for p in tree.leafpaths()] == + [p.relative for p in new_tree.leafpaths()] +) +``` + +Inspect symlinks: +```python +from scantree import CyclicLinkedDir + +file_links = [] +dir_links = [] +cyclic_links = [] + +def file_apply(path): + if path.is_symlink(): + file_links.append(path) + +def dir_apply(dir_node): + if dir_node.path.is_symlink(): + dir_links.append(dir_node.path) + if isinstance(dir_node, CyclicLinkedDir): + cyclic_links.append((dir_node.path, dir_node.target_path)) + +scantree('.', file_apply=file_apply, dir_apply=dir_apply) +``` + +%package -n python3-scantree +Summary: Flexible recursive directory iterator: scandir meets glob("**", recursive=True) +Provides: python-scantree +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-scantree +[](https://travis-ci.com/andhus/scantree) +[](https://codecov.io/gh/andhus/scantree) +# scantree +Recursive directory iterator supporting: +- flexible filtering including wildcard path matching +- in memory representation of file-tree (for repeated access) +- efficient access to directory entry properties (`posix.DirEntry` interface) extended with real path and path relative to the recursion root directory +- detection and handling of cyclic symlinks + +## Installation +```commandline +pip install scantree +``` + +## Usage +See source code for full documentation, some generic examples below. + +Get matching file paths: +```python +from scantree import scantree, RecursionFilter + +tree = scantree('/path/to/dir', RecursionFilter(match=['*.txt'])) +print([path.relative for path in tree.filepaths()]) +print([path.real for path in tree.filepaths()]) +``` +``` +['d1/d2/file3.txt', 'd1/file2.txt', 'file1.txt'] +['/path/to/other_dir/file3.txt', '/path/to/dir/d1/file2.txt', '/path/to/dir/file1.txt'] +``` + +Access metadata of directory entries in file tree: +```python +d2 = tree.directories[0].directories[0] +print(type(d2)) +print(d2.path.absolute) +print(d2.path.real) +print(d2.path.is_symlink()) +print(d2.files[0].relative) +``` +``` +scantree._node.DirNode +/path/to/dir/d1/d2 +/path/to/other_dir +True +d1/d2/file3.txt +``` + +Aggregate information by operating on tree: +```python +hello_count = tree.apply( + file_apply=lambda path: sum([ + w.lower() == 'hello' for w in + path.as_pathlib().read_text().split() + ]), + dir_apply=lambda dir_: sum(dir_.entries), +) +print(hello_count) +``` +``` +3 +``` + +```python +hello_count_tree = tree.apply( + file_apply=lambda path: { + 'name': path.name, + 'count': sum([ + w.lower() == 'hello' + for w in path.as_pathlib().read_text().split() + ]) + }, + dir_apply=lambda dir_: { + 'name': dir_.path.name, + 'count': sum(e['count'] for e in dir_.entries), + 'sub_counts': [e for e in dir_.entries] + }, +) +from pprint import pprint +pprint(hello_count_tree) +``` +``` +{'count': 3, + 'name': 'dir', + 'sub_counts': [{'count': 2, 'name': 'file1.txt'}, + {'count': 1, + 'name': 'd1', + 'sub_counts': [{'count': 1, 'name': 'file2.txt'}, + {'count': 0, + 'name': 'd2', + 'sub_counts': [{'count': 0, + 'name': 'file3.txt'}]}]}]} +``` + +Flexible filtering: +```python +without_hidden_files = scantree('.', RecursionFilter(match=['*', '!.*'])) + +without_palindrome_linked_dirs = scantree( + '.', + lambda paths: [ + p for p in paths if not ( + p.is_dir() and + p.is_symlink() and + p.name == p.name[::-1] + ) + ] +) +``` + +Comparison: +```python +tree = scandir('path/to/dir') +# make some operations on filesystem, make sure file tree is the same: +assert tree == scandir('path/to/dir') + +# tree contains absolute/real path info: +import shutil +shutil.copytree('path/to/dir', 'path/to/other_dir') +new_tree = scandir('path/to/other_dir') +assert tree != new_tree +assert ( + [p.relative for p in tree.leafpaths()] == + [p.relative for p in new_tree.leafpaths()] +) +``` + +Inspect symlinks: +```python +from scantree import CyclicLinkedDir + +file_links = [] +dir_links = [] +cyclic_links = [] + +def file_apply(path): + if path.is_symlink(): + file_links.append(path) + +def dir_apply(dir_node): + if dir_node.path.is_symlink(): + dir_links.append(dir_node.path) + if isinstance(dir_node, CyclicLinkedDir): + cyclic_links.append((dir_node.path, dir_node.target_path)) + +scantree('.', file_apply=file_apply, dir_apply=dir_apply) +``` + +%package help +Summary: Development documents and examples for scantree +Provides: python3-scantree-doc +%description help +[](https://travis-ci.com/andhus/scantree) +[](https://codecov.io/gh/andhus/scantree) +# scantree +Recursive directory iterator supporting: +- flexible filtering including wildcard path matching +- in memory representation of file-tree (for repeated access) +- efficient access to directory entry properties (`posix.DirEntry` interface) extended with real path and path relative to the recursion root directory +- detection and handling of cyclic symlinks + +## Installation +```commandline +pip install scantree +``` + +## Usage +See source code for full documentation, some generic examples below. + +Get matching file paths: +```python +from scantree import scantree, RecursionFilter + +tree = scantree('/path/to/dir', RecursionFilter(match=['*.txt'])) +print([path.relative for path in tree.filepaths()]) +print([path.real for path in tree.filepaths()]) +``` +``` +['d1/d2/file3.txt', 'd1/file2.txt', 'file1.txt'] +['/path/to/other_dir/file3.txt', '/path/to/dir/d1/file2.txt', '/path/to/dir/file1.txt'] +``` + +Access metadata of directory entries in file tree: +```python +d2 = tree.directories[0].directories[0] +print(type(d2)) +print(d2.path.absolute) +print(d2.path.real) +print(d2.path.is_symlink()) +print(d2.files[0].relative) +``` +``` +scantree._node.DirNode +/path/to/dir/d1/d2 +/path/to/other_dir +True +d1/d2/file3.txt +``` + +Aggregate information by operating on tree: +```python +hello_count = tree.apply( + file_apply=lambda path: sum([ + w.lower() == 'hello' for w in + path.as_pathlib().read_text().split() + ]), + dir_apply=lambda dir_: sum(dir_.entries), +) +print(hello_count) +``` +``` +3 +``` + +```python +hello_count_tree = tree.apply( + file_apply=lambda path: { + 'name': path.name, + 'count': sum([ + w.lower() == 'hello' + for w in path.as_pathlib().read_text().split() + ]) + }, + dir_apply=lambda dir_: { + 'name': dir_.path.name, + 'count': sum(e['count'] for e in dir_.entries), + 'sub_counts': [e for e in dir_.entries] + }, +) +from pprint import pprint +pprint(hello_count_tree) +``` +``` +{'count': 3, + 'name': 'dir', + 'sub_counts': [{'count': 2, 'name': 'file1.txt'}, + {'count': 1, + 'name': 'd1', + 'sub_counts': [{'count': 1, 'name': 'file2.txt'}, + {'count': 0, + 'name': 'd2', + 'sub_counts': [{'count': 0, + 'name': 'file3.txt'}]}]}]} +``` + +Flexible filtering: +```python +without_hidden_files = scantree('.', RecursionFilter(match=['*', '!.*'])) + +without_palindrome_linked_dirs = scantree( + '.', + lambda paths: [ + p for p in paths if not ( + p.is_dir() and + p.is_symlink() and + p.name == p.name[::-1] + ) + ] +) +``` + +Comparison: +```python +tree = scandir('path/to/dir') +# make some operations on filesystem, make sure file tree is the same: +assert tree == scandir('path/to/dir') + +# tree contains absolute/real path info: +import shutil +shutil.copytree('path/to/dir', 'path/to/other_dir') +new_tree = scandir('path/to/other_dir') +assert tree != new_tree +assert ( + [p.relative for p in tree.leafpaths()] == + [p.relative for p in new_tree.leafpaths()] +) +``` + +Inspect symlinks: +```python +from scantree import CyclicLinkedDir + +file_links = [] +dir_links = [] +cyclic_links = [] + +def file_apply(path): + if path.is_symlink(): + file_links.append(path) + +def dir_apply(dir_node): + if dir_node.path.is_symlink(): + dir_links.append(dir_node.path) + if isinstance(dir_node, CyclicLinkedDir): + cyclic_links.append((dir_node.path, dir_node.target_path)) + +scantree('.', file_apply=file_apply, dir_apply=dir_apply) +``` + +%prep +%autosetup -n scantree-0.0.1 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-scantree -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Tue Apr 11 2023 Python_Bot <Python_Bot@openeuler.org> - 0.0.1-1 +- Package Spec generated @@ -0,0 +1 @@ +e7b37d7292c0d4edc96246e8d681b2b5 scantree-0.0.1.tar.gz |
