96 txt_wrpr.initial_indent = txt_wrpr.subsequent_indent = ' ' |
96 txt_wrpr.initial_indent = txt_wrpr.subsequent_indent = ' ' |
97 try: |
97 try: |
98 [w_std(txt_wrpr.fill(_(para)) + '\n') for para |
98 [w_std(txt_wrpr.fill(_(para)) + '\n') for para |
99 in help_msgs[self.name]] |
99 in help_msgs[self.name]] |
100 except KeyError: |
100 except KeyError: |
101 w_err(1, _(u"Subcommand '%s' is not yet documented." % self.name), |
101 w_err(1, _("Subcommand '%s' is not yet documented." % self.name), |
102 'see also: vmm(1)') |
102 'see also: vmm(1)') |
103 |
103 |
104 |
104 |
105 class RunContext(object): |
105 class RunContext(object): |
106 """Contains all information necessary to run a subcommand.""" |
106 """Contains all information necessary to run a subcommand.""" |
107 __slots__ = ('argc', 'args', 'cget', 'hdlr', 'scmd') |
107 __slots__ = ('argc', 'args', 'cget', 'hdlr', 'scmd') |
108 plan_a_b = _(u'Plan A failed ... trying Plan B: %(subcommand)s %(object)s') |
108 plan_a_b = _('Plan A failed ... trying Plan B: %(subcommand)s %(object)s') |
109 |
109 |
110 def __init__(self, argv, handler, command): |
110 def __init__(self, argv, handler, command): |
111 """Create a new RunContext""" |
111 """Create a new RunContext""" |
112 self.argc = len(argv) |
112 self.argc = len(argv) |
113 self.args = [unicode(arg, ENCODING) for arg in argv] |
113 self.args = [str(arg, ENCODING) for arg in argv] |
114 self.cget = handler.cfg_dget |
114 self.cget = handler.cfg_dget |
115 self.hdlr = handler |
115 self.hdlr = handler |
116 self.scmd = command |
116 self.scmd = command |
117 |
117 |
118 |
118 |
119 def alias_add(ctx): |
119 def alias_add(ctx): |
120 """create a new alias e-mail address""" |
120 """create a new alias e-mail address""" |
121 if ctx.argc < 3: |
121 if ctx.argc < 3: |
122 usage(EX_MISSING_ARGS, _(u'Missing alias address and destination.'), |
122 usage(EX_MISSING_ARGS, _('Missing alias address and destination.'), |
123 ctx.scmd) |
123 ctx.scmd) |
124 elif ctx.argc < 4: |
124 elif ctx.argc < 4: |
125 usage(EX_MISSING_ARGS, _(u'Missing destination address.'), ctx.scmd) |
125 usage(EX_MISSING_ARGS, _('Missing destination address.'), ctx.scmd) |
126 ctx.hdlr.alias_add(ctx.args[2].lower(), *ctx.args[3:]) |
126 ctx.hdlr.alias_add(ctx.args[2].lower(), *ctx.args[3:]) |
127 |
127 |
128 |
128 |
129 def alias_delete(ctx): |
129 def alias_delete(ctx): |
130 """delete the specified alias e-mail address or one of its destinations""" |
130 """delete the specified alias e-mail address or one of its destinations""" |
131 if ctx.argc < 3: |
131 if ctx.argc < 3: |
132 usage(EX_MISSING_ARGS, _(u'Missing alias address.'), ctx.scmd) |
132 usage(EX_MISSING_ARGS, _('Missing alias address.'), ctx.scmd) |
133 elif ctx.argc < 4: |
133 elif ctx.argc < 4: |
134 ctx.hdlr.alias_delete(ctx.args[2].lower()) |
134 ctx.hdlr.alias_delete(ctx.args[2].lower()) |
135 else: |
135 else: |
136 ctx.hdlr.alias_delete(ctx.args[2].lower(), ctx.args[3:]) |
136 ctx.hdlr.alias_delete(ctx.args[2].lower(), ctx.args[3:]) |
137 |
137 |
138 |
138 |
139 def alias_info(ctx): |
139 def alias_info(ctx): |
140 """show the destination(s) of the specified alias""" |
140 """show the destination(s) of the specified alias""" |
141 if ctx.argc < 3: |
141 if ctx.argc < 3: |
142 usage(EX_MISSING_ARGS, _(u'Missing alias address.'), ctx.scmd) |
142 usage(EX_MISSING_ARGS, _('Missing alias address.'), ctx.scmd) |
143 address = ctx.args[2].lower() |
143 address = ctx.args[2].lower() |
144 try: |
144 try: |
145 _print_aliase_info(address, ctx.hdlr.alias_info(address)) |
145 _print_aliase_info(address, ctx.hdlr.alias_info(address)) |
146 except VMMError, err: |
146 except VMMError as err: |
147 if err.code is ACCOUNT_EXISTS: |
147 if err.code is ACCOUNT_EXISTS: |
148 w_err(0, ctx.plan_a_b % {'subcommand': u'userinfo', |
148 w_err(0, ctx.plan_a_b % {'subcommand': 'userinfo', |
149 'object': address}) |
149 'object': address}) |
150 ctx.scmd = ctx.args[1] = 'userinfo' |
150 ctx.scmd = ctx.args[1] = 'userinfo' |
151 user_info(ctx) |
151 user_info(ctx) |
152 elif err.code is RELOCATED_EXISTS: |
152 elif err.code is RELOCATED_EXISTS: |
153 w_err(0, ctx.plan_a_b % {'subcommand': u'relocatedinfo', |
153 w_err(0, ctx.plan_a_b % {'subcommand': 'relocatedinfo', |
154 'object': address}) |
154 'object': address}) |
155 ctx.scmd = ctx.args[1] = 'relocatedinfo' |
155 ctx.scmd = ctx.args[1] = 'relocatedinfo' |
156 relocated_info(ctx) |
156 relocated_info(ctx) |
157 else: |
157 else: |
158 raise |
158 raise |
159 |
159 |
160 |
160 |
161 def aliasdomain_add(ctx): |
161 def aliasdomain_add(ctx): |
162 """create a new alias for an existing domain""" |
162 """create a new alias for an existing domain""" |
163 if ctx.argc < 3: |
163 if ctx.argc < 3: |
164 usage(EX_MISSING_ARGS, _(u'Missing alias domain name and destination ' |
164 usage(EX_MISSING_ARGS, _('Missing alias domain name and destination ' |
165 u'domain name.'), ctx.scmd) |
165 'domain name.'), ctx.scmd) |
166 elif ctx.argc < 4: |
166 elif ctx.argc < 4: |
167 usage(EX_MISSING_ARGS, _(u'Missing destination domain name.'), |
167 usage(EX_MISSING_ARGS, _('Missing destination domain name.'), |
168 ctx.scmd) |
168 ctx.scmd) |
169 ctx.hdlr.aliasdomain_add(ctx.args[2].lower(), ctx.args[3].lower()) |
169 ctx.hdlr.aliasdomain_add(ctx.args[2].lower(), ctx.args[3].lower()) |
170 |
170 |
171 |
171 |
172 def aliasdomain_delete(ctx): |
172 def aliasdomain_delete(ctx): |
173 """delete the specified alias domain""" |
173 """delete the specified alias domain""" |
174 if ctx.argc < 3: |
174 if ctx.argc < 3: |
175 usage(EX_MISSING_ARGS, _(u'Missing alias domain name.'), ctx.scmd) |
175 usage(EX_MISSING_ARGS, _('Missing alias domain name.'), ctx.scmd) |
176 ctx.hdlr.aliasdomain_delete(ctx.args[2].lower()) |
176 ctx.hdlr.aliasdomain_delete(ctx.args[2].lower()) |
177 |
177 |
178 |
178 |
179 def aliasdomain_info(ctx): |
179 def aliasdomain_info(ctx): |
180 """show the destination of the given alias domain""" |
180 """show the destination of the given alias domain""" |
181 if ctx.argc < 3: |
181 if ctx.argc < 3: |
182 usage(EX_MISSING_ARGS, _(u'Missing alias domain name.'), ctx.scmd) |
182 usage(EX_MISSING_ARGS, _('Missing alias domain name.'), ctx.scmd) |
183 try: |
183 try: |
184 _print_aliasdomain_info(ctx.hdlr.aliasdomain_info(ctx.args[2].lower())) |
184 _print_aliasdomain_info(ctx.hdlr.aliasdomain_info(ctx.args[2].lower())) |
185 except VMMError, err: |
185 except VMMError as err: |
186 if err.code is ALIASDOMAIN_ISDOMAIN: |
186 if err.code is ALIASDOMAIN_ISDOMAIN: |
187 w_err(0, ctx.plan_a_b % {'subcommand': u'domaininfo', |
187 w_err(0, ctx.plan_a_b % {'subcommand': 'domaininfo', |
188 'object': ctx.args[2].lower()}) |
188 'object': ctx.args[2].lower()}) |
189 ctx.scmd = ctx.args[1] = 'domaininfo' |
189 ctx.scmd = ctx.args[1] = 'domaininfo' |
190 domain_info(ctx) |
190 domain_info(ctx) |
191 else: |
191 else: |
192 raise |
192 raise |
193 |
193 |
194 |
194 |
195 def aliasdomain_switch(ctx): |
195 def aliasdomain_switch(ctx): |
196 """assign the given alias domain to an other domain""" |
196 """assign the given alias domain to an other domain""" |
197 if ctx.argc < 3: |
197 if ctx.argc < 3: |
198 usage(EX_MISSING_ARGS, _(u'Missing alias domain name and destination ' |
198 usage(EX_MISSING_ARGS, _('Missing alias domain name and destination ' |
199 u'domain name.'), ctx.scmd) |
199 'domain name.'), ctx.scmd) |
200 elif ctx.argc < 4: |
200 elif ctx.argc < 4: |
201 usage(EX_MISSING_ARGS, _(u'Missing destination domain name.'), |
201 usage(EX_MISSING_ARGS, _('Missing destination domain name.'), |
202 ctx.scmd) |
202 ctx.scmd) |
203 ctx.hdlr.aliasdomain_switch(ctx.args[2].lower(), ctx.args[3].lower()) |
203 ctx.hdlr.aliasdomain_switch(ctx.args[2].lower(), ctx.args[3].lower()) |
204 |
204 |
205 |
205 |
206 def catchall_add(ctx): |
206 def catchall_add(ctx): |
207 """create a new catchall alias e-mail address""" |
207 """create a new catchall alias e-mail address""" |
208 if ctx.argc < 3: |
208 if ctx.argc < 3: |
209 usage(EX_MISSING_ARGS, _(u'Missing domain and destination.'), |
209 usage(EX_MISSING_ARGS, _('Missing domain and destination.'), |
210 ctx.scmd) |
210 ctx.scmd) |
211 elif ctx.argc < 4: |
211 elif ctx.argc < 4: |
212 usage(EX_MISSING_ARGS, _(u'Missing destination address.'), ctx.scmd) |
212 usage(EX_MISSING_ARGS, _('Missing destination address.'), ctx.scmd) |
213 ctx.hdlr.catchall_add(ctx.args[2].lower(), *ctx.args[3:]) |
213 ctx.hdlr.catchall_add(ctx.args[2].lower(), *ctx.args[3:]) |
214 |
214 |
215 |
215 |
216 def catchall_delete(ctx): |
216 def catchall_delete(ctx): |
217 """delete the specified destination or all of the catchall destination""" |
217 """delete the specified destination or all of the catchall destination""" |
218 if ctx.argc < 3: |
218 if ctx.argc < 3: |
219 usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd) |
219 usage(EX_MISSING_ARGS, _('Missing domain name.'), ctx.scmd) |
220 elif ctx.argc < 4: |
220 elif ctx.argc < 4: |
221 ctx.hdlr.catchall_delete(ctx.args[2].lower()) |
221 ctx.hdlr.catchall_delete(ctx.args[2].lower()) |
222 else: |
222 else: |
223 ctx.hdlr.catchall_delete(ctx.args[2].lower(), ctx.args[3:]) |
223 ctx.hdlr.catchall_delete(ctx.args[2].lower(), ctx.args[3:]) |
224 |
224 |
225 |
225 |
226 def catchall_info(ctx): |
226 def catchall_info(ctx): |
227 """show the catchall destination(s) of the specified domain""" |
227 """show the catchall destination(s) of the specified domain""" |
228 if ctx.argc < 3: |
228 if ctx.argc < 3: |
229 usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd) |
229 usage(EX_MISSING_ARGS, _('Missing domain name.'), ctx.scmd) |
230 address = ctx.args[2].lower() |
230 address = ctx.args[2].lower() |
231 _print_catchall_info(address, ctx.hdlr.catchall_info(address)) |
231 _print_catchall_info(address, ctx.hdlr.catchall_info(address)) |
232 |
232 |
233 |
233 |
234 def config_get(ctx): |
234 def config_get(ctx): |
235 """show the actual value of the configuration option""" |
235 """show the actual value of the configuration option""" |
236 if ctx.argc < 3: |
236 if ctx.argc < 3: |
237 usage(EX_MISSING_ARGS, _(u"Missing option name."), ctx.scmd) |
237 usage(EX_MISSING_ARGS, _("Missing option name."), ctx.scmd) |
238 |
238 |
239 noop = lambda option: option |
239 noop = lambda option: option |
240 opt_formater = { |
240 opt_formater = { |
241 'misc.dovecot_version': version_str, |
241 'misc.dovecot_version': version_str, |
242 'domain.quota_bytes': human_size, |
242 'domain.quota_bytes': human_size, |
266 |
266 |
267 |
267 |
268 def domain_add(ctx): |
268 def domain_add(ctx): |
269 """create a new domain""" |
269 """create a new domain""" |
270 if ctx.argc < 3: |
270 if ctx.argc < 3: |
271 usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd) |
271 usage(EX_MISSING_ARGS, _('Missing domain name.'), ctx.scmd) |
272 elif ctx.argc < 4: |
272 elif ctx.argc < 4: |
273 ctx.hdlr.domain_add(ctx.args[2].lower()) |
273 ctx.hdlr.domain_add(ctx.args[2].lower()) |
274 else: |
274 else: |
275 ctx.hdlr.domain_add(ctx.args[2].lower(), ctx.args[3]) |
275 ctx.hdlr.domain_add(ctx.args[2].lower(), ctx.args[3]) |
276 if ctx.cget('domain.auto_postmaster'): |
276 if ctx.cget('domain.auto_postmaster'): |
277 w_std(_(u'Creating account for postmaster@%s') % ctx.args[2].lower()) |
277 w_std(_('Creating account for postmaster@%s') % ctx.args[2].lower()) |
278 ctx.scmd = 'useradd' |
278 ctx.scmd = 'useradd' |
279 ctx.args = [prog, ctx.scmd, u'postmaster@' + ctx.args[2].lower()] |
279 ctx.args = [prog, ctx.scmd, 'postmaster@' + ctx.args[2].lower()] |
280 ctx.argc = 3 |
280 ctx.argc = 3 |
281 user_add(ctx) |
281 user_add(ctx) |
282 |
282 |
283 |
283 |
284 def domain_delete(ctx): |
284 def domain_delete(ctx): |
285 """delete the given domain and all its alias domains""" |
285 """delete the given domain and all its alias domains""" |
286 if ctx.argc < 3: |
286 if ctx.argc < 3: |
287 usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd) |
287 usage(EX_MISSING_ARGS, _('Missing domain name.'), ctx.scmd) |
288 elif ctx.argc < 4: |
288 elif ctx.argc < 4: |
289 ctx.hdlr.domain_delete(ctx.args[2].lower()) |
289 ctx.hdlr.domain_delete(ctx.args[2].lower()) |
290 elif ctx.args[3].lower() == 'force': |
290 elif ctx.args[3].lower() == 'force': |
291 ctx.hdlr.domain_delete(ctx.args[2].lower(), True) |
291 ctx.hdlr.domain_delete(ctx.args[2].lower(), True) |
292 else: |
292 else: |
293 usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % ctx.args[3], |
293 usage(INVALID_ARGUMENT, _("Invalid argument: '%s'") % ctx.args[3], |
294 ctx.scmd) |
294 ctx.scmd) |
295 |
295 |
296 |
296 |
297 def domain_info(ctx): |
297 def domain_info(ctx): |
298 """display information about the given domain""" |
298 """display information about the given domain""" |
299 if ctx.argc < 3: |
299 if ctx.argc < 3: |
300 usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd) |
300 usage(EX_MISSING_ARGS, _('Missing domain name.'), ctx.scmd) |
301 if ctx.argc < 4: |
301 if ctx.argc < 4: |
302 details = None |
302 details = None |
303 else: |
303 else: |
304 details = ctx.args[3].lower() |
304 details = ctx.args[3].lower() |
305 if details not in ('accounts', 'aliasdomains', 'aliases', 'full', |
305 if details not in ('accounts', 'aliasdomains', 'aliases', 'full', |
306 'relocated', 'catchall'): |
306 'relocated', 'catchall'): |
307 usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % details, |
307 usage(INVALID_ARGUMENT, _("Invalid argument: '%s'") % details, |
308 ctx.scmd) |
308 ctx.scmd) |
309 try: |
309 try: |
310 info = ctx.hdlr.domain_info(ctx.args[2].lower(), details) |
310 info = ctx.hdlr.domain_info(ctx.args[2].lower(), details) |
311 except VMMError, err: |
311 except VMMError as err: |
312 if err.code is DOMAIN_ALIAS_EXISTS: |
312 if err.code is DOMAIN_ALIAS_EXISTS: |
313 w_err(0, ctx.plan_a_b % {'subcommand': u'aliasdomaininfo', |
313 w_err(0, ctx.plan_a_b % {'subcommand': 'aliasdomaininfo', |
314 'object': ctx.args[2].lower()}) |
314 'object': ctx.args[2].lower()}) |
315 ctx.scmd = ctx.args[1] = 'aliasdomaininfo' |
315 ctx.scmd = ctx.args[1] = 'aliasdomaininfo' |
316 aliasdomain_info(ctx) |
316 aliasdomain_info(ctx) |
317 else: |
317 else: |
318 raise |
318 raise |
319 else: |
319 else: |
320 q_limit = u'Storage: %(bytes)s; Messages: %(messages)s' |
320 q_limit = 'Storage: %(bytes)s; Messages: %(messages)s' |
321 if not details: |
321 if not details: |
322 info['bytes'] = human_size(info['bytes']) |
322 info['bytes'] = human_size(info['bytes']) |
323 info['messages'] = locale.format('%d', info['messages'], |
323 info['messages'] = locale.format('%d', info['messages'], |
324 True).decode(ENCODING, 'replace') |
324 True).decode(ENCODING, 'replace') |
325 info['quota limit/user'] = q_limit % info |
325 info['quota limit/user'] = q_limit % info |
326 _print_info(ctx, info, _(u'Domain')) |
326 _print_info(ctx, info, _('Domain')) |
327 else: |
327 else: |
328 info[0]['bytes'] = human_size(info[0]['bytes']) |
328 info[0]['bytes'] = human_size(info[0]['bytes']) |
329 info[0]['messages'] = locale.format('%d', info[0]['messages'], |
329 info[0]['messages'] = locale.format('%d', info[0]['messages'], |
330 True).decode(ENCODING, |
330 True).decode(ENCODING, |
331 'replace') |
331 'replace') |
332 info[0]['quota limit/user'] = q_limit % info[0] |
332 info[0]['quota limit/user'] = q_limit % info[0] |
333 _print_info(ctx, info[0], _(u'Domain')) |
333 _print_info(ctx, info[0], _('Domain')) |
334 if details == u'accounts': |
334 if details == 'accounts': |
335 _print_list(info[1], _(u'accounts')) |
335 _print_list(info[1], _('accounts')) |
336 elif details == u'aliasdomains': |
336 elif details == 'aliasdomains': |
337 _print_list(info[1], _(u'alias domains')) |
337 _print_list(info[1], _('alias domains')) |
338 elif details == u'aliases': |
338 elif details == 'aliases': |
339 _print_list(info[1], _(u'aliases')) |
339 _print_list(info[1], _('aliases')) |
340 elif details == u'relocated': |
340 elif details == 'relocated': |
341 _print_list(info[1], _(u'relocated users')) |
341 _print_list(info[1], _('relocated users')) |
342 elif details == u'catchall': |
342 elif details == 'catchall': |
343 _print_list(info[1], _(u'catch-all destinations')) |
343 _print_list(info[1], _('catch-all destinations')) |
344 else: |
344 else: |
345 _print_list(info[1], _(u'alias domains')) |
345 _print_list(info[1], _('alias domains')) |
346 _print_list(info[2], _(u'accounts')) |
346 _print_list(info[2], _('accounts')) |
347 _print_list(info[3], _(u'aliases')) |
347 _print_list(info[3], _('aliases')) |
348 _print_list(info[4], _(u'relocated users')) |
348 _print_list(info[4], _('relocated users')) |
349 _print_list(info[5], _(u'catch-all destinations')) |
349 _print_list(info[5], _('catch-all destinations')) |
350 |
350 |
351 |
351 |
352 def domain_quota(ctx): |
352 def domain_quota(ctx): |
353 """update the quota limit of the specified domain""" |
353 """update the quota limit of the specified domain""" |
354 if ctx.argc < 3: |
354 if ctx.argc < 3: |
355 usage(EX_MISSING_ARGS, _(u'Missing domain name and storage value.'), |
355 usage(EX_MISSING_ARGS, _('Missing domain name and storage value.'), |
356 ctx.scmd) |
356 ctx.scmd) |
357 if ctx.argc < 4: |
357 if ctx.argc < 4: |
358 usage(EX_MISSING_ARGS, _(u'Missing storage value.'), ctx.scmd) |
358 usage(EX_MISSING_ARGS, _('Missing storage value.'), ctx.scmd) |
359 messages = 0 |
359 messages = 0 |
360 force = None |
360 force = None |
361 try: |
361 try: |
362 bytes_ = size_in_bytes(ctx.args[3]) |
362 bytes_ = size_in_bytes(ctx.args[3]) |
363 except (ValueError, TypeError): |
363 except (ValueError, TypeError): |
364 usage(INVALID_ARGUMENT, _(u"Invalid storage value: '%s'") % |
364 usage(INVALID_ARGUMENT, _("Invalid storage value: '%s'") % |
365 ctx.args[3], ctx.scmd) |
365 ctx.args[3], ctx.scmd) |
366 if ctx.argc < 5: |
366 if ctx.argc < 5: |
367 pass |
367 pass |
368 elif ctx.argc < 6: |
368 elif ctx.argc < 6: |
369 try: |
369 try: |
370 messages = int(ctx.args[4]) |
370 messages = int(ctx.args[4]) |
371 except ValueError: |
371 except ValueError: |
372 if ctx.args[4].lower() != 'force': |
372 if ctx.args[4].lower() != 'force': |
373 usage(INVALID_ARGUMENT, |
373 usage(INVALID_ARGUMENT, |
374 _(u"Neither a valid number of messages nor the keyword " |
374 _("Neither a valid number of messages nor the keyword " |
375 u"'force': '%s'") % ctx.args[4], ctx.scmd) |
375 "'force': '%s'") % ctx.args[4], ctx.scmd) |
376 force = 'force' |
376 force = 'force' |
377 else: |
377 else: |
378 try: |
378 try: |
379 messages = int(ctx.args[4]) |
379 messages = int(ctx.args[4]) |
380 except ValueError: |
380 except ValueError: |
381 usage(INVALID_ARGUMENT, |
381 usage(INVALID_ARGUMENT, |
382 _(u"Not a valid number of messages: '%s'") % ctx.args[4], |
382 _("Not a valid number of messages: '%s'") % ctx.args[4], |
383 ctx.scmd) |
383 ctx.scmd) |
384 if ctx.args[5].lower() != 'force': |
384 if ctx.args[5].lower() != 'force': |
385 usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % ctx.args[5], |
385 usage(INVALID_ARGUMENT, _("Invalid argument: '%s'") % ctx.args[5], |
386 ctx.scmd) |
386 ctx.scmd) |
387 force = 'force' |
387 force = 'force' |
388 ctx.hdlr.domain_quotalimit(ctx.args[2].lower(), bytes_, messages, force) |
388 ctx.hdlr.domain_quotalimit(ctx.args[2].lower(), bytes_, messages, force) |
389 |
389 |
390 |
390 |
391 def domain_services(ctx): |
391 def domain_services(ctx): |
392 """allow all named service and block the uncredited.""" |
392 """allow all named service and block the uncredited.""" |
393 if ctx.argc < 3: |
393 if ctx.argc < 3: |
394 usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd) |
394 usage(EX_MISSING_ARGS, _('Missing domain name.'), ctx.scmd) |
395 services = [] |
395 services = [] |
396 force = False |
396 force = False |
397 if ctx.argc is 3: |
397 if ctx.argc is 3: |
398 pass |
398 pass |
399 elif ctx.argc is 4: |
399 elif ctx.argc is 4: |
547 |
546 |
548 def relocated_add(ctx): |
547 def relocated_add(ctx): |
549 """create a new record for a relocated user""" |
548 """create a new record for a relocated user""" |
550 if ctx.argc < 3: |
549 if ctx.argc < 3: |
551 usage(EX_MISSING_ARGS, |
550 usage(EX_MISSING_ARGS, |
552 _(u'Missing relocated address and destination.'), ctx.scmd) |
551 _('Missing relocated address and destination.'), ctx.scmd) |
553 elif ctx.argc < 4: |
552 elif ctx.argc < 4: |
554 usage(EX_MISSING_ARGS, _(u'Missing destination address.'), ctx.scmd) |
553 usage(EX_MISSING_ARGS, _('Missing destination address.'), ctx.scmd) |
555 ctx.hdlr.relocated_add(ctx.args[2].lower(), ctx.args[3]) |
554 ctx.hdlr.relocated_add(ctx.args[2].lower(), ctx.args[3]) |
556 |
555 |
557 |
556 |
558 def relocated_delete(ctx): |
557 def relocated_delete(ctx): |
559 """delete the record of the relocated user""" |
558 """delete the record of the relocated user""" |
560 if ctx.argc < 3: |
559 if ctx.argc < 3: |
561 usage(EX_MISSING_ARGS, _(u'Missing relocated address.'), ctx.scmd) |
560 usage(EX_MISSING_ARGS, _('Missing relocated address.'), ctx.scmd) |
562 ctx.hdlr.relocated_delete(ctx.args[2].lower()) |
561 ctx.hdlr.relocated_delete(ctx.args[2].lower()) |
563 |
562 |
564 |
563 |
565 def relocated_info(ctx): |
564 def relocated_info(ctx): |
566 """print information about a relocated user""" |
565 """print information about a relocated user""" |
567 if ctx.argc < 3: |
566 if ctx.argc < 3: |
568 usage(EX_MISSING_ARGS, _(u'Missing relocated address.'), ctx.scmd) |
567 usage(EX_MISSING_ARGS, _('Missing relocated address.'), ctx.scmd) |
569 relocated = ctx.args[2].lower() |
568 relocated = ctx.args[2].lower() |
570 try: |
569 try: |
571 _print_relocated_info(addr=relocated, |
570 _print_relocated_info(addr=relocated, |
572 dest=ctx.hdlr.relocated_info(relocated)) |
571 dest=ctx.hdlr.relocated_info(relocated)) |
573 except VMMError, err: |
572 except VMMError as err: |
574 if err.code is ACCOUNT_EXISTS: |
573 if err.code is ACCOUNT_EXISTS: |
575 w_err(0, ctx.plan_a_b % {'subcommand': u'userinfo', |
574 w_err(0, ctx.plan_a_b % {'subcommand': 'userinfo', |
576 'object': relocated}) |
575 'object': relocated}) |
577 ctx.scmd = ctx.args[1] = 'userinfoi' |
576 ctx.scmd = ctx.args[1] = 'userinfoi' |
578 user_info(ctx) |
577 user_info(ctx) |
579 elif err.code is ALIAS_EXISTS: |
578 elif err.code is ALIAS_EXISTS: |
580 w_err(0, ctx.plan_a_b % {'subcommand': u'aliasinfo', |
579 w_err(0, ctx.plan_a_b % {'subcommand': 'aliasinfo', |
581 'object': relocated}) |
580 'object': relocated}) |
582 ctx.scmd = ctx.args[1] = 'aliasinfo' |
581 ctx.scmd = ctx.args[1] = 'aliasinfo' |
583 alias_info(ctx) |
582 alias_info(ctx) |
584 else: |
583 else: |
585 raise |
584 raise |
586 |
585 |
587 |
586 |
588 def user_add(ctx): |
587 def user_add(ctx): |
589 """create a new e-mail user with the given address""" |
588 """create a new e-mail user with the given address""" |
590 if ctx.argc < 3: |
589 if ctx.argc < 3: |
591 usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), ctx.scmd) |
590 usage(EX_MISSING_ARGS, _('Missing e-mail address.'), ctx.scmd) |
592 elif ctx.argc < 4: |
591 elif ctx.argc < 4: |
593 password = None |
592 password = None |
594 else: |
593 else: |
595 password = ctx.args[3] |
594 password = ctx.args[3] |
596 gen_pass = ctx.hdlr.user_add(ctx.args[2].lower(), password) |
595 gen_pass = ctx.hdlr.user_add(ctx.args[2].lower(), password) |
597 if ctx.argc < 4 and gen_pass: |
596 if ctx.argc < 4 and gen_pass: |
598 w_std(_(u"Generated password: %s") % gen_pass) |
597 w_std(_("Generated password: %s") % gen_pass) |
599 |
598 |
600 |
599 |
601 def user_delete(ctx): |
600 def user_delete(ctx): |
602 """delete the specified user""" |
601 """delete the specified user""" |
603 if ctx.argc < 3: |
602 if ctx.argc < 3: |
604 usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), ctx.scmd) |
603 usage(EX_MISSING_ARGS, _('Missing e-mail address.'), ctx.scmd) |
605 elif ctx.argc < 4: |
604 elif ctx.argc < 4: |
606 ctx.hdlr.user_delete(ctx.args[2].lower()) |
605 ctx.hdlr.user_delete(ctx.args[2].lower()) |
607 elif ctx.args[3].lower() == 'force': |
606 elif ctx.args[3].lower() == 'force': |
608 ctx.hdlr.user_delete(ctx.args[2].lower(), True) |
607 ctx.hdlr.user_delete(ctx.args[2].lower(), True) |
609 else: |
608 else: |
610 usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % ctx.args[3], |
609 usage(INVALID_ARGUMENT, _("Invalid argument: '%s'") % ctx.args[3], |
611 ctx.scmd) |
610 ctx.scmd) |
612 |
611 |
613 |
612 |
614 def user_info(ctx): |
613 def user_info(ctx): |
615 """display information about the given address""" |
614 """display information about the given address""" |
616 if ctx.argc < 3: |
615 if ctx.argc < 3: |
617 usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), ctx.scmd) |
616 usage(EX_MISSING_ARGS, _('Missing e-mail address.'), ctx.scmd) |
618 if ctx.argc < 4: |
617 if ctx.argc < 4: |
619 details = None |
618 details = None |
620 else: |
619 else: |
621 details = ctx.args[3].lower() |
620 details = ctx.args[3].lower() |
622 if details not in ('aliases', 'du', 'full'): |
621 if details not in ('aliases', 'du', 'full'): |
623 usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % details, |
622 usage(INVALID_ARGUMENT, _("Invalid argument: '%s'") % details, |
624 ctx.scmd) |
623 ctx.scmd) |
625 try: |
624 try: |
626 info = ctx.hdlr.user_info(ctx.args[2].lower(), details) |
625 info = ctx.hdlr.user_info(ctx.args[2].lower(), details) |
627 except VMMError, err: |
626 except VMMError as err: |
628 if err.code is ALIAS_EXISTS: |
627 if err.code is ALIAS_EXISTS: |
629 w_err(0, ctx.plan_a_b % {'subcommand': u'aliasinfo', |
628 w_err(0, ctx.plan_a_b % {'subcommand': 'aliasinfo', |
630 'object': ctx.args[2].lower()}) |
629 'object': ctx.args[2].lower()}) |
631 ctx.scmd = ctx.args[1] = 'aliasinfo' |
630 ctx.scmd = ctx.args[1] = 'aliasinfo' |
632 alias_info(ctx) |
631 alias_info(ctx) |
633 elif err.code is RELOCATED_EXISTS: |
632 elif err.code is RELOCATED_EXISTS: |
634 w_err(0, ctx.plan_a_b % {'subcommand': u'relocatedinfo', |
633 w_err(0, ctx.plan_a_b % {'subcommand': 'relocatedinfo', |
635 'object': ctx.args[2].lower()}) |
634 'object': ctx.args[2].lower()}) |
636 ctx.scmd = ctx.args[1] = 'relocatedinfo' |
635 ctx.scmd = ctx.args[1] = 'relocatedinfo' |
637 relocated_info(ctx) |
636 relocated_info(ctx) |
638 else: |
637 else: |
639 raise |
638 raise |
693 |
692 |
694 |
693 |
695 def user_quota(ctx): |
694 def user_quota(ctx): |
696 """update the quota limit for the given address""" |
695 """update the quota limit for the given address""" |
697 if ctx.argc < 3: |
696 if ctx.argc < 3: |
698 usage(EX_MISSING_ARGS, _(u'Missing e-mail address and storage value.'), |
697 usage(EX_MISSING_ARGS, _('Missing e-mail address and storage value.'), |
699 ctx.scmd) |
698 ctx.scmd) |
700 elif ctx.argc < 4: |
699 elif ctx.argc < 4: |
701 usage(EX_MISSING_ARGS, _(u'Missing storage value.'), ctx.scmd) |
700 usage(EX_MISSING_ARGS, _('Missing storage value.'), ctx.scmd) |
702 if ctx.args[3] != 'domain': |
701 if ctx.args[3] != 'domain': |
703 try: |
702 try: |
704 bytes_ = size_in_bytes(ctx.args[3]) |
703 bytes_ = size_in_bytes(ctx.args[3]) |
705 except (ValueError, TypeError): |
704 except (ValueError, TypeError): |
706 usage(INVALID_ARGUMENT, _(u"Invalid storage value: '%s'") % |
705 usage(INVALID_ARGUMENT, _("Invalid storage value: '%s'") % |
707 ctx.args[3], ctx.scmd) |
706 ctx.args[3], ctx.scmd) |
708 else: |
707 else: |
709 bytes_ = ctx.args[3] |
708 bytes_ = ctx.args[3] |
710 if ctx.argc < 5: |
709 if ctx.argc < 5: |
711 messages = 0 |
710 messages = 0 |
712 else: |
711 else: |
713 try: |
712 try: |
714 messages = int(ctx.args[4]) |
713 messages = int(ctx.args[4]) |
715 except ValueError: |
714 except ValueError: |
716 usage(INVALID_ARGUMENT, |
715 usage(INVALID_ARGUMENT, |
717 _(u"Not a valid number of messages: '%s'") % ctx.args[4], |
716 _("Not a valid number of messages: '%s'") % ctx.args[4], |
718 ctx.scmd) |
717 ctx.scmd) |
719 ctx.hdlr.user_quotalimit(ctx.args[2].lower(), bytes_, messages) |
718 ctx.hdlr.user_quotalimit(ctx.args[2].lower(), bytes_, messages) |
720 |
719 |
721 |
720 |
722 def user_services(ctx): |
721 def user_services(ctx): |
723 """allow all named service and block the uncredited.""" |
722 """allow all named service and block the uncredited.""" |
724 if ctx.argc < 3: |
723 if ctx.argc < 3: |
725 usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), ctx.scmd) |
724 usage(EX_MISSING_ARGS, _('Missing e-mail address.'), ctx.scmd) |
726 services = [] |
725 services = [] |
727 if ctx.argc >= 4: |
726 if ctx.argc >= 4: |
728 services.extend([service.lower() for service in ctx.args[3:]]) |
727 services.extend([service.lower() for service in ctx.args[3:]]) |
729 unknown = [service for service in services if service not in SERVICES] |
728 unknown = [service for service in services if service not in SERVICES] |
730 if unknown and ctx.args[3] != 'domain': |
729 if unknown and ctx.args[3] != 'domain': |
731 usage(INVALID_ARGUMENT, _(u'Invalid service arguments: %s') % |
730 usage(INVALID_ARGUMENT, _('Invalid service arguments: %s') % |
732 ' '.join(unknown), ctx.scmd) |
731 ' '.join(unknown), ctx.scmd) |
733 ctx.hdlr.user_services(ctx.args[2].lower(), *services) |
732 ctx.hdlr.user_services(ctx.args[2].lower(), *services) |
734 |
733 |
735 |
734 |
736 def user_transport(ctx): |
735 def user_transport(ctx): |
737 """update the transport of the given address""" |
736 """update the transport of the given address""" |
738 if ctx.argc < 3: |
737 if ctx.argc < 3: |
739 usage(EX_MISSING_ARGS, _(u'Missing e-mail address and transport.'), |
738 usage(EX_MISSING_ARGS, _('Missing e-mail address and transport.'), |
740 ctx.scmd) |
739 ctx.scmd) |
741 if ctx.argc < 4: |
740 if ctx.argc < 4: |
742 usage(EX_MISSING_ARGS, _(u'Missing transport.'), ctx.scmd) |
741 usage(EX_MISSING_ARGS, _('Missing transport.'), ctx.scmd) |
743 ctx.hdlr.user_transport(ctx.args[2].lower(), ctx.args[3]) |
742 ctx.hdlr.user_transport(ctx.args[2].lower(), ctx.args[3]) |
744 |
743 |
745 |
744 |
746 def usage(errno, errmsg, subcommand=None): |
745 def usage(errno, errmsg, subcommand=None): |
747 """print usage message for the given command or all commands. |
746 """print usage message for the given command or all commands. |
748 When errno > 0, sys,exit(errno) will interrupt the program. |
747 When errno > 0, sys,exit(errno) will interrupt the program. |
749 """ |
748 """ |
750 if subcommand and subcommand in cmd_map: |
749 if subcommand and subcommand in cmd_map: |
751 w_err(errno, _(u"Error: %s") % errmsg, |
750 w_err(errno, _("Error: %s") % errmsg, |
752 _(u"usage: ") + cmd_map[subcommand].usage) |
751 _("usage: ") + cmd_map[subcommand].usage) |
753 |
752 |
754 # TP: Please adjust translated words like the original text. |
753 # TP: Please adjust translated words like the original text. |
755 # (It's a table header.) Extract from usage text: |
754 # (It's a table header.) Extract from usage text: |
756 # usage: vmm subcommand arguments |
755 # usage: vmm subcommand arguments |
757 # short long |
756 # short long |
758 # subcommand arguments |
757 # subcommand arguments |
759 # |
758 # |
760 # da domainadd fqdn [transport] |
759 # da domainadd fqdn [transport] |
761 # dd domaindelete fqdn [force] |
760 # dd domaindelete fqdn [force] |
762 u_head = _(u"""usage: %s subcommand arguments |
761 u_head = _("""usage: %s subcommand arguments |
763 short long |
762 short long |
764 subcommand arguments\n""") % prog |
763 subcommand arguments\n""") % prog |
765 order = cmd_map.keys() |
764 order = sorted(list(cmd_map.keys())) |
766 order.sort() |
|
767 w_err(0, u_head) |
765 w_err(0, u_head) |
768 for key in order: |
766 for key in order: |
769 scmd = cmd_map[key] |
767 scmd = cmd_map[key] |
770 w_err(0, ' %-5s %-19s %s' % (scmd.alias, scmd.name, scmd.args)) |
768 w_err(0, ' %-5s %-19s %s' % (scmd.alias, scmd.name, scmd.args)) |
771 w_err(errno, '', _(u"Error: %s") % errmsg) |
769 w_err(errno, '', _("Error: %s") % errmsg) |
772 |
770 |
773 |
771 |
774 def version(ctx_unused): |
772 def version(ctx_unused): |
775 """Write version and copyright information to stdout.""" |
773 """Write version and copyright information to stdout.""" |
776 w_std('%s, %s %s (%s %s)\nPython %s %s %s\n\n%s\n%s %s' % (prog, |
774 w_std('%s, %s %s (%s %s)\nPython %s %s %s\n\n%s\n%s %s' % (prog, |
777 # TP: The words 'from', 'version' and 'on' are used in |
775 # TP: The words 'from', 'version' and 'on' are used in |
778 # the version information, e.g.: |
776 # the version information, e.g.: |
779 # vmm, version 0.5.2 (from 09/09/09) |
777 # vmm, version 0.5.2 (from 09/09/09) |
780 # Python 2.5.4 on FreeBSD |
778 # Python 2.5.4 on FreeBSD |
781 _(u'version'), __version__, _(u'from'), |
779 _('version'), __version__, _('from'), |
782 strftime(locale.nl_langinfo(locale.D_FMT), |
780 strftime(locale.nl_langinfo(locale.D_FMT), |
783 strptime(__date__, '%Y-%m-%d')).decode(ENCODING, 'replace'), |
781 strptime(__date__, '%Y-%m-%d')).decode(ENCODING, 'replace'), |
784 os.sys.version.split()[0], _(u'on'), os.uname()[0], |
782 os.sys.version.split()[0], _('on'), os.uname()[0], |
785 __copyright__, prog, |
783 __copyright__, prog, |
786 _(u'is free software and comes with ABSOLUTELY NO WARRANTY.'))) |
784 _('is free software and comes with ABSOLUTELY NO WARRANTY.'))) |
787 |
785 |
788 |
786 |
789 def update_cmd_map(): |
787 def update_cmd_map(): |
790 """Update the cmd_map, after gettext's _ was installed.""" |
788 """Update the cmd_map, after gettext's _ was installed.""" |
791 cmd = Command |
789 cmd = Command |
792 cmd_map.update({ |
790 cmd_map.update({ |
793 # Account commands |
791 # Account commands |
794 'getuser': cmd('getuser', 'gu', get_user, 'uid', |
792 'getuser': cmd('getuser', 'gu', get_user, 'uid', |
795 _(u'get the address of the user with the given UID')), |
793 _('get the address of the user with the given UID')), |
796 'useradd': cmd('useradd', 'ua', user_add, 'address [password]', |
794 'useradd': cmd('useradd', 'ua', user_add, 'address [password]', |
797 _(u'create a new e-mail user with the given address')), |
795 _('create a new e-mail user with the given address')), |
798 'userdelete': cmd('userdelete', 'ud', user_delete, 'address [force]', |
796 'userdelete': cmd('userdelete', 'ud', user_delete, 'address [force]', |
799 _(u'delete the specified user')), |
797 _('delete the specified user')), |
800 'userinfo': cmd('userinfo', 'ui', user_info, 'address [details]', |
798 'userinfo': cmd('userinfo', 'ui', user_info, 'address [details]', |
801 _(u'display information about the given address')), |
799 _('display information about the given address')), |
802 'username': cmd('username', 'un', user_name, 'address [name]', |
800 'username': cmd('username', 'un', user_name, 'address [name]', |
803 _(u'set, update or delete the real name for an address')), |
801 _('set, update or delete the real name for an address')), |
804 'userpassword': cmd('userpassword', 'up', user_password, |
802 'userpassword': cmd('userpassword', 'up', user_password, |
805 'address [password]', |
803 'address [password]', |
806 _(u'update the password for the given address')), |
804 _('update the password for the given address')), |
807 'userquota': cmd('userquota', 'uq', user_quota, |
805 'userquota': cmd('userquota', 'uq', user_quota, |
808 'address storage [messages] | address domain', |
806 'address storage [messages] | address domain', |
809 _(u'update the quota limit for the given address')), |
807 _('update the quota limit for the given address')), |
810 'userservices': cmd('userservices', 'us', user_services, |
808 'userservices': cmd('userservices', 'us', user_services, |
811 'address [service ...] | address domain', |
809 'address [service ...] | address domain', |
812 _(u'enables the specified services and disables all ' |
810 _('enables the specified services and disables all ' |
813 u'not specified services')), |
811 'not specified services')), |
814 'usertransport': cmd('usertransport', 'ut', user_transport, |
812 'usertransport': cmd('usertransport', 'ut', user_transport, |
815 'address transport | address domain', |
813 'address transport | address domain', |
816 _(u'update the transport of the given address')), |
814 _('update the transport of the given address')), |
817 'usernote': cmd('usernote', 'uo', user_note, 'address [note]', |
815 'usernote': cmd('usernote', 'uo', user_note, 'address [note]', |
818 _(u'set, update or delete the note of the given address')), |
816 _('set, update or delete the note of the given address')), |
819 # Alias commands |
817 # Alias commands |
820 'aliasadd': cmd('aliasadd', 'aa', alias_add, 'address destination ...', |
818 'aliasadd': cmd('aliasadd', 'aa', alias_add, 'address destination ...', |
821 _(u'create a new alias e-mail address with one or more ' |
819 _('create a new alias e-mail address with one or more ' |
822 u'destinations')), |
820 'destinations')), |
823 'aliasdelete': cmd('aliasdelete', 'ad', alias_delete, |
821 'aliasdelete': cmd('aliasdelete', 'ad', alias_delete, |
824 'address [destination ...]', |
822 'address [destination ...]', |
825 _(u'delete the specified alias e-mail address or one ' |
823 _('delete the specified alias e-mail address or one ' |
826 u'of its destinations')), |
824 'of its destinations')), |
827 'aliasinfo': cmd('aliasinfo', 'ai', alias_info, 'address', |
825 'aliasinfo': cmd('aliasinfo', 'ai', alias_info, 'address', |
828 _(u'show the destination(s) of the specified alias')), |
826 _('show the destination(s) of the specified alias')), |
829 # AliasDomain commands |
827 # AliasDomain commands |
830 'aliasdomainadd': cmd('aliasdomainadd', 'ada', aliasdomain_add, |
828 'aliasdomainadd': cmd('aliasdomainadd', 'ada', aliasdomain_add, |
831 'fqdn destination', |
829 'fqdn destination', |
832 _(u'create a new alias for an existing domain')), |
830 _('create a new alias for an existing domain')), |
833 'aliasdomaindelete': cmd('aliasdomaindelete', 'add', aliasdomain_delete, |
831 'aliasdomaindelete': cmd('aliasdomaindelete', 'add', aliasdomain_delete, |
834 'fqdn', _(u'delete the specified alias domain')), |
832 'fqdn', _('delete the specified alias domain')), |
835 'aliasdomaininfo': cmd('aliasdomaininfo', 'adi', aliasdomain_info, 'fqdn', |
833 'aliasdomaininfo': cmd('aliasdomaininfo', 'adi', aliasdomain_info, 'fqdn', |
836 _(u'show the destination of the given alias domain')), |
834 _('show the destination of the given alias domain')), |
837 'aliasdomainswitch': cmd('aliasdomainswitch', 'ads', aliasdomain_switch, |
835 'aliasdomainswitch': cmd('aliasdomainswitch', 'ads', aliasdomain_switch, |
838 'fqdn destination', _(u'assign the given alias ' |
836 'fqdn destination', _('assign the given alias ' |
839 'domain to an other domain')), |
837 'domain to an other domain')), |
840 # CatchallAlias commands |
838 # CatchallAlias commands |
841 'catchalladd': cmd('catchalladd', 'caa', catchall_add, |
839 'catchalladd': cmd('catchalladd', 'caa', catchall_add, |
842 'fqdn destination ...', |
840 'fqdn destination ...', |
843 _(u'add one or more catch-all destinations for a ' |
841 _('add one or more catch-all destinations for a ' |
844 u'domain')), |
842 'domain')), |
845 'catchalldelete': cmd('catchalldelete', 'cad', catchall_delete, |
843 'catchalldelete': cmd('catchalldelete', 'cad', catchall_delete, |
846 'fqdn [destination ...]', |
844 'fqdn [destination ...]', |
847 _(u'delete the specified catch-all destination or all ' |
845 _('delete the specified catch-all destination or all ' |
848 u'of a domain\'s destinations')), |
846 'of a domain\'s destinations')), |
849 'catchallinfo': cmd('catchallinfo', 'cai', catchall_info, 'fqdn', |
847 'catchallinfo': cmd('catchallinfo', 'cai', catchall_info, 'fqdn', |
850 _(u'show the catch-all destination(s) of the ' |
848 _('show the catch-all destination(s) of the ' |
851 u'specified domain')), |
849 'specified domain')), |
852 # Domain commands |
850 # Domain commands |
853 'domainadd': cmd('domainadd', 'da', domain_add, 'fqdn [transport]', |
851 'domainadd': cmd('domainadd', 'da', domain_add, 'fqdn [transport]', |
854 _(u'create a new domain')), |
852 _('create a new domain')), |
855 'domaindelete': cmd('domaindelete', 'dd', domain_delete, 'fqdn [force]', |
853 'domaindelete': cmd('domaindelete', 'dd', domain_delete, 'fqdn [force]', |
856 _(u'delete the given domain and all its alias domains')), |
854 _('delete the given domain and all its alias domains')), |
857 'domaininfo': cmd('domaininfo', 'di', domain_info, 'fqdn [details]', |
855 'domaininfo': cmd('domaininfo', 'di', domain_info, 'fqdn [details]', |
858 _(u'display information about the given domain')), |
856 _('display information about the given domain')), |
859 'domainquota': cmd('domainquota', 'dq', domain_quota, |
857 'domainquota': cmd('domainquota', 'dq', domain_quota, |
860 'fqdn storage [messages] [force]', |
858 'fqdn storage [messages] [force]', |
861 _(u'update the quota limit of the specified domain')), |
859 _('update the quota limit of the specified domain')), |
862 'domainservices': cmd('domainservices', 'ds', domain_services, |
860 'domainservices': cmd('domainservices', 'ds', domain_services, |
863 'fqdn [service ...] [force]', |
861 'fqdn [service ...] [force]', |
864 _(u'enables the specified services and disables all ' |
862 _('enables the specified services and disables all ' |
865 u'not specified services of the given domain')), |
863 'not specified services of the given domain')), |
866 'domaintransport': cmd('domaintransport', 'dt', domain_transport, |
864 'domaintransport': cmd('domaintransport', 'dt', domain_transport, |
867 'fqdn transport [force]', |
865 'fqdn transport [force]', |
868 _(u'update the transport of the specified domain')), |
866 _('update the transport of the specified domain')), |
869 'domainnote': cmd('domainnote', 'do', domain_note, 'fqdn [note]', |
867 'domainnote': cmd('domainnote', 'do', domain_note, 'fqdn [note]', |
870 _(u'set, update or delete the note of the given domain')), |
868 _('set, update or delete the note of the given domain')), |
871 # List commands |
869 # List commands |
872 'listdomains': cmd('listdomains', 'ld', list_domains, '[pattern]', |
870 'listdomains': cmd('listdomains', 'ld', list_domains, '[pattern]', |
873 _(u'list all domains or search for domains by pattern')), |
871 _('list all domains or search for domains by pattern')), |
874 'listaddresses': cmd('listaddresses', 'll', list_addresses, '[pattern]', |
872 'listaddresses': cmd('listaddresses', 'll', list_addresses, '[pattern]', |
875 _(u'list all addresses or search for addresses by ' |
873 _('list all addresses or search for addresses by ' |
876 u'pattern')), |
874 'pattern')), |
877 'listusers': cmd('listusers', 'lu', list_users, '[pattern]', |
875 'listusers': cmd('listusers', 'lu', list_users, '[pattern]', |
878 _(u'list all user accounts or search for accounts by ' |
876 _('list all user accounts or search for accounts by ' |
879 u'pattern')), |
877 'pattern')), |
880 'listaliases': cmd('listaliases', 'la', list_aliases, '[pattern]', |
878 'listaliases': cmd('listaliases', 'la', list_aliases, '[pattern]', |
881 _(u'list all aliases or search for aliases by pattern')), |
879 _('list all aliases or search for aliases by pattern')), |
882 'listrelocated': cmd('listrelocated', 'lr', list_relocated, '[pattern]', |
880 'listrelocated': cmd('listrelocated', 'lr', list_relocated, '[pattern]', |
883 _(u'list all relocated users or search for relocated ' |
881 _('list all relocated users or search for relocated ' |
884 u'users by pattern')), |
882 'users by pattern')), |
885 # Relocated commands |
883 # Relocated commands |
886 'relocatedadd': cmd('relocatedadd', 'ra', relocated_add, |
884 'relocatedadd': cmd('relocatedadd', 'ra', relocated_add, |
887 'address newaddress', |
885 'address newaddress', |
888 _(u'create a new record for a relocated user')), |
886 _('create a new record for a relocated user')), |
889 'relocateddelete': cmd('relocateddelete', 'rd', relocated_delete, |
887 'relocateddelete': cmd('relocateddelete', 'rd', relocated_delete, |
890 'address', |
888 'address', |
891 _(u'delete the record of the relocated user')), |
889 _('delete the record of the relocated user')), |
892 'relocatedinfo': cmd('relocatedinfo', 'ri', relocated_info, 'address', |
890 'relocatedinfo': cmd('relocatedinfo', 'ri', relocated_info, 'address', |
893 _(u'print information about a relocated user')), |
891 _('print information about a relocated user')), |
894 # cli commands |
892 # cli commands |
895 'configget': cmd('configget', 'cg', config_get, 'option', |
893 'configget': cmd('configget', 'cg', config_get, 'option', |
896 _('show the actual value of the configuration option')), |
894 _('show the actual value of the configuration option')), |
897 'configset': cmd('configset', 'cs', config_set, 'option value', |
895 'configset': cmd('configset', 'cs', config_set, 'option value', |
898 _('set a new value for the configuration option')), |
896 _('set a new value for the configuration option')), |
899 'configure': cmd('configure', 'cf', configure, '[section]', |
897 'configure': cmd('configure', 'cf', configure, '[section]', |
900 _(u'start interactive configuration mode')), |
898 _('start interactive configuration mode')), |
901 'listpwschemes': cmd('listpwschemes', 'lp', list_pwschemes, '', |
899 'listpwschemes': cmd('listpwschemes', 'lp', list_pwschemes, '', |
902 _(u'lists all usable password schemes and password ' |
900 _('lists all usable password schemes and password ' |
903 u'encoding suffixes')), |
901 'encoding suffixes')), |
904 'help': cmd('help', 'h', help_, '[subcommand]', |
902 'help': cmd('help', 'h', help_, '[subcommand]', |
905 _(u'show a help overview or help for the given subcommand')), |
903 _('show a help overview or help for the given subcommand')), |
906 'version': cmd('version', 'v', version, '', |
904 'version': cmd('version', 'v', version, '', |
907 _(u'show version and copyright information')), |
905 _('show version and copyright information')), |
908 }) |
906 }) |
909 |
907 |
910 |
908 |
911 def _get_order(ctx): |
909 def _get_order(ctx): |
912 """returns a tuple with (key, 1||0) tuples. Used by functions, which |
910 """returns a tuple with (key, 1||0) tuples. Used by functions, which |
913 get a dict from the handler.""" |
911 get a dict from the handler.""" |
914 order = () |
912 order = () |
915 if ctx.scmd == 'domaininfo': |
913 if ctx.scmd == 'domaininfo': |
916 order = ((u'domain name', 0), (u'gid', 1), (u'domain directory', 0), |
914 order = (('domain name', 0), ('gid', 1), ('domain directory', 0), |
917 (u'quota limit/user', 0), (u'active services', 0), |
915 ('quota limit/user', 0), ('active services', 0), |
918 (u'transport', 0), (u'alias domains', 0), (u'accounts', 0), |
916 ('transport', 0), ('alias domains', 0), ('accounts', 0), |
919 (u'aliases', 0), (u'relocated', 0), (u'catch-all dests', 0)) |
917 ('aliases', 0), ('relocated', 0), ('catch-all dests', 0)) |
920 elif ctx.scmd == 'userinfo': |
918 elif ctx.scmd == 'userinfo': |
921 if ctx.argc == 4 and ctx.args[3] != u'aliases' or \ |
919 if ctx.argc == 4 and ctx.args[3] != 'aliases' or \ |
922 ctx.cget('account.disk_usage'): |
920 ctx.cget('account.disk_usage'): |
923 order = ((u'address', 0), (u'name', 0), (u'uid', 1), (u'gid', 1), |
921 order = (('address', 0), ('name', 0), ('uid', 1), ('gid', 1), |
924 (u'home', 0), (u'mail_location', 0), |
922 ('home', 0), ('mail_location', 0), |
925 (u'quota storage', 0), (u'quota messages', 0), |
923 ('quota storage', 0), ('quota messages', 0), |
926 (u'disk usage', 0), (u'transport', 0), (u'smtp', 1), |
924 ('disk usage', 0), ('transport', 0), ('smtp', 1), |
927 (u'pop3', 1), (u'imap', 1), (u'sieve', 1)) |
925 ('pop3', 1), ('imap', 1), ('sieve', 1)) |
928 else: |
926 else: |
929 order = ((u'address', 0), (u'name', 0), (u'uid', 1), (u'gid', 1), |
927 order = (('address', 0), ('name', 0), ('uid', 1), ('gid', 1), |
930 (u'home', 0), (u'mail_location', 0), |
928 ('home', 0), ('mail_location', 0), |
931 (u'quota storage', 0), (u'quota messages', 0), |
929 ('quota storage', 0), ('quota messages', 0), |
932 (u'transport', 0), (u'smtp', 1), (u'pop3', 1), |
930 ('transport', 0), ('smtp', 1), ('pop3', 1), |
933 (u'imap', 1), (u'sieve', 1)) |
931 ('imap', 1), ('sieve', 1)) |
934 elif ctx.scmd == 'getuser': |
932 elif ctx.scmd == 'getuser': |
935 order = ((u'uid', 1), (u'gid', 1), (u'address', 0)) |
933 order = (('uid', 1), ('gid', 1), ('address', 0)) |
936 return order |
934 return order |
937 |
935 |
938 |
936 |
939 def _format_quota_usage(limit, used, human=False, domaindefault=False): |
937 def _format_quota_usage(limit, used, human=False, domaindefault=False): |
940 """Put quota's limit / usage / percentage in a formatted string.""" |
938 """Put quota's limit / usage / percentage in a formatted string.""" |