new spanking

This commit is contained in:
Ville Rantanen
2020-12-28 22:51:17 +02:00
parent 9c1fab0d21
commit 906f6fd457

229
flit.py
View File

@@ -3,16 +3,14 @@
from datetime import datetime, timedelta
import argparse
import os
import sys
import random
import shutil
import string
from urllib.parse import quote
import json
DEL_TIME = '.delete_in'
DESCRIPTION = '.description'
CONFIG = '.flit.json'
CONFIG = ".flit.json"
def parse_opts():
class _HelpAction(argparse._HelpAction):
@@ -21,7 +19,8 @@ def parse_opts():
print("")
# retrieve subparsers from parser
subparsers_actions = [
action for action in parser._actions
action
for action in parser._actions
if isinstance(action, argparse._SubParsersAction)
]
for subparsers_action in subparsers_actions:
@@ -34,74 +33,73 @@ def parse_opts():
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument(
'--help', '-h',
action = _HelpAction,
help = 'Show this help message and exit'
"--help", "-h", action=_HelpAction, help="Show this help message and exit"
)
parser.add_argument(
'--verbose', '-v',
action = "store_true",
dest = "verbose",
default = False,
help = 'Increase verbosity'
"--verbose",
"-v",
action="store_true",
dest="verbose",
default=False,
help="Increase verbosity",
)
parser.add_argument(
'--root', '-r',
action = "store",
dest = "root",
type = str,
default = "",
help = 'Root address for printing URLS'
"--root",
"-r",
action="store",
dest="root",
type=str,
default="",
help="Root address for printing URLS",
)
subparsers = parser.add_subparsers(
dest="command",
help = "Command defaults to add"
)
add_parser = subparsers.add_parser('add', add_help=False)
subparsers = parser.add_subparsers(dest="command", help="Command defaults to add")
add_parser = subparsers.add_parser("add", add_help=False)
add_parser.add_argument(
"-d",
action = "store",
type = int,
help = "Days to keep files",
default = 30,
dest = 'days'
action="store",
type=int,
help="Days to keep files",
default=30,
dest="days",
)
add_parser.add_argument(
"-m",
action = "store",
type = str,
help = "Describe share",
default = "-",
dest = 'description'
action="store",
type=str,
help="Describe share",
default="-",
dest="description",
)
add_parser.add_argument(
"files",
action = "store",
type = str,
help = "Copy files/folders under the new share",
default = [],
nargs = '*'
action="store",
type=str,
help="Copy files/folders under the new share",
default=[],
nargs="*",
)
list_parser = subparsers.add_parser('list', add_help=False)
list_parser = subparsers.add_parser("list", add_help=False)
list_parser.add_argument(
'--verbose', '-v',
action = "store_true",
dest = "verbose",
default = False,
help = 'Print individual files too'
"--verbose",
"-v",
action="store_true",
dest="verbose",
default=False,
help="Print individual files too",
)
del_parser = subparsers.add_parser('del', add_help=False)
del_parser = subparsers.add_parser("del", add_help=False)
return parser.parse_args()
def random_char():
return random.choice(string.ascii_uppercase + string.digits)
def random_name():
while True:
existing_names = get_folder_names()
existing_names = [c["name"] for c in get_folders()]
index = 0
for existing in existing_names:
try:
@@ -112,7 +110,7 @@ def random_name():
name = "{:03d}-{}-{}".format(
index,
"".join([random_char() for x in range(3)]),
"".join([random_char() for x in range(3)])
"".join([random_char() for x in range(3)]),
)
if not os.path.exists(name):
break
@@ -121,10 +119,14 @@ def random_name():
def create_new(p, days, description):
os.mkdir(p)
with open(os.path.join(p, DEL_TIME), 'wt') as fp:
fp.write(str(days))
with open(os.path.join(p, DESCRIPTION), 'wt') as fp:
fp.write(description)
now = datetime.now()
del_delta = timedelta(days=days)
del_time = now + del_delta
config = {}
config["description"] = description
config["delete_time"] = del_time.isoformat()
config["created"] = now.isoformat()
write_config(p, config)
def copy_files(cwd, new_name, files):
@@ -133,52 +135,57 @@ def copy_files(cwd, new_name, files):
print(f"Copying: {f}")
source = os.path.join(cwd, f)
if os.path.isfile(source):
shutil.copy2(
source,
target
)
shutil.copy2(source, target)
else:
shutil.copytree(
source,
os.path.join(target,f),
symlinks = True,
os.path.join(target, f),
symlinks=True,
)
def get_description(f):
try:
with open(f) as fp:
return "".join(filter(lambda x: x in string.printable, fp.read(32).split("\n")[0]))
except:
return "-"
# def get_description(f):
# try:
# with open(f) as fp:
# return "".join(filter(lambda x: x in string.printable, fp.read(32).split("\n")[0]))
# except:
# return "-"
def get_stats(p):
# TODO: named tuple
config = read_config(p)
if config is None:
with open(os.path.join(p, DEL_TIME), 'rt') as fp:
with open(os.path.join(p, DEL_TIME), "rt") as fp:
do_del = int(fp.read(64))
desc = get_description(os.path.join(p, DESCRIPTION))
now = datetime.now()
mtime = datetime.fromtimestamp( os.path.getmtime(os.path.join(p, DEL_TIME)) )
del_delta = timedelta(days = do_del)
mtime = datetime.fromtimestamp(os.path.getmtime(os.path.join(p, DEL_TIME)))
del_delta = timedelta(days=do_del)
del_time = mtime + del_delta
to_del_time = del_time - now
is_due = now > del_time
config = {}
config['description'] = desc
config['delete_time'] = del_time.isoformat()
config['created'] = mtime.isoformat()
config["description"] = desc
config["delete_time"] = del_time
config["created"] = mtime
else:
desc = config['description']
del_time = datetime.fromisoformat(config['delete_time'])
desc = config["description"]
del_time = datetime.fromisoformat(config["delete_time"])
now = datetime.now()
mtime = datetime.fromisoformat(config['created'])
mtime = datetime.fromisoformat(config["created"])
to_del_time = del_time - now
is_due = now > del_time
config["delete_time"] = del_time
config["created"] = mtime
config["name"] = p
config["to_deletion"] = to_del_time
config["due"] = is_due
write_config(p, config)
return mtime, del_time, to_del_time, is_due, desc
# mtime, del_time, to_del_time, is_due, desc
# write_config(p, config)
return config
def get_sub_files(p):
@@ -188,78 +195,74 @@ def get_sub_files(p):
return dir_list + file_list
def get_folder_names():
dir_list = [(p,os.path.getmtime(os.path.join(p, DEL_TIME))) for p in os.listdir(".") if os.path.exists(os.path.join(p, DEL_TIME))]
dir_list.sort(key = lambda t: -t[1])
return [p[0] for p in dir_list]
def get_folders():
dir_list = [p for p in os.listdir(".") if os.path.exists(os.path.join(p, CONFIG))]
configs = [get_stats(p) for p in dir_list]
configs.sort(key=lambda c: c["created"], reverse=True)
return configs
def list_folders(root_folder, verbose = False, filter_name = None):
names = get_folder_names()
def list_folders(root_folder, verbose=False, filter_name=None):
folders = get_folders()
print("Folder Created ToDelete InDays")
for p in names:
for c in folders:
if filter_name is not None:
if filter_name != p:
if filter_name != c["name"]:
continue
stats = get_stats(p)
sub_files = get_sub_files(p)
due = "*" if stats[3] else " "
print("{}/{}/ {} {} {: 4d}d{} {}".format(
due = "*" if c["due"] else " "
print(
"{}/{}/ {} {} {: 4d}d{} {}".format(
root_folder,
p,
stats[0].isoformat()[0:10],
stats[1].isoformat()[0:10],
stats[2].days,
c["name"],
c["created"].isoformat()[0:10],
c["delete_time"].isoformat()[0:10],
c["to_deletion"].days,
due,
stats[4]
))
c["description"],
)
)
if verbose:
sub_files = get_sub_files(c["name"])
for sp in sub_files:
print(" {}/{}/{}".format(root_folder,p,quote(sp,"/")))
#print(p, stats, sub_files)
print(" {}/{}/{}".format(root_folder, c["name"], quote(sp, "/")))
# print(p, stats, sub_files)
def del_due_folders():
names = get_folder_names()
for p in names:
stats = get_stats(p)
due = stats[3]
if due:
print("Deleting {}".format(p))
shutil.rmtree(p)
folders = get_folders()
for c in folders:
if c["due"]:
print("Deleting {}".format(c["name"]))
shutil.rmtree(c["name"])
def read_config(p):
try:
with open(os.path.join(p,CONFIG),'rt') as fp:
with open(os.path.join(p, CONFIG), "rt") as fp:
return json.load(fp)
except:
return None
def write_config(p, config):
with open(os.path.join(p,CONFIG),'wt') as fp:
return json.dump(config, fp, indent=2,sort_keys=True)
with open(os.path.join(p, CONFIG), "wt") as fp:
return json.dump(config, fp, indent=2, sort_keys=True)
if __name__ == '__main__':
if __name__ == "__main__":
opts = parse_opts()
cwd = os.getcwd()
os.chdir(os.path.dirname(__file__))
if opts.command == 'add':
if opts.command == "add":
new_name = random_name()
create_new(new_name, opts.days, opts.description)
print(os.path.abspath(new_name))
print("")
copy_files(cwd, new_name, opts.files)
list_folders(opts.root, verbose = True, filter_name = new_name)
list_folders(opts.root, verbose=True, filter_name=new_name)
if opts.command == "list" or opts.command is None:
list_folders(opts.root, verbose = opts.verbose)
list_folders(opts.root, verbose=opts.verbose)
if opts.command == "del":
del_due_folders()