ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/FreeBSDAdmin/Reminder/reminder.py
(Generate patch)

Comparing:
FreeBSDAdmin/Reminder/common.py (file contents), Revision 1178 by douglas, 2009-05-17T14:30:08-07:00 vs.
FreeBSDAdmin/Reminder/reminder.py (file contents), Revision 1425 by douglas, 2011-05-03T17:47:50-07:00

# Line 1 | Line 1
1 < # Common
1 > #!/usr/local/bin/python
2 > # Reminder
3   #
4   # Douglas Thrift
5   #
6   # $Id$
7  
8 < import base64
9 < from ConfigParser import SafeConfigParser
8 > from ConfigParser import NoOptionError, SafeConfigParser
9 > import gdata.calendar.service
10 > import getpass
11 > import imaplib
12 > import keyring
13   import optparse
14 < import os.path
14 > import os
15   import sys
16  
17 < FORBIDDEN = ('common', 'creditcard', 'google', 'wesabe')
17 > MODULES = frozenset(('creditcards', 'facebook'))
18  
19 < class Bank(object):
20 <        def download(self, account):
21 <                raise NotImplementedError
19 > class Config(object):
20 >        def __init__(self, config, module):
21 >                self.config = config
22 >                self.module = module
23  
24 <        def due(self, account):
25 <                raise NotImplementedError
24 >        def get(self, *args, **kwargs):
25 >                return self.config.get(self.module, *args, **kwargs)
26 >
27 >        def getboolean(self, *args, **kwargs):
28 >                return self.config.getboolean(self.module, *args, **kwargs)
29 >
30 >        def getfloat(self, *args, **kwargs):
31 >                return self.config.getfloat(self.module, *args, **kwargs)
32 >
33 >        def getint(self, *args, **kwargs):
34 >                return self.config.getint(self.module, *args, **kwargs)
35 >
36 >        def getlist(self, *args, **kwargs):
37 >                return self.config.getlist(self.module, *args, **kwargs)
38 >
39 >        def getpassword(self):
40 >                return self.config.getpassword(self.module)
41 >
42 >        def getusername(self):
43 >                return self.config.getusername(self.module)
44 >
45 > class ConfigParser(SafeConfigParser):
46 >        def __init__(self, *args, **kwargs):
47 >                SafeConfigParser.__init__(self, *args, **kwargs)
48 >
49 >        def getlist(self, *args, **kwargs):
50 >                return self.get(*args, **kwargs).split(',')
51 >
52 >        def getpassword(self, section):
53 >                return keyring.get_password('reminder_%s' % section, self.getusername(section))
54 >
55 >        def getusername(self, section):
56 >                return self.get(section, 'username')
57  
58   class OptionParser(optparse.OptionParser):
59          def __init__(self, *args, **kwargs):
60                  optparse.OptionParser.__init__(self, *args, **kwargs)
61                  self.add_option('-A', '--all', action = 'store_true', dest = 'all')
62 <                self.add_option('-b', '--bank', action = 'callback', callback = self.__bank, dest = 'banks', type = 'string')
63 <                self.add_option('-a', '--account', action = 'callback', callback = self.__account, dest = 'banks', type = 'string')
64 <                self.add_option('-l', '--list', action = 'store_true', dest = 'list')
62 >                self.add_option('-d', '--dbus', action = 'store_true', dest = 'dbus')
63 >                self.add_option('-m', '--module', action = 'callback', callback = self.__module, dest = 'modules', type = 'string')
64 >                self.add_option('-p', '--password', action = 'callback', callback = self.__password, dest = 'passwords', type = 'string')
65                  self.add_option('-D', '--debug', action = 'store_true', dest = 'debug')
30        
31        def __bank(self, option, opt_str, value, parser):
32                if value in FORBIDDEN:
33                        raise optparse.OptionValueError, '%s must not be %s' % (opt_str, value)
66  
67 <                self.bank = value
67 >        def __module(self, option, opt_str, value, parser):
68 >                if value not in MODULES:
69 >                        raise optparse.OptionValueError, '%s unknown module %s' % (opt_str, value)
70 >
71 >                parser.values.ensure_value(option.dest, []).append(value)
72  
73 <                parser.values.ensure_value(option.dest, {}).setdefault(value, [])
73 >        def __password(self, option, opt_str, value, parser):
74 >                parser.values.ensure_value(option.dest, []).append(value)
75  
76 <        def __account(self, option, opt_str, value, parser):
77 <                try:
78 <                        getattr(parser.values, option.dest)[self.bank].append(value)
79 <                except NameError:
80 <                        raise optparse.OptionValueError, '%s must be after -b/--bank' % opt_str
76 > class OnDemand(object):
77 >        def __init__(self, constructor, destructor = None):
78 >                self.constructor = constructor
79 >                self.destructor = destructor
80 >                self.instance = None
81  
82 < def config(parser, options, file):
83 <        if not options.all and not options.banks and not options.list:
84 <                parser.error('-A, -b, or -l not specified')
82 >        def __getattr__(self, name):
83 >                if self.instance is None:
84 >                        self.instance = self.constructor()
85  
86 <        config = SafeConfigParser()
86 >                return getattr(self.instance, name)
87  
88 <        config.read([os.path.expanduser('~/%s' % file)])
88 >        def __del__(self):
89 >                if self.destructor is not None and self.instance is not None:
90 >                        self.destructor(self.instance)
91  
92 <        banks = dict(map(lambda bank: (bank, config.get(bank, 'accounts').split(',')), (options.banks.iterkeys() if options.banks else filter(lambda section: section not in FORBIDDEN, config.sections()))))
92 > if __name__ == '__main__':
93 >        parser = OptionParser()
94 >        options = parser.parse_args()[0]
95 >        config = ConfigParser()
96  
97 <        if options.banks:
56 <                for bank in banks.iterkeys():
57 <                        accounts = frozenset(options.banks[bank])
97 >        config.read([os.path.expanduser('~/.reminder')])
98  
99 <                        if accounts:
100 <                                all_accounts = frozenset(banks[bank])
99 >        if options.dbus:
100 >                dbus = os.environ['DBUS_SESSION_BUS_ADDRESS']
101  
102 <                                if accounts <= all_accounts:
103 <                                        banks[bank] = accounts
64 <                                else:
65 <                                        parser.error('not account(s): %s' % ', '.join(accounts - all_accounts))
102 >                with open(os.path.expanduser('~/.reminder.dbus'), 'wb') as file:
103 >                        file.write(dbus + '\n')
104  
105 <        if options.list:
68 <                for bank, accounts in banks.iteritems():
69 <                        print bank
105 >                sys.exit(0)
106  
107 <                        for account in accounts:
108 <                                print '   ' + account
107 >        try:
108 >                os.environ['DBUS_SESSION_BUS_ADDRESS']
109 >        except KeyError:
110 >                with open(os.path.expanduser('~/.reminder.dbus'), 'rb') as file:
111 >                        os.environ['DBUS_SESSION_BUS_ADDRESS'] = file.readline().rstrip()
112 >
113 >        if options.passwords:
114 >                for section in options.passwords:
115 >                        try:
116 >                                username = config.getusername(section)
117 >                                password = getpass.getpass('%s password for %s: ' % (section, username))
118 >
119 >                                keyring.set_password('reminder_%s' % section, username, password)
120 >                        except NoOptionError:
121 >                                pass
122  
123                  sys.exit(0)
124  
125 <        return config, banks
125 >        if not options.all and not options.modules:
126 >                parser.error('-A or -m not specified')
127 >
128 >        def calendar_constructor():
129 >                calendar = gdata.calendar.service.CalendarService()
130 >                calendar.email = config.getusername('google')
131 >                calendar.password = config.getpassword('google')
132 >                calendar.source = 'Reminder-0.9'
133 >
134 >                calendar.ProgrammaticLogin()
135 >
136 >                return calendar
137 >
138 >        def imap_constructor():
139 >                if options.debug:
140 >                        imaplib.Debug = 4
141 >
142 >                imap = imaplib.IMAP4_SSL(config.get('imap', 'server'))
143 >
144 >                imap.login(config.getusername('imap'), config.getpassword('imap'))
145  
146 < def decode(string):
79 <        return base64.b64decode(string.decode('rot13'))
146 >                return imap
147  
148 < def bank(bank, options, config):
149 <        exec 'import %s' % bank
83 <        exec "bank = %s.Bank(config.get(bank, 'username'), decode(config.get(bank, 'password')), options.debug)" % bank
148 >        calendar = OnDemand(calendar_constructor)
149 >        imap = OnDemand(imap_constructor, lambda imap: imap.logout())
150  
151 <        return bank
151 >        for module in options.modules if not options.all else sorted(MODULES):
152 >                exec 'import %s' % module
153 >                exec '%s.main(calendar, imap, Config(config, module), options.debug)' % module

Comparing:
FreeBSDAdmin/Reminder/common.py (property svn:executable), Revision 1178 by douglas, 2009-05-17T14:30:08-07:00 vs.
FreeBSDAdmin/Reminder/reminder.py (property svn:executable), Revision 1425 by douglas, 2011-05-03T17:47:50-07:00

# Line 0 | Line 1
1 + *

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines