diff --git a/main.py b/main.py new file mode 100644 index 0000000..6f345cc --- /dev/null +++ b/main.py @@ -0,0 +1,139 @@ +import argparse +from datetime import date, datetime, timedelta +from dateutil.relativedelta import relativedelta +import os +from pathlib import Path +import re + + +def get_quarter(p_date: date) -> int: + return (p_date.month - 1) // 3 + 1 + + +def get_day_minus_x(p_date: date, limitdays: int): + # return list of dates + list = [] + while (limitdays >= 0): + list.append(p_date + relativedelta(days=-limitdays)) + limitdays = limitdays - 1 + return list + + +def get_month_minus_x(p_date: date, limitmonths: int): + # return list of dates + list = [] + limitmonths = limitmonths - 1 + while (limitmonths >= 0): + list.append((datetime(p_date.year, p_date.month, 1) + + relativedelta(months=-limitmonths) + timedelta(days=-1)).date()) + limitmonths = limitmonths - 1 + return list + + +def get_quarter_minus_x(p_date: date, limitquarter: int): + # return list of dates + list = [] + while (limitquarter > 0): + last_quarter = get_quarter(p_date) - limitquarter + list.append((datetime(p_date.year + 3 * last_quarter // 12, + 3 * last_quarter % 12 + 1, 1) + timedelta(days=-1)).date()) + limitquarter = limitquarter - 1 + return list + + +def get_year_minus_x(p_date: date, limityear: int): + # return list of dates + list = [] + limityear = limityear - 1 + while (limityear >= 0): + list.append((datetime(p_date.year, 1, 1) + relativedelta(years=-limityear) + + timedelta(days=-1)).date()) + limityear = limityear - 1 + return list + + +def set_keep(keep, reason): + if isinstance(keep, bool): + return f"True - {reason}" + else: + return f"{keep} & {reason}" + + +def process_file(child, daydates, monthdates, quarterdates, yeardates): + date_reg_exp = re.compile('\d{4}\d{2}\d{2}') + matches_list = date_reg_exp.findall(child.name) + if(len(matches_list) < 1): + print(f'{{"name": "{child.name}", "filedate": "", "keep": "True - no YYYYMMDD to parse", "action": "none"}}') + else: + filedate = datetime.strptime(matches_list[0], '%Y%m%d') + keep = test_for_keep(filedate, daydates, monthdates, + quarterdates, yeardates) + + if (keep): + print( + f'{{"name": "{child.name}", "filedate": "{filedate}", "keep": "{keep}", "action": "none"}}') + else: + print( + f'{{"name": "{child.name}", "filedate": "{filedate}", "keep": "{keep}" , "action": "to remove"}}') + os.remove(child) + print( + f'{{"name": "{child.name}", "filedate": "{filedate}", "keep": "{keep}" , "action": "removed"}}') + + +def test_for_keep(filedate, daydates, monthdates, quarterdates, yeardates): + keep = False + + # Keep last days of backups + if(filedate.date() in daydates): + keep = set_keep(keep, "last days") + + # Keep backup from last day of month + if(filedate.date() in monthdates): + keep = set_keep(keep, "last day of month") + + # Keep backup from last day of quarter + if(filedate.date() in quarterdates): + keep = set_keep(keep, "last day of quarter") + + # Keep backup from last day of year + if(filedate.date() in yeardates): + keep = set_keep(keep, "last day of year") + + # Keep backups from the future + if(filedate.date() > date.today()): + keep = set_keep(keep, "Future") + + return keep + + +def main(path, days, months, quarters, years): + print(f'Path is {path}') + print( + f'Keeping {years} end of year, {quarters} end of quarter, {months} end of month, {days} daily backups') + + daydates = get_day_minus_x(date.today(), days) + monthdates = get_month_minus_x(date.today(), months) + quarterdates = get_quarter_minus_x(date.today(), quarters) + yeardates = get_year_minus_x(date.today(), years) + + for child in Path(path).iterdir(): + if child.is_file(): + process_file(child, daydates, monthdates, quarterdates, yeardates) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description='Test a path for backup rotation') + parser.add_argument('--path', type=str, required=True, + help="The path to check") + parser.add_argument('--days', type=int, required=True, + help="Daily backups to keep") + parser.add_argument('--months', type=int, required=True, + help="Last day of months to keep") + parser.add_argument('--quarters', type=int, required=True, + help="Last day of quarter to keep") + parser.add_argument('--years', type=int, required=True, + help="Last day of years to keep") + args = parser.parse_args() + + main(args.path, args.days, args.months, args.quarters, args.years)