import logging import argparse import os import re import datetime import redis BACKUP_START_TIME = datetime.time(1, 30, 0) BACKUP_END_TIME = datetime.time(3, 30, 0) def parse_args(): parser = argparse.ArgumentParser() parser.add_argument("-v", "--verbose", action="store_true", help="increase output verbosity") parser.add_argument("-r", "--redis-host", default="127.0.0.1", help="specify redis host") parser.add_argument("-f", "--file-dir", default="/var/drop/files", help="specify dir where files are stored") parser.add_argument("-d", "--dry", action="store_true", help="Run in dry mode") return parser.parse_args() def convert_bytes_to_string(bytes_or_string): if isinstance(bytes_or_string, str): return bytes_or_string if isinstance(bytes_or_string, bytes): return bytes_or_string.decode('UTF-8') return None def configure_logging(args): log_level = logging.INFO if args.verbose: log_level = logging.DEBUG logging.basicConfig(level=log_level) def create_redis_client(args): logging.debug('Connecting to redist host %s...', args.redis_host) redis_client = redis.StrictRedis(host=args.redis_host) logging.debug('Subscribing to events...') pubsub = redis_client.pubsub() pubsub.psubscribe("*") return redis_client, pubsub def locate_file_with_id(args, file_id): for file in os.listdir(args.file_dir): if re.match(r'^[0-9]+-' + file_id + r'$', file): return os.path.join(args.file_dir, file) return None def delete_files(args, file_ids): for file_id in file_ids: delete_file(args, file_id) def delete_file(args, file_id): logging.info('File with id %s will be deleted', file_id) if not re.match(r'^[a-f0-9]{16}$', file_id): logging.warning('file id %s is not valid', file_id) return file_path = locate_file_with_id(args, file_id) if not file_path: logging.warning('file with id %s was no found', file_id) return logging.info('Removing file with id %s on disk', file_id) if not args.dry: os.remove(file_path) def is_in_backup_period(): now = datetime.datetime.now().time() if BACKUP_START_TIME <= BACKUP_END_TIME: return BACKUP_START_TIME <= now <= BACKUP_END_TIME else: return BACKUP_START_TIME <= now or now <= BACKUP_END_TIME def main(): args = parse_args() file_ids_to_delete = [] configure_logging(args) redis_client, pubsub = create_redis_client(args) logging.debug('Listen to messages...') for msg in pubsub.listen(): msg_type = msg.get('type', None) channel = convert_bytes_to_string(msg.get('channel', None)) data = convert_bytes_to_string(msg.get('data', None)) if msg_type != 'pmessage': logging.debug('Message of type %s ignored', msg_type) continue if channel != '__keyevent@0__:expired': logging.debug('Event of type %s ignored', channel) continue file_ids_to_delete.append(data) if not is_in_backup_period(): delete_files(args, file_ids_to_delete) if __name__ == "__main__": main()