139
									
								
								main.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								main.py
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
			
		||||
		Reference in New Issue
	
	Block a user