dotfiles/hm/scripts/archive

194 lines
6.2 KiB
Plaintext
Raw Permalink Normal View History

#!/usr/bin/env nix-shell
#! nix-shell -i python3 --pure
#! nix-shell -p python3 python3Packages.coloredlogs
2017-10-30 11:44:12 +01:00
import argparse
2018-10-06 10:27:36 +02:00
import logging
import os
import sys
2023-11-23 22:59:09 +01:00
import coloredlogs
2021-06-13 11:49:21 +02:00
coloredlogs.install(level="DEBUG", fmt="%(levelname)s %(message)s")
2018-10-06 10:27:36 +02:00
log = logging.getLogger()
2017-10-30 11:44:12 +01:00
2018-10-06 10:27:36 +02:00
# Coding conventions:
# No leading or trailing slashes. Let os.path.join do its job
# TODO Config arparse and pass args to the functions. No globals
2017-10-30 11:44:12 +01:00
# Finding directories
2021-06-13 11:49:21 +02:00
assert "HOME" in os.environ, "Home directory unknown"
DOCS = os.path.realpath(os.path.join(os.environ["HOME"], "Documents"))
2018-10-06 10:27:36 +02:00
assert os.path.isdir(DOCS), "Documents folder not found"
2021-06-13 11:49:21 +02:00
ARCS = os.path.realpath(os.path.join(os.environ["HOME"], "Archives"))
2018-10-06 10:27:36 +02:00
assert os.path.isdir(ARCS), "Archives folder not found"
def dirRange(relpath):
splits = relpath.split(os.path.sep)
res = list()
for p in range(len(splits)):
2021-06-13 11:49:21 +02:00
partPath = os.path.join(*splits[: p + 1])
2018-10-06 10:27:36 +02:00
arcPath = os.path.join(os.path.join(ARCS, partPath))
docPath = os.path.join(os.path.join(DOCS, partPath))
res.append((docPath, arcPath))
return res
2021-06-13 11:49:21 +02:00
2018-10-06 10:27:36 +02:00
def travel(relpath):
"""
Dunno what this will do, let's write code and see.
"""
wholeRange = dirRange(relpath)
for tup in wholeRange:
isLast = wholeRange[-1] == tup
docPath, arcPath = tup
linkPath = os.path.relpath(arcPath, start=docPath)
log.debug(f"47 {tup}")
if not os.path.exists(docPath) and not os.path.exists(arcPath):
log.error("Not existing")
sys.exit(1)
elif os.path.isdir(docPath) and os.path.isdir(arcPath) and not isLast:
log.debug("Both folder")
continue
elif os.path.isdir(docPath) and os.path.isdir(arcPath) and isLast:
log.error("This should fail for some reason, maybe")
sys.exit(1)
elif os.path.islink(docPath) and os.path.exists(arcPath):
currentLink = os.readlink(docPath)
if currentLink != linkPath:
2021-06-13 11:49:21 +02:00
log.warning(
f"'{docPath}' is pointing to '{currentLink}' "
+ f"but should point to '{linkPath}'."
)
2018-10-06 10:27:36 +02:00
# TODO Fixing if asked for
sys.exit(1)
log.debug("Early link already exists {docPath} → {arcPath}")
return
elif not os.path.exists(docPath) and os.path.exists(arcPath):
log.debug("Only existing on archive side, linking")
print(f"ln -s {linkPath} {docPath}")
2021-06-13 11:49:21 +02:00
elif os.path.exists(docPath) and not os.path.exists(arcPath) and isLast:
2018-10-06 10:27:36 +02:00
log.debug("Only existing on doc side, moving and linking")
print(f"mv {docPath} {arcPath}")
print(f"ln -s {linkPath} {docPath}")
2021-06-13 11:49:21 +02:00
elif os.path.exists(docPath) and not os.path.exists(arcPath) and not isLast:
2018-10-06 10:27:36 +02:00
raise NotImplementedError("Here comes the trouble")
else:
log.error("Unhandled case")
sys.exit(1)
def ensureLink(relpath):
"""
Ensure that ~/Documents/$relpath points to ~/Archives/$relpath
"""
arcPath = os.path.join(os.path.join(ARCS, relpath))
docPath = os.path.join(os.path.join(DOCS, relpath))
assert os.path.exists(arcPath)
# For each tree element of the path
for docPath, arcPath in dirRange(relpath):
linkPath = os.path.relpath(arcPath, start=docPath)
def installLink():
if args.dry:
print(f"ln -s {linkPath} {docPath}")
else:
os.symlink(linkPath, docPath)
if os.path.islink(docPath):
currentLink = os.readlink(docPath)
if currentLink != linkPath:
2021-06-13 11:49:21 +02:00
log.warning(
f"'{docPath}' is pointing to '{currentLink}' "
+ f"but should point to '{linkPath}'. Fixing"
)
2018-10-06 10:27:36 +02:00
if args.dry:
print(f"rm {docPath}")
else:
os.unlink(docPath)
installLink()
return
elif not os.path.exists(docPath):
installLink()
return
elif os.path.isdir(docPath):
continue
else:
2021-06-13 11:49:21 +02:00
raise RuntimeError(
f"'{docPath}' exists and is not a directory "
+ f"or a link. Unable to link it to '{linkPath}'"
)
raise RuntimeError(
f"'{docPath}' is a directory. Unable to link it to " + f"'{linkPath}'"
)
2018-10-06 10:27:36 +02:00
2017-10-30 11:44:12 +01:00
2018-01-08 12:26:49 +01:00
def archive(docdir):
docdir = os.path.realpath(args.dir)
2018-10-06 10:27:36 +02:00
assert os.path.isdir(docdir), docdir + " must be a directory"
2018-01-08 12:26:49 +01:00
2018-10-06 10:27:36 +02:00
assert docdir.startswith(DOCS), "Directory is not in the document folder"
assert not docdir.startswith(ARCS), "Directory is already in the archive folder"
2018-01-08 12:26:49 +01:00
2018-10-06 10:27:36 +02:00
reldir = os.path.relpath(docdir, DOCS)
2018-01-08 12:26:49 +01:00
print("ARC", reldir)
2018-10-06 10:27:36 +02:00
arcdir = os.path.join(ARCS, reldir)
2021-06-13 11:49:21 +02:00
parentArcdir = os.path.realpath(os.path.join(arcdir, ".."))
parentDocdir = os.path.realpath(os.path.join(docdir, ".."))
2018-01-08 12:26:49 +01:00
linkDest = os.path.relpath(arcdir, parentDocdir)
# BULLSHIT
# If the directory exists
if os.path.isdir(arcdir):
return
2018-10-06 10:27:36 +02:00
# for f in os.listdir(arcdir):
# assert os.path.isdir(f), "Something unknown in Archive dir")
# archive(os.path.join(arcdir, f))
2018-01-08 12:26:49 +01:00
# If the directory doesn't exist, create the directories under it and move all the folder
else:
if args.dry:
print("mkdir -p", parentArcdir)
else:
os.makedirs(parentArcdir, exist_ok=True)
if args.dry:
print("mv", docdir, arcdir)
else:
os.rename(docdir, arcdir)
if args.dry:
print("ln -s", linkDest, docdir)
else:
os.symlink(linkDest, docdir)
def unarchive(arcdir):
2018-10-06 10:27:36 +02:00
pass
if __name__ == "__main__":
2021-06-13 11:49:21 +02:00
parser = argparse.ArgumentParser(
description="Place a folder in ~/Documents in ~/Documents/Archives and symlink it"
)
parser.add_argument(
"dir", metavar="DIRECTORY", type=str, help="The directory to archive"
)
parser.add_argument("-d", "--dry", action="store_true")
2018-10-06 10:27:36 +02:00
args = parser.parse_args()
2021-06-13 11:49:21 +02:00
args.dry = True # DEBUG
2017-10-30 11:44:12 +01:00
2018-10-06 10:27:36 +02:00
# archive(args.dir)
ensureLink(args.dir)