skilleter-thingy 0.0.75__py3-none-any.whl → 0.0.77__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/multigit.py +78 -17
- skilleter_thingy/thingy/colour.py +4 -1
- skilleter_thingy/thingy/git2.py +32 -0
- {skilleter_thingy-0.0.75.dist-info → skilleter_thingy-0.0.77.dist-info}/METADATA +80 -56
- {skilleter_thingy-0.0.75.dist-info → skilleter_thingy-0.0.77.dist-info}/RECORD +9 -9
- {skilleter_thingy-0.0.75.dist-info → skilleter_thingy-0.0.77.dist-info}/LICENSE +0 -0
- {skilleter_thingy-0.0.75.dist-info → skilleter_thingy-0.0.77.dist-info}/WHEEL +0 -0
- {skilleter_thingy-0.0.75.dist-info → skilleter_thingy-0.0.77.dist-info}/entry_points.txt +0 -0
- {skilleter_thingy-0.0.75.dist-info → skilleter_thingy-0.0.77.dist-info}/top_level.txt +0 -0
skilleter_thingy/multigit.py
CHANGED
|
@@ -25,6 +25,7 @@ import thingy.colour as colour
|
|
|
25
25
|
default branch = name
|
|
26
26
|
"""
|
|
27
27
|
|
|
28
|
+
# TODO: [ ] If the config file isn't in the current directory then search up the directory tree for it but run in the current directory
|
|
28
29
|
# TODO: [ ] -j option to run in parallel?
|
|
29
30
|
# TODO: [ ] init function
|
|
30
31
|
# TODO: [/] Use the configuration file
|
|
@@ -37,6 +38,7 @@ import thingy.colour as colour
|
|
|
37
38
|
# TODO: [ ] Better error-handling - e.g. continue/abort option after failure in one repo
|
|
38
39
|
# TODO: [ ] Dry-run option
|
|
39
40
|
# TODO: [ ] Verbose option
|
|
41
|
+
# TODO: [ ] When specifying list of repos, if repo name doesn't contain '/' prefix it with '*'?
|
|
40
42
|
|
|
41
43
|
################################################################################
|
|
42
44
|
|
|
@@ -69,8 +71,13 @@ def show_progress(width, msg):
|
|
|
69
71
|
def find_git_repos(directory, wildcard):
|
|
70
72
|
"""Locate and return a list of '.git' directory parent directories in the
|
|
71
73
|
specified path.
|
|
74
|
+
|
|
72
75
|
If wildcard is not None then it is treated as a list of wildcards and
|
|
73
|
-
only repos matching at least one of the wildcards are returned.
|
|
76
|
+
only repos matching at least one of the wildcards are returned.
|
|
77
|
+
|
|
78
|
+
If the same repo matches multiple times it will only be returned once. """
|
|
79
|
+
|
|
80
|
+
repos = set()
|
|
74
81
|
|
|
75
82
|
for root, dirs, _ in os.walk(directory):
|
|
76
83
|
if '.git' in dirs:
|
|
@@ -80,10 +87,14 @@ def find_git_repos(directory, wildcard):
|
|
|
80
87
|
if wildcard:
|
|
81
88
|
for card in wildcard:
|
|
82
89
|
if fnmatch.fnmatch(root, card):
|
|
83
|
-
|
|
90
|
+
if root not in repos:
|
|
91
|
+
yield root
|
|
92
|
+
repos.add(root)
|
|
84
93
|
break
|
|
85
94
|
else:
|
|
86
|
-
|
|
95
|
+
if root not in repos:
|
|
96
|
+
yield root
|
|
97
|
+
repos.add(root)
|
|
87
98
|
|
|
88
99
|
################################################################################
|
|
89
100
|
|
|
@@ -233,8 +244,8 @@ def mg_push(args, config, console):
|
|
|
233
244
|
and where the most recent commit was the current user and was on the branch
|
|
234
245
|
"""
|
|
235
246
|
|
|
236
|
-
# TODO: Add option for force-push?
|
|
237
|
-
# TODO: Add option for manual confirmation?
|
|
247
|
+
# TODO: [/] Add option for force-push?
|
|
248
|
+
# TODO: [ ] Add option for manual confirmation?
|
|
238
249
|
|
|
239
250
|
for repo in find_git_repos(args.directory, args.repos):
|
|
240
251
|
if not args.quiet:
|
|
@@ -245,11 +256,10 @@ def mg_push(args, config, console):
|
|
|
245
256
|
if branch != config[repo]['default branch']:
|
|
246
257
|
colour.write(f'Pushing changes to [BLUE:{branch}] in [BOLD:{repo}]')
|
|
247
258
|
|
|
248
|
-
result = git.push(path=repo)
|
|
259
|
+
result = git.push(path=repo, force_with_lease=args.force)
|
|
249
260
|
|
|
250
261
|
if result:
|
|
251
|
-
|
|
252
|
-
colour.write(f' {line}')
|
|
262
|
+
colour.write(result, indent=4)
|
|
253
263
|
|
|
254
264
|
colour.write()
|
|
255
265
|
|
|
@@ -261,7 +271,10 @@ def mg_checkout(args, config, console):
|
|
|
261
271
|
if the branch exists in the repo.
|
|
262
272
|
If the 'create' option is specified then branch is created"""
|
|
263
273
|
|
|
264
|
-
# TODO: Add --create handling
|
|
274
|
+
# TODO: [ ] Add --create handling
|
|
275
|
+
# TODO: [ ] Checkout remote branches
|
|
276
|
+
# TODO: [ ] only try checkout if branch exists
|
|
277
|
+
# TODO: [ ] option to fetch before checking out
|
|
265
278
|
|
|
266
279
|
for repo in find_git_repos(args.directory, args.repos):
|
|
267
280
|
if not args.quiet:
|
|
@@ -270,9 +283,9 @@ def mg_checkout(args, config, console):
|
|
|
270
283
|
branch = args.branch or config[repo]['default branch']
|
|
271
284
|
|
|
272
285
|
if git.branch(path=repo) != branch:
|
|
273
|
-
|
|
286
|
+
colour.write(f'Checking out [BLUE:{branch}] in [BOLD:{repo}]')
|
|
274
287
|
|
|
275
|
-
git.checkout(branch, path=repo)
|
|
288
|
+
git.checkout(branch, create=args.create, path=repo)
|
|
276
289
|
|
|
277
290
|
################################################################################
|
|
278
291
|
|
|
@@ -281,7 +294,8 @@ def mg_commit(args, config, console):
|
|
|
281
294
|
commit those changes onto the branch"""
|
|
282
295
|
|
|
283
296
|
# TODO [ ] Option to amend the commit if it is not the first one on the current branch
|
|
284
|
-
# TODO [
|
|
297
|
+
# TODO [/] Prevent commits if current branch is the default branch
|
|
298
|
+
# TODO [ ] Option to specify wildcard for files to commit (default is all files)
|
|
285
299
|
|
|
286
300
|
for repo in find_git_repos(args.directory, args.repos):
|
|
287
301
|
if not args.quiet:
|
|
@@ -323,7 +337,37 @@ def mg_update(args, config, console):
|
|
|
323
337
|
if branch != default_branch:
|
|
324
338
|
git.checkout(branch, path=repo)
|
|
325
339
|
result = git.rebase(default_branch, path=repo)
|
|
326
|
-
colour.write(
|
|
340
|
+
colour.write(result[0], indent=4)
|
|
341
|
+
|
|
342
|
+
################################################################################
|
|
343
|
+
|
|
344
|
+
def mg_clean(args, config, console):
|
|
345
|
+
"""Clean the repos"""
|
|
346
|
+
|
|
347
|
+
for repo in find_git_repos(args.directory, args.repos):
|
|
348
|
+
if not args.quiet:
|
|
349
|
+
show_progress(console.columns, repo)
|
|
350
|
+
|
|
351
|
+
result = git.clean(recurse=args.recurse, force=args.force, dry_run=args.dry_run,
|
|
352
|
+
quiet=args.quiet, exclude=args.exclude, ignore_rules=args.x,
|
|
353
|
+
remove_only_ignored=args.X, path=repo)
|
|
354
|
+
|
|
355
|
+
first_skip = True
|
|
356
|
+
|
|
357
|
+
if result:
|
|
358
|
+
colour.write(f'[BOLD:{repo}]')
|
|
359
|
+
|
|
360
|
+
for item in result:
|
|
361
|
+
skipping = item.startswith('Skipping repository ')
|
|
362
|
+
|
|
363
|
+
if skipping and not args.verbose:
|
|
364
|
+
if first_skip:
|
|
365
|
+
colour.write(f' Skipping sub-repositories')
|
|
366
|
+
first_skip = False
|
|
367
|
+
else:
|
|
368
|
+
colour.write(f' {item.strip()}')
|
|
369
|
+
|
|
370
|
+
colour.write()
|
|
327
371
|
|
|
328
372
|
################################################################################
|
|
329
373
|
|
|
@@ -339,6 +383,7 @@ def main():
|
|
|
339
383
|
'checkout': mg_checkout,
|
|
340
384
|
'commit': mg_commit,
|
|
341
385
|
'update': mg_update,
|
|
386
|
+
'clean': mg_clean,
|
|
342
387
|
}
|
|
343
388
|
|
|
344
389
|
# Parse args in the form COMMAND OPTIONS SUBCOMMAND SUBCOMMAND_OPTIONS PARAMETERS
|
|
@@ -351,7 +396,7 @@ def main():
|
|
|
351
396
|
parser.add_argument('--quiet', '-q', action='store_true', help='Minimal console output')
|
|
352
397
|
parser.add_argument('--config', '-c', action='store', default=DEFAULT_CONFIG_FILE, help=f'The configuration file (defaults to {DEFAULT_CONFIG_FILE})')
|
|
353
398
|
parser.add_argument('--directory', '--dir', action='store', default='.', help='The top-level directory of the multigit tree (defaults to the current directory)')
|
|
354
|
-
parser.add_argument('--repos', '-r', action='append', default=None, help='The
|
|
399
|
+
parser.add_argument('--repos', '-r', action='append', default=None, help='The repo names to work on (defaults to all repos and can contain shell wildcards and can be issued multiple times on the command line)')
|
|
355
400
|
|
|
356
401
|
subparsers = parser.add_subparsers(dest='command')
|
|
357
402
|
|
|
@@ -362,10 +407,12 @@ def main():
|
|
|
362
407
|
parser_status = subparsers.add_parser('status', help='Report git status in every repo that has something to report')
|
|
363
408
|
parser_fetch = subparsers.add_parser('fetch', help='Run git fetch in every repo')
|
|
364
409
|
parser_pull = subparsers.add_parser('pull', help='Run git pull in every repo')
|
|
410
|
+
|
|
365
411
|
parser_push = subparsers.add_parser('push', help='Run git push in every repo where the current branch isn\'t the default and the most recent commit was by the current user')
|
|
412
|
+
parser_push.add_argument('--force', '-f', action='store_true', help='Use --force-push-with-least to update a remote branch if the local branch has been rebased')
|
|
366
413
|
|
|
367
414
|
parser_checkout = subparsers.add_parser('checkout', help='Checkout the specified branch')
|
|
368
|
-
parser_checkout.add_argument('--create', action='store_true', help='Create the specified branch and check it out')
|
|
415
|
+
parser_checkout.add_argument('--create', '-b', action='store_true', help='Create the specified branch and check it out')
|
|
369
416
|
parser_checkout.add_argument('branch', nargs='?', default=None, action='store', help='The branch name to check out (defaults to the default branch)')
|
|
370
417
|
|
|
371
418
|
parser_commit = subparsers.add_parser('commit', help='Commit changes')
|
|
@@ -373,6 +420,17 @@ def main():
|
|
|
373
420
|
|
|
374
421
|
parser_update = subparsers.add_parser('update', help='Pull the default branch and if the current branch isn\'t the default branch, rebase it onto the default branch')
|
|
375
422
|
|
|
423
|
+
parser_clean = subparsers.add_parser('clean', help='Remove untracked files from the working tree')
|
|
424
|
+
|
|
425
|
+
parser_clean.add_argument('--recurse', '-d', action='store_true', help='Recurse into subdirectories')
|
|
426
|
+
parser_clean.add_argument('--force', '-f', action='store_true', help='If the Git configuration variable clean.requireForce is not set to false, git clean will refuse to delete files or directories unless given -f or -i')
|
|
427
|
+
#parser_clean.add_argument('--interactive', '-i', action='store_true', help='Show what would be done and clean files interactively.')
|
|
428
|
+
parser_clean.add_argument('--dry-run', '-n', action='store_true', help='Don’t actually remove anything, just show what would be done.')
|
|
429
|
+
#parser_clean.add_argument('--quiet', '-q', , action='store_true', help='Be quiet, only report errors, but not the files that are successfully removed.')
|
|
430
|
+
parser_clean.add_argument('--exclude', '-e', action='store', help='Use the given exclude pattern in addition to the standard ignore rules.')
|
|
431
|
+
parser_clean.add_argument('-x', action='store_true', help='Don’t use the standard ignore rules, but still use the ignore rules given with -e options from the command line.')
|
|
432
|
+
parser_clean.add_argument('-X', action='store_true', help='Remove only files ignored by Git. This may be useful to rebuild everything from scratch, but keep manually created files.')
|
|
433
|
+
|
|
376
434
|
# Parse the command line
|
|
377
435
|
|
|
378
436
|
args = parser.parse_args()
|
|
@@ -382,8 +440,6 @@ def main():
|
|
|
382
440
|
if not args.command:
|
|
383
441
|
error('No command specified')
|
|
384
442
|
|
|
385
|
-
# TODO: If the config file isn't in the current directory then search up the directory tree for it but run in the current directory
|
|
386
|
-
|
|
387
443
|
# If the configuration file exists, read it
|
|
388
444
|
|
|
389
445
|
config = configparser.ConfigParser()
|
|
@@ -418,9 +474,14 @@ def multigit():
|
|
|
418
474
|
main()
|
|
419
475
|
except KeyboardInterrupt:
|
|
420
476
|
sys.exit(1)
|
|
477
|
+
|
|
421
478
|
except BrokenPipeError:
|
|
422
479
|
sys.exit(2)
|
|
423
480
|
|
|
481
|
+
except git.GitError as exc:
|
|
482
|
+
print(exc)
|
|
483
|
+
sys.exit(3)
|
|
484
|
+
|
|
424
485
|
################################################################################
|
|
425
486
|
|
|
426
487
|
if __name__ == '__main__':
|
|
@@ -144,7 +144,7 @@ def format(txt):
|
|
|
144
144
|
|
|
145
145
|
################################################################################
|
|
146
146
|
|
|
147
|
-
def write(txt=None, newline=True, stream=sys.stdout, indent=0):
|
|
147
|
+
def write(txt=None, newline=True, stream=sys.stdout, indent=0, strip=False):
|
|
148
148
|
""" Write to the specified stream (defaulting to stdout), converting colour codes to ANSI
|
|
149
149
|
txt can be None, a string or a list of strings."""
|
|
150
150
|
|
|
@@ -155,6 +155,9 @@ def write(txt=None, newline=True, stream=sys.stdout, indent=0):
|
|
|
155
155
|
for n, line in enumerate(txt):
|
|
156
156
|
line = format(line)
|
|
157
157
|
|
|
158
|
+
if strip:
|
|
159
|
+
line = line.strip()
|
|
160
|
+
|
|
158
161
|
if indent:
|
|
159
162
|
stream.write(' ' * indent)
|
|
160
163
|
|
skilleter_thingy/thingy/git2.py
CHANGED
|
@@ -1239,6 +1239,38 @@ def log(branch1, branch2=None):
|
|
|
1239
1239
|
|
|
1240
1240
|
return git(cmd)
|
|
1241
1241
|
|
|
1242
|
+
################################################################################
|
|
1243
|
+
|
|
1244
|
+
def clean(recurse=False, force=False, dry_run=False, quiet=False,
|
|
1245
|
+
exclude=None, ignore_rules=False, remove_only_ignored=False, path=None):
|
|
1246
|
+
|
|
1247
|
+
""" Run git clean """
|
|
1248
|
+
|
|
1249
|
+
cmd = ['clean']
|
|
1250
|
+
|
|
1251
|
+
if recurse:
|
|
1252
|
+
cmd.append('-d')
|
|
1253
|
+
|
|
1254
|
+
if force:
|
|
1255
|
+
cmd.append('--force')
|
|
1256
|
+
|
|
1257
|
+
if dry_run:
|
|
1258
|
+
cmd.append('--dry-run')
|
|
1259
|
+
|
|
1260
|
+
if quiet:
|
|
1261
|
+
cmd.append('--quiet')
|
|
1262
|
+
|
|
1263
|
+
if exclude:
|
|
1264
|
+
cmd += ['--exclude', exclude]
|
|
1265
|
+
|
|
1266
|
+
if ignore_rules:
|
|
1267
|
+
cmd.append('-x')
|
|
1268
|
+
|
|
1269
|
+
if remove_only_ignored:
|
|
1270
|
+
cmd.append('-X')
|
|
1271
|
+
|
|
1272
|
+
return git(cmd, path=path)
|
|
1273
|
+
|
|
1242
1274
|
################################################################################
|
|
1243
1275
|
# Entry point
|
|
1244
1276
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: skilleter_thingy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.77
|
|
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
|
|
@@ -33,16 +33,62 @@ The following commands are documented in detail in the help output that can be d
|
|
|
33
33
|
|
|
34
34
|
This README just contains a summary of the functionality of each command.
|
|
35
35
|
|
|
36
|
+
# Git Utilities
|
|
37
|
+
|
|
38
|
+
## ggit
|
|
39
|
+
|
|
40
|
+
Run a git command in all repos under the current directory
|
|
41
|
+
|
|
42
|
+
## ggrep
|
|
43
|
+
|
|
44
|
+
Run 'git grep' in all repos under the current directory
|
|
45
|
+
|
|
46
|
+
## gitprompt
|
|
47
|
+
|
|
48
|
+
Output a string containing colour-coded shell nesting level, current directory and git working tree status (used in the shell prompt).
|
|
49
|
+
|
|
50
|
+
## git ca
|
|
51
|
+
|
|
52
|
+
Improved version of 'git commit --amend'. Updates files that are already in the commit and, optionally, adds and commits additional files.
|
|
53
|
+
|
|
54
|
+
## git cleanup
|
|
55
|
+
|
|
56
|
+
List or delete branches that have already been merged and delete tracking branches that are no longer on ther remote.
|
|
57
|
+
|
|
58
|
+
## git co
|
|
59
|
+
|
|
60
|
+
Equivalent to 'git checkout' but with intelligent branch matching
|
|
61
|
+
|
|
62
|
+
## git mr
|
|
63
|
+
|
|
64
|
+
Push a feature branch to GitLab and create a merge request
|
|
65
|
+
|
|
66
|
+
## git parent
|
|
67
|
+
|
|
68
|
+
Attempt to determine the parent branch for the specified branch (defaulting to the current one)
|
|
69
|
+
|
|
70
|
+
## git update
|
|
71
|
+
|
|
72
|
+
Update the repo from the remote, rebase branches against their parents, optionally run git cleanup
|
|
73
|
+
|
|
74
|
+
## git wt
|
|
75
|
+
|
|
76
|
+
Output the top level directory of the git working tree or return an error if we are not in a git working tree.
|
|
77
|
+
|
|
78
|
+
## git review
|
|
79
|
+
|
|
80
|
+
Console-based git change review tool.
|
|
81
|
+
|
|
82
|
+
## multigit
|
|
83
|
+
|
|
84
|
+
Manage a collection of related git repoitories.
|
|
85
|
+
|
|
36
86
|
# General Commands
|
|
37
87
|
|
|
38
88
|
## addpath
|
|
39
89
|
|
|
40
90
|
Update a $PATH-type variable by adding or removing entries.
|
|
41
91
|
|
|
42
|
-
## borger
|
|
43
|
-
|
|
44
|
-
Wrapper for the borg backup utility to make it easier to use with a fixed set of options.
|
|
45
|
-
|
|
46
92
|
## console-colours
|
|
47
93
|
|
|
48
94
|
Display all available colours in the console.
|
|
@@ -63,33 +109,10 @@ Simple file find utility
|
|
|
63
109
|
|
|
64
110
|
Implements the functionality of the find command that is regularly used in a simpler fashion and ignores all the options that nobody ever uses.
|
|
65
111
|
|
|
66
|
-
## gl
|
|
67
|
-
|
|
68
|
-
### gphotosync
|
|
69
|
-
|
|
70
|
-
Utility for syncing photos from Google Photos to local storage
|
|
71
|
-
|
|
72
112
|
## linecount
|
|
73
113
|
|
|
74
114
|
Count lines of code in a directory tree organised by file type.
|
|
75
115
|
|
|
76
|
-
## moviemover
|
|
77
|
-
|
|
78
|
-
Search for files matching a wildcard in a directory tree and move them to an equivalent location in a different tree
|
|
79
|
-
|
|
80
|
-
## phototidier
|
|
81
|
-
|
|
82
|
-
Perform various tidying operations on a directory full of photos:
|
|
83
|
-
|
|
84
|
-
* Remove leading '$' and '_' from filenames
|
|
85
|
-
* Move files in hidden directories up 1 level
|
|
86
|
-
* If the EXIF data in a photo indicates that it was taken on date that doesn't match the name of the directory it is stored in (in YYYY-MM-DD format) then it is moved to the correct directory, creating it if necessary.
|
|
87
|
-
|
|
88
|
-
All move/rename operations are carried out safely with the file being moved having
|
|
89
|
-
a numeric suffix added to the name if it conflicts with an existing file.
|
|
90
|
-
|
|
91
|
-
## photodupe
|
|
92
|
-
|
|
93
116
|
## py-audit
|
|
94
117
|
|
|
95
118
|
Query api.osv.dev to determine whether a specified version of a particular Python package is subject to known security vulnerabilities
|
|
@@ -114,16 +137,10 @@ Run pylint on all the Python source files in the current tree
|
|
|
114
137
|
|
|
115
138
|
Synchronise files from S3 to local storage.
|
|
116
139
|
|
|
117
|
-
## splitpics
|
|
118
|
-
|
|
119
|
-
Copy a directory full of pictures to a destination, creating subdiretories with a fixed number of pictures in each in the destination directory for use with FAT filesystems and digital photo frames.
|
|
120
|
-
|
|
121
140
|
## strreplace
|
|
122
141
|
|
|
123
142
|
Simple search and replace utility for those times when trying to escape characters in a regexp to use sed is more hassle than it is worth.
|
|
124
143
|
|
|
125
|
-
## sysmon
|
|
126
|
-
|
|
127
144
|
## tfm
|
|
128
145
|
|
|
129
146
|
Console-based file-manager, similar to Midnight Commander but better.
|
|
@@ -138,7 +155,9 @@ no way of doing this directly from Terraform
|
|
|
138
155
|
|
|
139
156
|
Intelligently trim a path to fit a given width (used by gitprompt)
|
|
140
157
|
|
|
141
|
-
##
|
|
158
|
+
## venv-create
|
|
159
|
+
|
|
160
|
+
Create a script to create/update a virtual environment and run a python script in it.
|
|
142
161
|
|
|
143
162
|
## xchmod
|
|
144
163
|
|
|
@@ -150,44 +169,49 @@ Currently implements a *very* restricted set of functionality.
|
|
|
150
169
|
|
|
151
170
|
YAML validator - checks that a file is valid YAML (use yamllint to verify that it is nicely-formatted YAML).
|
|
152
171
|
|
|
153
|
-
#
|
|
172
|
+
# Obsolescent Utilities
|
|
154
173
|
|
|
155
|
-
|
|
174
|
+
These will be moved to the skilleter-extras package in due course.
|
|
156
175
|
|
|
157
|
-
|
|
176
|
+
## borger
|
|
158
177
|
|
|
159
|
-
|
|
178
|
+
Wrapper for the borg backup utility to make it easier to use with a fixed set of options.
|
|
160
179
|
|
|
161
|
-
|
|
180
|
+
## gl
|
|
162
181
|
|
|
163
|
-
|
|
182
|
+
Command line for GitLab
|
|
164
183
|
|
|
165
|
-
|
|
184
|
+
## gphotosync
|
|
166
185
|
|
|
167
|
-
|
|
186
|
+
Utility for syncing photos from Google Photos to local storage
|
|
168
187
|
|
|
169
|
-
|
|
188
|
+
## moviemover
|
|
170
189
|
|
|
171
|
-
|
|
190
|
+
Search for files matching a wildcard in a directory tree and move them to an equivalent location in a different tree
|
|
172
191
|
|
|
173
|
-
|
|
192
|
+
## phototidier
|
|
174
193
|
|
|
175
|
-
|
|
194
|
+
Perform various tidying operations on a directory full of photos:
|
|
176
195
|
|
|
177
|
-
|
|
196
|
+
* Remove leading '$' and '_' from filenames
|
|
197
|
+
* Move files in hidden directories up 1 level
|
|
198
|
+
* If the EXIF data in a photo indicates that it was taken on date that doesn't match the name of the directory it is stored in (in YYYY-MM-DD format) then it is moved to the correct directory, creating it if necessary.
|
|
178
199
|
|
|
179
|
-
|
|
200
|
+
All move/rename operations are carried out safely with the file being moved having
|
|
201
|
+
a numeric suffix added to the name if it conflicts with an existing file.
|
|
180
202
|
|
|
181
|
-
##
|
|
203
|
+
## photodupe
|
|
182
204
|
|
|
183
|
-
|
|
205
|
+
Search for duplicate images in a directory tree
|
|
184
206
|
|
|
185
|
-
##
|
|
207
|
+
## splitpics
|
|
186
208
|
|
|
187
|
-
|
|
209
|
+
Copy a directory full of pictures to a destination, creating subdiretories with a fixed number of pictures in each in the destination directory for use with FAT filesystems and digital photo frames.
|
|
188
210
|
|
|
189
|
-
##
|
|
211
|
+
## sysmon
|
|
190
212
|
|
|
191
|
-
|
|
213
|
+
Simple console system monitor
|
|
192
214
|
|
|
193
|
-
|
|
215
|
+
## window-rename
|
|
216
|
+
|
|
217
|
+
Monitor window titles and rename them to fit an alphabetical grouping in 'Appname - Document' format.
|
|
@@ -25,7 +25,7 @@ skilleter_thingy/gl.py,sha256=9zbGpKxw6lX9RghLkdy-Q5sZlqtbB3uGFO04qTu1dH8,5954
|
|
|
25
25
|
skilleter_thingy/gphotosync.py,sha256=Vb2zYTEFp26BYdkG810SRg9afyfDqvq4CLHTk-MFf60,22388
|
|
26
26
|
skilleter_thingy/linecount.py,sha256=5voQtjJjDCVx4zjPwVRy620NpuLiwwFitzxjIsRGtxQ,4310
|
|
27
27
|
skilleter_thingy/moviemover.py,sha256=j_Xb9_jFdgpFBAXcF4tEqbnKH_FonlnUU39LiCK980k,4470
|
|
28
|
-
skilleter_thingy/multigit.py,sha256=
|
|
28
|
+
skilleter_thingy/multigit.py,sha256=DES_T2XpyR82jR30e26KvrXMgmSepUhSiSffjTru1AU,19026
|
|
29
29
|
skilleter_thingy/photodupe.py,sha256=l0hbzSLb2Vk2ceteg-x9fHXCEE1uUuFo84hz5rsZUPA,4184
|
|
30
30
|
skilleter_thingy/phototidier.py,sha256=5gSjlINUxf3ZQl3NG0o7CsWwODvTbokIMIafLFvn8Hc,7818
|
|
31
31
|
skilleter_thingy/py_audit.py,sha256=xJm5k5qyeA6ii8mODa4dOkmP8L1drv94UHuxR54RsIM,4384
|
|
@@ -44,7 +44,7 @@ skilleter_thingy/window_rename.py,sha256=dCBgZqih_3YKHt35hsOAhARFp3QxOi8w8huC63s
|
|
|
44
44
|
skilleter_thingy/xchmod.py,sha256=F9_lxKuLqVlHHr3oBI3dkMoFOuwRzYDlpQMTmDcjpBI,4590
|
|
45
45
|
skilleter_thingy/yamlcheck.py,sha256=FXylZ5NtHirDlPVhVEUZUZkTugVR-g51BbjaN06akAc,2868
|
|
46
46
|
skilleter_thingy/thingy/__init__.py,sha256=rVPTxm8L5w52U0YdTd7r_D44SBP7pS3JCJtsf0iIsow,110
|
|
47
|
-
skilleter_thingy/thingy/colour.py,sha256
|
|
47
|
+
skilleter_thingy/thingy/colour.py,sha256=-I5HOfWZNVxN85DjNPpzYLIUlzGrzMr3oLRwim7O6us,7103
|
|
48
48
|
skilleter_thingy/thingy/dc_curses.py,sha256=fuuQPR11zV_akAhygL_cAhVLC5YAgKgowzlITVbETE8,8539
|
|
49
49
|
skilleter_thingy/thingy/dc_defaults.py,sha256=ahcteQvoWZrO5iTU68zkIY1Zex6iX5uR5ubwI4CCYBk,6170
|
|
50
50
|
skilleter_thingy/thingy/dc_util.py,sha256=Df73imXhHx3HzcPHiRcHAoea0e3HURdLcrolUsMhOFs,1783
|
|
@@ -52,7 +52,7 @@ skilleter_thingy/thingy/dircolors.py,sha256=5NbXMsGWdABLvvZfB70VPmN6N5HyyihfpgoQ
|
|
|
52
52
|
skilleter_thingy/thingy/docker.py,sha256=9EFatudoVPfB1UbDEtzdJDB3o6ToHiNHv8-oLsUeqiQ,2449
|
|
53
53
|
skilleter_thingy/thingy/files.py,sha256=oW6E6WWwVFSUPdrZnKMx7P_w_hh3etjoN7RrqvYHCHc,4705
|
|
54
54
|
skilleter_thingy/thingy/git.py,sha256=qXWIduF4jbP5pKFYt_hW9Ex5iL9mSBBrcNKBkULhRTg,38834
|
|
55
|
-
skilleter_thingy/thingy/git2.py,sha256=
|
|
55
|
+
skilleter_thingy/thingy/git2.py,sha256=UEXeSyT5PlYGtdUAQDEZC7Sc7JmYdAlP6osa1tVmpO8,36620
|
|
56
56
|
skilleter_thingy/thingy/gitlab.py,sha256=uXAF918xnPk6qQyiwPQDbMZfqtJzhiRqDS7yEtJEIAg,6079
|
|
57
57
|
skilleter_thingy/thingy/path.py,sha256=8uM2Q9zFRWv_SaVOX49PeecQXttl7J6lsmBuRXWsXKY,4732
|
|
58
58
|
skilleter_thingy/thingy/popup.py,sha256=jW-nbpdeswqEMTli7OmBv1J8XQsvFoMI0J33O6dOeu8,2529
|
|
@@ -61,9 +61,9 @@ skilleter_thingy/thingy/run.py,sha256=6SNKWF01fSxzB10GMU9ajraXYZqAL1w0PXkqjJdr1U
|
|
|
61
61
|
skilleter_thingy/thingy/tfm_pane.py,sha256=oqy5zBzKwfbjbGqetbbhpKi4x5He7sl4qkmhUeqtdZc,19789
|
|
62
62
|
skilleter_thingy/thingy/tidy.py,sha256=71DCyj0VJrj52RmjQyj1eOiQJIfy5EIPHuThOrS6ZTA,5876
|
|
63
63
|
skilleter_thingy/thingy/venv_template.py,sha256=SsVNvSwojd8NnFeQaZPCRQYTNdwJRplpZpygbUEXRnY,1015
|
|
64
|
-
skilleter_thingy-0.0.
|
|
65
|
-
skilleter_thingy-0.0.
|
|
66
|
-
skilleter_thingy-0.0.
|
|
67
|
-
skilleter_thingy-0.0.
|
|
68
|
-
skilleter_thingy-0.0.
|
|
69
|
-
skilleter_thingy-0.0.
|
|
64
|
+
skilleter_thingy-0.0.77.dist-info/LICENSE,sha256=ljOS4DjXvqEo5VzGfdaRwgRZPbNScGBmfwyC8PChvmQ,32422
|
|
65
|
+
skilleter_thingy-0.0.77.dist-info/METADATA,sha256=OuTAQKPCHRzc4K-j1oHaFnpO8piPz-pKO5uT-0uPs3s,5938
|
|
66
|
+
skilleter_thingy-0.0.77.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
67
|
+
skilleter_thingy-0.0.77.dist-info/entry_points.txt,sha256=uW11ofmIbfPP_5B-pxb8YDkHbeZ_xeCoO6358R9wGVI,2146
|
|
68
|
+
skilleter_thingy-0.0.77.dist-info/top_level.txt,sha256=8-JhgToBBiWURunmvfpSxEvNkDHQQ7r25-aBXtZv61g,17
|
|
69
|
+
skilleter_thingy-0.0.77.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|