wooo
This commit is contained in:
13
README.md
Normal file
13
README.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# FLIT
|
||||||
|
|
||||||
|
create fluttering folders
|
||||||
|
|
||||||
|
- flit add [days]
|
||||||
|
- create folder with 30 days or specified life time
|
||||||
|
- flit list
|
||||||
|
- list folders with due dates
|
||||||
|
- flit del
|
||||||
|
- delete due folders
|
||||||
|
|
||||||
|
hint: add `flit del` to cron.daily
|
||||||
|
|
||||||
5
flit
Executable file
5
flit
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
cd $( dirname $( readlink -f $0 ) )
|
||||||
|
python3 flit.py "$@"
|
||||||
144
flit.py
Executable file
144
flit.py
Executable file
@@ -0,0 +1,144 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
import shutil
|
||||||
|
import string
|
||||||
|
|
||||||
|
DEL_TIME = '.delete_in'
|
||||||
|
|
||||||
|
def parse_opts():
|
||||||
|
class _HelpAction(argparse._HelpAction):
|
||||||
|
def __call__(self, parser, namespace, values, option_string=None):
|
||||||
|
parser.print_help()
|
||||||
|
print("")
|
||||||
|
# retrieve subparsers from parser
|
||||||
|
subparsers_actions = [
|
||||||
|
action for action in parser._actions
|
||||||
|
if isinstance(action, argparse._SubParsersAction)
|
||||||
|
]
|
||||||
|
for subparsers_action in subparsers_actions:
|
||||||
|
# get all subparsers and print help
|
||||||
|
for choice, subparser in subparsers_action.choices.items():
|
||||||
|
print("Command: {}".format(choice))
|
||||||
|
print(subparser.format_help())
|
||||||
|
|
||||||
|
parser.exit()
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(add_help=False)
|
||||||
|
parser.add_argument(
|
||||||
|
'--help', '-h',
|
||||||
|
action = _HelpAction,
|
||||||
|
help = 'Show this help message and exit'
|
||||||
|
)
|
||||||
|
|
||||||
|
subparsers = parser.add_subparsers(
|
||||||
|
dest="command",
|
||||||
|
help = "Command defaults to add"
|
||||||
|
)
|
||||||
|
add_parser = subparsers.add_parser('add', add_help=False)
|
||||||
|
add_parser.add_argument(
|
||||||
|
"days",
|
||||||
|
action = "store",
|
||||||
|
type = int,
|
||||||
|
help = "Days to keep files",
|
||||||
|
default = 30,
|
||||||
|
nargs = '?'
|
||||||
|
)
|
||||||
|
add_parser = subparsers.add_parser('list', add_help=False)
|
||||||
|
add_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():
|
||||||
|
chars = [random_char() for x in range(6)]
|
||||||
|
chars.insert(3, '-')
|
||||||
|
return ''.join(chars)
|
||||||
|
|
||||||
|
|
||||||
|
def create_new(p, days):
|
||||||
|
os.mkdir(p)
|
||||||
|
with open(os.path.join(p, DEL_TIME), 'wt') as fp:
|
||||||
|
fp.write(str(days))
|
||||||
|
|
||||||
|
|
||||||
|
def get_stats(p):
|
||||||
|
try:
|
||||||
|
with open(os.path.join(p, DEL_TIME), 'rt') as fp:
|
||||||
|
do_del = int(fp.read(64))
|
||||||
|
now = datetime.now()
|
||||||
|
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
|
||||||
|
return mtime, del_time, to_del_time, is_due
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return (None, None, False)
|
||||||
|
|
||||||
|
|
||||||
|
def get_sub_files(p):
|
||||||
|
file_list = sorted([x for x in os.listdir(p) if not x.startswith(".")])
|
||||||
|
dir_list = [x + "/" for x in file_list if os.path.isdir(os.path.join(p, x))]
|
||||||
|
file_list = [x for x in file_list if os.path.isfile(os.path.join(p, x))]
|
||||||
|
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 list_folders():
|
||||||
|
names = get_folder_names()
|
||||||
|
print("Folder Created ToDelete InDays")
|
||||||
|
for p in names:
|
||||||
|
stats = get_stats(p)
|
||||||
|
sub_files = get_sub_files(p)
|
||||||
|
due = "*" if stats[3] else ""
|
||||||
|
print("{}/ {} {} {: 3d}d{}".format(
|
||||||
|
p,
|
||||||
|
stats[0].isoformat()[0:10],
|
||||||
|
stats[1].isoformat()[0:10],
|
||||||
|
stats[2].days,
|
||||||
|
due
|
||||||
|
))
|
||||||
|
for sp in sub_files:
|
||||||
|
print(" {}".format(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)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
opts = parse_opts()
|
||||||
|
|
||||||
|
if opts.command == 'add':
|
||||||
|
new_name = random_name()
|
||||||
|
while os.path.exists(new_name):
|
||||||
|
new_name = random_name()
|
||||||
|
create_new(new_name, opts.days)
|
||||||
|
print(os.path.abspath(new_name))
|
||||||
|
|
||||||
|
if opts.command == "list" or opts.command == None:
|
||||||
|
list_folders()
|
||||||
|
|
||||||
|
if opts.command == "del":
|
||||||
|
del_due_folders()
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user