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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytree2
3
- Version: 0.2.2
3
+ Version: 0.2.3
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.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:main_loc"
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 get_skip_bool
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 = get_skip_bool(folder_path=folder_path,
127
- start_path=start_path,
128
- start_is_cache=start_is_cache,
129
- cache_folders=CACHE_FOLDERS)
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
- Docstring.
361
+ Given a file name/path updates tree
362
+ dict accordingly.
342
363
  """
343
- # getting folders/subfolders/files in start path
344
- folders_subfolders_files = walk(self.start_path,
345
- topdown=False)
364
+ # getting current file dict
365
+ file_dict = self.get_file_dict(file_name=file_name,
366
+ file_path=file_path)
346
367
 
347
- # iterating over folders/subfolders/files
348
- for item in folders_subfolders_files:
368
+ # assembling path dict
369
+ path_dict = {file_path: file_dict}
349
370
 
350
- # getting current folder path/subfolders/files
351
- folder_path, subfolders, files = item
371
+ # updating tree dict
372
+ self.tree_dict.update(path_dict)
352
373
 
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)
374
+ # checking include sizes toggle
375
+ if self.include_sizes:
358
376
 
359
- # checking whether to skip current folder
360
- if skip_folder:
377
+ # getting file size
378
+ file_size = file_dict['size']
361
379
 
362
- # skipping current folder
363
- continue
380
+ # updating folder size
381
+ self.current_folder_size += file_size
364
382
 
365
- # updating progress tracker attributes
366
- self.progress_tracker.current_folder += 1
383
+ # updating total size
384
+ self.total_size += file_size
367
385
 
368
- # updating totals
369
- self.total_folders += 1
386
+ # checking include counts toggle
387
+ if self.include_counts:
370
388
 
371
- # sorting subfolders/files alphabetically
372
- subfolders = sorted(subfolders)
373
- files = sorted(files)
389
+ # updating items count
390
+ self.current_items_count += 1
391
+ self.valid_files += 1
374
392
 
375
- # getting current folder name
376
- folder_name = get_path_name(path=folder_path)
393
+ # checking mode
394
+ if self.mode_is_loc:
377
395
 
378
- # getting current files num
379
- files_num = len(files)
396
+ # getting file loc
397
+ file_loc = file_dict['loc']
380
398
 
381
- # updating progress tracker attributes
382
- self.progress_tracker.files_num = files_num
399
+ # updating folder loc
400
+ self.current_folder_loc += file_loc
383
401
 
384
- # resetting progress tracker attributes
385
- self.progress_tracker.current_file = 0
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
- # iterating over current files
390
- for file_name in files:
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
- # updating progress tracker attributes
393
- self.progress_tracker.current_iteration += 1
394
- self.progress_tracker.current_file += 1
418
+ # checking include sizes toggle
419
+ if self.include_sizes:
395
420
 
396
- # updating totals
397
- self.total_files += 1
421
+ # getting file size
422
+ subfolder_size = subfolder_dict['size']
398
423
 
399
- # checking extension toggle
400
- if self.extension is not None:
424
+ # updating folder size
425
+ self.current_folder_size += subfolder_size
401
426
 
402
- # getting file matches extension bool
403
- file_matches_extension = file_name.endswith(self.extension)
427
+ # checking include counts toggle
428
+ if self.include_counts:
404
429
 
405
- # checking if current file matches extension
406
- if not file_matches_extension:
430
+ # updating items count
431
+ self.current_items_count += 1
407
432
 
408
- # skipping file
409
- continue
433
+ # checking mode
434
+ if self.mode_is_loc:
410
435
 
411
- # checking include counts toggle
412
- if self.include_counts:
436
+ # getting file loc
437
+ subfolder_loc = subfolder_dict['loc']
413
438
 
414
- # updating valid files count
415
- self.valid_files += 1
439
+ # updating folder loc
440
+ self.current_folder_loc += subfolder_loc
416
441
 
417
- # checking keyword toggle
418
- if self.keyword is not None:
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
- # getting file matches keyword bool
421
- file_matches_keyword = (self.keyword in file_name)
456
+ # getting current folder name
457
+ folder_name = get_path_name(path=folder_path)
422
458
 
423
- # checking if current file matches keyword
424
- if not file_matches_keyword:
459
+ # getting current files num
460
+ files_num = len(files)
425
461
 
426
- # skipping file
427
- continue
462
+ # updating progress tracker attributes
463
+ self.progress_tracker.files_num = files_num
428
464
 
429
- # checking include counts toggle
430
- if self.include_counts:
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
- # updating valid files count
433
- self.valid_files += 1
470
+ # iterating over current files
471
+ for file_name in files:
434
472
 
435
- # getting current file path
436
- file_path = join(folder_path,
437
- file_name)
473
+ # updating progress tracker attributes
474
+ self.progress_tracker.current_iteration += 1
475
+ self.progress_tracker.current_file += 1
438
476
 
439
- # getting current file dict
440
- file_dict = self.get_file_dict(file_name=file_name,
441
- file_path=file_path)
477
+ # updating totals
478
+ self.total_files += 1
442
479
 
443
- # assembling path dict
444
- path_dict = {file_path: file_dict}
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
- # updating tree dict
447
- self.tree_dict.update(path_dict)
485
+ # checking whether to skip current file
486
+ if skip_file:
448
487
 
449
- # checking include sizes toggle
450
- if self.include_sizes:
488
+ # skipping current file
489
+ continue
451
490
 
452
- # getting file size
453
- file_size = file_dict['size']
491
+ # getting current file path
492
+ file_path = join(folder_path,
493
+ file_name)
454
494
 
455
- # updating folder size
456
- self.current_folder_size += file_size
495
+ # scanning current file
496
+ self.scan_file(file_name=file_name,
497
+ file_path=file_path)
457
498
 
458
- # updating total size
459
- self.total_size += file_size
499
+ # iterating over current subfolders
500
+ for subfolder_name in subfolders:
460
501
 
461
- # checking include counts toggle
462
- if self.include_counts:
502
+ # getting current subfolder path
503
+ subfolder_path = join(folder_path,
504
+ subfolder_name)
463
505
 
464
- # updating items count
465
- self.current_items_count += 1
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
- # iterating over current subfolders
468
- for subfolder_name in subfolders:
512
+ # checking whether to skip current folder
513
+ if skip_folder:
469
514
 
470
- # getting current subfolder path
471
- subfolder_path = join(folder_path,
472
- subfolder_name)
515
+ # skipping current folder
516
+ continue
473
517
 
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)
518
+ # scanning current subfolder
519
+ self.scan_subfolder(subfolder_path=subfolder_path)
479
520
 
480
- # checking whether to skip current folder
481
- if skip_folder:
521
+ # getting current folder dict
522
+ folder_dict = self.get_folder_dict(folder_name=folder_name,
523
+ folder_path=folder_path)
482
524
 
483
- # skipping current folder
484
- continue
525
+ # assembling path dict
526
+ path_dict = {folder_path: folder_dict}
485
527
 
486
- # getting current subfolder dict
487
- subfolder_dict = self.tree_dict.get(subfolder_path) # this will never be None due to topdown=False!
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
- # checking include sizes toggle
492
- if self.include_sizes:
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
- # getting file size
495
- subfolder_size = subfolder_dict['size']
545
+ # getting current folder path/subfolders/files
546
+ folder_path, subfolders, files = item
496
547
 
497
- # updating folder size
498
- self.current_folder_size += subfolder_size
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
- # checking include counts toggle
501
- if self.include_counts:
554
+ # checking whether to skip current folder
555
+ if skip_folder:
502
556
 
503
- # updating items count
504
- self.current_items_count += 1
557
+ # skipping current folder
558
+ continue
505
559
 
506
- # getting current folder dict
507
- folder_dict = self.get_folder_dict(folder_name=folder_name,
508
- folder_path=folder_path)
560
+ # updating progress tracker attributes
561
+ self.progress_tracker.current_folder += 1
509
562
 
510
- # assembling path dict
511
- path_dict = {folder_path: folder_dict}
563
+ # updating totals
564
+ self.total_folders += 1
512
565
 
513
- # updating tree dict
514
- self.tree_dict.update(path_dict)
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 visualizing folder trees with sizes and counts"
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 = args_dict['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 get_skip_bool(folder_path: str,
193
- start_path: str,
194
- start_is_cache: bool,
195
- cache_folders: list
196
- ) -> bool:
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
- # updating skip bool
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytree2
3
- Version: 0.2.2
3
+ Version: 0.2.3
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
@@ -1,3 +1,3 @@
1
1
  [console_scripts]
2
2
  pytree = pytree.main:main
3
- pytree-loc = pytree.main:main_loc
3
+ pytree-loc = pytree.main_loc:main
File without changes
File without changes
File without changes
File without changes