pytree2 0.2.0__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.0
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.0"
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,14 +122,16 @@ class ModuleProgressTracker(ProgressTracker):
117
122
  # getting current folder path/subfolders/files
118
123
  folder_path, _, files = item
119
124
 
120
- # getting folder is cache bool
121
- folder_is_cache = is_cache(path=folder_path,
122
- 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)
123
130
 
124
- # checking if current folder is cache
125
- if folder_is_cache:
131
+ # checking whether to skip current folder
132
+ if skip_folder:
126
133
 
127
- # skipping cache folder
134
+ # skipping current folder
128
135
  continue
129
136
 
130
137
  # updating progress tracker attributes
@@ -197,6 +204,10 @@ class PyTree:
197
204
  self.cache_folders = cache_folders
198
205
  self.progress_tracker = progress_tracker
199
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
+
200
211
  # getting start level
201
212
  self.start_level = get_path_depth(path=self.start_path)
202
213
 
@@ -211,6 +222,10 @@ class PyTree:
211
222
  self.total_files = 0
212
223
  self.total_size = 0
213
224
 
225
+ # defining placeholder values for current folder size/count
226
+ self.current_folder_size = 0
227
+ self.current_items_count = 0
228
+
214
229
  # valid files
215
230
  self.valid_files = 0
216
231
 
@@ -283,9 +298,7 @@ class PyTree:
283
298
 
284
299
  def get_folder_dict(self,
285
300
  folder_name: str,
286
- folder_path: str,
287
- folder_size: int,
288
- items_count: int
301
+ folder_path: str
289
302
  ) -> dict:
290
303
  """
291
304
  Given a folder path, returns
@@ -302,17 +315,27 @@ class PyTree:
302
315
  if self.include_sizes:
303
316
 
304
317
  # updating base dict
305
- base_dict['size'] = folder_size
318
+ base_dict['size'] = self.current_folder_size
306
319
 
307
320
  # checking include counts toggle
308
321
  if self.include_counts:
309
322
 
310
323
  # updating base dict
311
- base_dict['count'] = items_count
324
+ base_dict['count'] = self.current_items_count
312
325
 
313
326
  # returning base dict
314
327
  return base_dict
315
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
+
316
339
  def get_tree_dict(self) -> dict:
317
340
  """
318
341
  Docstring.
@@ -327,30 +350,17 @@ class PyTree:
327
350
  # getting current folder path/subfolders/files
328
351
  folder_path, subfolders, files = item
329
352
 
330
- # getting path is root bool
331
- path_is_root = (folder_path == self.start_path)
332
-
333
- # checking if current path is root
334
- if not path_is_root:
335
-
336
- # getting folder is symlink bool
337
- folder_is_symlink = islink(path=folder_path)
338
-
339
- # checking if current folder is symlink
340
- if folder_is_symlink:
341
-
342
- # skipping symlink folder
343
- continue
344
-
345
- # getting folder is cache bool
346
- folder_is_cache = is_cache(path=folder_path,
347
- cache_folders=self.cache_folders)
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)
348
358
 
349
- # checking if current folder is cache
350
- if folder_is_cache:
359
+ # checking whether to skip current folder
360
+ if skip_folder:
351
361
 
352
- # skipping cache folder
353
- continue
362
+ # skipping current folder
363
+ continue
354
364
 
355
365
  # updating progress tracker attributes
356
366
  self.progress_tracker.current_folder += 1
@@ -362,17 +372,8 @@ class PyTree:
362
372
  subfolders = sorted(subfolders)
363
373
  files = sorted(files)
364
374
 
365
- # getting current folder split
366
- folder_split = split(p=folder_path)
367
-
368
375
  # getting current folder name
369
- folder_name = folder_split[-1]
370
-
371
- # defining placeholder value for current folder size/count
372
- # TODO: convert this to class attributes
373
- # (update this function to smaller functions, which update/reset these attributes)
374
- folder_size = 0
375
- items_count = 0
376
+ folder_name = get_path_name(path=folder_path)
376
377
 
377
378
  # getting current files num
378
379
  files_num = len(files)
@@ -382,9 +383,11 @@ class PyTree:
382
383
 
383
384
  # resetting progress tracker attributes
384
385
  self.progress_tracker.current_file = 0
386
+ self.current_folder_size = 0
387
+ self.current_items_count = 0
385
388
 
386
389
  # iterating over current files
387
- for file in files:
390
+ for file_name in files:
388
391
 
389
392
  # updating progress tracker attributes
390
393
  self.progress_tracker.current_iteration += 1
@@ -397,7 +400,7 @@ class PyTree:
397
400
  if self.extension is not None:
398
401
 
399
402
  # getting file matches extension bool
400
- file_matches_extension = file.endswith(self.extension)
403
+ file_matches_extension = file_name.endswith(self.extension)
401
404
 
402
405
  # checking if current file matches extension
403
406
  if not file_matches_extension:
@@ -415,7 +418,7 @@ class PyTree:
415
418
  if self.keyword is not None:
416
419
 
417
420
  # getting file matches keyword bool
418
- file_matches_keyword = (self.keyword in file)
421
+ file_matches_keyword = (self.keyword in file_name)
419
422
 
420
423
  # checking if current file matches keyword
421
424
  if not file_matches_keyword:
@@ -431,10 +434,10 @@ class PyTree:
431
434
 
432
435
  # getting current file path
433
436
  file_path = join(folder_path,
434
- file)
437
+ file_name)
435
438
 
436
439
  # getting current file dict
437
- file_dict = self.get_file_dict(file_name=file,
440
+ file_dict = self.get_file_dict(file_name=file_name,
438
441
  file_path=file_path)
439
442
 
440
443
  # assembling path dict
@@ -450,7 +453,7 @@ class PyTree:
450
453
  file_size = file_dict['size']
451
454
 
452
455
  # updating folder size
453
- folder_size += file_size
456
+ self.current_folder_size += file_size
454
457
 
455
458
  # updating total size
456
459
  self.total_size += file_size
@@ -459,38 +462,31 @@ class PyTree:
459
462
  if self.include_counts:
460
463
 
461
464
  # updating items count
462
- items_count += 1
465
+ self.current_items_count += 1
463
466
 
464
467
  # iterating over current subfolders
465
- for subfolder in subfolders:
468
+ for subfolder_name in subfolders:
466
469
 
467
470
  # getting current subfolder path
468
471
  subfolder_path = join(folder_path,
469
- subfolder)
470
-
471
- # getting subfolder is symlink bool
472
- subfolder_is_symlink = islink(path=subfolder_path)
473
-
474
- # checking if current subfolder is symlink
475
- if subfolder_is_symlink:
476
-
477
- # skipping symlink subfolder
478
- continue
472
+ subfolder_name)
479
473
 
480
- # getting subfolder is cache bool
481
- subfolder_is_cache = is_cache(path=subfolder_path,
482
- 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)
483
479
 
484
- # checking if current subfolder is cache
485
- if subfolder_is_cache:
480
+ # checking whether to skip current folder
481
+ if skip_folder:
486
482
 
487
- # skipping cache subfolder
483
+ # skipping current folder
488
484
  continue
489
485
 
490
486
  # getting current subfolder dict
491
487
  subfolder_dict = self.tree_dict.get(subfolder_path) # this will never be None due to topdown=False!
492
488
  # The subfolder will always have already been a
493
- # folder in previous iteration!
489
+ # folder in a previous iteration!
494
490
 
495
491
  # checking include sizes toggle
496
492
  if self.include_sizes:
@@ -499,19 +495,17 @@ class PyTree:
499
495
  subfolder_size = subfolder_dict['size']
500
496
 
501
497
  # updating folder size
502
- folder_size += subfolder_size
498
+ self.current_folder_size += subfolder_size
503
499
 
504
500
  # checking include counts toggle
505
501
  if self.include_counts:
506
502
 
507
503
  # updating items count
508
- items_count += 1
504
+ self.current_items_count += 1
509
505
 
510
506
  # getting current folder dict
511
507
  folder_dict = self.get_folder_dict(folder_name=folder_name,
512
- folder_path=folder_path,
513
- folder_size=folder_size,
514
- items_count=items_count)
508
+ folder_path=folder_path)
515
509
 
516
510
  # assembling path dict
517
511
  path_dict = {folder_path: folder_dict}
@@ -520,7 +514,7 @@ class PyTree:
520
514
  self.tree_dict.update(path_dict)
521
515
 
522
516
  # reversing dict (required since topdown was set to False in os.walk to enable size obtaining optimization)
523
- tree_dict = dict(reversed(self.tree_dict.items()))
517
+ tree_dict = reverse_dict(a_dict=self.tree_dict)
524
518
 
525
519
  # returning tree dict
526
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
@@ -16,6 +16,7 @@ ONE_TB = ONE_GB * MULTIPLIER
16
16
  CACHE_FOLDERS = ['__pycache__',
17
17
  '.git',
18
18
  '.idea',
19
+ '.cache',
19
20
  'egg-info']
20
21
 
21
22
  ######################################################################
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytree2
3
- Version: 0.2.0
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