storage-viewer 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Lingaraj Sa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,138 @@
1
+ Metadata-Version: 2.4
2
+ Name: storage-viewer
3
+ Version: 1.0.0
4
+ Summary: Advanced directory tree visualizer with filtering options
5
+ Author: Lingaraj Sa
6
+ License: MIT License
7
+
8
+ Copyright (c) 2024 Lingaraj Sa
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Classifier: License :: OSI Approved :: MIT License
29
+ Classifier: Programming Language :: Python :: 3
30
+ Classifier: Programming Language :: Python :: 3 :: Only
31
+ Requires-Python: >=3.7
32
+ Description-Content-Type: text/markdown
33
+ License-File: LICENSE
34
+ Dynamic: license-file
35
+
36
+ # Storage Viewer CLI
37
+
38
+ ![Python Version](https://img.shields.io/badge/python-3.7%2B-blue)
39
+ ![License](https://img.shields.io/badge/license-MIT-green)
40
+ ![PyPI](https://img.shields.io/badge/pypi-v1.0.0-orange)
41
+
42
+ A powerful, feature-rich directory tree visualizer with advanced filtering options for the command line.
43
+
44
+ ## Features
45
+
46
+ - **Hierarchical tree display** — Clean, readable directory structures
47
+ - **Advanced filtering** — Filter by extension, folder, pattern, and size
48
+ - **Size analysis** — Show file sizes in human-readable formats
49
+ - **File type icons** — Visual indicators for different file types
50
+ - **Depth control** — Limit directory traversal depth
51
+ - **Export capability** — Save tree structures to files
52
+ - **Statistics** — Summaries of directories and files
53
+ - **Fast and lightweight** — No external dependencies
54
+
55
+ ## Basic usage
56
+
57
+ View a directory tree:
58
+
59
+ ```console
60
+ stree /path/to/directory
61
+ ```
62
+
63
+ Show file type icons:
64
+
65
+ ```console
66
+ stree . --icons
67
+ ```
68
+
69
+ Show file sizes:
70
+
71
+ ```console
72
+ stree . --show-size
73
+ ```
74
+
75
+ Limit traversal depth:
76
+
77
+ ```console
78
+ stree . --max-depth 3
79
+ ```
80
+
81
+ ## Examples
82
+
83
+ Exclude development folders:
84
+
85
+ ```console
86
+ stree . --exclude-folders __pycache__,node_modules,.git,venv --max-depth 4
87
+ ```
88
+
89
+ Find large files:
90
+
91
+ ```console
92
+ stree /home --min-size 100M --show-size --sort-by size --reverse-sort
93
+ ```
94
+
95
+ Export the tree to a file:
96
+
97
+ ```console
98
+ stree /path --export directory_structure.txt
99
+ ```
100
+
101
+ Show only code files:
102
+
103
+ ```console
104
+ stree . --include-patterns "*.py,*.js,*.java,*.cpp"
105
+ ```
106
+
107
+ Exclude temporary files:
108
+
109
+ ```console
110
+ stree . --exclude-extensions tmp,bak,log --exclude-files "*.tmp,*.bak"
111
+ ```
112
+
113
+ ## Options
114
+
115
+ ```text
116
+ Usage: stree [OPTIONS] PATH
117
+
118
+ Display directory tree structure with advanced filtering.
119
+
120
+ Options:
121
+ --show-hidden Show hidden files and folders
122
+ --no-file Exclude all files
123
+ --no-folder Exclude all folders
124
+ --exclude-extensions Comma-separated file extensions to exclude
125
+ --exclude-folders Comma-separated folder names to exclude
126
+ --exclude-files Comma-separated file patterns to exclude
127
+ --include-patterns Comma-separated patterns to include
128
+ --max-depth Maximum depth to traverse
129
+ --min-size Minimum file size (e.g., 1M, 100K, 1G)
130
+ --max-size Maximum file size (e.g., 1M, 100K, 1G)
131
+ --show-size Show file sizes
132
+ --icons Show file type icons
133
+ --sort-by Sort method: name, size, or type
134
+ --reverse-sort Reverse sort order
135
+ --export Export tree to specified file
136
+ --version Show version
137
+ --help Show this help message
138
+ ```
@@ -0,0 +1,103 @@
1
+ # Storage Viewer CLI
2
+
3
+ ![Python Version](https://img.shields.io/badge/python-3.7%2B-blue)
4
+ ![License](https://img.shields.io/badge/license-MIT-green)
5
+ ![PyPI](https://img.shields.io/badge/pypi-v1.0.0-orange)
6
+
7
+ A powerful, feature-rich directory tree visualizer with advanced filtering options for the command line.
8
+
9
+ ## Features
10
+
11
+ - **Hierarchical tree display** — Clean, readable directory structures
12
+ - **Advanced filtering** — Filter by extension, folder, pattern, and size
13
+ - **Size analysis** — Show file sizes in human-readable formats
14
+ - **File type icons** — Visual indicators for different file types
15
+ - **Depth control** — Limit directory traversal depth
16
+ - **Export capability** — Save tree structures to files
17
+ - **Statistics** — Summaries of directories and files
18
+ - **Fast and lightweight** — No external dependencies
19
+
20
+ ## Basic usage
21
+
22
+ View a directory tree:
23
+
24
+ ```console
25
+ stree /path/to/directory
26
+ ```
27
+
28
+ Show file type icons:
29
+
30
+ ```console
31
+ stree . --icons
32
+ ```
33
+
34
+ Show file sizes:
35
+
36
+ ```console
37
+ stree . --show-size
38
+ ```
39
+
40
+ Limit traversal depth:
41
+
42
+ ```console
43
+ stree . --max-depth 3
44
+ ```
45
+
46
+ ## Examples
47
+
48
+ Exclude development folders:
49
+
50
+ ```console
51
+ stree . --exclude-folders __pycache__,node_modules,.git,venv --max-depth 4
52
+ ```
53
+
54
+ Find large files:
55
+
56
+ ```console
57
+ stree /home --min-size 100M --show-size --sort-by size --reverse-sort
58
+ ```
59
+
60
+ Export the tree to a file:
61
+
62
+ ```console
63
+ stree /path --export directory_structure.txt
64
+ ```
65
+
66
+ Show only code files:
67
+
68
+ ```console
69
+ stree . --include-patterns "*.py,*.js,*.java,*.cpp"
70
+ ```
71
+
72
+ Exclude temporary files:
73
+
74
+ ```console
75
+ stree . --exclude-extensions tmp,bak,log --exclude-files "*.tmp,*.bak"
76
+ ```
77
+
78
+ ## Options
79
+
80
+ ```text
81
+ Usage: stree [OPTIONS] PATH
82
+
83
+ Display directory tree structure with advanced filtering.
84
+
85
+ Options:
86
+ --show-hidden Show hidden files and folders
87
+ --no-file Exclude all files
88
+ --no-folder Exclude all folders
89
+ --exclude-extensions Comma-separated file extensions to exclude
90
+ --exclude-folders Comma-separated folder names to exclude
91
+ --exclude-files Comma-separated file patterns to exclude
92
+ --include-patterns Comma-separated patterns to include
93
+ --max-depth Maximum depth to traverse
94
+ --min-size Minimum file size (e.g., 1M, 100K, 1G)
95
+ --max-size Maximum file size (e.g., 1M, 100K, 1G)
96
+ --show-size Show file sizes
97
+ --icons Show file type icons
98
+ --sort-by Sort method: name, size, or type
99
+ --reverse-sort Reverse sort order
100
+ --export Export tree to specified file
101
+ --version Show version
102
+ --help Show this help message
103
+ ```
@@ -0,0 +1,13 @@
1
+ """
2
+ Storage Viewer - Advanced directory tree visualizer with filtering
3
+ A powerful CLI tool for visualizing directory structures with advanced filtering option>
4
+ """
5
+
6
+ __version__ = "1.0.0"
7
+ __author__ = "Lingaraj Sa"
8
+ __email__ = "infofusiontechlab@gmail.com"
9
+ __description__ = "Advanced directory tree visualizer with filtering options"
10
+ __url__ = "https://github.com/fusion-tech-lab-mastet/storage-viewer"
11
+ __license__ = "MIT"
12
+
13
+ from .main import DirectoryTree, parse_size, main
@@ -0,0 +1,386 @@
1
+ # src/storage_viewer/storage_viewer.py
2
+ import os
3
+ import sys
4
+ import argparse
5
+ from pathlib import Path
6
+ import fnmatch
7
+
8
+ __version__ = "1.0.0"
9
+
10
+ class DirectoryTree:
11
+ def __init__(self):
12
+ self.stats = {
13
+ 'directories': 0,
14
+ 'files': 0,
15
+ 'total_size': 0,
16
+ 'skipped_items': 0
17
+ }
18
+
19
+ def should_include_item(self, item_path, item_name, options):
20
+ """Determine if an item should be included based on filters"""
21
+ # Skip hidden files unless explicitly shown
22
+ if not getattr(options, 'show_hidden', False) and item_name.startswith('.'):
23
+ return False
24
+
25
+ # Check if it's a directory
26
+ is_directory = os.path.isdir(item_path)
27
+
28
+ # Skip files if --no-file is specified
29
+ if not is_directory and getattr(options, 'no_file', False):
30
+ self.stats['skipped_items'] += 1
31
+ return False
32
+
33
+ # Skip folders if --no-folder is specified
34
+ if is_directory and getattr(options, 'no_folder', False):
35
+ self.stats['skipped_items'] += 1
36
+ return False
37
+
38
+ # Check folder name exclusion
39
+ if is_directory and getattr(options, 'exclude_folders', []):
40
+ for folder_pattern in options.exclude_folders:
41
+ if fnmatch.fnmatch(item_name.lower(), folder_pattern.lower()):
42
+ self.stats['skipped_items'] += 1
43
+ return False
44
+
45
+ # Check file extension exclusion
46
+ if not is_directory and getattr(options, 'exclude_extensions', []):
47
+ file_ext = Path(item_name).suffix.lower()
48
+ if file_ext and file_ext[1:] in [ext.lower() for ext in options.exclude_extensions]:
49
+ self.stats['skipped_items'] += 1
50
+ return False
51
+
52
+ # Check file pattern exclusion
53
+ if not is_directory and getattr(options, 'exclude_files', []):
54
+ for file_pattern in options.exclude_files:
55
+ if fnmatch.fnmatch(item_name.lower(), file_pattern.lower()):
56
+ self.stats['skipped_items'] += 1
57
+ return False
58
+
59
+ # Check include patterns
60
+ if getattr(options, 'include_patterns', []):
61
+ matched = False
62
+ for pattern in options.include_patterns:
63
+ if fnmatch.fnmatch(item_name.lower(), pattern.lower()):
64
+ matched = True
65
+ break
66
+ if not matched:
67
+ self.stats['skipped_items'] += 1
68
+ return False
69
+
70
+ # Check max depth
71
+ if getattr(options, 'max_depth', None) and self.current_depth >= options.max_depth:
72
+ return False
73
+
74
+ # Check size filters
75
+ if not is_directory and getattr(options, 'min_size', None):
76
+ try:
77
+ file_size = os.path.getsize(item_path)
78
+ if file_size < options.min_size:
79
+ self.stats['skipped_items'] += 1
80
+ return False
81
+ except (OSError, PermissionError):
82
+ return False
83
+
84
+ if not is_directory and getattr(options, 'max_size', None):
85
+ try:
86
+ file_size = os.path.getsize(item_path)
87
+ if file_size > options.max_size:
88
+ self.stats['skipped_items'] += 1
89
+ return False
90
+ except (OSError, PermissionError):
91
+ return False
92
+
93
+ return True
94
+
95
+ def get_file_icon(self, item_name, is_directory):
96
+ """Get appropriate icon for the item"""
97
+ if is_directory:
98
+ return "📁 "
99
+
100
+ file_ext = Path(item_name).suffix.lower()
101
+ icons = {
102
+ '.py': '🐍 ', '.js': '📜 ', '.html': '🌐 ', '.css': '🎨 ',
103
+ '.json': '📋 ', '.xml': '📄 ', '.txt': '📝 ', '.md': '📖 ',
104
+ '.pdf': '📕 ', '.doc': '📘 ', '.docx': '📘 ',
105
+ '.jpg': '🖼 ', '.jpeg': '🖼 ', '.png': '🖼 ', '.gif': '🖼 ',
106
+ '.mp3': '🎵 ', '.mp4': '🎬 ', '.avi': '🎬 ', '.mkv': '🎬 ',
107
+ '.zip': '📦 ', '.tar': '📦 ', '.gz': '📦 ', '.rar': '📦 ',
108
+ '.exe': '⚙️ ', '.app': '⚙️ ', '.deb': '⚙️ ', '.rpm': '⚙️ ',
109
+ }
110
+ return icons.get(file_ext, '📄 ')
111
+
112
+ def print_tree(self, start_path, prefix="", is_last=True, options=None, current_depth=0):
113
+ """Recursively print the directory tree structure"""
114
+ self.current_depth = current_depth
115
+
116
+ item_name = os.path.basename(start_path)
117
+ is_directory = os.path.isdir(start_path)
118
+
119
+ # Get icon and format item name
120
+ icon = self.get_file_icon(item_name, is_directory) if getattr(options, 'icons', False) else ""
121
+ size_info = ""
122
+
123
+ if getattr(options, 'show_size', False) and not is_directory:
124
+ try:
125
+ file_size = os.path.getsize(start_path)
126
+ size_info = f" [{self.format_size(file_size)}]"
127
+ except (OSError, PermissionError):
128
+ size_info = " [N/A]"
129
+
130
+ # Print the current item
131
+ connector = "└── " if is_last else "├── "
132
+ print(prefix + connector + icon + item_name + size_info)
133
+
134
+ # Update statistics
135
+ if is_directory:
136
+ self.stats['directories'] += 1
137
+ else:
138
+ self.stats['files'] += 1
139
+ try:
140
+ self.stats['total_size'] += os.path.getsize(start_path)
141
+ except (OSError, PermissionError):
142
+ pass
143
+
144
+ # Process directory contents
145
+ if is_directory and (not getattr(options, 'max_depth', None) or current_depth < getattr(options, 'max_depth', 0)):
146
+ try:
147
+ items = []
148
+ for item in os.listdir(start_path):
149
+ item_path = os.path.join(start_path, item)
150
+ if self.should_include_item(item_path, item, options):
151
+ items.append((item, item_path))
152
+
153
+ # Sort based on options
154
+ sort_by = getattr(options, 'sort_by', 'name')
155
+ if sort_by == 'name':
156
+ items.sort(key=lambda x: x[0].lower())
157
+ elif sort_by == 'size':
158
+ items.sort(key=lambda x: os.path.getsize(x[1]) if os.path.isfile(x[1]) else 0)
159
+ elif sort_by == 'type':
160
+ items.sort(key=lambda x: (not os.path.isdir(x[1]), Path(x[0]).suffix.lower(), x[0].lower()))
161
+ else: # default: directories first
162
+ items.sort(key=lambda x: (not os.path.isdir(x[1]), x[0].lower()))
163
+
164
+ # Reverse if requested
165
+ if getattr(options, 'reverse_sort', False):
166
+ items.reverse()
167
+
168
+ # Calculate new prefix
169
+ new_prefix = prefix + (" " if is_last else "│ ")
170
+
171
+ # Process each item
172
+ for i, (item_name, item_path) in enumerate(items):
173
+ is_last_item = (i == len(items) - 1)
174
+ self.print_tree(item_path, new_prefix, is_last_item, options, current_depth + 1)
175
+
176
+ except PermissionError:
177
+ print(prefix + " └── 🔒 [Permission Denied]")
178
+ except Exception as e:
179
+ print(prefix + f" └── ❌ [Error: {str(e)}]")
180
+
181
+ def export_tree(self, start_path, output_file, options):
182
+ """Export tree to a file"""
183
+ original_stdout = sys.stdout
184
+ with open(output_file, 'w', encoding='utf-8') as f:
185
+ sys.stdout = f
186
+ self.print_detailed_tree(start_path, options)
187
+ sys.stdout = original_stdout
188
+ print(f"Tree exported to: {output_file}")
189
+
190
+ def print_detailed_tree(self, start_path, options):
191
+ """Print detailed directory tree with header information"""
192
+ print(f"Directory Tree: {start_path}")
193
+ print("=" * 60)
194
+
195
+ if getattr(options, 'show_size', False):
196
+ total_size = self.get_directory_size(start_path)
197
+ print(f"Total Size: {self.format_size(total_size)}")
198
+
199
+ print(f"Filters: {self.get_filters_summary(options)}")
200
+ print()
201
+
202
+ self.print_tree(start_path, options=options)
203
+
204
+ print()
205
+ print("=" * 60)
206
+ self.print_statistics()
207
+
208
+ def get_filters_summary(self, options):
209
+ """Get a summary of applied filters"""
210
+ filters = []
211
+ if getattr(options, 'no_file', False):
212
+ filters.append("No Files")
213
+ if getattr(options, 'no_folder', False):
214
+ filters.append("No Folders")
215
+ if getattr(options, 'exclude_folders', []):
216
+ filters.append(f"Exclude folders: {', '.join(options.exclude_folders)}")
217
+ if getattr(options, 'exclude_extensions', []):
218
+ filters.append(f"Exclude extensions: {', '.join(options.exclude_extensions)}")
219
+ if getattr(options, 'exclude_files', []):
220
+ filters.append(f"Exclude files: {', '.join(options.exclude_files)}")
221
+ if getattr(options, 'include_patterns', []):
222
+ filters.append(f"Include patterns: {', '.join(options.include_patterns)}")
223
+ if getattr(options, 'max_depth', None):
224
+ filters.append(f"Max depth: {options.max_depth}")
225
+ if getattr(options, 'min_size', None):
226
+ filters.append(f"Min size: {self.format_size(options.min_size)}")
227
+ if getattr(options, 'max_size', None):
228
+ filters.append(f"Max size: {self.format_size(options.max_size)}")
229
+
230
+ return "; ".join(filters) if filters else "None"
231
+
232
+ def print_statistics(self):
233
+ """Print summary statistics"""
234
+ print("Statistics:")
235
+ print(f" 📁 Directories: {self.stats['directories']}")
236
+ print(f" 📄 Files: {self.stats['files']}")
237
+ print(f" 💾 Total Size: {self.format_size(self.stats['total_size'])}")
238
+ print(f" 🚫 Skipped Items: {self.stats['skipped_items']}")
239
+
240
+ def get_directory_size(self, path):
241
+ """Calculate total directory size"""
242
+ total_size = 0
243
+ try:
244
+ for dirpath, dirnames, filenames in os.walk(path):
245
+ for filename in filenames:
246
+ filepath = os.path.join(dirpath, filename)
247
+ try:
248
+ total_size += os.path.getsize(filepath)
249
+ except (OSError, PermissionError):
250
+ continue
251
+ except (OSError, PermissionError):
252
+ pass
253
+ return total_size
254
+
255
+ def format_size(self, size_bytes):
256
+ """Convert bytes to human readable format"""
257
+ if size_bytes == 0:
258
+ return "0 B"
259
+
260
+ size_names = ["B", "KB", "MB", "GB", "TB"]
261
+ i = 0
262
+ while size_bytes >= 1024 and i < len(size_names) - 1:
263
+ size_bytes /= 1024.0
264
+ i += 1
265
+ return f"{size_bytes:.2f} {size_names[i]}"
266
+
267
+ def parse_size(size_str):
268
+ """Parse size string like '10M', '1G', '500K' to bytes"""
269
+ if not size_str:
270
+ return None
271
+
272
+ size_str = size_str.upper().strip()
273
+ multipliers = {'B': 1, 'K': 1024, 'M': 1024**2, 'G': 1024**3, 'T': 1024**4}
274
+
275
+ if size_str[-1] in multipliers:
276
+ number = float(size_str[:-1])
277
+ multiplier = multipliers[size_str[-1]]
278
+ return int(number * multiplier)
279
+ else:
280
+ return int(size_str)
281
+
282
+ def main():
283
+ parser = argparse.ArgumentParser(
284
+ description="Display directory tree structure with advanced filtering",
285
+ formatter_class=argparse.RawDescriptionHelpFormatter,
286
+ epilog="""
287
+ Examples:
288
+ stree /path/to/directory
289
+ stree /path --no-file
290
+ stree /path --no-folder
291
+ stree /path --exclude-extensions py,txt,log
292
+ stree /path --exclude-folders node_modules,__pycache__
293
+ stree /path --exclude-files "*.tmp,*.bak"
294
+ stree /path --include-patterns "*.py,*.js"
295
+ stree /path --max-depth 3
296
+ stree /path --min-size 1M --max-size 10M
297
+ stree /path --sort-by size --reverse-sort
298
+ stree /path --show-hidden --show-size
299
+ stree /path --icons
300
+ stree /path --export tree.txt
301
+ """
302
+ )
303
+
304
+ # Basic options
305
+ parser.add_argument("path", help="Path to the directory to analyze")
306
+ parser.add_argument("--show-hidden", action="store_true", help="Show hidden files and folders")
307
+
308
+ # Exclusion filters
309
+ parser.add_argument("--no-file", action="store_true", help="Exclude all files")
310
+ parser.add_argument("--no-folder", action="store_true", help="Exclude all folders")
311
+ parser.add_argument("--exclude-extensions", help="Comma-separated file extensions to exclude (e.g., py,txt,log)")
312
+ parser.add_argument("--exclude-folders", help="Comma-separated folder names to exclude (e.g., node_modules,__pycache__)")
313
+ parser.add_argument("--exclude-files", help="Comma-separated file patterns to exclude (e.g., *.tmp,*.bak)")
314
+
315
+ # Inclusion filters
316
+ parser.add_argument("--include-patterns", help="Comma-separated patterns to include (e.g., *.py,*.js)")
317
+
318
+ # Size and depth filters
319
+ parser.add_argument("--max-depth", type=int, help="Maximum depth to traverse")
320
+ parser.add_argument("--min-size", help="Minimum file size (e.g., 1M, 100K, 1G)")
321
+ parser.add_argument("--max-size", help="Maximum file size (e.g., 1M, 100K, 1G)")
322
+
323
+ # Display options
324
+ parser.add_argument("--show-size", action="store_true", help="Show file sizes")
325
+ parser.add_argument("--icons", action="store_true", help="Show file type icons")
326
+ parser.add_argument("--sort-by", choices=['name', 'size', 'type'], default='name', help="Sort method")
327
+ parser.add_argument("--reverse-sort", action="store_true", help="Reverse sort order")
328
+ parser.add_argument("--export", help="Export tree to specified file")
329
+
330
+ # Version
331
+ parser.add_argument("--version", action="version", version=f"storage-viewer {__version__}")
332
+
333
+ args = parser.parse_args()
334
+
335
+ # Validate path
336
+ if not os.path.exists(args.path):
337
+ print(f"Error: Path '{args.path}' does not exist")
338
+ sys.exit(1)
339
+
340
+ # Parse comma-separated lists
341
+ if args.exclude_extensions:
342
+ args.exclude_extensions = [ext.strip() for ext in args.exclude_extensions.split(',')]
343
+ else:
344
+ args.exclude_extensions = []
345
+
346
+ if args.exclude_folders:
347
+ args.exclude_folders = [folder.strip() for folder in args.exclude_folders.split(',')]
348
+ else:
349
+ args.exclude_folders = []
350
+
351
+ if args.exclude_files:
352
+ args.exclude_files = [pattern.strip() for pattern in args.exclude_files.split(',')]
353
+ else:
354
+ args.exclude_files = []
355
+
356
+ if args.include_patterns:
357
+ args.include_patterns = [pattern.strip() for pattern in args.include_patterns.split(',')]
358
+ else:
359
+ args.include_patterns = []
360
+
361
+ # Parse size filters
362
+ if args.min_size:
363
+ args.min_size = parse_size(args.min_size)
364
+ if args.max_size:
365
+ args.max_size = parse_size(args.max_size)
366
+
367
+ # Convert to absolute path
368
+ abs_path = os.path.abspath(args.path)
369
+
370
+ try:
371
+ tree = DirectoryTree()
372
+
373
+ if args.export:
374
+ tree.export_tree(abs_path, args.export, args)
375
+ else:
376
+ tree.print_detailed_tree(abs_path, args)
377
+
378
+ except KeyboardInterrupt:
379
+ print("\nOperation cancelled by user")
380
+ except Exception as e:
381
+ print(f"Error: {str(e)}")
382
+ import traceback
383
+ traceback.print_exc()
384
+
385
+ if __name__ == "__main__":
386
+ main()
@@ -0,0 +1,25 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "storage-viewer"
7
+ version = "1.0.0"
8
+ description = "Advanced directory tree visualizer with filtering options"
9
+ readme = "README.md"
10
+ requires-python = ">=3.7"
11
+ license = { file = "LICENSE" }
12
+ authors = [
13
+ { name = "Lingaraj Sa" }
14
+ ]
15
+ classifiers = [
16
+ "License :: OSI Approved :: MIT License",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3 :: Only",
19
+ ]
20
+
21
+ [project.scripts]
22
+ stree = "SourceCode.main:main"
23
+
24
+ [tool.setuptools]
25
+ packages = ["SourceCode"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,138 @@
1
+ Metadata-Version: 2.4
2
+ Name: storage-viewer
3
+ Version: 1.0.0
4
+ Summary: Advanced directory tree visualizer with filtering options
5
+ Author: Lingaraj Sa
6
+ License: MIT License
7
+
8
+ Copyright (c) 2024 Lingaraj Sa
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Classifier: License :: OSI Approved :: MIT License
29
+ Classifier: Programming Language :: Python :: 3
30
+ Classifier: Programming Language :: Python :: 3 :: Only
31
+ Requires-Python: >=3.7
32
+ Description-Content-Type: text/markdown
33
+ License-File: LICENSE
34
+ Dynamic: license-file
35
+
36
+ # Storage Viewer CLI
37
+
38
+ ![Python Version](https://img.shields.io/badge/python-3.7%2B-blue)
39
+ ![License](https://img.shields.io/badge/license-MIT-green)
40
+ ![PyPI](https://img.shields.io/badge/pypi-v1.0.0-orange)
41
+
42
+ A powerful, feature-rich directory tree visualizer with advanced filtering options for the command line.
43
+
44
+ ## Features
45
+
46
+ - **Hierarchical tree display** — Clean, readable directory structures
47
+ - **Advanced filtering** — Filter by extension, folder, pattern, and size
48
+ - **Size analysis** — Show file sizes in human-readable formats
49
+ - **File type icons** — Visual indicators for different file types
50
+ - **Depth control** — Limit directory traversal depth
51
+ - **Export capability** — Save tree structures to files
52
+ - **Statistics** — Summaries of directories and files
53
+ - **Fast and lightweight** — No external dependencies
54
+
55
+ ## Basic usage
56
+
57
+ View a directory tree:
58
+
59
+ ```console
60
+ stree /path/to/directory
61
+ ```
62
+
63
+ Show file type icons:
64
+
65
+ ```console
66
+ stree . --icons
67
+ ```
68
+
69
+ Show file sizes:
70
+
71
+ ```console
72
+ stree . --show-size
73
+ ```
74
+
75
+ Limit traversal depth:
76
+
77
+ ```console
78
+ stree . --max-depth 3
79
+ ```
80
+
81
+ ## Examples
82
+
83
+ Exclude development folders:
84
+
85
+ ```console
86
+ stree . --exclude-folders __pycache__,node_modules,.git,venv --max-depth 4
87
+ ```
88
+
89
+ Find large files:
90
+
91
+ ```console
92
+ stree /home --min-size 100M --show-size --sort-by size --reverse-sort
93
+ ```
94
+
95
+ Export the tree to a file:
96
+
97
+ ```console
98
+ stree /path --export directory_structure.txt
99
+ ```
100
+
101
+ Show only code files:
102
+
103
+ ```console
104
+ stree . --include-patterns "*.py,*.js,*.java,*.cpp"
105
+ ```
106
+
107
+ Exclude temporary files:
108
+
109
+ ```console
110
+ stree . --exclude-extensions tmp,bak,log --exclude-files "*.tmp,*.bak"
111
+ ```
112
+
113
+ ## Options
114
+
115
+ ```text
116
+ Usage: stree [OPTIONS] PATH
117
+
118
+ Display directory tree structure with advanced filtering.
119
+
120
+ Options:
121
+ --show-hidden Show hidden files and folders
122
+ --no-file Exclude all files
123
+ --no-folder Exclude all folders
124
+ --exclude-extensions Comma-separated file extensions to exclude
125
+ --exclude-folders Comma-separated folder names to exclude
126
+ --exclude-files Comma-separated file patterns to exclude
127
+ --include-patterns Comma-separated patterns to include
128
+ --max-depth Maximum depth to traverse
129
+ --min-size Minimum file size (e.g., 1M, 100K, 1G)
130
+ --max-size Maximum file size (e.g., 1M, 100K, 1G)
131
+ --show-size Show file sizes
132
+ --icons Show file type icons
133
+ --sort-by Sort method: name, size, or type
134
+ --reverse-sort Reverse sort order
135
+ --export Export tree to specified file
136
+ --version Show version
137
+ --help Show this help message
138
+ ```
@@ -0,0 +1,10 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ SourceCode/__init__.py
5
+ SourceCode/main.py
6
+ storage_viewer.egg-info/PKG-INFO
7
+ storage_viewer.egg-info/SOURCES.txt
8
+ storage_viewer.egg-info/dependency_links.txt
9
+ storage_viewer.egg-info/entry_points.txt
10
+ storage_viewer.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ stree = SourceCode.main:main
@@ -0,0 +1 @@
1
+ SourceCode