skilleter-thingy 0.1.18__py3-none-any.whl → 0.1.21__py3-none-any.whl
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.
Potentially problematic release.
This version of skilleter-thingy might be problematic. Click here for more details.
- skilleter_thingy/ffind.py +2 -2
- skilleter_thingy/ggit.py +1 -1
- skilleter_thingy/ggrep.py +2 -1
- skilleter_thingy/git_br.py +3 -3
- skilleter_thingy/git_common.py +2 -2
- skilleter_thingy/git_hold.py +6 -6
- skilleter_thingy/git_parent.py +4 -3
- skilleter_thingy/git_review.py +16 -12
- skilleter_thingy/git_update.py +2 -2
- skilleter_thingy/git_wt.py +5 -5
- skilleter_thingy/gitcmp_helper.py +6 -1
- skilleter_thingy/gphotosync.py +12 -8
- skilleter_thingy/localphotosync.py +77 -358
- skilleter_thingy/multigit.py +30 -34
- skilleter_thingy/photodupe.py +10 -10
- skilleter_thingy/py_audit.py +4 -2
- skilleter_thingy/readable.py +13 -11
- skilleter_thingy/sysmon.py +2 -2
- skilleter_thingy/thingy/colour.py +6 -2
- skilleter_thingy/thingy/dircolors.py +20 -18
- skilleter_thingy/thingy/git2.py +0 -1
- skilleter_thingy/thingy/popup.py +1 -1
- skilleter_thingy/thingy/tfm_pane.py +3 -3
- skilleter_thingy/thingy/tidy.py +14 -13
- skilleter_thingy/trimpath.py +5 -4
- skilleter_thingy/venv_create.py +1 -1
- {skilleter_thingy-0.1.18.dist-info → skilleter_thingy-0.1.21.dist-info}/METADATA +1 -1
- skilleter_thingy-0.1.21.dist-info/PKG-INFO 2 +193 -0
- {skilleter_thingy-0.1.18.dist-info → skilleter_thingy-0.1.21.dist-info}/RECORD +33 -32
- {skilleter_thingy-0.1.18.dist-info → skilleter_thingy-0.1.21.dist-info}/WHEEL +0 -0
- {skilleter_thingy-0.1.18.dist-info → skilleter_thingy-0.1.21.dist-info}/entry_points.txt +0 -0
- {skilleter_thingy-0.1.18.dist-info → skilleter_thingy-0.1.21.dist-info}/licenses/LICENSE +0 -0
- {skilleter_thingy-0.1.18.dist-info → skilleter_thingy-0.1.21.dist-info}/top_level.txt +0 -0
skilleter_thingy/multigit.py
CHANGED
|
@@ -133,14 +133,6 @@ class Arguments():
|
|
|
133
133
|
|
|
134
134
|
################################################################################
|
|
135
135
|
|
|
136
|
-
def error(msg, status=1):
|
|
137
|
-
"""Quit with an error"""
|
|
138
|
-
|
|
139
|
-
colour.write(f'[RED:ERROR:] {msg}\n', stream=sys.stderr)
|
|
140
|
-
sys.exit(status)
|
|
141
|
-
|
|
142
|
-
################################################################################
|
|
143
|
-
|
|
144
136
|
def verbose(args, msg):
|
|
145
137
|
"""Output a message to stderr if running verbosely"""
|
|
146
138
|
|
|
@@ -174,7 +166,11 @@ def find_configuration(default_config_file):
|
|
|
174
166
|
if '/' in default_config_file:
|
|
175
167
|
config_file = default_config_file
|
|
176
168
|
else:
|
|
177
|
-
|
|
169
|
+
try:
|
|
170
|
+
config_path = os.getcwd()
|
|
171
|
+
except FileNotFoundError:
|
|
172
|
+
colour.error('Unable to determine current directory', prefix=True)
|
|
173
|
+
|
|
178
174
|
config_file = os.path.join(config_path, default_config_file)
|
|
179
175
|
|
|
180
176
|
while not os.path.isfile(config_file) and config_path != '/':
|
|
@@ -314,10 +310,10 @@ def mg_clone(args, config, console):
|
|
|
314
310
|
# Sanity checks
|
|
315
311
|
|
|
316
312
|
if not args.parameters:
|
|
317
|
-
error('The "clone" subcommand takes 1 or 2 parameters - the repo to clone and, optionally, the branch to check out')
|
|
313
|
+
colour.error('The "clone" subcommand takes 1 or 2 parameters - the repo to clone and, optionally, the branch to check out', prefix=True)
|
|
318
314
|
|
|
319
315
|
if args.branched or args.modified:
|
|
320
|
-
error('The "modified" and "branched" options cannot be used with the "clone" subcommand')
|
|
316
|
+
colour.error('The "modified" and "branched" options cannot be used with the "clone" subcommand', prefix=True)
|
|
321
317
|
|
|
322
318
|
# Destination directory is the last portion of the repo URL with the extension removed
|
|
323
319
|
|
|
@@ -325,9 +321,9 @@ def mg_clone(args, config, console):
|
|
|
325
321
|
|
|
326
322
|
if os.path.exists(directory):
|
|
327
323
|
if os.path.isdir(directory):
|
|
328
|
-
error(f'The "[BLUE:{directory}]" directory already exists')
|
|
324
|
+
colour.error(f'The "[BLUE:{directory}]" directory already exists', prefix=True)
|
|
329
325
|
else:
|
|
330
|
-
error(f'[BLUE:{directory}]" already exists')
|
|
326
|
+
colour.error(f'[BLUE:{directory}]" already exists', prefix=True)
|
|
331
327
|
|
|
332
328
|
# Clone the repo and chdir into it
|
|
333
329
|
|
|
@@ -349,7 +345,7 @@ def mg_clone(args, config, console):
|
|
|
349
345
|
args.configuration_file = args.default_configuration_file
|
|
350
346
|
|
|
351
347
|
if not os.path.isfile(args.configuration_file):
|
|
352
|
-
error(f'Cannot find the configuration file: [BOLD:{args.default_configuration_file}]')
|
|
348
|
+
colour.error(f'Cannot find the configuration file: [BOLD:{args.default_configuration_file}]', prefix=True)
|
|
353
349
|
|
|
354
350
|
config.read(args.configuration_file)
|
|
355
351
|
|
|
@@ -383,7 +379,7 @@ def mg_init(args, config, console):
|
|
|
383
379
|
# Sanity checks
|
|
384
380
|
|
|
385
381
|
if args.modified or args.branched or args.tag or args.subdirectories:
|
|
386
|
-
error('The "--tag", "--modified" "--sub", and "--branched" options cannot be used with the "init" subcommand')
|
|
382
|
+
colour.error('The "--tag", "--modified" "--sub", and "--branched" options cannot be used with the "init" subcommand', prefix=True)
|
|
387
383
|
|
|
388
384
|
# Search for .git directories and add any that aren't already in the configuration
|
|
389
385
|
|
|
@@ -400,12 +396,12 @@ def mg_init(args, config, console):
|
|
|
400
396
|
|
|
401
397
|
abs_repo_path = absolute_repo_path(args, repo)
|
|
402
398
|
|
|
403
|
-
config[repo] = {
|
|
399
|
+
config[repo] = {}
|
|
404
400
|
|
|
405
401
|
default_branch = git.branch(path=abs_repo_path)
|
|
406
402
|
|
|
407
403
|
if not default_branch:
|
|
408
|
-
error(f'Unable to determine default branch in [BLUE:{repo}]')
|
|
404
|
+
colour.error(f'Unable to determine default branch in [BLUE:{repo}]', prefix=True)
|
|
409
405
|
|
|
410
406
|
config[repo]['default branch'] = default_branch
|
|
411
407
|
|
|
@@ -451,12 +447,12 @@ def mg_dir(args, config, console):
|
|
|
451
447
|
verbose(args, f'dir: Parameters: {", ".join(args.parameters)}')
|
|
452
448
|
|
|
453
449
|
if len(args.parameters) > 1:
|
|
454
|
-
error('The +dir command takes no more than one parameter - the name of the working tree to search for')
|
|
450
|
+
colour.error('The +dir command takes no more than one parameter - the name of the working tree to search for', prefix=True)
|
|
455
451
|
|
|
456
452
|
# TODO: mg_dir _should_ use these options
|
|
457
453
|
|
|
458
454
|
if args.modified or args.branched or args.tag or args.subdirectories:
|
|
459
|
-
error('The "--tag", "--modified" "--sub", and "--branched" options cannot be used with the "dir" subcommand')
|
|
455
|
+
colour.error('The "--tag", "--modified" "--sub", and "--branched" options cannot be used with the "dir" subcommand', prefix=True)
|
|
460
456
|
|
|
461
457
|
# If a parameter is specified, look for matches, otherwise just return the location of the
|
|
462
458
|
# configuration file
|
|
@@ -490,7 +486,7 @@ def mg_dir(args, config, console):
|
|
|
490
486
|
destination = destinations
|
|
491
487
|
|
|
492
488
|
if not destination:
|
|
493
|
-
error(f'No matches with [BLUE:{search_name}]')
|
|
489
|
+
colour.error(f'No matches with [BLUE:{search_name}]', prefix=True)
|
|
494
490
|
|
|
495
491
|
colour.write("\n".join([relative_repo_path(args, d) for d in destination]))
|
|
496
492
|
|
|
@@ -505,7 +501,7 @@ def mg_tag(args, config, console):
|
|
|
505
501
|
_ = console
|
|
506
502
|
|
|
507
503
|
if len(args.parameters) > 1:
|
|
508
|
-
error('The +tag command takes no more than one parameter')
|
|
504
|
+
colour.error('The +tag command takes no more than one parameter', prefix=True)
|
|
509
505
|
|
|
510
506
|
for repo in select_git_repos(args, config):
|
|
511
507
|
try:
|
|
@@ -529,7 +525,7 @@ def mg_untag(args, config, console):
|
|
|
529
525
|
_ = console
|
|
530
526
|
|
|
531
527
|
if len(args.parameters) > 1:
|
|
532
|
-
error('The +tag command takes no more than one parameter')
|
|
528
|
+
colour.error('The +tag command takes no more than one parameter', prefix=True)
|
|
533
529
|
|
|
534
530
|
for repo in select_git_repos(args, config):
|
|
535
531
|
try:
|
|
@@ -551,7 +547,7 @@ def mg_config(args, config, console):
|
|
|
551
547
|
_ = console
|
|
552
548
|
|
|
553
549
|
if len(args.parameters):
|
|
554
|
-
error('The +config command does not take parameters')
|
|
550
|
+
colour.error('The +config command does not take parameters', prefix=True)
|
|
555
551
|
|
|
556
552
|
colour.write(os.path.relpath(args.configuration_file))
|
|
557
553
|
|
|
@@ -614,28 +610,28 @@ def parse_command_line():
|
|
|
614
610
|
|
|
615
611
|
elif param in ('config', 'c'):
|
|
616
612
|
if params:
|
|
617
|
-
error('--config - missing configuration file parameter')
|
|
613
|
+
colour.error('--config - missing configuration file parameter', prefix=True)
|
|
618
614
|
else:
|
|
619
615
|
try:
|
|
620
616
|
args.default_configuration_file = arg_list.pop(0)
|
|
621
617
|
except IndexError:
|
|
622
|
-
error('--config - missing configuration file parameter')
|
|
618
|
+
colour.error('--config - missing configuration file parameter', prefix=True)
|
|
623
619
|
|
|
624
620
|
elif param in ('repos', 'r'):
|
|
625
621
|
if params:
|
|
626
|
-
error('--repos - missing repo parameter')
|
|
622
|
+
colour.error('--repos - missing repo parameter', prefix=True)
|
|
627
623
|
try:
|
|
628
624
|
args.repos.append(arg_list.pop(0))
|
|
629
625
|
except IndexError:
|
|
630
|
-
error('--repos - missing repo parameter')
|
|
626
|
+
colour.error('--repos - missing repo parameter', prefix=True)
|
|
631
627
|
|
|
632
628
|
elif param in ('tag', 't'):
|
|
633
629
|
if params:
|
|
634
|
-
error('--tag - missing tag parameter')
|
|
630
|
+
colour.error('--tag - missing tag parameter', prefix=True)
|
|
635
631
|
try:
|
|
636
632
|
args.tag.append(arg_list.pop(0))
|
|
637
633
|
except IndexError:
|
|
638
|
-
error('--tag - missing tag parameter')
|
|
634
|
+
colour.error('--tag - missing tag parameter', prefix=True)
|
|
639
635
|
|
|
640
636
|
elif param in ('modified', 'm'):
|
|
641
637
|
args.modified = True
|
|
@@ -654,7 +650,7 @@ def parse_command_line():
|
|
|
654
650
|
sys.exit(0)
|
|
655
651
|
|
|
656
652
|
else:
|
|
657
|
-
error(f'Invalid option: "{param}"')
|
|
653
|
+
colour.error(f'Invalid option: "{param}"', prefix=True)
|
|
658
654
|
|
|
659
655
|
# After the options, we either have a multigit command (prefixed with '+') or a git command
|
|
660
656
|
# followed by parameter
|
|
@@ -670,7 +666,7 @@ def parse_command_line():
|
|
|
670
666
|
args.internal_command = False
|
|
671
667
|
|
|
672
668
|
except IndexError:
|
|
673
|
-
error('Missing command')
|
|
669
|
+
colour.error('Missing command', prefix=True)
|
|
674
670
|
|
|
675
671
|
# Save the command parameters
|
|
676
672
|
|
|
@@ -702,7 +698,7 @@ def main():
|
|
|
702
698
|
args = parse_command_line()
|
|
703
699
|
|
|
704
700
|
if args.internal_command and args.command not in COMMANDS:
|
|
705
|
-
error(f'Invalid command "{args.command}"')
|
|
701
|
+
colour.error(f'Invalid command "{args.command}"', prefix=True)
|
|
706
702
|
|
|
707
703
|
# If the configuration file exists, read it
|
|
708
704
|
|
|
@@ -717,7 +713,7 @@ def main():
|
|
|
717
713
|
if args.command == 'init':
|
|
718
714
|
args.configuration_file = os.path.abspath(args.default_configuration_file)
|
|
719
715
|
else:
|
|
720
|
-
error('Cannot locate configuration file')
|
|
716
|
+
colour.error('Cannot locate configuration file', prefix=True)
|
|
721
717
|
|
|
722
718
|
if args.configuration_file and os.path.isfile(args.configuration_file):
|
|
723
719
|
config.read(args.configuration_file)
|
|
@@ -736,7 +732,7 @@ def main():
|
|
|
736
732
|
# Everything except '+init' and '+clone' requires the configuration file
|
|
737
733
|
|
|
738
734
|
if args.command not in ('init', 'clone') and args.configuration_file is None:
|
|
739
|
-
error('Configuration file not found')
|
|
735
|
+
colour.error('Configuration file not found', prefix=True)
|
|
740
736
|
|
|
741
737
|
COMMANDS[args.command](args, config, console)
|
|
742
738
|
|
skilleter_thingy/photodupe.py
CHANGED
|
@@ -21,21 +21,21 @@ def read_image_hashes(directories):
|
|
|
21
21
|
hashes = defaultdict(list)
|
|
22
22
|
|
|
23
23
|
# Walk each directory tree
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
for directory in directories:
|
|
26
26
|
print(f'Scanning directory tree {directory}')
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
for root, _, files in os.walk(directory):
|
|
29
29
|
print(f'Scanning directory {root}')
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
for file in files:
|
|
32
32
|
filepath = os.path.join(root, file)
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
fileext = os.path.splitext(file)[1]
|
|
35
35
|
|
|
36
36
|
if fileext.lower() not in ('.jbf', '.ini', '.xml', '.ffs_db'):
|
|
37
37
|
# Calculate the hash and store path, dimensions and file size under the hash entry in the hashes table
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
try:
|
|
40
40
|
with Image.open(filepath) as image:
|
|
41
41
|
hash_value = imagehash.average_hash(image, hash_size=12)
|
|
@@ -48,9 +48,9 @@ def read_image_hashes(directories):
|
|
|
48
48
|
|
|
49
49
|
except OSError:
|
|
50
50
|
sys.stderr.write(f'ERROR: Unable to read {filepath} (size={size})\n')
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
# Return the hash table
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
return hashes
|
|
55
55
|
|
|
56
56
|
################################################################################
|
|
@@ -62,11 +62,11 @@ def main():
|
|
|
62
62
|
parser.add_argument('directories', nargs='*', action='store', help='Directories to search')
|
|
63
63
|
|
|
64
64
|
args = parser.parse_args()
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
if not args.directories:
|
|
67
67
|
print('You must be specify at least one directory')
|
|
68
68
|
sys.exit(1)
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
try:
|
|
71
71
|
print('Loading cached data')
|
|
72
72
|
|
|
@@ -78,7 +78,7 @@ def main():
|
|
|
78
78
|
hashes = read_image_hashes(args.directories)
|
|
79
79
|
|
|
80
80
|
# Sort the list of hashes so that we can easily find close matches
|
|
81
|
-
|
|
81
|
+
|
|
82
82
|
print('Sorting hashes')
|
|
83
83
|
|
|
84
84
|
hash_values = sorted([str(hashval) for hashval in hashes])
|
skilleter_thingy/py_audit.py
CHANGED
|
@@ -70,8 +70,10 @@ def audit(package, version):
|
|
|
70
70
|
def main():
|
|
71
71
|
""" Entry point """
|
|
72
72
|
|
|
73
|
-
parser = argparse.ArgumentParser(
|
|
74
|
-
|
|
73
|
+
parser = argparse.ArgumentParser(
|
|
74
|
+
description='Query api.osv.dev to determine whether Python packagers in a requirments.txt file are subject to known security vulnerabilities')
|
|
75
|
+
parser.add_argument('requirements', nargs='*', type=str, action='store',
|
|
76
|
+
help='The requirements file (if not specified, then the script searches for a requirements.txt file)')
|
|
75
77
|
args = parser.parse_args()
|
|
76
78
|
|
|
77
79
|
requirements = args.requirements or glob.glob('**/requirements.txt', recursive=True)
|
skilleter_thingy/readable.py
CHANGED
|
@@ -47,13 +47,13 @@ TF_TAG_ENTRY_IGNORE = re.compile(r'^ +".*" += +".*"')
|
|
|
47
47
|
TF_TAG_CHANGE_BLOCK_END = re.compile(r'^ +}$')
|
|
48
48
|
|
|
49
49
|
TF_MISC_REGEX = \
|
|
50
|
-
[
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
]
|
|
50
|
+
[
|
|
51
|
+
{'regex': re.compile(r'(Read complete after) (\d+s|\d+m\d+s)'), 'replace': r'\1 {ELAPSED}'},
|
|
52
|
+
{'regex': re.compile(r'"(.*:.*)"( = ".*")'), 'replace': r'\1\2'},
|
|
53
|
+
{'regex': re.compile(r'"(.*:.*)"( = \[$)'), 'replace': r'\1\2'},
|
|
54
|
+
{'regex': re.compile(r'^last "terraform apply":$'), 'replace': r'last "terraform apply" which may have affected this plan:'},
|
|
55
|
+
{'find': ' ~ ', 'replace': ' * '},
|
|
56
|
+
]
|
|
57
57
|
|
|
58
58
|
TF_IGNORE_LIST = [
|
|
59
59
|
{'start': TF_HAS_CHANGED, 'end': TF_HAS_CHANGED_END},
|
|
@@ -91,8 +91,10 @@ def parse_command_line():
|
|
|
91
91
|
parser.add_argument('--terraform', '-T', action='store_true', help='Clean Terraform plan/apply log files')
|
|
92
92
|
parser.add_argument('--replace', '-R', action='append', default=None, help='Additional regex replacements in the form "REGEX=REPLACEMENT"')
|
|
93
93
|
parser.add_argument('--verbose', '-v', action='store_true', help='Output verbose status')
|
|
94
|
-
parser.add_argument('--minimal', '-m', action='store_true',
|
|
95
|
-
|
|
94
|
+
parser.add_argument('--minimal', '-m', action='store_true',
|
|
95
|
+
help='Remove unnecessary data from the file (e.g. Terraform progress updates (Refreshing..., Reading..., etc.))')
|
|
96
|
+
parser.add_argument('--non-minimal', '-M', action='store_true',
|
|
97
|
+
help='Do not remove unnecessary data from the file (e.g. Terraform progress updates (Refreshing..., Reading..., etc.))')
|
|
96
98
|
parser.add_argument('files', nargs='*', default=None, help='The files to convert (use stdin/stout if no input files are specified)')
|
|
97
99
|
|
|
98
100
|
args = parser.parse_args()
|
|
@@ -144,7 +146,7 @@ def parse_command_line():
|
|
|
144
146
|
for entry in args.replace:
|
|
145
147
|
regex, replace = entry.split('=')
|
|
146
148
|
try:
|
|
147
|
-
args.regex_replace.append({'regex': re.compile(regex), 'replace':replace})
|
|
149
|
+
args.regex_replace.append({'regex': re.compile(regex), 'replace': replace})
|
|
148
150
|
except re.error as exc:
|
|
149
151
|
print(f'ERROR in regular expression {regex}: {exc}')
|
|
150
152
|
sys.exit(1)
|
|
@@ -291,7 +293,7 @@ def cleanfile(args, infile, outfile):
|
|
|
291
293
|
# Write normal output, skipping >1 blank lines and skipping ignore blocks when the pre-ignore
|
|
292
294
|
# count has hit zero.
|
|
293
295
|
|
|
294
|
-
if clean is not None and not (ignore_until and pre_ignore_count==0):
|
|
296
|
+
if clean is not None and not (ignore_until and pre_ignore_count == 0):
|
|
295
297
|
if clean != '' or prev_line != '':
|
|
296
298
|
outfile.write(clean)
|
|
297
299
|
outfile.write('\n')
|
skilleter_thingy/sysmon.py
CHANGED
|
@@ -57,7 +57,7 @@ def show_cpu_times(scr, first, w, h, x, y):
|
|
|
57
57
|
scr.addstr(y+2, x, 'IRQ:')
|
|
58
58
|
scr.addstr(y+3, x, 'Soft IRQ:')
|
|
59
59
|
|
|
60
|
-
x+= w//3
|
|
60
|
+
x += w//3
|
|
61
61
|
|
|
62
62
|
scr.addstr(y+1, x, 'Guest:')
|
|
63
63
|
scr.addstr(y+2, x, 'Guest Nice:')
|
|
@@ -320,7 +320,7 @@ def show_temperatures(scr, first, w, h, x, y):
|
|
|
320
320
|
|
|
321
321
|
# Panel title and the functions used to update them
|
|
322
322
|
|
|
323
|
-
BOXES= {
|
|
323
|
+
BOXES = {
|
|
324
324
|
'System Load': show_system_load,
|
|
325
325
|
'Disk Access': show_disk_access,
|
|
326
326
|
'Processes': show_processes,
|
|
@@ -184,9 +184,13 @@ def write(txt=None, newline=True, stream=sys.stdout, indent=0, strip=False, clea
|
|
|
184
184
|
|
|
185
185
|
################################################################################
|
|
186
186
|
|
|
187
|
-
def error(txt, newline=True, stream=sys.stderr, status=1):
|
|
187
|
+
def error(txt, newline=True, stream=sys.stderr, status=1, prefix=False):
|
|
188
188
|
""" Write an error message to the specified stream (defaulting to
|
|
189
|
-
stderr) and exit with the specified status code (defaulting to 1)
|
|
189
|
+
stderr) and exit with the specified status code (defaulting to 1)
|
|
190
|
+
Prefix the output with 'ERROR:' in red if prefix==True """
|
|
191
|
+
|
|
192
|
+
if prefix:
|
|
193
|
+
write('[RED:ERROR]: ', newline=False, stream=stream, )
|
|
190
194
|
|
|
191
195
|
write(txt, newline, stream)
|
|
192
196
|
|
|
@@ -20,6 +20,7 @@ import thingy.dc_util as dc_util
|
|
|
20
20
|
__all__ = ['Dircolors']
|
|
21
21
|
|
|
22
22
|
_CODE_MAP = OrderedDict()
|
|
23
|
+
|
|
23
24
|
def _init_code_map():
|
|
24
25
|
""" mapping between the key name in the .dircolors file and the two letter
|
|
25
26
|
code found in the LS_COLORS environment variable.
|
|
@@ -53,6 +54,7 @@ class Dircolors:
|
|
|
53
54
|
""" Main dircolors class. Contains a database of formats corresponding to file types,
|
|
54
55
|
modes, and extensions. Use the format() method to check a file and color it appropriately.
|
|
55
56
|
"""
|
|
57
|
+
|
|
56
58
|
def __init__(self, load=True):
|
|
57
59
|
""" Initialize a Dircolors object. If load=True (the default), then try
|
|
58
60
|
to load dircolors info from the LS_COLORS environment variable.
|
|
@@ -98,7 +100,7 @@ class Dircolors:
|
|
|
98
100
|
try:
|
|
99
101
|
code, color = item.split('=', 1)
|
|
100
102
|
except ValueError:
|
|
101
|
-
continue
|
|
103
|
+
continue # no key=value, just ignore
|
|
102
104
|
if code.startswith('*.'):
|
|
103
105
|
self._extensions[code[1:]] = color
|
|
104
106
|
else:
|
|
@@ -134,7 +136,7 @@ class Dircolors:
|
|
|
134
136
|
elif isinstance(database, TextIOBase):
|
|
135
137
|
file = database
|
|
136
138
|
else:
|
|
137
|
-
raise ValueError('database must be str or io.TextIOBase, not %s'%type(database))
|
|
139
|
+
raise ValueError('database must be str or io.TextIOBase, not %s' % type(database))
|
|
138
140
|
|
|
139
141
|
try:
|
|
140
142
|
for line in file:
|
|
@@ -147,18 +149,18 @@ class Dircolors:
|
|
|
147
149
|
split = line.split()
|
|
148
150
|
if len(split) != 2:
|
|
149
151
|
if strict:
|
|
150
|
-
raise ValueError('Warning: unable to parse dircolors line "%s"'%line)
|
|
152
|
+
raise ValueError('Warning: unable to parse dircolors line "%s"' % line)
|
|
151
153
|
continue
|
|
152
154
|
|
|
153
155
|
key, val = split
|
|
154
156
|
if key == 'TERM':
|
|
155
|
-
continue
|
|
157
|
+
continue # ignore TERM directives
|
|
156
158
|
elif key in _CODE_MAP:
|
|
157
159
|
self._codes[_CODE_MAP[key]] = val
|
|
158
160
|
elif key.startswith('.'):
|
|
159
161
|
self._extensions[key] = val
|
|
160
162
|
elif strict:
|
|
161
|
-
raise ValueError('Warning: unable to parse dircolors line "%s"'%line)
|
|
163
|
+
raise ValueError('Warning: unable to parse dircolors line "%s"' % line)
|
|
162
164
|
# elif not strict, skip
|
|
163
165
|
|
|
164
166
|
if self._codes or self._extensions:
|
|
@@ -184,14 +186,14 @@ class Dircolors:
|
|
|
184
186
|
# change .xyz to *.xyz
|
|
185
187
|
yield '*' + pair[0], pair[1]
|
|
186
188
|
|
|
187
|
-
return ':'.join('%s=%s'%pair for pair in gen_pairs())
|
|
189
|
+
return ':'.join('%s=%s' % pair for pair in gen_pairs())
|
|
188
190
|
|
|
189
191
|
def _format_code(self, text, code):
|
|
190
192
|
""" format text with an lscolors code. Return text unmodified if code
|
|
191
193
|
isn't found in the database """
|
|
192
194
|
val = self._codes.get(code, None)
|
|
193
195
|
if val:
|
|
194
|
-
return '\033[%sm%s\033[%sm'%(val, text, self._codes.get('rs', '0'))
|
|
196
|
+
return '\033[%sm%s\033[%sm' % (val, text, self._codes.get('rs', '0'))
|
|
195
197
|
return text
|
|
196
198
|
|
|
197
199
|
def _format_ext(self, text, ext):
|
|
@@ -200,7 +202,7 @@ class Dircolors:
|
|
|
200
202
|
text need not actually end in '.ext' """
|
|
201
203
|
val = self._extensions.get(ext, '0')
|
|
202
204
|
if val:
|
|
203
|
-
return '\033[%sm%s\033[%sm'%(val, text, self._codes.get('rs', '0'))
|
|
205
|
+
return '\033[%sm%s\033[%sm' % (val, text, self._codes.get('rs', '0'))
|
|
204
206
|
return text
|
|
205
207
|
|
|
206
208
|
def format_mode(self, text, mode):
|
|
@@ -225,7 +227,7 @@ class Dircolors:
|
|
|
225
227
|
elif isinstance(mode, os.stat_result):
|
|
226
228
|
mode = mode.st_mode
|
|
227
229
|
else:
|
|
228
|
-
raise ValueError('mode must be int or os.stat_result, not %s'%type(mode))
|
|
230
|
+
raise ValueError('mode must be int or os.stat_result, not %s' % type(mode))
|
|
229
231
|
|
|
230
232
|
if mode:
|
|
231
233
|
if stat.S_ISDIR(mode):
|
|
@@ -244,13 +246,13 @@ class Dircolors:
|
|
|
244
246
|
# special file?
|
|
245
247
|
# pylint: disable=bad-whitespace
|
|
246
248
|
special_types = (
|
|
247
|
-
(stat.S_IFLNK, 'ln'),
|
|
248
|
-
(stat.S_IFIFO, 'pi'),
|
|
249
|
-
(stat.S_IFSOCK, 'so'),
|
|
250
|
-
(stat.S_IFBLK, 'bd'),
|
|
251
|
-
(stat.S_IFCHR, 'cd'),
|
|
252
|
-
(stat.S_ISUID, 'su'),
|
|
253
|
-
(stat.S_ISGID, 'sg'),
|
|
249
|
+
(stat.S_IFLNK, 'ln'), # symlink
|
|
250
|
+
(stat.S_IFIFO, 'pi'), # pipe (FIFO)
|
|
251
|
+
(stat.S_IFSOCK, 'so'), # socket
|
|
252
|
+
(stat.S_IFBLK, 'bd'), # block device
|
|
253
|
+
(stat.S_IFCHR, 'cd'), # character device
|
|
254
|
+
(stat.S_ISUID, 'su'), # setuid
|
|
255
|
+
(stat.S_ISGID, 'sg'), # setgid
|
|
254
256
|
)
|
|
255
257
|
|
|
256
258
|
for mask, code in special_types:
|
|
@@ -290,13 +292,13 @@ class Dircolors:
|
|
|
290
292
|
try:
|
|
291
293
|
statbuf = dc_util.stat_at(file, cwd, follow_symlinks)
|
|
292
294
|
except OSError as e:
|
|
293
|
-
return '%s [Error stat-ing: %s]'%(file, e.strerror)
|
|
295
|
+
return '%s [Error stat-ing: %s]' % (file, e.strerror)
|
|
294
296
|
|
|
295
297
|
mode = statbuf.st_mode
|
|
296
298
|
if (not follow_symlinks) and show_target and stat.S_ISLNK(mode):
|
|
297
299
|
target_path = dc_util.readlink_at(file, cwd)
|
|
298
300
|
try:
|
|
299
|
-
dc_util.stat_at(target_path, cwd)
|
|
301
|
+
dc_util.stat_at(target_path, cwd) # check for broken link
|
|
300
302
|
target = self.format(target_path, cwd, False, False)
|
|
301
303
|
except OSError:
|
|
302
304
|
# format as "orphan"
|
skilleter_thingy/thingy/git2.py
CHANGED
skilleter_thingy/thingy/popup.py
CHANGED
|
@@ -148,7 +148,7 @@ class Pane():
|
|
|
148
148
|
|
|
149
149
|
filestat = os.stat(filename, follow_symlinks=False)
|
|
150
150
|
|
|
151
|
-
info = {'name':filename,
|
|
151
|
+
info = {'name': filename,
|
|
152
152
|
'mode': filestat.st_mode,
|
|
153
153
|
'uid': filestat.st_uid,
|
|
154
154
|
'gid': filestat.st_gid,
|
|
@@ -310,7 +310,7 @@ class Pane():
|
|
|
310
310
|
else:
|
|
311
311
|
self.screen.clrtoeol()
|
|
312
312
|
|
|
313
|
-
#if len(filename) < self.width:
|
|
313
|
+
# if len(filename) < self.width:
|
|
314
314
|
# self.screen.addstr(self.file_list_y + ypos, len(filename), ' ' * (self.width - len(filename)), normal_colour)
|
|
315
315
|
|
|
316
316
|
current_dir = path.trimpath(self.current_dir, self.width)
|
|
@@ -541,7 +541,7 @@ class Pane():
|
|
|
541
541
|
|
|
542
542
|
self.height = height
|
|
543
543
|
self.file_list_h = height-1
|
|
544
|
-
self.width = pane_width-1
|
|
544
|
+
self.width = pane_width-1 # TODO: Why '-1'?
|
|
545
545
|
self.screen.resize(height, pane_width)
|
|
546
546
|
self.screen.mvwin(y, x + pane_width*self.index)
|
|
547
547
|
|
skilleter_thingy/thingy/tidy.py
CHANGED
|
@@ -76,23 +76,24 @@ RE_SHA1 = [
|
|
|
76
76
|
# AWS ids
|
|
77
77
|
|
|
78
78
|
RE_AWS = \
|
|
79
|
-
[
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
79
|
+
[
|
|
80
|
+
{'regex': re.compile(r'eni-0[0-9a-f]{16}'), 'replace': '{ENI-ID}'},
|
|
81
|
+
{'regex': re.compile(r'ami-0[0-9a-f]{16}'), 'replace': '{AMI-ID}'},
|
|
82
|
+
{'regex': re.compile(r'snap-0[0-9a-f]{16}'), 'replace': '{AMI-SNAP}'},
|
|
83
|
+
{'regex': re.compile(r'vol-0[0-9a-f]{16}'), 'replace': '{AMI-VOL}'},
|
|
84
|
+
{'regex': re.compile(r'sir-[0-9a-z]{8}'), 'replace': '{SPOT-INSTANCE}'},
|
|
85
|
+
{'regex': re.compile(r'i-0[0-9a-f]{16}'), 'replace': '{EC2-ID}'},
|
|
86
|
+
{'regex': re.compile(r'request id: [0-0a-f]{8}-[0-0a-f]{4}-[0-0a-f]{4}-[0-0a-f]{4}-[0-0a-f]{12}'),
|
|
87
|
+
'replace': 'request id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
|
|
88
|
+
]
|
|
88
89
|
|
|
89
90
|
# Data transfer speeds
|
|
90
91
|
|
|
91
92
|
RE_SPEED = \
|
|
92
|
-
[
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
]
|
|
93
|
+
[
|
|
94
|
+
{'regex': re.compile(r'[0-9.]+ *MB/s'), 'replace': '{SPEED}'},
|
|
95
|
+
{'regex': re.compile(r'[0-9.]+ *MiB/s'), 'replace': '{SPEED}'},
|
|
96
|
+
]
|
|
96
97
|
|
|
97
98
|
################################################################################
|
|
98
99
|
|
skilleter_thingy/trimpath.py
CHANGED
|
@@ -52,10 +52,11 @@ def main():
|
|
|
52
52
|
|
|
53
53
|
# Set the path, defaulting to the current directory
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
full_path = args.path
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
try:
|
|
56
|
+
full_path = args.path or os.getcwd()
|
|
57
|
+
except FileNotFoundError:
|
|
58
|
+
logging.critical('Unable to locate directory')
|
|
59
|
+
sys.exit(1)
|
|
59
60
|
|
|
60
61
|
trimmed = path.trimpath(full_path, trim_width)
|
|
61
62
|
|
skilleter_thingy/venv_create.py
CHANGED
|
@@ -24,7 +24,7 @@ def main():
|
|
|
24
24
|
|
|
25
25
|
statinfo = os.stat(script)
|
|
26
26
|
|
|
27
|
-
os.chmod(script, statinfo.st_mode|stat.S_IXUSR|stat.S_IXGRP|stat.S_IXOTH)
|
|
27
|
+
os.chmod(script, statinfo.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
|
28
28
|
|
|
29
29
|
print(f'Created virtual environment: {script}')
|
|
30
30
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: skilleter_thingy
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.21
|
|
4
4
|
Summary: A collection of useful utilities, mainly aimed at making Git more friendly
|
|
5
5
|
Author-email: John Skilleter <john@skilleter.org.uk>
|
|
6
6
|
Project-URL: Home, https://skilleter.org.uk
|