# -*- coding: utf-8 -*-
#!/usr/bin/python
##-------------------------------------------------------------------
## @copyright 2017 DennyZhang.com
## Licensed under MIT
##   https://raw.githubusercontent.com/DennyZhang/devops_public/master/LICENSE
##
## File : cleanup_old_files.py
## Author : Denny <denny@dennyzhang.com>
## Created : <2017-05-03>
## Updated: Time-stamp: <2017-05-15 15:03:50>
## Description :
##    Remove old files in a safe and organized way
## Sample:
##    # Remove files: Check /opt/app and remove files naming "app-.*-SNAPSHOT.jar". But keep latest 2 copies
##    python cleanup_old_files.py --working_dir "/opt/app" --filename_pattern "app-.*-SNAPSHOT.jar" \
##               --cleanup_type file --min_copies 3 --min_size_kb 10240
##
##    # Only list delete candidates, instead of perform the actual changes
##    python cleanup_old_files.py --working_dir "/opt/app" --filename_pattern "app-.*-SNAPSHOT.jar" \
##               --examine_only
##
##    # Remove files: Only cleanup files over 200MB
##    python cleanup_old_files.py --working_dir "/opt/app" --filename_pattern "app-.*-SNAPSHOT.jar" \
##               --cleanup_type file --min_size_kb 204800
##
##    # Remove folders: Cleanup subdirectories, keeping latest 2 directories
##    python cleanup_old_files.py --working_dir "/opt/app" --filename_pattern ".*" --cleanup_type directory
##-------------------------------------------------------------------
import os, sys
import argparse
import re
import shutil

import logging
log_file = "/var/log/%s.log" % (os.path.basename(__file__).rstrip('\.py'))

logging.basicConfig(filename=log_file, level=logging.DEBUG, format='%(asctime)s %(message)s')
logging.getLogger().addHandler(logging.StreamHandler())

def list_old_files(filename_pattern, min_copies, min_size_kb):
    l = []
    files = [f for f in os.listdir(".") if re.search(filename_pattern, f)]
    files.sort(key=os.path.getmtime, reverse=True)
    i = 0
    for f in files:
        if os.path.isfile(f) is False:
            continue
        # skip too small files
        filesize_kb = os.stat(f).st_size/1000
        if filesize_kb < min_size_kb:
            continue
        i = i + 1
        if i > min_copies:
            l.append(f)
    return l

def list_old_folders(filename_pattern, min_copies):
    l = []
    files = [f for f in os.listdir(".") if re.search(filename_pattern, f)]
    files.sort(key=os.path.getmtime, reverse=True)
    i = 0
    for f in files:
        if os.path.isdir(f) is False:
            continue
        i = i + 1
        if i > min_copies:
            l.append(f)
    return l

if __name__ == '__main__':
    # get parameters from users
    parser = argparse.ArgumentParser()
    parser.add_argument('--working_dir', required=True, \
                        help="Perform cleanup under which directory", type=str)
    parser.add_argument('--examine_only', dest='examine_only', action='store_true', default=False, \
                        help="Only list delete candidates, instead perform the actual removal")
    parser.add_argument('--filename_pattern', required=False, default=".*", \
                        help="Filter files/directories by filename, before cleanup", type=str)
    parser.add_argument('--cleanup_type', required=False, default='file', \
                        help="Whether to perform the cleanup for files or directories", type=str)
    parser.add_argument('--min_copies', default=3, required=False, \
                        help='minimal copies to keep, before removal.', type=int)
    parser.add_argument('--min_size_kb', default=100, required=False, \
                        help='When remove files, skip files too small. It will be skipped when removing directories', type=int)
    l = parser.parse_args()

    working_dir = l.working_dir
    examine_only = l.examine_only
    cleanup_type = l.cleanup_type.lower()
    filename_pattern = l.filename_pattern
    min_copies = l.min_copies
    min_size_kb = l.min_size_kb

    logging.info("Start to run cleanup for folder: %s." % working_dir)
    if os.path.exists(working_dir) is False:
        logging.warning("Directory(%s) doesn't exists." % (working_dir))
        sys.exit(0)

    os.chdir(working_dir)
    if cleanup_type == 'file':
        l = list_old_files(filename_pattern, min_copies, min_size_kb)
    else:
        l = list_old_folders(filename_pattern, min_copies)

    if l == []:
        logging.info("No matched files/directories to be clean.")
        sys.exit(0)
    else:
        if examine_only is True:
            logging.info("Below files/directories are selected to be removed: %s.\n"\
                         "Skip following removal, since --examine_only has already been given." \
                         % ",".join(l)) 
            sys.exit(0)
        else:
            # Perform the actual removal
            for f in l:
                if cleanup_type == 'file':
                    logging.info("Remove file. %s/%s" % (working_dir, f))
                else:
                    logging.info("Remove folder: %s/%s" % (working_dir, f))
                # TODO: error handling
                shutil.rmtree(f)
            logging.info("Cleanup is done.")
## File : cleanup_old_files.py ends

@@ -385,12 +385,12 @@
 15:0
-3:50
+6:31
 %3E%0A##
@@ -2219,32 +2219,76 @@
     l.append(f)%0A
+    # print %22files: %25s, l: %25s%22 %25 (files, l)%0A
     return l%0A%0Ade
@@ -5008,32 +5008,65 @@
 orking_dir, f))%0A
+                    os.remove(f)%0A
                 
@@ -5163,16 +5163,20 @@
         
+    
 # TODO: 
@@ -5190,16 +5190,20 @@
 andling%0A
+    
         

improve logic