new spanking
This commit is contained in:
167
flit.py
167
flit.py
@@ -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,38 +33,35 @@ 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',
|
||||
"--verbose",
|
||||
"-v",
|
||||
action="store_true",
|
||||
dest="verbose",
|
||||
default=False,
|
||||
help = 'Increase verbosity'
|
||||
help="Increase verbosity",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--root', '-r',
|
||||
"--root",
|
||||
"-r",
|
||||
action="store",
|
||||
dest="root",
|
||||
type=str,
|
||||
default="",
|
||||
help = 'Root address for printing URLS'
|
||||
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'
|
||||
dest="days",
|
||||
)
|
||||
add_parser.add_argument(
|
||||
"-m",
|
||||
@@ -73,7 +69,7 @@ def parse_opts():
|
||||
type=str,
|
||||
help="Describe share",
|
||||
default="-",
|
||||
dest = 'description'
|
||||
dest="description",
|
||||
)
|
||||
add_parser.add_argument(
|
||||
"files",
|
||||
@@ -81,27 +77,29 @@ def parse_opts():
|
||||
type=str,
|
||||
help="Copy files/folders under the new share",
|
||||
default=[],
|
||||
nargs = '*'
|
||||
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',
|
||||
"--verbose",
|
||||
"-v",
|
||||
action="store_true",
|
||||
dest="verbose",
|
||||
default=False,
|
||||
help = 'Print individual files too'
|
||||
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,10 +135,7 @@ 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,
|
||||
@@ -144,19 +143,20 @@ def copy_files(cwd, new_name, files):
|
||||
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()
|
||||
@@ -166,19 +166,26 @@ def get_stats(p):
|
||||
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,67 +195,65 @@ 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()
|
||||
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(" {}/{}/{}".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:
|
||||
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))
|
||||
@@ -261,5 +266,3 @@ if __name__ == '__main__':
|
||||
|
||||
if opts.command == "del":
|
||||
del_due_folders()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user