fix resolv.conf issue on plc
[myplc.git] / plc-orphan-accounts.py
1 #!/usr/bin/env plcsh
2 #
3 # $Id$
4 #
5 # searches and displays any local orphan account (not attached to a site)
6 # remote accounts with identical emails are displayed as well
7
8 import sys
9 import time
10 import readline
11 from optparse import OptionParser
12
13 logdir="/var/log/accounts"
14
15 def run_in_log (options):
16     monthstring=time.strftime("%Y-%m")
17     if not os.path.isdir(logdir):
18         os.mkdir(logdir)
19     logname="%s/orphans-%s.log"%(logdir,monthstring)
20     sys.stdout=open(logname,'a')
21     sys.stderr=sys.stdout
22     run(options)
23     sys.stderr.close()
24     sys.stdout.close()
25
26 # sort filters look broken
27 def sort_email (p1,p2):
28     if p1['email'] == p2['email']: return 0
29     if p1['email'] < p2['email'] : return -1
30     return 1
31
32 def get_orphans ():
33     orphans = [p for p in GetPersons({'peer_id':None,'-SORT':'email'}) if not p['site_ids'] ]
34     orphans.sort(sort_email)
35     return orphans
36
37 def list_person (margin,p):
38     print margin,'%6d'%p['person_id'], time.asctime(time.gmtime(p['date_created'])),
39     if not p['peer_id']: print 'LOCAL',
40     else: print 'pr=',p['peer_id'],
41     if p['enabled']: print 'ENB',
42     else: print 'DIS',
43     print p['email']
44
45 date_keys=['date_created','last_updated']
46 def details_person (p):
47     keys=p.keys()
48     keys.sort()
49     for key in keys:
50         print key,'->',
51         value=p[key]
52         if key in date_keys:    print time.asctime(time.gmtime(value))
53         else:                   print value
54
55 def get_related(email):
56     return GetPersons ({'email':email,'~peer_id':None})
57
58 def header (message):
59     print '--------------------'
60     print GetPeerName(),
61     print time.asctime(time.gmtime())
62     print 'Listing orphan accounts and any similar remote'
63     print '--------------------'
64
65 def delete_local (person,default_bool,options):
66     
67     # just in case
68     if person['peer_id'] != None:
69         print 'ERROR: cannot delete non-local person',person['email']
70         return
71
72     prompt = 'want to delete '+person['email']
73     if default_bool:    prompt += ' v(erbose)/[y]/n ? '
74     else:               prompt += ' v(erbose)y/[n] ? '
75
76     done=False
77
78     while not done:
79         done=True
80         try:
81             answer = raw_input(prompt).strip()
82         except EOFError :
83             print 'bailing out'
84             sys.exit(1)
85
86         if answer=='':
87             do_delete=default_bool
88         elif answer.lower()[0]=='y':
89             do_delete=True
90         elif answer.lower()[0]=='n':
91             do_delete=False
92         elif answer.lower()[0]=='v':
93             details_person(person)
94             done=False
95         else:
96             done=False
97     id=person['person_id']
98     email=person['email']
99     if options.dry_run:
100         if do_delete:                   print 'Would delete',id,'->',email
101         else:                           print 'Would preserve',id,'->',email
102     elif do_delete:
103         print 'Deleting',id,'->',email,
104         if DeletePerson(id) == 1:       print 'OK',id,'deleted'
105         else:                           print 'Deletion failed'
106
107 def main_orphans (options):
108     orphans = get_orphans()
109     header ('Listing  %d  local accounts with no site - and similar remote accounts'%len(orphans))
110     index=0
111     for local in orphans:
112         index+=1
113         list_person ("%3d"%index,local)
114         for related in get_related(local['email']):
115             list_person("dup",related)
116         if options.delete:
117             delete_default = not local['enabled']
118             delete_local(local,delete_default,options)
119     
120 def main_duplicates(options):
121
122     header ('Listing all duplicate accounts')
123     locals = GetPersons({'peer_id':None,'-SORT':'email'})
124     locals.sort(sort_email)
125     index=0
126     for local in locals:
127         remotes=GetPersons({'email':local['email'],'~peer_id':None})
128         if remotes:
129             index+=1
130             list_person('%3d'%index,local)
131             for remote in remotes:
132                 list_person('dup',remote)
133             if options.delete:
134                 delete_default = not local['enabled']
135                 delete_local(local,delete_default,options)
136
137 def run (options):
138     main_orphans(options)
139     main_duplicates(options)
140
141 def main():
142
143     usage="%prog [ -- options]"
144
145     parser = OptionParser(usage=usage)
146     parser.add_option("-l","--log", dest="log", action="store_true",default=False,
147                       help="write current status in /var/log/accounts")
148     parser.add_option("-d","--delete", dest="delete", action="store_true",default=False,
149                       help="interactively delete extraneous accounts")
150     parser.add_option("-n","--dry-run", dest="dry_run", action="store_true",default=False,
151                       help="go through the delete prompting but does not delete")
152
153     (options,args) = parser.parse_args()
154     if len(args)!=0:
155         parser.error("Unexpected arguments",args)
156
157     if options.dry_run: options.delete=True
158     
159     if options.log:
160         options.delete=False
161         run_in_log(options)
162     else:
163         run(options)
164     
165 if __name__ == '__main__':
166     main()