Example #1
0
def to_internal(option_spec, parsed_options):
    internal = AttributeDict()
    for k, v in option_spec.items():
        if not v.get('metavar', ''):
            if v.get('multiple', ''):
                internal[k] = []
            else:
                internal[k] = False
    options_used = AttributeDict()
    values_used = AttributeDict()
    position = AttributeDict()
    i = -1
    for pair in parsed_options:
        i += 1
        option, value = pair
        for int_var, opt in option_spec.items():
            if option in opt.get('options', []):
                if not opt.get('metavar', '') and value:
                    raise getopt.GetoptError(
                        'The argument %r after %r was unexpected' %
                        (value, option))
                # Make this check optional at some point
                multiple = opt.get('multiple', False)
                if options_used.has_key(int_var) and not multiple:
                    raise getopt.GetoptError(
                        'The option %r is unexpected (the related option %r '
                        'has already been used)' % (
                            option,
                            options_used[int_var][-1],
                        ))
                else:
                    if opt.get('metavar', ''):
                        if multiple:
                            if not internal.has_key(int_var):
                                internal[int_var] = [value]
                            else:
                                internal[int_var].append(value)
                        else:
                            internal[int_var] = value
                    else:
                        if multiple:
                            internal[int_var].append(True)
                        else:
                            internal[int_var] = True
                    if options_used.has_key(int_var):
                        options_used[int_var].append(option)
                        values_used[int_var].append(value)
                        position[int_var].append(i)
                    else:
                        options_used[int_var] = [option]
                        values_used[int_var] = [value]
                        position[int_var] = [i]
    log.debug('Internal: %r', internal)
    return AttributeDict(opts=internal,
                         options=options_used,
                         values=values_used,
                         position=position)
Example #2
0
    def userService_constructor(service, name, aliases=None, *k, **p):
        @ensure_function_bag(connection_name)
        def enter(flow):
            oself = Self()
            oself.connection_name = connection_name
            flow[name] = ProxyingAttributeDict(flow, module, oself)

        return AttributeDict(start=enter, enter=enter)
Example #3
0
    def convertAndCache_converter(conversion, service=None):
        parts = conversion.value
        if cache:
            if convert_type == 'generate':
                a = parts['vars'].items()
                b = parts['current'].items()
                a.sort()
                b.sort()
                p = (
                    tuple(a),
                    tuple(b),
                )
            elif convert_type == 'match':
                p = parts.items()
                p.sort()
                p = (tuple(p), None)
            else:
                raise URLConvertError('Unknown convert_type for caching %r' %
                                      convert_type)
            if p in cached:
                log.debug(
                    'Converting from cache: %r, convert_type: %r, result: %r',
                    parts,
                    convert_type,
                    cached[p],
                )
                conversion.result = cached[p]
                return

        log.debug('Not cached: %r, convert_type: %r', parts, convert_type)
        log.debug('%s converters available', len(converters))
        log.debug('Trying each rule in turn...')
        conversion.perform(
            tryEach(
                converters,
                stop_on_first_result=True,
                MSG_NONE_SUCCESSFUL='No rule matched',
            ))
        if conversion.successful:
            set_result(conversion, AttributeDict(conversion.result))
            if cache:
                cached[p] = conversion.result
                log.info(
                    'Converting and adding to cache: %r, convert_type: %r, result: %r',
                    parts,
                    convert_type,
                    cached[p],
                )
            else:
                log.debug(
                    'Converting, not caching: %r, convert_type: %r, result: %r',
                    parts,
                    convert_type,
                    conversion.result,
                )
        else:
            log.info('%r. (%r)', conversion.error, parts)
Example #4
0
    def __call__(self, environ, start_response):
        # This is effectively the WSGI app.
        # Fake a pipestack setup so we cna port this code eventually
        flow = AttributeDict()
        flow['app'] = AttributeDict()
        flow['app']['config'] = AttributeDict()
        flow['app']['config']['proxy'] = AttributeDict(
            max_length=int(self.max_length))
        flow['environ'] = environ
        flow['http_response'] = HTTPResponseMarble()
        flow.http_response.header_list = [
            dict(name='Content-Type', value='application/javascript'),
            dict(name='Access-Control-Allow-Origin', value='*')
        ]
        flow['query'] = FieldStorage(environ=flow.environ)

        self.index(flow)

        start_response(
            str(flow.http_response.status),
            [
                tuple([item['name'], item['value']])
                for item in flow.http_response.header_list
            ],
        )
        resp = ''.join([x.encode('utf-8') for x in flow.http_response.body])
        format = None

        if flow.query.has_key('format'):
            format = flow.query.getfirst('format')

        if not format or format == 'jsonp':
            callback = 'callback'
            if flow.query.has_key('callback'):
                callback = flow.query.getfirst('callback')
            return [callback + '(' + resp + ')']
        elif format == 'json':
            return [resp]
        else:
            title = 'Unknown reply format'
            msg = 'Reply format %s is not supported, try json or jsonp' % format
            flow.http_response.status = '200 Error %s' % title
            return error(title=title, message=msg)
Example #5
0
    def start(self, flow, name):
        if not flow.has_key(name):
            flow[name] = AttributeDict()
            if self.config.get('debug_folder') and not \
               os.path.exists(self.config['debug_folder']):
                os.mkdir(self.config['debug_folder'])

            def send(
                message,
                to,
                from_email,
                from_name,
                subject=None,
                type='plain',
                charset=None,
            ):
                if self.config.get('to_email_override'):
                    log.warning(
                        'Replacing the email %s with %s',
                        to,
                        self.config.get('to_email_override'),
                    )
                    to = self.config.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 self.config['subject']
                message = prepare(
                    plain(message, type=type, charset=charset),
                    from_name=from_name,
                    from_email=from_email,
                    to=to,
                    subject=subject,
                )
                debug_folder = self.config.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 = self.config.get('sendmail')
                    if sendmail:
                        return send_sendmail(
                            message,
                            sendmail,
                        )
                    smtp_args = self.config['smtp']
                    return send_smtp(message, **str_dict(smtp_args))

            self.send = send
        flow[name]['send'] = self.send
Example #6
0
 def generate_url(self, routing_vars, default_url_parts):
     d = default_url_parts.copy()
     rv = dict([(unicode(k), unicode(v)) for k, v in routing_vars.items()])
     conversion = self.generate(rv, default_url_parts)
     if conversion.successful:
         res = conversion.result
         d.update(res.url_parts)
         # @@@ Should really use a post converter
         result = Conversion(
             AttributeDict(url=build_url(**d),
                           extra=res.extra)).perform(noConversion())
         return result
     raise Exception('No matching generation rule could be found')
Example #7
0
    def enter(self, service):
        _set_cookie = []
        _remove_cookie = []

        def remove():
            _remove_cookie.append(True)

        def set(message, message_type=None):
            while (_set_cookie):
                _set_cookie.pop()
            if message_type is None:
                message_type = self.allowed_message_types[0]
            elif message_type not in self.allowed_message_types:
                raise FlashMessageError('No such message type %r',
                                        message_type)
            _set_cookie.append((message_type, message))

        def set_now(message, message_type=None):
            service[self.name]['message'] = message
            service[self.name]['message_type'] = message_type

        service[self.name] = AttributeDict(
            message=None,
            message_type=None,
            remove=remove,
            set=set,
            set_now=set_now,
            _set_cookie=_set_cookie,
            _remove_cookie=_remove_cookie,
        )

        # Populate service.flash
        cookie = get_cookie(service.environ.get('HTTP_COOKIE', ''),
                            name=self.cookie_name)
        if cookie:
            result = decode_flash(cookie)
            service[self.name]['message'] = result['message']
            service[self.name]['message_type'] = result['message_type']
Example #8
0
    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)
Example #9
0
 def start(service):
     service[name] = AttributeDict(send=send)
Example #10
0
 def extraVariables_post_converter(conversion, state):
     if conversion.successful:
         vars = conversion.result
         set_result(conversion, AttributeDict(extra=extra, **{key: vars}))
Example #11
0
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))
Example #12
0
def handle_command(commands,
                   cmd_line_parts=None,
                   program=None,
                   service=None,
                   cmd=None,
                   out=print_fn,
                   err=print_fn):
    if service is not None:
        warnings.warn(
            'The \'service\' argument is deprecated, please change your '
            'commands to be classes with simplified \'on_run()\' methods')
    # Prepare the cmd object to have the args and opts set
    if cmd is None:
        cmd = AttributeDict(
            args=None,
            opts=None,
            chain=[],
            raw_args=None,
            raw_opts=None,
            instance=None,
            service=service,
        )
    else:
        cmd.chain.append(AttributeDict(cmd))
        # Reset the command
        cmd['args'] = None
        cmd['opts'] = None
        cmd['raw_args'] = None
        cmd['raw_opts'] = None
        cmd['instance'] = None
        cmd['service'] = service
    cmd['out'] = out
    cmd['err'] = err
    if program is None:
        program = sys.argv[0]
        if os.sep in sys.argv[0]:
            program = program.split(os.sep)[-1]
    if cmd_line_parts is None:
        cmd_line_parts = sys.argv[1:]
    if not isinstance(commands, dict):
        commands = OrderedDict(commands)
    for name, command in commands.items():
        check_command(name, command)
    if None not in commands:
        commands[None] = Cmd()
    sub_command = None
    try:
        # Run the main service
        main_args, main_opts, args, new_cmd_line_parts, main_opts_used = process_command(
            cmd_line_parts,
            None,
            commands[None],
        )
        k, p, h = on_initial_convert(
            service,
            commands[None].arg_spec,
            commands[None].option_spec,
            main_args,
            main_opts,
        )
        if h:
            help = assemble_help(commands, None, program)
            print help(service)
            return 0
        # Need to be smarter here, want to call the inner functions in the scope of the outer.
        cmd['args'] = k
        cmd['opts'] = p
        cmd['raw_args'] = main_args
        cmd['raw_opts'] = main_opts
        cmd['instance'] = commands[None]
        cmd['service'] = service
        # Have to check this first because all commands inherit a run() method from Cmd.
        if hasattr(commands[None], 'on_run'):
            # Backwards compatibility
            result = commands[None].on_run(service, k, p)
        elif hasattr(commands[None], 'run'):
            result = commands[None].run(cmd)
        else:
            raise Exception('Unknown command type %r, no run() method' %
                            commands[sub_command])
        if result:
            return result
        # Now try to run the sub-command
        if not args:
            raise getopt.GetoptError('No command specified')
        sub_command = args.pop(0)
        if not sub_command in commands:
            error = 'No such command `%s\'' % sub_command
            sub_command = None
            raise getopt.GetoptError(error)
        if isinstance(commands[sub_command], dict):
            return handle_command(
                commands[sub_command],
                cmd_line_parts=args,
                program='%s %s' % (program, sub_command),
                service=service,
                cmd=cmd,
                err=err,
                out=out,
            )
        sub_args, sub_opts = process_command(
            args,  #new_cmd_line_parts, 
            sub_command,
            commands[sub_command],
        )
        k, p, h = on_initial_convert(
            service,
            commands[sub_command].arg_spec,
            commands[sub_command].option_spec,
            sub_args,
            sub_opts,
        )
        if h:
            help = assemble_help(
                commands,
                sub_command,
                program,
            )
            print help(service)
            return 0
        cmd.chain.append(AttributeDict(cmd))
        cmd['args'] = k
        cmd['opts'] = p
        cmd['raw_args'] = sub_args
        cmd['raw_opts'] = sub_opts
        cmd['instance'] = commands[None]
        cmd['service'] = service
        # Have to check this first because all commands inherit a run() method from Cmd.
        if hasattr(commands[sub_command], 'on_run'):
            # Backwards compatibility
            result = commands[sub_command].on_run(service, k, p)
        elif hasattr(commands[sub_command], 'run'):
            result = commands[sub_command].run(cmd)
        else:
            raise Exception('Unknown command type %r' % commands[sub_command])
    except getopt.GetoptError, err:
        print 'Error:', str(err)
        if sub_command:
            args = commands[None].arg_spec and ' %s' % (' '.join(
                [arg[0] for arg in commands[None].arg_spec]))
            if args == []:
                args = ''
            print(
                "Try `%(program)s%(args)s %(sub_command)s --help' for more "
                "information.") % {
                    'program': program,
                    'sub_command': sub_command,
                    'args': args,
                }
            return 1
        else:
            print "Try `%(program)s --help' for more information." % {
                'program': program,
            }
            return 1
Example #13
0
 def __init__(self, bag=None, name=None, aliases=None):
     if bag is None:
         bag = AttributeDict()
     aliases = aliases and self.default_aliases.copy().update(
         aliases) or self.default_aliases.copy()
     MarbleLike.__init__(self, bag, name, aliases)