Mini Shell

Direktori : /usr/local/bin/
Upload File :
Current File : //usr/local/bin/imap-archiver

#!/opt/imh-python/bin/python3
import subprocess
import os.path
import getpass
import argparse
import yaml
import json
import sys
import crontab
import random
from rads.shared import is_cpanel_user

#DEFAULTS: creates monthly archives for messages more than 30 days old in the format of "Archive.YYYY.MM-Jan"
#these are the settings pretty much everyone will be using
#most invocations will just be 'archive-email -a' with -c if its setting up a weekly cron
archive_name='Archive'
archive_period='2' #1=yearly 2=monthly
age=30            #dont touch mail until its this many days old
user=None       #cpanel user
email=None      #user's email account
dry_run=False    #pretend we're archiving but dont move anything
trial_run=None  #pretend we're archiving but dont move anything
add_cron=False    #create user cron to run weekly
is_cron=False    #is this a cron?
quiet=False        #suppress output (for cron)

def do_archive(email, user, dry_run, quiet):
    path = os.path.join('/home', user, 'mail', email.split('@')[1], email.split('@')[0])

    cmd_opts = [
        '/usr/local/bin/cleanup-maildir',
        '--archive-folder={}'.format(archive_name),
        '--archive-hierarchy-depth={}'.format(archive_period),
        '--age={}'.format(age),
        '--maildir-root={}'.format(path)
    ]
    if dry_run:
        cmd_opts.append('--trial-run')
    if quiet:
        cmd_opts.append('--quiet')

    cmd_opts.extend(['archive', ''])
    if os.path.exists(os.path.join(path, 'cur')):
        subprocess.Popen(cmd_opts).wait()

def parse_args():
    #argparsing here
    parser = argparse.ArgumentParser(description='Archive large email accounts')
    parser.add_argument('-a', '--all', action='store_true', dest='user',
                        help='archive all accounts for a cpanel user')
    parser.add_argument('-e', '--email', action='store', dest='email', metavar="",
                        help='archive a single email account')
    parser.add_argument('-c', '--add-cron', action='store_true', dest='add_cron',
                        help='add a weekly cron to continually archive configured users')
    parser.add_argument('-n', '--dry-run', action='store_true', dest='dry_run',
                        help='run archive script without moving any files')
    parser.add_argument('-q', '--quiet', action='store_true', dest='quiet', default=False,
                        help='quiet output')
    parser.add_argument('-p', action='store_true',dest='is_cron',
                        help='archives users from config silently (for cron jobs)')
    args = parser.parse_args()
    if not args.user and not args.email and not args.is_cron and not args.add_cron:
        sys.exit("imap-archiver.py : no option selected")
    return args

def read_config(reader, path):
    try:
        with open(path) as handle:
            return reader(handle)
    except (ValueError, IOError):
        return

def setup_cron(user):
    ctab = crontab.CronTab(user=user)

    cmd = '/usr/local/bin/imap-archiver -p -q'
    if len([x for x in ctab.find_command(cmd) if x.is_enabled()]) > 0:
        print('Cron already enabled: {}'.format(cmd))
        return
    job = ctab.new(command=cmd)
    job.dow.on('SUN')
    job.hour.on(random.randint(0,9))
    job.minute.on(random.randint(0, 59))

    print("Adding weekly cron to the crontab for {}".format(user))
    ctab.write()

def main():
    args = parse_args()

    user = getpass.getuser()
    #has to be run as the user just like the old one, so the folders it creates arent goofy. 
    if not is_cpanel_user(user):
        print("This script must be run as the cpanel user to ensure proper file ownership")
        sys.exit()
    #since we're sure we're running as a user, set user to me

    #if run with -e just archive the one email and exit
    if args.email is not None:
        print("archiving {0.email}".format(args))
        # single email so get value from args
        do_archive(args.email, user, args.dry_run, args.quiet)
        sys.exit()

    #read a list of accounts to load ours > cpanel new > cpanel old
    try_confs = [
        (json.load, os.path.join('/home', user, '.archived-accounts.json')),
        (json.load, os.path.join('/home', user, '.cpanel/email_accounts.json')),
        (yaml.load, os.path.join('/home', user, '.cpanel/email_accounts.yaml'))
    ]

    data = None
    for reader, path in try_confs:
        data = read_config(reader, path)
        if data is not None:
            break # stop at the first config which could be loaded

    if data is None: # still none
        sys.exit('no valid config')

    if args.is_cron:    #imap-archiver -p
        quiet = True    #ensure we're running silently

    #generate list of emails to archive
    addrs = []
    if isinstance(data, dict):
        # then we read this from cpanel's config
        data.pop('__version', None) # trim __version key off the end since it jacks up our loops
        for domain in data.keys():
            for email_user in data[domain]['accounts'].keys():
                addrs.append("{}@{}".format(email_user,domain))
    else:
        # then we read this from our own config
        addrs = data

    try:
        with open (os.path.join('/home', user, '.archived-accounts.json'), 'w') as f:
            json.dump(addrs, f, indent=4)
    except (ValueError, IOError):
        print("Unable to write to config file")

    #archive the things
    for email in addrs:
        #forcing quiet to True here because output gets horrible with multiple accts
        do_archive(email, user, args.dry_run, True) 

    if args.add_cron:
        setup_cron(user)
 
if __name__ == "__main__":
    main()

Zerion Mini Shell 1.0