r22881 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r22880‎ | r22881 | r22882 >
Date:14:42, 10 June 2007
Author:Mark Bergsma
Status:old
Tags:
Comment:
- Implement loading filter files
- Add action 'show' (field), e.g. to view filter files
Modified paths:
  • /trunk/wmfmailadmin/wmfmailadmin.py (modified) (history)

Diff [purge]

Index: trunk/wmfmailadmin/wmfmailadmin.py
@@ -11,11 +11,12 @@
1212 conn = None
1313
1414 actions = {
15 - # Option: ( action, description )
16 - 'l': ('list', "List accounts"),
17 - 'c': ('create', "Create account"),
18 - 'd': ('delete', "Delete account"),
19 - 'u': ('update', "Update account")
 15+ # Option: ( action, description, argument required )
 16+ 'l': ('list', "List accounts", False),
 17+ 'c': ('create', "Create account", False),
 18+ 'd': ('delete', "Delete account", False),
 19+ 'u': ('update', "Update account", False),
 20+ 's': ('show', "Show field", True)
2021 }
2122 longactions = {}
2223
@@ -31,7 +32,8 @@
3233 }
3334 longmappings = {}
3435
35 -updateables = ('password', 'quota', 'realname', 'active')
 36+updateables = ('password', 'quota', 'realname', 'active', 'filter')
 37+table_fields = ('id', 'localpart', 'domain', 'password', 'realname', 'active', 'quota', 'filter')
3638
3739 supported_hash_algorithms = ('{SHA1}')
3840
@@ -80,15 +82,22 @@
8183 require_fields( (required_fields, ), fields)
8284
8385 # Set default values for fields not given
84 - value_fields = ['localpart', 'domain', 'realname']
 86+ value_fields = ['localpart', 'domain', 'realname', 'filter']
8587 for fieldname in updateables:
8688 default = longmappings[fieldname][2]
87 - if fieldname not in fields and default is not None:
88 - fields[fieldname] = default
89 - value_fields.append(fieldname)
90 -
 89+ if fieldname not in fields:
 90+ if default is not None:
 91+ # Use the default value
 92+ fields[fieldname] = default
 93+ value_fields.append(fieldname)
 94+ else:
 95+ # Field is not given on the command line, and apparently not required
 96+ value_fields.remote(fieldname)
 97+
9198 # Input password if needed
92 - password_input(fields)
 99+ input_password(fields)
 100+ # Read filter file if needed
 101+ input_filter(fields)
93102
94103 # Construct list of fields that are either given, or should get default values
95104 values_list = "(" + ", ".join(value_fields) + ") VALUES (:" + ", :".join(value_fields) + ")"
@@ -116,18 +125,20 @@
117126 Update an existing account
118127 """
119128
120 - global conn
 129+ global conn, updateables
121130
122131 require_fields( (('id', ), ('email', )), fields)
123 - require_fields( (('password', ), ('realname', ), ('quota', ), ('active', ), ), fields)
 132+ require_fields( (('password', ), ('realname', ), ('quota', ), ('active', ), ('filter', ), ), fields)
124133
125134 # Input password if needed
126 - password_input(fields)
 135+ input_password(fields)
 136+ # Read filter file if needed
 137+ input_filter(fields)
127138
128139 # Build UPDATE clause from update arguments
129140 update_clause = " AND ".join(
130141 [f+'=:'+f
131 - for f in ('password', 'realname', 'quota', 'active')
 142+ for f in updateables
132143 if f in fields])
133144
134145 # Build WHERE clause from selectables
@@ -138,6 +149,34 @@
139150 conn.cursor().execute("UPDATE account SET %s WHERE %s" % (update_clause, where_clause), fields)
140151 conn.commit()
141152
 153+def show_field(fields):
 154+ """
 155+ Shows a single field of an account - useful for larger text fields such as 'filter'
 156+ """
 157+
 158+ global conn, table_fields
 159+
 160+ require_fields( (('id', ), ('email', )), fields)
 161+
 162+ # Determine the field to display
 163+ field = fields['show']
 164+ if not field in table_fields:
 165+ raise Exception("Invalid selected field " + field)
 166+
 167+ # Build WHERE clause from selectables
 168+ where_clause = (fields.has_key('id')
 169+ and "id=:id"
 170+ or "localpart=:localpart AND domain=:domain")
 171+
 172+ cur = conn.cursor()
 173+ cur.execute("SELECT " + field + " FROM account WHERE " + where_clause, fields)
 174+
 175+ value = cur.fetchone()[0]
 176+ if value is not None:
 177+ print value
 178+ else:
 179+ print >> sys.stderr, "(NULL)"
 180+
142181 def require_fields(required_fields, fields):
143182 """
144183 Checks whether all required fields given in the nested tuple
@@ -159,7 +198,7 @@
160199 # TODO: syntax checking
161200 return fields
162201
163 -def password_input(fields):
 202+def input_password(fields):
164203 """
165204 Checks if the password argument on the commandline was "-" or empty,
166205 and prompts for a password if that is the case
@@ -167,7 +206,7 @@
168207
169208 global supported_hash_algorithms
170209
171 - if fields['password'] not in ('', '-'): return
 210+ if not fields.has_key('password') or fields['password'] not in ('', '-'): return
172211
173212 # Simply outsource to dovecotpw
174213 pipe = os.popen('dovecotpw -s sha1', 'r')
@@ -177,8 +216,24 @@
178217 fields['password'] = password
179218 else:
180219 raise Exception("Problem invoking dovecotpw")
181 -
182220
 221+def input_filter(fields):
 222+ """
 223+ Reads a filter from a file into fields['filter'] (overwriting)
 224+ """
 225+
 226+ if fields['filter'] == "": return
 227+
 228+ if fields['filter'] == '-':
 229+ filterfile = sys.stdin
 230+ else:
 231+ try:
 232+ filterfile = open(fields['filter'])
 233+ except IOError, e:
 234+ raise Exception("Could not open filter file %s: %e" % (fields['filter'], e.message))
 235+
 236+ fields['filter'] = filterfile.read(4096)
 237+
183238 def add_index(dct, fieldindex):
184239 """
185240 Expects: a dict containing tuples
@@ -225,10 +280,19 @@
226281 import getopt
227282 global actions, fieldmappings, dbname
228283
229 - # Build option list
230 - options = "".join(actions.keys() + [c+':' for c in fieldmappings.keys()]) + "h"
231 - long_options = [o[0] for o in actions.values()] + \
232 - [o[0]+'=' for o in fieldmappings.values()] + \
 284+ # Build option lists for actions
 285+ options, long_options = "", []
 286+ for action, attributes in actions.iteritems():
 287+ if attributes[2]: # Argument required
 288+ options += action + ':'
 289+ long_options.append(attributes[0] + '=')
 290+ else:
 291+ options += action
 292+ long_options.append(attributes[0])
 293+
 294+ # Build option lists for fields
 295+ options += "".join([c+':' for c in fieldmappings.keys()]) + "h"
 296+ long_options += [o[0]+'=' for o in fieldmappings.values()] + \
233297 ["--help"]
234298
235299 try:
@@ -253,6 +317,8 @@
254318 optionc = o[1]
255319 if optionc in actions and action is None:
256320 action = actions[optionc][0]
 321+ if actions[optionc][2]: # Action with parameter, store in fields
 322+ fields[action] = a
257323 elif optionc in fieldmappings:
258324 fields[fieldmappings[optionc][0]] = a
259325 else:
@@ -263,6 +329,8 @@
264330 loption = o[2:]
265331 if loption in actions and action is None:
266332 action = loption
 333+ if actions[action][2]: # Action with parameter, store in fields
 334+ fields[action] = a
267335 elif loption in fieldmappings:
268336 fields[loption] = a
269337 else:
@@ -308,6 +376,8 @@
309377 update_account(fields)
310378 print "Account updated:"
311379 list_accounts(fields)
 380+ elif action == 'show':
 381+ show_field(fields)
312382 except sqlite3.IntegrityError, e:
313383 print >> sys.stderr, "SQL integrity error. Account does already exist? (%s)" % e.message
314384 sys.exit(2)

Status & tagging log