From 0a79872d4b9908e9342f437e1a172137d8bb60e3 Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Wed, 20 May 2009 20:37:02 +0000 Subject: [PATCH] can be used to monitor accounts in /var/log/accounts - or to actually cleanup with --delete --- plc-orphan-accounts.py | 126 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 113 insertions(+), 13 deletions(-) diff --git a/plc-orphan-accounts.py b/plc-orphan-accounts.py index c2f9b59..b8ce321 100755 --- a/plc-orphan-accounts.py +++ b/plc-orphan-accounts.py @@ -1,9 +1,27 @@ #!/usr/bin/env plcsh - +# +# $Id$ +# # searches and displays any local orphan account (not attached to a site) # remote accounts with identical emails are displayed as well +import sys import time +import readline +from optparse import OptionParser + +logdir="/var/log/accounts" + +def run_in_log (options): + monthstring=time.strftime("%Y-%m") + if not os.path.isdir(logdir): + os.mkdir(logdir) + logname="%s/orphans-%s.log"%(logdir,monthstring) + sys.stdout=open(logname,'a') + sys.stderr=sys.stdout + run(options) + sys.stderr.close() + sys.stdout.close() # sort filters look broken def sort_email (p1,p2): @@ -24,6 +42,16 @@ def list_person (margin,p): else: print 'DIS', print p['email'] +date_keys=['date_created','last_updated'] +def details_person (p): + keys=p.keys() + keys.sort() + for key in keys: + print key,'->', + value=p[key] + if key in date_keys: print time.asctime(time.gmtime(value)) + else: print value + def get_related(email): return GetPersons ({'email':email,'~peer_id':None}) @@ -34,33 +62,105 @@ def header (message): print 'Listing orphan accounts and any similar remote' print '--------------------' -def main_orphans (): +def delete_local (person,default_bool,options): + + # just in case + if person['peer_id'] != None: + print 'ERROR: cannot delete non-local person',person['email'] + return + + prompt = 'want to delete '+person['email'] + if default_bool: prompt += ' v(erbose)/[y]/n ? ' + else: prompt += ' v(erbose)y/[n] ? ' + + done=False + + while not done: + done=True + try: + answer = raw_input(prompt).strip() + except EOFError : + print 'bailing out' + sys.exit(1) + + if answer=='': + do_delete=default_bool + elif answer.lower()[0]=='y': + do_delete=True + elif answer.lower()[0]=='n': + do_delete=False + elif answer.lower()[0]=='v': + details_person(person) + done=False + else: + done=False + id=person['person_id'] + email=person['email'] + if options.dry_run: + if do_delete: print 'Would delete',id,'->',email + else: print 'Would preserve',id,'->',email + elif do_delete: + print 'Deleting',id,'->',email, + if DeletePerson(id) == 1: print 'OK',id,'deleted' + else: print 'Deletion failed' + +def main_orphans (options): orphans = get_orphans() header ('Listing %d local accounts with no site - and similar remote accounts'%len(orphans)) - index=1 - for p in orphans: - list_person ("%3d"%index,p) - for related in get_related(p['email']): - list_person("dup",related) + index=0 + for local in orphans: index+=1 + list_person ("%3d"%index,local) + for related in get_related(local['email']): + list_person("dup",related) + if options.delete: + delete_default = not local['enabled'] + delete_local(local,delete_default,options) -def main_duplicates(): +def main_duplicates(options): header ('Listing all duplicate accounts') locals = GetPersons({'peer_id':None,'-SORT':'email'}) locals.sort(sort_email) - index=1 + index=0 for local in locals: remotes=GetPersons({'email':local['email'],'~peer_id':None}) if remotes: + index+=1 list_person('%3d'%index,local) for remote in remotes: list_person('dup',remote) - - index+=1 + if options.delete: + delete_default = not local['enabled'] + delete_local(local,delete_default,options) + +def run (options): + main_orphans(options) + main_duplicates(options) + def main(): - main_orphans() - main_duplicates() + usage="%prog [ -- options]" + + parser = OptionParser(usage=usage) + parser.add_option("-l","--log", dest="log", action="store_true",default=False, + help="write current status in /var/log/accounts") + parser.add_option("-d","--delete", dest="delete", action="store_true",default=False, + help="interactively delete extraneous accounts") + parser.add_option("-n","--dry-run", dest="dry_run", action="store_true",default=False, + help="go through the delete prompting but does not delete") + + (options,args) = parser.parse_args() + if len(args)!=0: + parser.error("Unexpected arguments",args) + + if options.dry_run: options.delete=True + + if options.log: + options.delete=False + run_in_log(options) + else: + run(options) + if __name__ == '__main__': main() -- 2.43.0