Last active
June 21, 2018 20:48
-
-
Save krig/a67d8f0d65843a3ff237409f7d9a87e7 to your computer and use it in GitHub Desktop.
Get files out of git-annex without any dependencies except Python 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# | |
# A small utility for pulling files out of git-annex without | |
# actually having git-annex installed, with minimal | |
# dependencies. | |
import sys | |
import os | |
import argparse | |
import shutil | |
import hashlib | |
def print_win(f): | |
try: | |
print(f) | |
except UnicodeEncodeError: | |
print(f.encode('utf-8', 'surrogateescape').decode('ISO-8859-1')) | |
def parseargs(): | |
parser = argparse.ArgumentParser(description='Extract files from a git-annex.') | |
parser.add_argument('--to', dest='output', required=True, | |
help='path to the output directory') | |
parser.add_argument('--from', dest='annex', required=True, | |
help='path to the git annex') | |
parser.add_argument('--action', dest='action', choices=['copy', 'move', 'none'], default='none', | |
help='action to perform for each file') | |
return parser.parse_args() | |
def do_copy(src, dst): | |
print_win("cp {} {}".format(src, dst)) | |
try: | |
shutil.copy2(src, dst) | |
return True | |
except shutil.Error as err: | |
print(err) | |
return False | |
except PermissionError as err: | |
print(err) | |
return False | |
def do_remove(src): | |
print_win("rm {}".format(src)) | |
try: | |
os.remove(src) | |
return True | |
except OSError as err: | |
print(err) | |
return False | |
def main(): | |
args = parseargs() | |
output = args.output | |
annex = args.annex | |
action = args.action | |
tgttail = len(annex) | |
for dirpath, dirnames, filenames in os.walk(annex): | |
if dirpath.startswith(os.path.join(annex, ".git")): | |
continue | |
target = output + dirpath[tgttail:] | |
if not os.path.isdir(target): | |
print_win("mkdir {}".format(target)) | |
if action in ['copy', 'move']: | |
os.mkdir(target) | |
for f in filenames: | |
src = os.path.join(dirpath, f) | |
dst = os.path.join(target, f) | |
if os.path.exists(dst): | |
if action == 'move' and os.path.exists(src): | |
print_win("md5sum {} ...".format(src)) | |
m = hashlib.md5() | |
m.update(open(src, 'rb').read()) | |
srcdigest = m.digest() | |
print_win("md5sum {} ...".format(dst)) | |
m = hashlib.md5() | |
m.update(open(dst, 'rb').read()) | |
dstdigest = m.digest() | |
if srcdigest == dstdigest: | |
if do_remove(dst) and do_copy(src, dst) and action == 'move': | |
do_remove(src) | |
else: | |
print_win("diff! ls -l \"{}\" \"{}\"".format(src, dst)) | |
else: | |
if action in ['copy', 'move']: | |
if do_copy(src, dst) and action == 'move': | |
do_remove(src) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment