def config(flow, name): from configconvert import handle_option_error, handle_section_error if not flow.config.option_group.has_key(name): raise handle_section_error( flow, name, "'%s.sendmail' or '%s.smtp.host'" % (name, name)) from nestedrecord import decodeNestedRecord from conversionkit import chainConverters, chainPostConverters, Conversion from stringconvert import unicodeToInteger, unicodeToBoolean, unicodeToUnicode from stringconvert.email import listOfEmails from recordconvert import toRecord from configconvert import existingFile, existingDirectory to_unicode = unicodeToUnicode() smtp_converter = chainPostConverters( toRecord(missing_errors=dict( host="The required option '%s.smtp.host' is missing" % (name, ), ), empty_errors=dict( host="The option '%s.smtp.host' cannot be empty" % (name, ), ), missing_defaults=dict(starttls=False), converters=dict( host=to_unicode, username=to_unicode, password=to_unicode, port=unicodeToInteger(), starttls=unicodeToBoolean(), verbose=unicodeToBoolean(), )), requireIfPresent('username', ['password']), ) mail_converter = chainConverters( decodeNestedRecord(depth=1), chainPostConverters( toRecord(converters=dict( sendmail=existingFile(), smtp=smtp_converter, debug_folder=existingDirectory(), to_email_override=listOfEmails(split_name=False), ), ), exacltyOneFieldFrom('sendmail', 'smtp'), )) conversion = Conversion( flow.config.option_group[name]).perform(mail_converter) if not conversion.successful: handle_option_error(conversion, name) else: flow.config[name] = conversion.result return flow.config[name]
def psycopg2_update_config(flow, name, config): from configconvert import handle_option_error, handle_section_error from stringconvert import unicodeToUnicode, unicodeToInteger,\ unicodeToBoolean from recordconvert import toRecord from configconvert import stringToObject from conversionkit import Conversion, chainConverters # Re-use the converters unicode_to_integer = unicodeToInteger() null = unicodeToUnicode() database_config = chainConverters( dbport, toRecord( missing_defaults=dict( creator=psycopg2.connect, fetch_converter=psycopg2_utf8_fetch, execute_converter=None, ), missing_or_empty_errors = dict( database="The required option '%s.database' is missing"%(name,), ), converters=dict( database = null, user = null, # Could use formencode.validators.URL() for host? host = null, password = null, port = unicode_to_integer, creator = stringToObject(), fetch_converter = stringToObject(), execute_converter = stringToObject(), ), # Keep the pool options as they are filter_extra_fields = False ), ) conversion = Conversion(config).perform(database_config) if not conversion.successful: handle_option_error(conversion, name) else: config = conversion.result return config
def mailService_constructor(service, name, *k, **p): from mail.helper import send_smtp, send_sendmail, prepare, plain # Imports from configconvert import handle_option_error, handle_section_error from nestedrecord import decodeNestedRecord from conversionkit import chainConverters, chainPostConverters, Conversion from stringconvert import unicodeToInteger, unicodeToBoolean, unicodeToUnicode from stringconvert.email import listOfEmails from recordconvert import toRecord from configconvert import existingFile, existingDirectory # Config parsing if not service.app.option.has_key(name): raise handle_section_error(service, name, "'%s.sendmail' or '%s.smtp.host'"%(name, name)) to_unicode = unicodeToUnicode() smtp_converter = chainPostConverters( toRecord( missing_errors = dict( host = "The required option '%s.smtp.host' is missing" % (name,), ), empty_errors = dict( host="The option '%s.smtp.host' cannot be empty"%(name,), ), missing_defaults = dict(starttls=False), converters = dict( host = to_unicode, username = to_unicode, password = to_unicode, port = unicodeToInteger(), starttls = unicodeToBoolean(), verbose = unicodeToBoolean(), ) ), requireIfPresent('username', ['password']), ) mail_converter = chainConverters( decodeNestedRecord(depth=1), chainPostConverters( toRecord( converters = dict( sendmail = existingFile(), smtp = smtp_converter, debug_folder = existingDirectory(), to_email_override = listOfEmails(split_name=False), ), ), exacltyOneFieldFrom('sendmail', 'smtp'), ) ) conversion = Conversion(service.app.option[name]).perform( mail_converter ) if not conversion.successful: handle_option_error(conversion, name) else: service.app.config[name] = conversion.result if service.app.config[name].get('debug_folder') and not \ os.path.exists(service.app.config[name]['debug_folder']): os.mkdir(service.app.config[name]['debug_folder']) def send( message, to, from_email, from_name, subject=None, type='plain', charset=None, ): if service.app.config[name].get('to_email_override'): log.warning( 'Replacing the email %s with %s', to, service.app.config[name].get('to_email_override'), ) to = service.app.config[name].get('to_email_override') if to and isinstance(to, list) and isinstance(to[0], dict): to = ['%s <%s>'%(x.name, x.email) for x in to] subject = subject or service.app.config[name]['subject'] message = prepare( plain(message, type=type, charset=charset), from_name = from_name, from_email = from_email, to=to, subject=subject, ) debug_folder = service.app.config[name].get('debug_folder') if debug_folder: log.warning( 'Writing message to the debug folder, not sending ' 'it directly' ) fp = open( os.path.join( debug_folder, '%s - %s.txt'%(subject, to) ), 'wb' ) fp.write(str(message)) fp.close() else: sendmail = service.app.config[name].get('sendmail') if sendmail: return send_sendmail( message, sendmail, ) smtp_args = service.app.config[name]['smtp'] return send_smtp(message, **str_dict(smtp_args)) def start(service): service[name] = AttributeDict(send=send) def leave(service, error=False): pass return AttributeDict(start=start, enter=start, leave=leave)
def mailService_constructor(service, name, *k, **p): from mail.helper import send_smtp, send_sendmail, prepare, plain # Imports from configconvert import handle_option_error, handle_section_error from nestedrecord import decodeNestedRecord from conversionkit import chainConverters, chainPostConverters, Conversion from stringconvert import unicodeToInteger, unicodeToBoolean, unicodeToUnicode from stringconvert.email import listOfEmails from recordconvert import toRecord from configconvert import existingFile, existingDirectory # Config parsing if not service.app.option.has_key(name): raise handle_section_error( service, name, "'%s.sendmail' or '%s.smtp.host'" % (name, name)) to_unicode = unicodeToUnicode() smtp_converter = chainPostConverters( toRecord(missing_errors=dict( host="The required option '%s.smtp.host' is missing" % (name, ), ), empty_errors=dict( host="The option '%s.smtp.host' cannot be empty" % (name, ), ), missing_defaults=dict(starttls=False), converters=dict( host=to_unicode, username=to_unicode, password=to_unicode, port=unicodeToInteger(), starttls=unicodeToBoolean(), verbose=unicodeToBoolean(), )), requireIfPresent('username', ['password']), ) mail_converter = chainConverters( decodeNestedRecord(depth=1), chainPostConverters( toRecord(converters=dict( sendmail=existingFile(), smtp=smtp_converter, debug_folder=existingDirectory(), to_email_override=listOfEmails(split_name=False), ), ), exacltyOneFieldFrom('sendmail', 'smtp'), )) conversion = Conversion( service.app.option[name]).perform(mail_converter) if not conversion.successful: handle_option_error(conversion, name) else: service.app.config[name] = conversion.result if service.app.config[name].get('debug_folder') and not \ os.path.exists(service.app.config[name]['debug_folder']): os.mkdir(service.app.config[name]['debug_folder']) def send( message, to, from_email, from_name, subject=None, type='plain', charset=None, ): if service.app.config[name].get('to_email_override'): log.warning( 'Replacing the email %s with %s', to, service.app.config[name].get('to_email_override'), ) to = service.app.config[name].get('to_email_override') if to and isinstance(to, list) and isinstance(to[0], dict): to = ['%s <%s>' % (x.name, x.email) for x in to] subject = subject or service.app.config[name]['subject'] message = prepare( plain(message, type=type, charset=charset), from_name=from_name, from_email=from_email, to=to, subject=subject, ) debug_folder = service.app.config[name].get('debug_folder') if debug_folder: log.warning('Writing message to the debug folder, not sending ' 'it directly') fp = open( os.path.join(debug_folder, '%s - %s.txt' % (subject, to)), 'wb') fp.write(str(message)) fp.close() else: sendmail = service.app.config[name].get('sendmail') if sendmail: return send_sendmail( message, sendmail, ) smtp_args = service.app.config[name]['smtp'] return send_smtp(message, **str_dict(smtp_args)) def start(service): service[name] = AttributeDict(send=send) def leave(service, error=False): pass return AttributeDict(start=start, enter=start, leave=leave)
def rule(rule, add=None, extra=None): if not isinstance(rule, unicode): raise URLConvertError( 'Expected the rule to be specified as a Unicode string') if add is not None: for k in parse_vars(rule): # This gets checked later too, but better to do it now. if k in add: raise URLConvertError( "The 'add' dictionary cannot contain the same key %r " "as a routing variable defined in the rule" % k) for k, v in add.items(): if not isinstance(k, unicode): raise URLConvertError( 'Expected the key %r to be a Unicode string' % k) if not isinstance(v, unicode): raise URLConvertError( 'Expected the value %r to be a Unicode string' % v) add = add.copy() # Start making the chain chain = [] # Split up the rule parts = Conversion(rule).perform(_rule_to_parts).result # Now create a match and generate converter for each part. match = {} generate = {} # Start with the easy ones which either don't exist, take a static part, # or have a single dynamic part for key in ['scheme', 'query', 'port']: if parts[key] not in [u'{}', u'{*}']: if parts[key].startswith('{'): if not parts[key].endswith('}'): raise URLConvertError( "Expected the %s part to end with '}' since it " "can only contain one routing variable" % key) var = parts[key][1:-1] if '{' in var or '}' in var: raise URLConvertError( 'The %s part of the rule is invalid' % key) match[key] = matchDynamic(part=key, dynamic=var) generate[key] = generateStaticOrDynamic(part=key, dynamic=var) elif '{' in parts[key] or '}' in parts[key]: raise URLConvertError('The %s part of the rule is invalid' % key) else: match[key] = matchStatic(key, parts[key]) generate[key] = generateStaticOrDynamic( part=key, expected_value=parts[key], ) if parts['host'] != u'{*}': if u'{*}' in parts['host']: raise URLConvertError( "The host part %r is invalid, you cannot use {*} as well " "as text or named variables." % parts['host']) if not re.match( '[A-Za-z0-9](([A-Za-z0-9\-])+.)*', parts['host'][:].replace('{', 'a').replace('}', 'a'), ): raise URLConvertError('The host name is invalid') if not '{' in parts['host']: # Static text. Check the characters. match['host'] = matchStatic('host', parts['host']) generate['host'] = generateStaticOrDynamic( part='host', expected_value=parts['host'], ) else: match['host'] = matchDynamicDomain(parts['host']) generate['host'] = generateDynamicHost(parts['host']) # The path and script for key in ['path', 'script']: if parts[key] not in [u'{*}']: #if u'{}' in parts[key]: # raise URLConvertError( # "The %s part %r is invalid, you cannot use {} as well as " # "named variables, only instead of them"%(key, parts[key]) # ) if not re.match('([A-Za-z0-9\-\%\/\:\"@&=+\$\,_\.\!\~\*\'\(\)])*', parts[key][:].replace('{', 'a').replace('}', 'a')): raise URLConvertError('The %s contains invalid characters' % key) if not '{' in parts['path']: # Static text. Check the characters. match[key] = matchStatic(key, parts[key]) generate[key] = generateStaticOrDynamic( part=key, expected_value=parts[key], ) else: match[key] = matchDynamicPath(key, parts[key]) generate[key] = generateDynamicPath(key, parts[key]) # Finally, create a converter capable of parsing all this data post_converters = [ toDictionary(match), mergeParts(), ] if add is not None: post_converters.append(addExtras(add)) post_converters.append(extraVariables(extra)) to_vars = chainConverters(missingKey(match.keys(), 'match'), chainPostConverters(*post_converters)) to_url = chainPostConverters( chainConverters( removeExtras(add or {}), # This is expecting a dictionary, we have a tuple, and want each # of the generate converters called for each tuple. # ie: We need a for_each with a key for each. tryEach(generate.values(), stop_on_first_result=False, stop_on_first_error=True, children_keys=generate.keys()), ), joinVars(add or {}), extraVariables(extra, 'url_parts'), ) return AttributeDict(dict(to_vars=to_vars, to_url=to_url))
if not isinstance(query, unicode): raise URLConvertError('Expected the query to be a unicode string') match = path_regex.match(query) if not match: conversion.error = 'The %s part of the query is not valid' else: conversion.result = query return matchQuery_converter # # Helper functions for building the initial URL # decode_scheme = chainConverters(makeUnicode(), matchScheme(), plainDecode('utf8')) decode_host = chainConverters(makeUnicode(), matchHost(), plainDecode('utf8')) decode_port = chainConverters(makeUnicode(), matchPort(), plainDecode('utf8')) decode_script = chainConverters(makeUnicode(), matchScript(), decodeScript('utf8')) decode_path = chainConverters(makeUnicode(), matchPath(), decodePath('utf8')) decode_query = chainConverters(makeUnicode(), matchQuery(), decodeQuery('utf8')) def extract_scheme(service, converter=None): """\ Calculate the scheme from a services dictionary. Attempts to get the scheme by trying each of these in order:
for char in conversion.value: if char not in string.digits+'_'+string.ascii_letters: conversion.error = 'Usernames may contain only letters, numbers and underscores, not the %r character'%(char.encode('utf-8'),) return conversion.result = conversion.value return validUsername_converter def userExists(): def userExists_converter(conversion, bag): if user_exists(bag, conversion.value): conversion.error = 'User %r already exists'%(conversion.value.encode('utf-8')) else: conversion.result = conversion.value return userExists_converter valid_new_username = chainConverters(validUsername(), userExists()) # Create Methods def user_create( service, username, password, group=None, name='user', encrypt=_nothing, terms=False, email='', ): """\ Create a new user with the username, password and group name specified. """