pytree2 0.2.1__tar.gz → 0.2.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytree2
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: A Python CLI utility for visualizing folder trees with sizes and counts.
5
5
  Author-email: Angelo Luiz Angonezi <angeloangonezi2@gmail.com>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pytree2"
7
- version = "0.2.1"
7
+ version = "0.2.2"
8
8
  description = "A Python CLI utility for visualizing folder trees with sizes and counts."
9
9
  authors = [{name = "Angelo Luiz Angonezi", email = "angeloangonezi2@gmail.com"}]
10
10
  readme = "README.md"
@@ -20,6 +20,7 @@ Issues = "https://github.com/angelo-angonezi/pytree/issues"
20
20
 
21
21
  [project.scripts]
22
22
  pytree = "pytree.main:main"
23
+ pytree-loc = "pytree.main:main_loc"
23
24
 
24
25
  [tool.setuptools]
25
26
  package-dir = {"" = "src"}
@@ -11,14 +11,15 @@
11
11
  from os import walk
12
12
  from treelib import Tree
13
13
  from os.path import join
14
- from os.path import split
15
- from os.path import islink
16
14
  from os.path import abspath
17
15
  from os.path import dirname
18
16
  from os.path import getsize
19
17
  from os import _exit # noqa
20
18
  from pytree.utils.aux_funcs import is_cache
19
+ from pytree.utils.aux_funcs import reverse_dict
21
20
  from pytree.utils.aux_funcs import get_size_str
21
+ from pytree.utils.aux_funcs import get_skip_bool
22
+ from pytree.utils.aux_funcs import get_path_name
22
23
  from pytree.utils.aux_funcs import get_path_depth
23
24
  from pytree.utils.aux_funcs import get_start_path
24
25
  from pytree.utils.global_vars import CACHE_FOLDERS
@@ -107,6 +108,10 @@ class ModuleProgressTracker(ProgressTracker):
107
108
  start_path = args_dict['start_path']
108
109
  start_path = get_start_path(start_path)
109
110
 
111
+ # getting start is cache bool
112
+ start_is_cache = is_cache(path=start_path,
113
+ cache_folders=CACHE_FOLDERS)
114
+
110
115
  # getting folders/subfolders/files in start path
111
116
  folders_subfolders_files = walk(start_path,
112
117
  topdown=False)
@@ -117,30 +122,17 @@ class ModuleProgressTracker(ProgressTracker):
117
122
  # getting current folder path/subfolders/files
118
123
  folder_path, _, files = item
119
124
 
120
- # getting path is root bool
121
- path_is_root = (folder_path == start_path)
122
-
123
- # checking if current path is root
124
- if not path_is_root:
125
-
126
- # getting folder is symlink bool
127
- folder_is_symlink = islink(path=folder_path)
128
-
129
- # checking if current folder is symlink
130
- if folder_is_symlink:
131
-
132
- # skipping symlink folder
133
- continue
134
-
135
- # getting folder is cache bool
136
- folder_is_cache = is_cache(path=folder_path,
137
- cache_folders=CACHE_FOLDERS)
125
+ # getting skip folder bool
126
+ skip_folder = get_skip_bool(folder_path=folder_path,
127
+ start_path=start_path,
128
+ start_is_cache=start_is_cache,
129
+ cache_folders=CACHE_FOLDERS)
138
130
 
139
- # checking if current folder is cache
140
- if folder_is_cache:
131
+ # checking whether to skip current folder
132
+ if skip_folder:
141
133
 
142
- # skipping cache folder
143
- continue
134
+ # skipping current folder
135
+ continue
144
136
 
145
137
  # updating progress tracker attributes
146
138
  self.folders_num += 1
@@ -212,6 +204,10 @@ class PyTree:
212
204
  self.cache_folders = cache_folders
213
205
  self.progress_tracker = progress_tracker
214
206
 
207
+ # getting start is cache bool
208
+ self.start_is_cache = is_cache(path=self.start_path,
209
+ cache_folders=self.cache_folders)
210
+
215
211
  # getting start level
216
212
  self.start_level = get_path_depth(path=self.start_path)
217
213
 
@@ -226,6 +222,10 @@ class PyTree:
226
222
  self.total_files = 0
227
223
  self.total_size = 0
228
224
 
225
+ # defining placeholder values for current folder size/count
226
+ self.current_folder_size = 0
227
+ self.current_items_count = 0
228
+
229
229
  # valid files
230
230
  self.valid_files = 0
231
231
 
@@ -298,9 +298,7 @@ class PyTree:
298
298
 
299
299
  def get_folder_dict(self,
300
300
  folder_name: str,
301
- folder_path: str,
302
- folder_size: int,
303
- items_count: int
301
+ folder_path: str
304
302
  ) -> dict:
305
303
  """
306
304
  Given a folder path, returns
@@ -317,17 +315,27 @@ class PyTree:
317
315
  if self.include_sizes:
318
316
 
319
317
  # updating base dict
320
- base_dict['size'] = folder_size
318
+ base_dict['size'] = self.current_folder_size
321
319
 
322
320
  # checking include counts toggle
323
321
  if self.include_counts:
324
322
 
325
323
  # updating base dict
326
- base_dict['count'] = items_count
324
+ base_dict['count'] = self.current_items_count
327
325
 
328
326
  # returning base dict
329
327
  return base_dict
330
328
 
329
+ def scan_file(self,
330
+ file_path: str
331
+ ) -> None:
332
+ pass
333
+
334
+ def scan_folder(self,
335
+ folder_path: str
336
+ ) -> None:
337
+ pass
338
+
331
339
  def get_tree_dict(self) -> dict:
332
340
  """
333
341
  Docstring.
@@ -342,30 +350,17 @@ class PyTree:
342
350
  # getting current folder path/subfolders/files
343
351
  folder_path, subfolders, files = item
344
352
 
345
- # getting path is root bool
346
- path_is_root = (folder_path == self.start_path)
353
+ # getting skip folder bool
354
+ skip_folder = get_skip_bool(folder_path=folder_path,
355
+ start_path=self.start_path,
356
+ start_is_cache=self.start_is_cache,
357
+ cache_folders=self.cache_folders)
347
358
 
348
- # checking if current path is root
349
- if not path_is_root:
359
+ # checking whether to skip current folder
360
+ if skip_folder:
350
361
 
351
- # getting folder is symlink bool
352
- folder_is_symlink = islink(path=folder_path)
353
-
354
- # checking if current folder is symlink
355
- if folder_is_symlink:
356
-
357
- # skipping symlink folder
358
- continue
359
-
360
- # getting folder is cache bool
361
- folder_is_cache = is_cache(path=folder_path,
362
- cache_folders=self.cache_folders)
363
-
364
- # checking if current folder is cache
365
- if folder_is_cache:
366
-
367
- # skipping cache folder
368
- continue
362
+ # skipping current folder
363
+ continue
369
364
 
370
365
  # updating progress tracker attributes
371
366
  self.progress_tracker.current_folder += 1
@@ -377,17 +372,8 @@ class PyTree:
377
372
  subfolders = sorted(subfolders)
378
373
  files = sorted(files)
379
374
 
380
- # getting current folder split
381
- folder_split = split(p=folder_path)
382
-
383
375
  # getting current folder name
384
- folder_name = folder_split[-1]
385
-
386
- # defining placeholder value for current folder size/count
387
- # TODO: convert this to class attributes
388
- # (update this function to smaller functions, which update/reset these attributes)
389
- folder_size = 0
390
- items_count = 0
376
+ folder_name = get_path_name(path=folder_path)
391
377
 
392
378
  # getting current files num
393
379
  files_num = len(files)
@@ -397,9 +383,11 @@ class PyTree:
397
383
 
398
384
  # resetting progress tracker attributes
399
385
  self.progress_tracker.current_file = 0
386
+ self.current_folder_size = 0
387
+ self.current_items_count = 0
400
388
 
401
389
  # iterating over current files
402
- for file in files:
390
+ for file_name in files:
403
391
 
404
392
  # updating progress tracker attributes
405
393
  self.progress_tracker.current_iteration += 1
@@ -412,7 +400,7 @@ class PyTree:
412
400
  if self.extension is not None:
413
401
 
414
402
  # getting file matches extension bool
415
- file_matches_extension = file.endswith(self.extension)
403
+ file_matches_extension = file_name.endswith(self.extension)
416
404
 
417
405
  # checking if current file matches extension
418
406
  if not file_matches_extension:
@@ -430,7 +418,7 @@ class PyTree:
430
418
  if self.keyword is not None:
431
419
 
432
420
  # getting file matches keyword bool
433
- file_matches_keyword = (self.keyword in file)
421
+ file_matches_keyword = (self.keyword in file_name)
434
422
 
435
423
  # checking if current file matches keyword
436
424
  if not file_matches_keyword:
@@ -446,10 +434,10 @@ class PyTree:
446
434
 
447
435
  # getting current file path
448
436
  file_path = join(folder_path,
449
- file)
437
+ file_name)
450
438
 
451
439
  # getting current file dict
452
- file_dict = self.get_file_dict(file_name=file,
440
+ file_dict = self.get_file_dict(file_name=file_name,
453
441
  file_path=file_path)
454
442
 
455
443
  # assembling path dict
@@ -465,7 +453,7 @@ class PyTree:
465
453
  file_size = file_dict['size']
466
454
 
467
455
  # updating folder size
468
- folder_size += file_size
456
+ self.current_folder_size += file_size
469
457
 
470
458
  # updating total size
471
459
  self.total_size += file_size
@@ -474,38 +462,31 @@ class PyTree:
474
462
  if self.include_counts:
475
463
 
476
464
  # updating items count
477
- items_count += 1
465
+ self.current_items_count += 1
478
466
 
479
467
  # iterating over current subfolders
480
- for subfolder in subfolders:
468
+ for subfolder_name in subfolders:
481
469
 
482
470
  # getting current subfolder path
483
471
  subfolder_path = join(folder_path,
484
- subfolder)
485
-
486
- # getting subfolder is symlink bool
487
- subfolder_is_symlink = islink(path=subfolder_path)
488
-
489
- # checking if current subfolder is symlink
490
- if subfolder_is_symlink:
491
-
492
- # skipping symlink subfolder
493
- continue
472
+ subfolder_name)
494
473
 
495
- # getting subfolder is cache bool
496
- subfolder_is_cache = is_cache(path=subfolder_path,
497
- cache_folders=self.cache_folders)
474
+ # getting skip folder bool
475
+ skip_folder = get_skip_bool(folder_path=subfolder_path,
476
+ start_path=self.start_path,
477
+ start_is_cache=self.start_is_cache,
478
+ cache_folders=self.cache_folders)
498
479
 
499
- # checking if current subfolder is cache
500
- if subfolder_is_cache:
480
+ # checking whether to skip current folder
481
+ if skip_folder:
501
482
 
502
- # skipping cache subfolder
483
+ # skipping current folder
503
484
  continue
504
485
 
505
486
  # getting current subfolder dict
506
487
  subfolder_dict = self.tree_dict.get(subfolder_path) # this will never be None due to topdown=False!
507
488
  # The subfolder will always have already been a
508
- # folder in previous iteration!
489
+ # folder in a previous iteration!
509
490
 
510
491
  # checking include sizes toggle
511
492
  if self.include_sizes:
@@ -514,19 +495,17 @@ class PyTree:
514
495
  subfolder_size = subfolder_dict['size']
515
496
 
516
497
  # updating folder size
517
- folder_size += subfolder_size
498
+ self.current_folder_size += subfolder_size
518
499
 
519
500
  # checking include counts toggle
520
501
  if self.include_counts:
521
502
 
522
503
  # updating items count
523
- items_count += 1
504
+ self.current_items_count += 1
524
505
 
525
506
  # getting current folder dict
526
507
  folder_dict = self.get_folder_dict(folder_name=folder_name,
527
- folder_path=folder_path,
528
- folder_size=folder_size,
529
- items_count=items_count)
508
+ folder_path=folder_path)
530
509
 
531
510
  # assembling path dict
532
511
  path_dict = {folder_path: folder_dict}
@@ -535,7 +514,7 @@ class PyTree:
535
514
  self.tree_dict.update(path_dict)
536
515
 
537
516
  # reversing dict (required since topdown was set to False in os.walk to enable size obtaining optimization)
538
- tree_dict = dict(reversed(self.tree_dict.items()))
517
+ tree_dict = reverse_dict(a_dict=self.tree_dict)
539
518
 
540
519
  # returning tree dict
541
520
  return tree_dict
@@ -0,0 +1,187 @@
1
+ # pytree main loc module
2
+
3
+ print('initializing...') # noqa
4
+
5
+ # Code destined to scanning python files lines of
6
+ # code count in given input folder, and creating
7
+ # tree structure to print on console.
8
+
9
+ ######################################################################
10
+ # imports
11
+
12
+ # importing required libraries
13
+ print('importing required libraries...') # noqa
14
+ from argparse import ArgumentParser
15
+ from pytree.classes.PyTree import PyTree
16
+ from pytree.utils.aux_funcs import get_start_path
17
+ from pytree.classes.PyTree import ModuleProgressTracker
18
+ print('all required libraries successfully imported.') # noqa
19
+
20
+ #####################################################################
21
+ # argument parsing related functions
22
+
23
+
24
+ def get_args_dict() -> dict:
25
+ """
26
+ Parses the arguments and returns a dictionary of the arguments.
27
+ :return: Dictionary. Represents the parsed arguments.
28
+ """
29
+ # defining program description
30
+ description = "pytree - a python cli utility for visualizing folder trees with sizes and counts"
31
+
32
+ # creating a parser instance
33
+ parser = ArgumentParser(description=description)
34
+
35
+ # start path param
36
+ parser.add_argument('start_path',
37
+ nargs='*',
38
+ type=str or list,
39
+ help='defines path to directory to start building the tree',
40
+ default='.')
41
+
42
+ # dirs only param
43
+ parser.add_argument('-d', '--dirs-only',
44
+ dest='dirs_only',
45
+ required=False,
46
+ action='store_true',
47
+ help='tree displays directories only, and does not show files inside folders',
48
+ default=False)
49
+
50
+ # show sizes param
51
+ parser.add_argument('-s', '--show-sizes',
52
+ dest='show_sizes',
53
+ required=False,
54
+ action='store_true',
55
+ help='tree displays files and folder sizes, in mega or gigabytes',
56
+ default=False)
57
+
58
+ # show counts param
59
+ parser.add_argument('-c', '--show-counts',
60
+ dest='show_counts',
61
+ required=False,
62
+ action='store_true',
63
+ help='tree displays the number of files or folders inside each directory',
64
+ default=False)
65
+
66
+ # extension param
67
+ parser.add_argument('-x', '--extension',
68
+ dest='extension',
69
+ required=False,
70
+ type=str or None,
71
+ help='tree will include only files that match given extension (e.g. ".txt", ".pdf")',
72
+ default=None)
73
+
74
+ # keyword param
75
+ parser.add_argument('-k', '--keyword',
76
+ dest='keyword',
77
+ required=False,
78
+ type=str or None,
79
+ help='tree will include only files that contain specific keyword on file name',
80
+ default=None)
81
+
82
+ # level param
83
+ parser.add_argument('-l', '--level',
84
+ dest='level',
85
+ required=False,
86
+ type=int or None,
87
+ help="defines tree's depth (until which subfolder tree will be created) [0=start_path, -1=all]",
88
+ default=-1)
89
+
90
+ # creating arguments dictionary
91
+ args_dict = vars(parser.parse_args())
92
+
93
+ # returning the arguments dictionary
94
+ return args_dict
95
+
96
+ ######################################################################
97
+ # defining auxiliary functions
98
+
99
+
100
+ def pytree(start_path: str,
101
+ dirs_only: bool,
102
+ include_counts: bool,
103
+ include_sizes: bool,
104
+ extension: str,
105
+ keyword: str,
106
+ level: int,
107
+ progress_tracker: ModuleProgressTracker
108
+ ) -> None:
109
+ """
110
+ Prints folder structure tree
111
+ on the console.
112
+ """
113
+ # initializing PyTree object
114
+ tree = PyTree(start_path=start_path,
115
+ dirs_only=dirs_only,
116
+ include_counts=include_counts,
117
+ include_sizes=include_sizes,
118
+ extension=extension,
119
+ keyword=keyword,
120
+ level=level,
121
+ progress_tracker=progress_tracker)
122
+
123
+ # running pytree main
124
+ tree.run()
125
+
126
+
127
+ def parse_and_run(args_dict: dict,
128
+ progress_tracker: ModuleProgressTracker
129
+ ) -> None:
130
+ """
131
+ Extracts args from args_dict
132
+ and runs module function.
133
+ """
134
+ # getting start path
135
+ start_path = args_dict['start_path']
136
+ start_path = get_start_path(start_path)
137
+
138
+ # getting dirs only bool
139
+ dirs_only = args_dict['dirs_only']
140
+
141
+ # getting include counts bool
142
+ include_counts = args_dict['show_counts']
143
+
144
+ # getting include sizes bool
145
+ include_sizes = args_dict['show_sizes']
146
+
147
+ # getting extension
148
+ extension = args_dict['extension']
149
+
150
+ # getting keyword
151
+ keyword = args_dict['keyword']
152
+
153
+ # getting level
154
+ level = args_dict['level']
155
+
156
+ # running pytree function
157
+ pytree(start_path=start_path,
158
+ dirs_only=dirs_only,
159
+ include_counts=include_counts,
160
+ include_sizes=include_sizes,
161
+ extension=extension,
162
+ keyword=keyword,
163
+ level=level,
164
+ progress_tracker=progress_tracker)
165
+
166
+ ######################################################################
167
+ # defining main function
168
+
169
+
170
+ def main():
171
+ """Runs main code."""
172
+ # initializing current module progress tracker instance
173
+ progress_tracker = ModuleProgressTracker()
174
+
175
+ # running code in separate thread
176
+ progress_tracker.run(function=parse_and_run,
177
+ args_parser=get_args_dict)
178
+
179
+ ######################################################################
180
+ # running main function
181
+
182
+
183
+ if __name__ == '__main__':
184
+ main()
185
+
186
+ ######################################################################
187
+ # end of current module
@@ -9,6 +9,7 @@
9
9
  # importing required libraries
10
10
  from sys import stdout
11
11
  from os.path import sep
12
+ from os.path import islink
12
13
  from os.path import abspath
13
14
  from os import get_terminal_size
14
15
  from pytree.utils.global_vars import ONE_KB
@@ -134,6 +135,21 @@ def get_time_str(time_in_seconds: int) -> str:
134
135
  return time_string
135
136
 
136
137
 
138
+ def get_path_name(path: str) -> str:
139
+ """
140
+ Given a full path, returns its
141
+ name (final split item).
142
+ """
143
+ # getting path split
144
+ path_split = get_path_split(path=path)
145
+
146
+ # getting path name
147
+ path_name = path_split[-1]
148
+
149
+ # returning path name
150
+ return path_name
151
+
152
+
137
153
  def is_cache(path: str,
138
154
  cache_folders: list
139
155
  ) -> bool:
@@ -173,6 +189,47 @@ def get_start_path(start_path: str or list) -> str:
173
189
  return start_path
174
190
 
175
191
 
192
+ def get_skip_bool(folder_path: str,
193
+ start_path: str,
194
+ start_is_cache: bool,
195
+ cache_folders: list
196
+ ) -> bool:
197
+ """
198
+ Given a path to a folder, returns
199
+ True if folder should be skipped,
200
+ and False otherwise.
201
+ """
202
+ # defining placeholder value for skip conditions list
203
+ skip_conditions = []
204
+
205
+ # getting path is root bool
206
+ path_is_root = (folder_path == start_path)
207
+
208
+ # checking if current path is root
209
+ if not path_is_root:
210
+
211
+ # getting folder is symlink bool
212
+ folder_is_symlink = islink(path=folder_path)
213
+
214
+ # appending current condition to skip conditions list
215
+ skip_conditions.append(folder_is_symlink)
216
+
217
+ # checking if start path is cache
218
+ if not start_is_cache:
219
+
220
+ # getting folder is cache bool
221
+ folder_is_cache = is_cache(path=folder_path,
222
+ cache_folders=cache_folders)
223
+
224
+ # appending current condition to skip conditions list
225
+ skip_conditions.append(folder_is_cache)
226
+
227
+ # updating skip bool
228
+ skip_bool = any(skip_conditions)
229
+
230
+ # returning skip bool
231
+ return skip_bool
232
+
176
233
  def get_path_split(path: str) -> list:
177
234
  """
178
235
  Given a path, returns its split
@@ -249,5 +306,23 @@ def get_size_str(size_in_bytes: int) -> str:
249
306
  # returning size str
250
307
  return size_str
251
308
 
309
+
310
+ def reverse_dict(a_dict: dict) -> dict:
311
+ """
312
+ Given a dictionary, returns
313
+ reversed dict.
314
+ """
315
+ # getting dict items
316
+ dict_items = a_dict.items()
317
+
318
+ # reversing items
319
+ reversed_items = reversed(dict_items)
320
+
321
+ # reassembling dict
322
+ reversed_dict = dict(reversed_items)
323
+
324
+ # returning reversed dict
325
+ return reversed_dict
326
+
252
327
  ######################################################################
253
328
  # end of current module
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytree2
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: A Python CLI utility for visualizing folder trees with sizes and counts.
5
5
  Author-email: Angelo Luiz Angonezi <angeloangonezi2@gmail.com>
6
6
  License-Expression: MIT
@@ -3,6 +3,7 @@ README.md
3
3
  pyproject.toml
4
4
  src/pytree/__init__.py
5
5
  src/pytree/main.py
6
+ src/pytree/main_loc.py
6
7
  src/pytree2.egg-info/PKG-INFO
7
8
  src/pytree2.egg-info/SOURCES.txt
8
9
  src/pytree2.egg-info/dependency_links.txt
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
2
  pytree = pytree.main:main
3
+ pytree-loc = pytree.main:main_loc
File without changes
File without changes
File without changes
File without changes
File without changes