pytree2 0.2.2__tar.gz → 0.2.3__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.
- {pytree2-0.2.2 → pytree2-0.2.3}/PKG-INFO +1 -1
- {pytree2-0.2.2 → pytree2-0.2.3}/pyproject.toml +2 -2
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree/classes/PyTree.py +232 -136
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree/main.py +6 -0
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree/main_loc.py +8 -10
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree/utils/aux_funcs.py +138 -6
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree2.egg-info/PKG-INFO +1 -1
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree2.egg-info/entry_points.txt +1 -1
- {pytree2-0.2.2 → pytree2-0.2.3}/LICENSE.md +0 -0
- {pytree2-0.2.2 → pytree2-0.2.3}/README.md +0 -0
- {pytree2-0.2.2 → pytree2-0.2.3}/setup.cfg +0 -0
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree/__init__.py +0 -0
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree/classes/ProgressTracker.py +0 -0
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree/classes/__init__.py +0 -0
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree/utils/__init__.py +0 -0
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree/utils/global_vars.py +0 -0
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree2.egg-info/SOURCES.txt +0 -0
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree2.egg-info/dependency_links.txt +0 -0
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree2.egg-info/requires.txt +0 -0
- {pytree2-0.2.2 → pytree2-0.2.3}/src/pytree2.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pytree2"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.3"
|
|
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,7 +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
|
|
23
|
+
pytree-loc = "pytree.main_loc:main"
|
|
24
24
|
|
|
25
25
|
[tool.setuptools]
|
|
26
26
|
package-dir = {"" = "src"}
|
|
@@ -9,19 +9,23 @@
|
|
|
9
9
|
|
|
10
10
|
# importing required libraries
|
|
11
11
|
from os import walk
|
|
12
|
+
from sys import platform
|
|
12
13
|
from treelib import Tree
|
|
13
14
|
from os.path import join
|
|
14
15
|
from os.path import abspath
|
|
15
16
|
from os.path import dirname
|
|
16
17
|
from os.path import getsize
|
|
17
18
|
from os import _exit # noqa
|
|
19
|
+
from pytree.utils.aux_funcs import get_loc
|
|
18
20
|
from pytree.utils.aux_funcs import is_cache
|
|
21
|
+
from pytree.utils.aux_funcs import get_loc_str
|
|
19
22
|
from pytree.utils.aux_funcs import reverse_dict
|
|
20
23
|
from pytree.utils.aux_funcs import get_size_str
|
|
21
|
-
from pytree.utils.aux_funcs import
|
|
24
|
+
from pytree.utils.aux_funcs import get_skip_file
|
|
22
25
|
from pytree.utils.aux_funcs import get_path_name
|
|
23
26
|
from pytree.utils.aux_funcs import get_path_depth
|
|
24
27
|
from pytree.utils.aux_funcs import get_start_path
|
|
28
|
+
from pytree.utils.aux_funcs import get_skip_folder
|
|
25
29
|
from pytree.utils.global_vars import CACHE_FOLDERS
|
|
26
30
|
from pytree.classes.ProgressTracker import ProgressTracker
|
|
27
31
|
|
|
@@ -57,6 +61,7 @@ class ModuleProgressTracker(ProgressTracker):
|
|
|
57
61
|
|
|
58
62
|
# end string
|
|
59
63
|
self.end_string = ''
|
|
64
|
+
self.print_end_string = ''
|
|
60
65
|
|
|
61
66
|
# overwriting class methods (using current module specific attributes)
|
|
62
67
|
|
|
@@ -123,10 +128,10 @@ class ModuleProgressTracker(ProgressTracker):
|
|
|
123
128
|
folder_path, _, files = item
|
|
124
129
|
|
|
125
130
|
# getting skip folder bool
|
|
126
|
-
skip_folder =
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
131
|
+
skip_folder = get_skip_folder(folder_path=folder_path,
|
|
132
|
+
start_path=start_path,
|
|
133
|
+
start_is_cache=start_is_cache,
|
|
134
|
+
cache_folders=CACHE_FOLDERS)
|
|
130
135
|
|
|
131
136
|
# checking whether to skip current folder
|
|
132
137
|
if skip_folder:
|
|
@@ -168,7 +173,7 @@ class ModuleProgressTracker(ProgressTracker):
|
|
|
168
173
|
|
|
169
174
|
# printing end string
|
|
170
175
|
print(self.end_string,
|
|
171
|
-
end=
|
|
176
|
+
end=self.print_end_string)
|
|
172
177
|
|
|
173
178
|
#####################################################################
|
|
174
179
|
# PyTree definition
|
|
@@ -186,6 +191,7 @@ class PyTree:
|
|
|
186
191
|
extension: str or None,
|
|
187
192
|
keyword: str or None,
|
|
188
193
|
level: int,
|
|
194
|
+
mode: str,
|
|
189
195
|
cache_folders: list = CACHE_FOLDERS,
|
|
190
196
|
progress_tracker: ModuleProgressTracker = ModuleProgressTracker
|
|
191
197
|
) -> None:
|
|
@@ -201,9 +207,13 @@ class PyTree:
|
|
|
201
207
|
self.extension = extension
|
|
202
208
|
self.keyword = keyword
|
|
203
209
|
self.level = level
|
|
210
|
+
self.mode = mode
|
|
204
211
|
self.cache_folders = cache_folders
|
|
205
212
|
self.progress_tracker = progress_tracker
|
|
206
213
|
|
|
214
|
+
# getting mode is loc bool
|
|
215
|
+
self.mode_is_loc = (self.mode == 'loc')
|
|
216
|
+
|
|
207
217
|
# getting start is cache bool
|
|
208
218
|
self.start_is_cache = is_cache(path=self.start_path,
|
|
209
219
|
cache_folders=self.cache_folders)
|
|
@@ -221,10 +231,12 @@ class PyTree:
|
|
|
221
231
|
self.total_folders = 0
|
|
222
232
|
self.total_files = 0
|
|
223
233
|
self.total_size = 0
|
|
234
|
+
self.total_loc = 0
|
|
224
235
|
|
|
225
236
|
# defining placeholder values for current folder size/count
|
|
226
237
|
self.current_folder_size = 0
|
|
227
238
|
self.current_items_count = 0
|
|
239
|
+
self.current_folder_loc = 0
|
|
228
240
|
|
|
229
241
|
# valid files
|
|
230
242
|
self.valid_files = 0
|
|
@@ -293,6 +305,15 @@ class PyTree:
|
|
|
293
305
|
# updating base dict
|
|
294
306
|
base_dict['size'] = file_size
|
|
295
307
|
|
|
308
|
+
# checking mode
|
|
309
|
+
if self.mode_is_loc:
|
|
310
|
+
|
|
311
|
+
# getting lines of code
|
|
312
|
+
lines_of_code = get_loc(file_path=file_path)
|
|
313
|
+
|
|
314
|
+
# updating base dict
|
|
315
|
+
base_dict['loc'] = lines_of_code
|
|
316
|
+
|
|
296
317
|
# returning base dict
|
|
297
318
|
return base_dict
|
|
298
319
|
|
|
@@ -323,195 +344,229 @@ class PyTree:
|
|
|
323
344
|
# updating base dict
|
|
324
345
|
base_dict['count'] = self.current_items_count
|
|
325
346
|
|
|
347
|
+
# checking mode
|
|
348
|
+
if self.mode_is_loc:
|
|
349
|
+
|
|
350
|
+
# updating base dict
|
|
351
|
+
base_dict['loc'] = self.current_folder_loc
|
|
352
|
+
|
|
326
353
|
# returning base dict
|
|
327
354
|
return base_dict
|
|
328
355
|
|
|
329
356
|
def scan_file(self,
|
|
357
|
+
file_name: str,
|
|
330
358
|
file_path: str
|
|
331
359
|
) -> None:
|
|
332
|
-
pass
|
|
333
|
-
|
|
334
|
-
def scan_folder(self,
|
|
335
|
-
folder_path: str
|
|
336
|
-
) -> None:
|
|
337
|
-
pass
|
|
338
|
-
|
|
339
|
-
def get_tree_dict(self) -> dict:
|
|
340
360
|
"""
|
|
341
|
-
|
|
361
|
+
Given a file name/path updates tree
|
|
362
|
+
dict accordingly.
|
|
342
363
|
"""
|
|
343
|
-
# getting
|
|
344
|
-
|
|
345
|
-
|
|
364
|
+
# getting current file dict
|
|
365
|
+
file_dict = self.get_file_dict(file_name=file_name,
|
|
366
|
+
file_path=file_path)
|
|
346
367
|
|
|
347
|
-
#
|
|
348
|
-
|
|
368
|
+
# assembling path dict
|
|
369
|
+
path_dict = {file_path: file_dict}
|
|
349
370
|
|
|
350
|
-
|
|
351
|
-
|
|
371
|
+
# updating tree dict
|
|
372
|
+
self.tree_dict.update(path_dict)
|
|
352
373
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
start_path=self.start_path,
|
|
356
|
-
start_is_cache=self.start_is_cache,
|
|
357
|
-
cache_folders=self.cache_folders)
|
|
374
|
+
# checking include sizes toggle
|
|
375
|
+
if self.include_sizes:
|
|
358
376
|
|
|
359
|
-
#
|
|
360
|
-
|
|
377
|
+
# getting file size
|
|
378
|
+
file_size = file_dict['size']
|
|
361
379
|
|
|
362
|
-
|
|
363
|
-
|
|
380
|
+
# updating folder size
|
|
381
|
+
self.current_folder_size += file_size
|
|
364
382
|
|
|
365
|
-
# updating
|
|
366
|
-
self.
|
|
383
|
+
# updating total size
|
|
384
|
+
self.total_size += file_size
|
|
367
385
|
|
|
368
|
-
|
|
369
|
-
|
|
386
|
+
# checking include counts toggle
|
|
387
|
+
if self.include_counts:
|
|
370
388
|
|
|
371
|
-
#
|
|
372
|
-
|
|
373
|
-
|
|
389
|
+
# updating items count
|
|
390
|
+
self.current_items_count += 1
|
|
391
|
+
self.valid_files += 1
|
|
374
392
|
|
|
375
|
-
|
|
376
|
-
|
|
393
|
+
# checking mode
|
|
394
|
+
if self.mode_is_loc:
|
|
377
395
|
|
|
378
|
-
# getting
|
|
379
|
-
|
|
396
|
+
# getting file loc
|
|
397
|
+
file_loc = file_dict['loc']
|
|
380
398
|
|
|
381
|
-
# updating
|
|
382
|
-
self.
|
|
399
|
+
# updating folder loc
|
|
400
|
+
self.current_folder_loc += file_loc
|
|
383
401
|
|
|
384
|
-
#
|
|
385
|
-
self.
|
|
386
|
-
self.current_folder_size = 0
|
|
387
|
-
self.current_items_count = 0
|
|
402
|
+
# updating total loc
|
|
403
|
+
self.total_loc += file_loc
|
|
388
404
|
|
|
389
|
-
|
|
390
|
-
|
|
405
|
+
def scan_subfolder(self,
|
|
406
|
+
subfolder_path: str
|
|
407
|
+
) -> None:
|
|
408
|
+
"""
|
|
409
|
+
Given a folder path and respective
|
|
410
|
+
subfolder/files lists, updates tree
|
|
411
|
+
dict accordingly.
|
|
412
|
+
"""
|
|
413
|
+
# getting current subfolder dict
|
|
414
|
+
subfolder_dict = self.tree_dict.get(subfolder_path) # this will never be None due to topdown=False!
|
|
415
|
+
# The subfolder will always have already been a
|
|
416
|
+
# folder in a previous iteration!
|
|
391
417
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
self.progress_tracker.current_file += 1
|
|
418
|
+
# checking include sizes toggle
|
|
419
|
+
if self.include_sizes:
|
|
395
420
|
|
|
396
|
-
|
|
397
|
-
|
|
421
|
+
# getting file size
|
|
422
|
+
subfolder_size = subfolder_dict['size']
|
|
398
423
|
|
|
399
|
-
|
|
400
|
-
|
|
424
|
+
# updating folder size
|
|
425
|
+
self.current_folder_size += subfolder_size
|
|
401
426
|
|
|
402
|
-
|
|
403
|
-
|
|
427
|
+
# checking include counts toggle
|
|
428
|
+
if self.include_counts:
|
|
404
429
|
|
|
405
|
-
|
|
406
|
-
|
|
430
|
+
# updating items count
|
|
431
|
+
self.current_items_count += 1
|
|
407
432
|
|
|
408
|
-
|
|
409
|
-
|
|
433
|
+
# checking mode
|
|
434
|
+
if self.mode_is_loc:
|
|
410
435
|
|
|
411
|
-
|
|
412
|
-
|
|
436
|
+
# getting file loc
|
|
437
|
+
subfolder_loc = subfolder_dict['loc']
|
|
413
438
|
|
|
414
|
-
|
|
415
|
-
|
|
439
|
+
# updating folder loc
|
|
440
|
+
self.current_folder_loc += subfolder_loc
|
|
416
441
|
|
|
417
|
-
|
|
418
|
-
|
|
442
|
+
def scan_folder(self,
|
|
443
|
+
folder_path: str,
|
|
444
|
+
subfolders: list,
|
|
445
|
+
files: list
|
|
446
|
+
) -> None:
|
|
447
|
+
"""
|
|
448
|
+
Given a folder path and respective
|
|
449
|
+
subfolder/files lists, updates tree
|
|
450
|
+
dict accordingly.
|
|
451
|
+
"""
|
|
452
|
+
# sorting subfolders/files alphabetically
|
|
453
|
+
subfolders = sorted(subfolders)
|
|
454
|
+
files = sorted(files)
|
|
419
455
|
|
|
420
|
-
|
|
421
|
-
|
|
456
|
+
# getting current folder name
|
|
457
|
+
folder_name = get_path_name(path=folder_path)
|
|
422
458
|
|
|
423
|
-
|
|
424
|
-
|
|
459
|
+
# getting current files num
|
|
460
|
+
files_num = len(files)
|
|
425
461
|
|
|
426
|
-
|
|
427
|
-
|
|
462
|
+
# updating progress tracker attributes
|
|
463
|
+
self.progress_tracker.files_num = files_num
|
|
428
464
|
|
|
429
|
-
|
|
430
|
-
|
|
465
|
+
# resetting progress tracker attributes
|
|
466
|
+
self.progress_tracker.current_file = 0
|
|
467
|
+
self.current_folder_size = 0
|
|
468
|
+
self.current_items_count = 0
|
|
431
469
|
|
|
432
|
-
|
|
433
|
-
|
|
470
|
+
# iterating over current files
|
|
471
|
+
for file_name in files:
|
|
434
472
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
473
|
+
# updating progress tracker attributes
|
|
474
|
+
self.progress_tracker.current_iteration += 1
|
|
475
|
+
self.progress_tracker.current_file += 1
|
|
438
476
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
file_path=file_path)
|
|
477
|
+
# updating totals
|
|
478
|
+
self.total_files += 1
|
|
442
479
|
|
|
443
|
-
|
|
444
|
-
|
|
480
|
+
# getting skip file bool
|
|
481
|
+
skip_file = get_skip_file(file_name=file_name,
|
|
482
|
+
extension=self.extension,
|
|
483
|
+
keyword=self.keyword)
|
|
445
484
|
|
|
446
|
-
|
|
447
|
-
|
|
485
|
+
# checking whether to skip current file
|
|
486
|
+
if skip_file:
|
|
448
487
|
|
|
449
|
-
#
|
|
450
|
-
|
|
488
|
+
# skipping current file
|
|
489
|
+
continue
|
|
451
490
|
|
|
452
|
-
|
|
453
|
-
|
|
491
|
+
# getting current file path
|
|
492
|
+
file_path = join(folder_path,
|
|
493
|
+
file_name)
|
|
454
494
|
|
|
455
|
-
|
|
456
|
-
|
|
495
|
+
# scanning current file
|
|
496
|
+
self.scan_file(file_name=file_name,
|
|
497
|
+
file_path=file_path)
|
|
457
498
|
|
|
458
|
-
|
|
459
|
-
|
|
499
|
+
# iterating over current subfolders
|
|
500
|
+
for subfolder_name in subfolders:
|
|
460
501
|
|
|
461
|
-
|
|
462
|
-
|
|
502
|
+
# getting current subfolder path
|
|
503
|
+
subfolder_path = join(folder_path,
|
|
504
|
+
subfolder_name)
|
|
463
505
|
|
|
464
|
-
|
|
465
|
-
|
|
506
|
+
# getting skip folder bool
|
|
507
|
+
skip_folder = get_skip_folder(folder_path=subfolder_path,
|
|
508
|
+
start_path=self.start_path,
|
|
509
|
+
start_is_cache=self.start_is_cache,
|
|
510
|
+
cache_folders=self.cache_folders)
|
|
466
511
|
|
|
467
|
-
#
|
|
468
|
-
|
|
512
|
+
# checking whether to skip current folder
|
|
513
|
+
if skip_folder:
|
|
469
514
|
|
|
470
|
-
#
|
|
471
|
-
|
|
472
|
-
subfolder_name)
|
|
515
|
+
# skipping current folder
|
|
516
|
+
continue
|
|
473
517
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
start_path=self.start_path,
|
|
477
|
-
start_is_cache=self.start_is_cache,
|
|
478
|
-
cache_folders=self.cache_folders)
|
|
518
|
+
# scanning current subfolder
|
|
519
|
+
self.scan_subfolder(subfolder_path=subfolder_path)
|
|
479
520
|
|
|
480
|
-
|
|
481
|
-
|
|
521
|
+
# getting current folder dict
|
|
522
|
+
folder_dict = self.get_folder_dict(folder_name=folder_name,
|
|
523
|
+
folder_path=folder_path)
|
|
482
524
|
|
|
483
|
-
|
|
484
|
-
|
|
525
|
+
# assembling path dict
|
|
526
|
+
path_dict = {folder_path: folder_dict}
|
|
485
527
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
# The subfolder will always have already been a
|
|
489
|
-
# folder in a previous iteration!
|
|
528
|
+
# updating tree dict
|
|
529
|
+
self.tree_dict.update(path_dict)
|
|
490
530
|
|
|
491
|
-
|
|
492
|
-
|
|
531
|
+
def get_tree_dict(self) -> dict:
|
|
532
|
+
"""
|
|
533
|
+
Scans start path for subfolders/files
|
|
534
|
+
and returns dictionary of tree structure,
|
|
535
|
+
containing sizes/counts/loc info, according
|
|
536
|
+
to specified parameters.
|
|
537
|
+
"""
|
|
538
|
+
# getting folders/subfolders/files in start path
|
|
539
|
+
folders_subfolders_files = walk(self.start_path,
|
|
540
|
+
topdown=False)
|
|
541
|
+
|
|
542
|
+
# iterating over folders/subfolders/files
|
|
543
|
+
for item in folders_subfolders_files:
|
|
493
544
|
|
|
494
|
-
|
|
495
|
-
|
|
545
|
+
# getting current folder path/subfolders/files
|
|
546
|
+
folder_path, subfolders, files = item
|
|
496
547
|
|
|
497
|
-
|
|
498
|
-
|
|
548
|
+
# getting skip folder bool
|
|
549
|
+
skip_folder = get_skip_folder(folder_path=folder_path,
|
|
550
|
+
start_path=self.start_path,
|
|
551
|
+
start_is_cache=self.start_is_cache,
|
|
552
|
+
cache_folders=self.cache_folders)
|
|
499
553
|
|
|
500
|
-
|
|
501
|
-
|
|
554
|
+
# checking whether to skip current folder
|
|
555
|
+
if skip_folder:
|
|
502
556
|
|
|
503
|
-
|
|
504
|
-
|
|
557
|
+
# skipping current folder
|
|
558
|
+
continue
|
|
505
559
|
|
|
506
|
-
#
|
|
507
|
-
|
|
508
|
-
folder_path=folder_path)
|
|
560
|
+
# updating progress tracker attributes
|
|
561
|
+
self.progress_tracker.current_folder += 1
|
|
509
562
|
|
|
510
|
-
#
|
|
511
|
-
|
|
563
|
+
# updating totals
|
|
564
|
+
self.total_folders += 1
|
|
512
565
|
|
|
513
|
-
#
|
|
514
|
-
self.
|
|
566
|
+
# scanning current folder
|
|
567
|
+
self.scan_folder(folder_path=folder_path,
|
|
568
|
+
subfolders=subfolders,
|
|
569
|
+
files=files)
|
|
515
570
|
|
|
516
571
|
# reversing dict (required since topdown was set to False in os.walk to enable size obtaining optimization)
|
|
517
572
|
tree_dict = reverse_dict(a_dict=self.tree_dict)
|
|
@@ -545,6 +600,18 @@ class PyTree:
|
|
|
545
600
|
# updating file tag
|
|
546
601
|
file_tag += f' ({size_str})'
|
|
547
602
|
|
|
603
|
+
# checking mode
|
|
604
|
+
if self.mode_is_loc:
|
|
605
|
+
|
|
606
|
+
# getting additional path dict info
|
|
607
|
+
file_loc = path_dict['loc']
|
|
608
|
+
|
|
609
|
+
# getting loc string
|
|
610
|
+
loc_str = get_loc_str(loc=file_loc)
|
|
611
|
+
|
|
612
|
+
# updating file tag
|
|
613
|
+
file_tag += f' {{{loc_str}}}'
|
|
614
|
+
|
|
548
615
|
# returning file tag
|
|
549
616
|
return file_tag
|
|
550
617
|
|
|
@@ -740,9 +807,38 @@ class PyTree:
|
|
|
740
807
|
# updating end string
|
|
741
808
|
end_string += f', {total_size_str}'
|
|
742
809
|
|
|
810
|
+
# checking mode
|
|
811
|
+
if self.mode_is_loc:
|
|
812
|
+
|
|
813
|
+
# getting total loc string
|
|
814
|
+
total_loc_str = get_loc_str(loc=self.total_loc)
|
|
815
|
+
|
|
816
|
+
# updating end string
|
|
817
|
+
end_string += f', {total_loc_str}'
|
|
818
|
+
|
|
743
819
|
# updating progress tracker attributes
|
|
744
820
|
self.progress_tracker.end_string = end_string
|
|
745
821
|
|
|
822
|
+
def update_print_end_string(self) -> None:
|
|
823
|
+
"""
|
|
824
|
+
Updates end string with folder/files
|
|
825
|
+
description summary (counts/sizes).
|
|
826
|
+
"""
|
|
827
|
+
# defining placeholder value for new print end string
|
|
828
|
+
print_end_string = ''
|
|
829
|
+
|
|
830
|
+
# getting os is linux bool
|
|
831
|
+
os_is_linux = (platform == 'linux')
|
|
832
|
+
|
|
833
|
+
# checking if os is linux
|
|
834
|
+
if os_is_linux:
|
|
835
|
+
|
|
836
|
+
# updating print end string
|
|
837
|
+
print_end_string = '\n'
|
|
838
|
+
|
|
839
|
+
# updating progress tracker attributes
|
|
840
|
+
self.progress_tracker.print_end_string = print_end_string
|
|
841
|
+
|
|
746
842
|
def run(self):
|
|
747
843
|
"""
|
|
748
844
|
Runs main PyTree methods to
|
|
@@ -103,6 +103,7 @@ def pytree(start_path: str,
|
|
|
103
103
|
extension: str,
|
|
104
104
|
keyword: str,
|
|
105
105
|
level: int,
|
|
106
|
+
mode: str,
|
|
106
107
|
progress_tracker: ModuleProgressTracker
|
|
107
108
|
) -> None:
|
|
108
109
|
"""
|
|
@@ -117,6 +118,7 @@ def pytree(start_path: str,
|
|
|
117
118
|
extension=extension,
|
|
118
119
|
keyword=keyword,
|
|
119
120
|
level=level,
|
|
121
|
+
mode=mode,
|
|
120
122
|
progress_tracker=progress_tracker)
|
|
121
123
|
|
|
122
124
|
# running pytree main
|
|
@@ -152,6 +154,9 @@ def parse_and_run(args_dict: dict,
|
|
|
152
154
|
# getting level
|
|
153
155
|
level = args_dict['level']
|
|
154
156
|
|
|
157
|
+
# getting mode
|
|
158
|
+
mode = 'tree'
|
|
159
|
+
|
|
155
160
|
# running pytree function
|
|
156
161
|
pytree(start_path=start_path,
|
|
157
162
|
dirs_only=dirs_only,
|
|
@@ -160,6 +165,7 @@ def parse_and_run(args_dict: dict,
|
|
|
160
165
|
extension=extension,
|
|
161
166
|
keyword=keyword,
|
|
162
167
|
level=level,
|
|
168
|
+
mode=mode,
|
|
163
169
|
progress_tracker=progress_tracker)
|
|
164
170
|
|
|
165
171
|
######################################################################
|
|
@@ -27,7 +27,7 @@ def get_args_dict() -> dict:
|
|
|
27
27
|
:return: Dictionary. Represents the parsed arguments.
|
|
28
28
|
"""
|
|
29
29
|
# defining program description
|
|
30
|
-
description = "pytree - a python cli utility for
|
|
30
|
+
description = "pytree-loc - a python cli utility for counting lines of code in python projects"
|
|
31
31
|
|
|
32
32
|
# creating a parser instance
|
|
33
33
|
parser = ArgumentParser(description=description)
|
|
@@ -63,14 +63,6 @@ def get_args_dict() -> dict:
|
|
|
63
63
|
help='tree displays the number of files or folders inside each directory',
|
|
64
64
|
default=False)
|
|
65
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
66
|
# keyword param
|
|
75
67
|
parser.add_argument('-k', '--keyword',
|
|
76
68
|
dest='keyword',
|
|
@@ -104,6 +96,7 @@ def pytree(start_path: str,
|
|
|
104
96
|
extension: str,
|
|
105
97
|
keyword: str,
|
|
106
98
|
level: int,
|
|
99
|
+
mode: str,
|
|
107
100
|
progress_tracker: ModuleProgressTracker
|
|
108
101
|
) -> None:
|
|
109
102
|
"""
|
|
@@ -118,6 +111,7 @@ def pytree(start_path: str,
|
|
|
118
111
|
extension=extension,
|
|
119
112
|
keyword=keyword,
|
|
120
113
|
level=level,
|
|
114
|
+
mode=mode,
|
|
121
115
|
progress_tracker=progress_tracker)
|
|
122
116
|
|
|
123
117
|
# running pytree main
|
|
@@ -145,7 +139,7 @@ def parse_and_run(args_dict: dict,
|
|
|
145
139
|
include_sizes = args_dict['show_sizes']
|
|
146
140
|
|
|
147
141
|
# getting extension
|
|
148
|
-
extension =
|
|
142
|
+
extension = '.py'
|
|
149
143
|
|
|
150
144
|
# getting keyword
|
|
151
145
|
keyword = args_dict['keyword']
|
|
@@ -153,6 +147,9 @@ def parse_and_run(args_dict: dict,
|
|
|
153
147
|
# getting level
|
|
154
148
|
level = args_dict['level']
|
|
155
149
|
|
|
150
|
+
# getting mode
|
|
151
|
+
mode = 'loc'
|
|
152
|
+
|
|
156
153
|
# running pytree function
|
|
157
154
|
pytree(start_path=start_path,
|
|
158
155
|
dirs_only=dirs_only,
|
|
@@ -161,6 +158,7 @@ def parse_and_run(args_dict: dict,
|
|
|
161
158
|
extension=extension,
|
|
162
159
|
keyword=keyword,
|
|
163
160
|
level=level,
|
|
161
|
+
mode=mode,
|
|
164
162
|
progress_tracker=progress_tracker)
|
|
165
163
|
|
|
166
164
|
######################################################################
|
|
@@ -189,11 +189,11 @@ def get_start_path(start_path: str or list) -> str:
|
|
|
189
189
|
return start_path
|
|
190
190
|
|
|
191
191
|
|
|
192
|
-
def
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
192
|
+
def get_skip_folder(folder_path: str,
|
|
193
|
+
start_path: str,
|
|
194
|
+
start_is_cache: bool,
|
|
195
|
+
cache_folders: list
|
|
196
|
+
) -> bool:
|
|
197
197
|
"""
|
|
198
198
|
Given a path to a folder, returns
|
|
199
199
|
True if folder should be skipped,
|
|
@@ -224,12 +224,53 @@ def get_skip_bool(folder_path: str,
|
|
|
224
224
|
# appending current condition to skip conditions list
|
|
225
225
|
skip_conditions.append(folder_is_cache)
|
|
226
226
|
|
|
227
|
-
#
|
|
227
|
+
# getting skip bool
|
|
228
228
|
skip_bool = any(skip_conditions)
|
|
229
229
|
|
|
230
230
|
# returning skip bool
|
|
231
231
|
return skip_bool
|
|
232
232
|
|
|
233
|
+
|
|
234
|
+
def get_skip_file(file_name: str,
|
|
235
|
+
extension: str or None,
|
|
236
|
+
keyword: str or None
|
|
237
|
+
) -> bool:
|
|
238
|
+
"""
|
|
239
|
+
Given a file name, returns True
|
|
240
|
+
if file should be skipped, and
|
|
241
|
+
False otherwise.
|
|
242
|
+
"""
|
|
243
|
+
# defining placeholder value for skip conditions list
|
|
244
|
+
skip_conditions = []
|
|
245
|
+
|
|
246
|
+
# checking extension toggle
|
|
247
|
+
if extension is not None:
|
|
248
|
+
|
|
249
|
+
# getting file matches extension bool
|
|
250
|
+
file_matches_extension = file_name.endswith(extension)
|
|
251
|
+
|
|
252
|
+
# appending current condition to skip conditions list
|
|
253
|
+
skip_conditions.append(file_matches_extension)
|
|
254
|
+
|
|
255
|
+
# checking keyword toggle
|
|
256
|
+
if keyword is not None:
|
|
257
|
+
|
|
258
|
+
# getting file matches keyword bool
|
|
259
|
+
file_matches_keyword = (keyword in file_name)
|
|
260
|
+
|
|
261
|
+
# appending current condition to skip conditions list
|
|
262
|
+
skip_conditions.append(file_matches_keyword)
|
|
263
|
+
|
|
264
|
+
# reversing condition bools (skip should happen if they DON'T match)
|
|
265
|
+
skip_conditions = [(not condition) for condition in skip_conditions]
|
|
266
|
+
|
|
267
|
+
# getting skip bool
|
|
268
|
+
skip_bool = any(skip_conditions)
|
|
269
|
+
|
|
270
|
+
# returning skip bool
|
|
271
|
+
return skip_bool
|
|
272
|
+
|
|
273
|
+
|
|
233
274
|
def get_path_split(path: str) -> list:
|
|
234
275
|
"""
|
|
235
276
|
Given a path, returns its split
|
|
@@ -307,6 +348,97 @@ def get_size_str(size_in_bytes: int) -> str:
|
|
|
307
348
|
return size_str
|
|
308
349
|
|
|
309
350
|
|
|
351
|
+
def get_loc(file_path: str) -> int:
|
|
352
|
+
"""
|
|
353
|
+
Given a path to a python file,
|
|
354
|
+
returns number of lines of code
|
|
355
|
+
(disconsidering comments and enters)
|
|
356
|
+
"""
|
|
357
|
+
# defining placeholder value for lines of code (loc)
|
|
358
|
+
loc = 0
|
|
359
|
+
|
|
360
|
+
# defining bracket likes start/end
|
|
361
|
+
bracketlikes_start = ['"""', '(', '[', '{']
|
|
362
|
+
bracketlikes_end = ['"""', '(', '[', '{']
|
|
363
|
+
|
|
364
|
+
# defining read mode
|
|
365
|
+
read_mode = 'r'
|
|
366
|
+
|
|
367
|
+
# defining placeholder for skip next line bool
|
|
368
|
+
skip_next = False
|
|
369
|
+
|
|
370
|
+
# reading file
|
|
371
|
+
with open(file_path, read_mode) as open_file:
|
|
372
|
+
|
|
373
|
+
# getting file lines
|
|
374
|
+
lines = open_file.readlines()
|
|
375
|
+
|
|
376
|
+
# iterating over lines
|
|
377
|
+
for line in lines:
|
|
378
|
+
|
|
379
|
+
# checking skip next bool
|
|
380
|
+
if skip_next:
|
|
381
|
+
|
|
382
|
+
# skipping line
|
|
383
|
+
continue
|
|
384
|
+
|
|
385
|
+
# cleaning line
|
|
386
|
+
line = line.replace(' ', '')
|
|
387
|
+
|
|
388
|
+
# getting line is comment bool
|
|
389
|
+
line_is_comment = line.startswith('#')
|
|
390
|
+
|
|
391
|
+
# getting line is emtpy bool
|
|
392
|
+
line_is_empty = line.startswith('\n')
|
|
393
|
+
|
|
394
|
+
# getting line starts with bracket-like bool
|
|
395
|
+
startswith_bracketlike = any([line.startswith(bracketlike) for bracketlike in bracketlikes_start])
|
|
396
|
+
endswith_bracketlike = any([line.endswith(bracketlike) for bracketlike in bracketlikes_end])
|
|
397
|
+
|
|
398
|
+
# checking whether line starts with bracket-like
|
|
399
|
+
if startswith_bracketlike:
|
|
400
|
+
|
|
401
|
+
# updating skip next bool
|
|
402
|
+
skip_next = True
|
|
403
|
+
|
|
404
|
+
# checking whether line ends with bracket-like
|
|
405
|
+
if endswith_bracketlike:
|
|
406
|
+
|
|
407
|
+
# updating skip next bool
|
|
408
|
+
skip_next = False
|
|
409
|
+
|
|
410
|
+
# assembling skip conditions list
|
|
411
|
+
skip_conditions = [line_is_comment,
|
|
412
|
+
line_is_empty]
|
|
413
|
+
|
|
414
|
+
# getting skip bool
|
|
415
|
+
skip_bool = any(skip_conditions)
|
|
416
|
+
|
|
417
|
+
# checking whether line should be skipped
|
|
418
|
+
if skip_bool:
|
|
419
|
+
|
|
420
|
+
# skipping current line
|
|
421
|
+
continue
|
|
422
|
+
|
|
423
|
+
# updating lines of code count
|
|
424
|
+
loc += 1
|
|
425
|
+
|
|
426
|
+
# returning lines of code count
|
|
427
|
+
return loc
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
def get_loc_str(loc: int) -> str:
|
|
431
|
+
"""
|
|
432
|
+
Given a file/folder lines of code
|
|
433
|
+
count, returns its formatted string.
|
|
434
|
+
"""
|
|
435
|
+
# assembling loc string
|
|
436
|
+
loc_str = f'{loc} lines'
|
|
437
|
+
|
|
438
|
+
# returning loc string
|
|
439
|
+
return loc_str
|
|
440
|
+
|
|
441
|
+
|
|
310
442
|
def reverse_dict(a_dict: dict) -> dict:
|
|
311
443
|
"""
|
|
312
444
|
Given a dictionary, returns
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|