Mini Shell

Direktori : /opt/sharedrads/
Upload File :
Current File : //opt/sharedrads/fraudhunter.py

#!/opt/imh-python/bin/python3
"""Fraud Hunter Tool for Chuck H."""
import multiprocessing
import argparse
import os
import signal
import sys
import rads


def get_args():
    """Parse arguments"""
    parser = argparse.ArgumentParser(description=__doc__)
    # fmt: off
    parser.add_argument(
        '-n', '--name', dest='filenames', nargs='+', required=True,
        help='File name(s) to look for',
    )
    parser.add_argument(
        '-e', '--exclude', dest='exc_user', nargs='+', default=[],
        help='User(s) to exclude',
    )
    parser.add_argument(
        '-x', '--max', type=int, help='Max file size (in bytes)'
    )
    parser.add_argument(
        '-m', '--min', type=int, help='Min file size (in bytes)'
    )
    # fmt: on
    args = parser.parse_args()
    if args.min > args.max:
        print("The minimum size needs to be larger than the maximum size")
        sys.exit(1)

    return args.filenames, args.exc_user, args.max, args.min


def targets(excluded):
    """Get a list of users that aren't suspended, sys. users, or excluded"""
    return [
        user
        for user in rads.all_cpusers()
        if user not in rads.OUR_RESELLERS
        and not rads.cpuser_suspended(user)
        and user not in excluded
    ]


def check_size(filename, maxsize, minsize):
    """Confirm filesize within argument constraints"""
    size = os.path.getsize(filename)
    if maxsize is not None:
        if size > maxsize:
            return False
    if minsize is not None:
        if size < minsize:
            return False
    return True


def hunter(gdtuple):
    """Print any file that matches the filenames"""
    user, filenames, maxsize, minsize = gdtuple
    try:
        homedir = rads.get_homedir(user)
    except rads.CpuserError as exc:
        print(exc, file=sys.stderr)
        return
    for root, _, files in os.walk(homedir, topdown=False):
        for name in files:
            if name in filenames:
                fullpath = os.path.join(root, name)
                if maxsize is None and minsize is None:
                    print(fullpath)
                    continue
                if check_size(fullpath, maxsize, minsize):
                    print(fullpath)


def start_the_hunt(target_users, filenames, maxsize, minsize):
    """set up a multiprocessing queue to loop through accounts"""
    args = ((user, filenames, maxsize, minsize) for user in target_users)
    # shenanigans to deal with keyboard interrupts
    original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
    with multiprocessing.Pool(multiprocessing.cpu_count()) as pool:
        signal.signal(signal.SIGINT, original_sigint_handler)
        try:
            results = pool.map_async(hunter, args)
            # dealing with Python bug https://bugs.python.org/issue8296
            results.get(10)
        except multiprocessing.TimeoutError:
            pass
        except KeyboardInterrupt:
            print("Caught KeyboardInterrupt.")
            pool.terminate()
        pool.close()


def main():
    '''Main function: get args'''
    filenames, excluded, maxsize, minsize = get_args()
    target_users = targets(excluded)

    start_the_hunt(target_users, filenames, maxsize, minsize)


if __name__ == "__main__":
    main()

Zerion Mini Shell 1.0