Пример #1
0
def get_format_args(fstr):
    # TODO: memoize
    formatter = Formatter()
    fargs, fkwargs, _dedup = [], [], set()

    def _add_arg(argname, type_char='s'):
        if argname not in _dedup:
            _dedup.add(argname)
            argtype = _TYPE_MAP.get(type_char, str)  # TODO: unicode
            try:
                fargs.append((int(argname), argtype))
            except ValueError:
                fkwargs.append((argname, argtype))

    for lit, fname, fspec, conv in formatter.parse(fstr):
        if fname is not None:
            type_char = fspec[-1:]
            fname_list = re.split('[.[]', fname)
            if len(fname_list) > 1:
                raise ValueError('encountered compound format arg: %r' % fname)
            try:
                base_fname = fname_list[0]
                assert base_fname
            except (IndexError, AssertionError):
                raise ValueError('encountered anonymous positional argument')
            _add_arg(fname, type_char)
            for sublit, subfname, _, _ in formatter.parse(fspec):
                # TODO: positional and anon args not allowed here.
                if subfname is not None:
                    _add_arg(subfname)
    return fargs, fkwargs
Пример #2
0
    def formatMentions(cls, text, *args, **kwargs):
        """Like `str.format`, but takes tuples with a thread id and text instead.

        Returns a `Message` object, with the formatted string and relevant mentions.

        ```
        >>> Message.formatMentions("Hey {!r}! My name is {}", ("1234", "Peter"), ("4321", "Michael"))
        <Message (None): "Hey 'Peter'! My name is Michael", mentions=[<Mention 1234: offset=4 length=7>, <Mention 4321: offset=24 length=7>] emoji_size=None attachments=[]>

        >>> Message.formatMentions("Hey {p}! My name is {}", ("1234", "Michael"), p=("4321", "Peter"))
        <Message (None): 'Hey Peter! My name is Michael', mentions=[<Mention 4321: offset=4 length=5>, <Mention 1234: offset=22 length=7>] emoji_size=None attachments=[]>
        ```
        """
        result = ""
        mentions = list()
        offset = 0
        f = Formatter()
        field_names = [field_name[1] for field_name in f.parse(text)]
        automatic = "" in field_names
        i = 0

        for (literal_text, field_name, format_spec,
             conversion) in f.parse(text):
            offset += len(literal_text)
            result += literal_text

            if field_name is None:
                continue

            if field_name == "":
                field_name = str(i)
                i += 1
            elif automatic and field_name.isdigit():
                raise ValueError(
                    "cannot switch from automatic field numbering to manual field specification"
                )

            thread_id, name = f.get_field(field_name, args, kwargs)[0]

            if format_spec:
                name = f.format_field(name, format_spec)
            if conversion:
                name = f.convert_field(name, conversion)

            result += name
            mentions.append(
                Mention(thread_id=thread_id, offset=offset, length=len(name)))
            offset += len(name)

        message = cls(text=result, mentions=mentions)
        return message
Пример #3
0
    def format_mentions(text, *args, **kwargs):
        """Like `str.format`, but takes tuples with a thread id and text instead.

        Return a tuple, with the formatted string and relevant mentions.

        >>> Message.format_mentions("Hey {!r}! My name is {}", ("1234", "Peter"), ("4321", "Michael"))
        ("Hey 'Peter'! My name is Michael", [Mention(thread_id=1234, offset=4, length=7), Mention(thread_id=4321, offset=24, length=7)])

        >>> Message.format_mentions("Hey {p}! My name is {}", ("1234", "Michael"), p=("4321", "Peter"))
        ('Hey Peter! My name is Michael', [Mention(thread_id=4321, offset=4, length=5), Mention(thread_id=1234, offset=22, length=7)])
        """
        result = ""
        mentions = list()
        offset = 0
        f = Formatter()
        field_names = [field_name[1] for field_name in f.parse(text)]
        automatic = "" in field_names
        i = 0

        for (literal_text, field_name, format_spec,
             conversion) in f.parse(text):
            offset += len(literal_text)
            result += literal_text

            if field_name is None:
                continue

            if field_name == "":
                field_name = str(i)
                i += 1
            elif automatic and field_name.isdigit():
                raise ValueError(
                    "cannot switch from automatic field numbering to manual field specification"
                )

            thread_id, name = f.get_field(field_name, args, kwargs)[0]

            if format_spec:
                name = f.format_field(name, format_spec)
            if conversion:
                name = f.convert_field(name, conversion)

            result += name
            mentions.append(
                Mention(thread_id=thread_id, offset=offset, length=len(name)))
            offset += len(name)

        return result, mentions
Пример #4
0
def template_has_field(template: str, field: str) -> bool:
    q = StringFormatter()
    for (literal_text, field_name, format_spec,
         conversion) in q.parse(template):
        if field_name and field in field_name.split():
            return True
    return False
Пример #5
0
def SafeStringParse(formatter, s, keys):
    """
    A "safe" version :func:`string.Formatter.parse` that will 
    only parse the input keys specified in ``keys``
    
    Parameters
    ----------
    formatter : string.Formatter
        the string formatter class instance
    s : str
        the string we are formatting
    keys : list of str
        list of the keys to accept as valid
    """
    # the default list of keys
    l = list(Formatter.parse(formatter, s))

    toret = []
    for x in l:
        if x[1] in keys:
            toret.append(x)
        else:
            val = x[0]
            if x[1] is not None:
                fmt = "" if not x[2] else ":%s" % x[2]
                val += "{%s%s}" % (x[1], fmt)
            toret.append((val, None, None, None))
    return iter(toret)
Пример #6
0
 def template_opts(self):
     """Returns the template key/values, if a key from the template
     does not exist raises an exception.
     """
     template_opts = {}
     formatter = Formatter()
     keys = [
         opt[1] for opt in formatter.parse(self.template)
         if opt[1] not in ['sequence']
     ]
     template_opts.update(
         sequence=str(self.sequence_number).rjust(self.padding, '0'))
     for key in keys:
         try:
             value = getattr(self, key)
         except AttributeError:
             raise IdentifierMissingTemplateValue(
                 f'Required option not provided. Got \'{key}\'.')
         else:
             if value:
                 template_opts.update({key: value})
             else:
                 raise IdentifierMissingTemplateValue(
                     f'Required option cannot be None. Got \'{key}\'.')
     return template_opts
Пример #7
0
def parse_pattern(format_string, env, wrapper=lambda x, y: y):
    """ Parse the format_string and return prepared data according to the env.

    Pick each field found in the format_string from the env(ironment), apply
    the wrapper on each data and return a mapping between field-to-replace and
    values for each.
    """

    formatter = Formatter()
    fields = [x[1] for x in formatter.parse(format_string) if x[1] is not None]

    prepared_env = {}

    # Create a prepared environment with only used fields, all as list:
    for field in fields:
        # Search for a movie attribute for each alternative field separated
        # by a pipe sign:
        for field_alt in (x.strip() for x in field.split('|')):
            # Handle default values (enclosed by quotes):
            if field_alt[0] in '\'"' and field_alt[-1] in '\'"':
                field_values = field_alt[1:-1]
            else:
                field_values = env.get(field_alt)
            if field_values is not None:
                break
        else:
            field_values = []
        if not isinstance(field_values, list):
            field_values = [field_values]
        prepared_env[field] = wrapper(field_alt, field_values)

    return prepared_env
Пример #8
0
def strfdelta(tdelta,
              fmt='{D:02}d {H:02}h {M:02}m {S:02}s',
              inputtype='timedelta'):
    # convert time to our format
    if inputtype == 'timedelta':
        remainder = int(tdelta.total_seconds())
    elif inputtype in ['s', 'seconds']:
        remainder = int(tdelta)
    elif inputtype in ['m', 'minutes']:
        remainder = int(tdelta) * 60
    elif inputtype in ['h', 'hours']:
        remainder = int(tdelta) * 3600
    elif inputtype in ['d', 'days']:
        remainder = int(tdelta) * 86400
    elif inputtype in ['w', 'weeks']:
        remainder = int(tdelta) * 604800

    f = Formatter()
    desired_fields = [field_tuple[1] for field_tuple in f.parse(fmt)]
    possible_fields = ('W', 'D', 'H', 'M', 'S')
    constants = {'W': 604800, 'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
    values = {}
    for field in possible_fields:
        if field in desired_fields and field in constants:
            values[field], remainder = divmod(remainder, constants[field])
    return f.format(fmt, **values)
Пример #9
0
 def __str__(self):
     'Return: \"Format string.\"'
     try:
         fmt = Formatter()
         buff = []
         #
         for (dl, item, _, _) in fmt.parse(self.msg_format):
             if dl: buff.append(dl)
             #
             if item == 'chat_id':
                 buff.append(str(Request.get_chat_id(self._msg)))
                 #
             elif item == 'message_id':
                 buff.append(str(Request.get_message_id(self._msg)))
                 #
             elif item == 'username':
                 buff.append(Request.get_username(self._msg))
                 #
             elif item == 'chat_type':
                 buff.append(Request.get_chat_type(self._msg))
                 #
             elif item == 'msg_date':
                 date = Request.get_msg_date(self._msg)
                 buff.append(date.strftime(self.dt_format))
                 #
             elif item == 'chat_text':
                 buff.append(Request.get_chat_text(self._msg))
         #
         return ''.join(buff)
         #
     except KeyError:
         return
Пример #10
0
    def _open(self, id=None, mode='rb', compression='default', **kwargs):
        formatter = Formatter()
        fields = [f[1] for f in formatter.parse(self.url)]
        assert len(
            set(fields).intersection(['id', 'stubbypath', 'pairtreepath'])) > 0

        if compression == 'default':
            compression = self.compression
        if mode == 'wb':
            raise NotImplementedError("Mode is not defined")

        stubbypath, pairtreepath = None, None
        if 'stubbypath' in fields:
            stubbypath = id_to_stubbytree(id,
                                          format=self.format,
                                          compression=compression)
        if 'pairtreepath' in fields:
            pairtreepath = id_to_pairtree(id,
                                          format=self.format,
                                          compression=compression)

        path_or_url = self.url.format(id=id,
                                      stubbypath=stubbypath,
                                      pairtreepath=pairtreepath)

        try:
            byt = _urlopen(path_or_url).read()
            req = BytesIO(byt)
        except HTTPError:
            logging.exception("HTTP Error accessing %s" % path_or_url)
            raise
        return req
Пример #11
0
class DescriptionMapMethod(MapMethod):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.formatter = Formatter()
        self.translator = Translator()

    def map(self, *args, **kwargs):
        try:
            template = self.additional_args["template"]
            locale = kwargs["raw_ad"].feed_in.locale

            # We take all keywords (no positional) and we translate them and then we create a dict
            # eg:
            #     template = "That is an example {SALARY}: $ {0} in {COMPANY}: {1}"
            #     locale = "es_ar"
            #     translated_words = {"SALARY": "Salario", "COMPANY": "Compañía"}
            #
            translated_words = {
                parse[1]: self.translator.translate(locale, parse[1],
                                                    "addesc_label")
                for parse in self.formatter.parse(template)
                if type(parse[1]) == str and not parse[1].isdigit()
            }

            addesc = self.formatter.format(template, *args, **translated_words)

            return {"addesc": addesc}
        except KeyError:
            type_id = kwargs["raw_ad"].feed_in.feed_type.id if kwargs.get(
                "raw_ad", None) else ""
            msg = "El parámetro 'template' no se encuentra definido para " + type_id
            raise FeedMappingException(msg)
Пример #12
0
def SafeStringParse(formatter, s, keys):
    """
    A "safe" version :func:`string.Formatter.parse` that will 
    only parse the input keys specified in ``keys``
    
    Parameters
    ----------
    formatter : string.Formatter
        the string formatter class instance
    s : str
        the string we are formatting
    keys : list of str
        list of the keys to accept as valid
    """
    # the default list of keys
    l = list(Formatter.parse(formatter, s))
    
    toret = []
    for x in l:
        if x[1] in keys:
            toret.append(x)
        else:
            val = x[0]
            if x[1] is not None:
                fmt = "" if not x[2] else ":%s" %x[2]
                val += "{%s%s}" %(x[1], fmt)
            toret.append((val, None, None, None))
    return iter(toret)
Пример #13
0
 def _has_format(filename):
     if not isinstance(filename, str):
         return False
     formatter = Formatter()
     return any(
         any(t.isalnum() for t in fields)
         for _, fields, *__ in formatter.parse(filename) if fields)
Пример #14
0
def parse_route_path(path):
    fmt = Formatter()

    rule = turn_noncapturing(path)

    arguments = OrderedDict()
    pattern = ''
    for literal_text, field_name, format_spec, conversion in fmt.parse(rule):
        pattern += literal_text
        if field_name is None:
            continue

        format_spec = format_spec.lower()
        subpattern = _route_rule_types.get(format_spec, None)
        if subpattern is None:
            subpattern = _route_rule_types.get('str')

        if field_name in arguments:
            err = "The argument \{%s:%s\} are already defined in %s"
            err %= (field_name, format_spec, path)
            raise SyntaxError(err)

        arguments[field_name] = format_spec

        pattern += '(?P<' + field_name + '>' + subpattern + ')'

    return pattern, arguments
Пример #15
0
def info(cli):
    formatter = Formatter()
    for name, attr in cli.cfg.tasks.items():
        kind = 'remote'
        if attr.python:
            kind = 'python'
        elif attr.local:
            kind = 'local'
        elif attr.multi:
            kind = 'multi'
        elif attr.send:
            kind = 'send file'

        print(f'{name} [{kind}]:\n\tDescription: {attr.desc}')

        values = []
        for v in attr.values():
            if isinstance(v, list):
                values.extend(v)
            elif isinstance(v, dict):
                values.extend(v.values())
            else:
                values.append(v)
        values = filter(lambda x: isinstance(x, str), values)
        fmt_fields = [i[1] for v in values for i in formatter.parse(v) if i[1]]
        if fmt_fields:
            variables = ', '.join(sorted(set(fmt_fields)))
        else:
            variables = None

        if variables:
            print(f'\tVariables: {variables}')
Пример #16
0
def parse_route_path(path):
    fmt = Formatter()

    rule = turn_noncapturing(path)

    arguments = OrderedDict()
    pattern = ''
    for literal_text, field_name, format_spec, conversion in fmt.parse(rule):
        pattern += literal_text
        if field_name is None:
            continue

        format_spec = format_spec.lower()
        subpattern = _route_rule_types.get(format_spec, None)
        if subpattern is None:
            subpattern = _route_rule_types.get('str')

        if field_name in arguments:
            err = "The argument \{%s:%s\} are already defined in %s"
            err %= (field_name, format_spec, path)
            raise SyntaxError(err)

        arguments[field_name] = format_spec

        pattern += '(?P<' + field_name + '>' + subpattern + ')'

    return pattern, arguments
Пример #17
0
    def __init__(self, route_path):
        route_path = six.ensure_text(route_path)
        assert route_path.startswith('/')

        self.org_route_path = route_path
        # route_path = route_path[1:]
        self.route_path = route_path[:-1] if route_path.endswith(
            '/') else route_path

        self.key_set = set()
        re_segs = []
        fmt = Formatter()
        for prefix, key, fmt_spec, conversion in fmt.parse(self.route_path):
            if key is None:
                re_segs.append(prefix)
                continue

            assert key and not fmt_spec and not conversion, (
                'fail parsing parameter from path: ' + self.route_path)
            assert key not in self.key_set, 'duplicated key {}'.format(key)
            self.key_set.add(key)
            re_segs.append('{prefix}(?P<{key}>[^/]+)'.format(prefix=prefix,
                                                             key=key))

        # print('regex: ' + ''.join(re_segs))
        self.regex = re.compile('^' + ''.join(re_segs) + '$')
Пример #18
0
    def parse(self, fmt_string):
        for literal_txt, field_name, format_spec, conversion in Formatter.parse(
                self, fmt_string):

            # Find $foo patterns in the literal text.
            continue_from = 0
            txt = ""
            for m in self._dollar_pattern_ignore_single_quote.finditer(
                    literal_txt):
                new_txt, new_field = m.group(1, 2)
                # $$foo --> $foo
                if new_field.startswith("$"):
                    txt += new_txt + new_field
                else:
                    yield (txt + new_txt, new_field, "", None)
                    txt = ""
                continue_from = m.end()

            # Re-yield the {foo} style pattern
            yield (
                txt + literal_txt[continue_from:],
                field_name,
                format_spec,
                conversion,
            )
Пример #19
0
    def get_format_names(self, text: str) -> Set[str]:
        """Return the names of any variables mentioned in the templates of `text`"""

        formatter = Formatter()

        return set(template_name
                   for _, template_name, _, _ in formatter.parse(text)
                   if template_name is not None)
    def _extract_url_params(self):
        from string import Formatter

        formatter = Formatter()
        params = [
            format_tuple[1] for format_tuple in formatter.parse(self.url)
        ]
        return params
Пример #21
0
 def __get_field_list(self, text):
     formatter = Formatter()
     fields = []
     for literal_text, field_name, format_spec, conversion in formatter.parse(
             text):
         if field_name is not None:
             fields.append(field_name)
     return fields
Пример #22
0
def get_format_args(fstr):
    """
    Turn a format string into two lists of arguments referenced by the
    format string. One is positional arguments, and the other is named
    arguments. Each element of the list includes the name and the
    nominal type of the field.

    # >>> get_format_args("{noun} is {1:d} years old{punct}")
    # ([(1, <type 'int'>)], [('noun', <type 'str'>), ('punct', <type 'str'>)])

    # XXX: Py3k
    >>> get_format_args("{noun} is {1:d} years old{punct}") == \
        ([(1, int)], [('noun', str), ('punct', str)])
    True
    """
    # TODO: memoize
    formatter = Formatter()
    fargs, fkwargs, _dedup = [], [], set()

    def _add_arg(argname, type_char="s"):
        if argname not in _dedup:
            _dedup.add(argname)
            argtype = _TYPE_MAP.get(type_char, str)  # TODO: unicode
            try:
                fargs.append((int(argname), argtype))
            except ValueError:
                fkwargs.append((argname, argtype))

    for lit, fname, fspec, conv in formatter.parse(fstr):
        if fname is not None:
            type_char = fspec[-1:]
            fname_list = re.split("[.[]", fname)
            if len(fname_list) > 1:
                raise ValueError("encountered compound format arg: %r" % fname)
            try:
                base_fname = fname_list[0]
                assert base_fname
            except (IndexError, AssertionError):
                raise ValueError("encountered anonymous positional argument")
            _add_arg(fname, type_char)
            for sublit, subfname, _, _ in formatter.parse(fspec):
                # TODO: positional and anon args not allowed here.
                if subfname is not None:
                    _add_arg(subfname)
    return fargs, fkwargs
Пример #23
0
def get_format_args(fstr):
    """
    Turn a format string into two lists of arguments referenced by the
    format string. One is positional arguments, and the other is named
    arguments. Each element of the list includes the name and the
    nominal type of the field.

    # >>> get_format_args("{noun} is {1:d} years old{punct}")
    # ([(1, <type 'int'>)], [('noun', <type 'str'>), ('punct', <type 'str'>)])

    # XXX: Py3k
    >>> get_format_args("{noun} is {1:d} years old{punct}") == \
        ([(1, int)], [('noun', str), ('punct', str)])
    True
    """
    # TODO: memoize
    formatter = Formatter()
    fargs, fkwargs, _dedup = [], [], set()

    def _add_arg(argname, type_char='s'):
        if argname not in _dedup:
            _dedup.add(argname)
            argtype = _TYPE_MAP.get(type_char, str)  # TODO: unicode
            try:
                fargs.append((int(argname), argtype))
            except ValueError:
                fkwargs.append((argname, argtype))

    for lit, fname, fspec, conv in formatter.parse(fstr):
        if fname is not None:
            type_char = fspec[-1:]
            fname_list = re.split('[.[]', fname)
            if len(fname_list) > 1:
                raise ValueError('encountered compound format arg: %r' % fname)
            try:
                base_fname = fname_list[0]
                assert base_fname
            except (IndexError, AssertionError):
                raise ValueError('encountered anonymous positional argument')
            _add_arg(fname, type_char)
            for sublit, subfname, _, _ in formatter.parse(fspec):
                # TODO: positional and anon args not allowed here.
                if subfname is not None:
                    _add_arg(subfname)
    return fargs, fkwargs
Пример #24
0
    def select(self,type='VAV',subtype = ['RM STPT DIAL','ROOM TEMP'], floor = 0,nexp='', pattern ='{i}',cond = 'cmax(x,7)',maxn = 10, dtfilter = ''):
        env = self._genv()       
        env.init()
        l = env.getSensorsByType(type)
        lname = []

        for it in l:
            k = it.split(':')
            if floor != 0:
                fl = int(k[0].split('.')[1])
                if fl != floor:
                    continue

                if nexp != '':
                    sname = k[0].split('.')[3]
                    if not fnmatch.fnmatch(sname,nexp):
                        continue    

                if k[1] in subtype:
                    lname.append((it,env.getSensorId(it)))

        ltemp = sorted(lname,key=itemgetter(0))[:maxn]
        filt = ''
        i = 0

        f = Formatter()
        l = "{{%s}}"
        f.format(l)

        ns = ''
        exp = []
        i,m =0,len(ltemp)
        loopi=0
        while i < m:
            h = f.parse(pattern)
            for a,b,c,d in h :
                ns += a 
                if b is not None : 
                    ns += '{' + str(eval(b)) + '}'
                    i = eval(b)
                    loopi = max(i,loopi)
            if cond != '':
                ns += '.apply(lambda x:' + cond + ')'
            if loopi < m-1:
                ns += '; '
            i = loopi + 1

        cs = self.getSeries(ltemp,dtfilter)
        re = self.getExpression(ltemp,ns, cs)
        series = []
        for name ,c in re:
            dataserie = defaultdict()  
            json_s = c[['stime','svalue']].to_json(orient='values')
            dataserie['name']=name
            dataserie['data']=json_s
            series.append(dataserie)
        return series
Пример #25
0
def iter_format_fields(strings, split=False):
    formatter = Formatter()
    for string in strings:
        for _, field, _, _ in formatter.parse(string):
            if field is None:
                continue
            if split:
                field = field.partition('.')[0]
            yield field
Пример #26
0
 def parse(self, text, silent=False):
     try:
         for field in StringFormatter.parse(self, text):
             yield field
     except ValueError:
         # If string can't be formatted
         # We silence the error and return nothing
         if not silent:
             raise
Пример #27
0
 def strfdelta(tdelta, fmt):
     f = Formatter()
     d = {}
     lst = {'H': 3600, 'M': 60, 'S': 1}
     k = map(lambda x: x[1], list(f.parse(fmt)))
     rem = int(tdelta.total_seconds())
     for i in ('H', 'M', 'S'):
         if i in k and i in lst.keys():
             d[i], rem = divmod(rem, lst[i])
     return f.format(fmt, **d)
Пример #28
0
def get_zoned_dates_for_format_string(fmt_string, date):
    import pytz
    from string import Formatter
    sf = Formatter()
    variables = {}
    for literal_text, field_name, format_spec, conversion in sf.parse(
            fmt_string):
        if field_name in pytz.common_timezones:
            variables[field_name] = date.astimezone(pytz.timezone(field_name))
    return variables
Пример #29
0
def parse_files(sending_list_file, message_file):
    text_message = open(message_file).read()
    formatter = Formatter()
    number_of_fields = len(
        [a for a in formatter.parse(text_message) if a[1] is not None])
    sending_list = []
    line_num = 0
    for line in open(sending_list_file).read().splitlines():
        line_num = 1
        receiver = line.split(",")
        if len(receiver) is not number_of_fields + 1:
            print(list(formatter.parse(text_message)))
            raise Exception(
                "The number of fields must be {}. (line {})".format(
                    number_of_fields + 1, line_num))

        sending_list.append(receiver)

    return {"message": text_message, "sending_list": sending_list}
Пример #30
0
def iter_format_fields(strings, split=False):
    formatter = Formatter()
    for string in strings:
        for _, field, _, _ in formatter.parse(string):
            if field is None:
                continue
            field = [
                f for f in field.split('.') if '(' not in f and ')' not in f
            ]
            yield field if split else '.'.join(field)
Пример #31
0
    def _parse_with_formatting(string,
                               args,
                               kwargs,
                               *,
                               recursion_depth=2,
                               auto_arg_index=0,
                               recursive=False):
        # This function re-implements Formatter._vformat()

        if recursion_depth < 0:
            raise ValueError("Max string recursion exceeded")

        formatter = Formatter()
        parser = AnsiParser()

        for literal_text, field_name, format_spec, conversion in formatter.parse(
                string):
            parser.feed(literal_text, raw=recursive)

            if field_name is not None:
                if field_name == "":
                    if auto_arg_index is False:
                        raise ValueError("cannot switch from manual field "
                                         "specification to automatic field "
                                         "numbering")
                    field_name = str(auto_arg_index)
                    auto_arg_index += 1
                elif field_name.isdigit():
                    if auto_arg_index:
                        raise ValueError("cannot switch from manual field "
                                         "specification to automatic field "
                                         "numbering")
                    auto_arg_index = False

                obj, _ = formatter.get_field(field_name, args, kwargs)
                obj = formatter.convert_field(obj, conversion)

                format_spec, auto_arg_index = Colorizer._parse_with_formatting(
                    format_spec,
                    args,
                    kwargs,
                    recursion_depth=recursion_depth - 1,
                    auto_arg_index=auto_arg_index,
                    recursive=True,
                )

                formatted = formatter.format_field(obj, format_spec)
                parser.feed(formatted, raw=True)

        tokens = parser.done()

        if recursive:
            return AnsiParser.strip(tokens), auto_arg_index

        return tokens
Пример #32
0
def strfdelta(tdelta, fmt):
    """ Get a string from a timedelta.
    """
    f, d = Formatter(), {}
    l = {'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
    k = list(map(lambda x: x[1], list(f.parse(fmt))))
    rem = int(tdelta.total_seconds())
    for i in ('D', 'H', 'M', 'S'):
        if i in k and i in l.keys():
            d[i], rem = divmod(rem, l[i])
    return f.format(fmt, **d)
Пример #33
0
def strfdelta(tdelta, fmt):
    """ Get a string from a timedelta.
    """
    f, d = Formatter(), {}
    l = {'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
    k = list(map(lambda x: x[1], list(f.parse(fmt))))
    rem = int(tdelta.total_seconds())
    for i in ('D', 'H', 'M', 'S'):
        if i in k and i in l.keys():
            d[i], rem = divmod(rem, l[i])
    return f.format(fmt, **d)
Пример #34
0
def strfdelta(tdelta, fmt):
    """ Get a string from a timedelta.
    """
    f, d = Formatter(), {}
    l = {"D": 86400, "H": 3600, "M": 60, "S": 1}
    k = list(map(lambda x: x[1], list(f.parse(fmt))))
    rem = int(tdelta.total_seconds())
    for i in ("D", "H", "M", "S"):
        if i in k and i in l.keys():
            d[i], rem = divmod(rem, l[i])
    return f.format(fmt, **d)
Пример #35
0
def tokenize_format_str(fstr, resolve_pos=True):
    ret = []
    if resolve_pos:
        fstr = infer_positional_format_args(fstr)
    formatter = Formatter()
    for lit, fname, fspec, conv in formatter.parse(fstr):
        if lit:
            ret.append(lit)
        if fname is None:
            continue
        ret.append(BaseFormatField(fname, fspec, conv))
    return ret
Пример #36
0
def strfdelta(tdelta,
              fmt='{D:02}d {H:02}h {M:02}m {S:02}s',
              inputtype='timedelta'):
    """Convert a datetime.timedelta object or a regular number to a custom-
    formatted string, just like the stftime() method does for datetime.datetime
    objects.

    The fmt argument allows custom formatting to be specified.  Fields can
    include seconds, minutes, hours, days, and weeks.  Each field is optional.

    Some examples:
        '{D:02}d {H:02}h {M:02}m {S:02}s' --> '05d 08h 04m 02s' (default)
        '{W}w {D}d {H}:{M:02}:{S:02}'     --> '4w 5d 8:04:02'
        '{D:2}d {H:2}:{M:02}:{S:02}'      --> ' 5d  8:04:02'
        '{H}h {S}s'                       --> '72h 800s'

    The inputtype argument allows tdelta to be a regular number instead of the
    default, which is a datetime.timedelta object.  Valid inputtype strings:
        's', 'seconds',
        'm', 'minutes',
        'h', 'hours',
        'd', 'days',
        'w', 'weeks'

    :param tdelta: time (in datetime or integer)
    :param fmt: the desired format
    :param inputtype: type of input
    :return: formatted time
    """

    # Convert tdelta to integer seconds.
    if inputtype == 'timedelta':
        remainder = int(tdelta.total_seconds())
    elif inputtype in ['s', 'seconds']:
        remainder = int(tdelta)
    elif inputtype in ['m', 'minutes']:
        remainder = int(tdelta) * 60
    elif inputtype in ['h', 'hours']:
        remainder = int(tdelta) * 3600
    elif inputtype in ['d', 'days']:
        remainder = int(tdelta) * 86400
    elif inputtype in ['w', 'weeks']:
        remainder = int(tdelta) * 604800

    f = Formatter()
    desired_fields = [field_tuple[1] for field_tuple in f.parse(fmt)]
    possible_fields = ('W', 'D', 'H', 'M', 'S')
    constants = {'W': 604800, 'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
    values = {}
    for field in possible_fields:
        if field in desired_fields and field in constants:
            values[field], remainder = divmod(remainder, constants[field])
    return f.format(fmt, **values)
Пример #37
0
def getTimeFromTdelta(tdelta, fmt):
    f = Formatter()
    d = {}
    l = {'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
    k = map(lambda x: x[1], list(f.parse(fmt)))
    rem = int(tdelta.total_seconds())

    for i in ('D', 'H', 'M', 'S'):
        if i in k and i in l.keys():
            d[i], rem = divmod(rem, l[i])

    return f.format(fmt, **d)
Пример #38
0
def strfdelta(tdelta: datetime.timedelta, fmt: str) -> str:
    f = Formatter()
    d = {}
    l = {'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
    k = list(map(lambda x: x[1], list(f.parse(fmt))))
    rem = int(tdelta.total_seconds())

    for i in ('D', 'H', 'M', 'S'):
        if i in k and i in l.keys():
            d[i], rem = divmod(rem, l[i])

    return f.format(fmt, **d)
Пример #39
0
 def parse(self, fmt_string):
     for literal_txt, field_name, format_spec, conversion \
                 in Formatter.parse(self, fmt_string):
         
         # Find $foo patterns in the literal text.
         continue_from = 0
         for m in self._dollar_pattern.finditer(literal_txt):
             new_txt, new_field = m.group(1,2)
             yield (new_txt, new_field, "", None)
             continue_from = m.end()
         
         # Re-yield the {foo} style pattern
         yield (literal_txt[continue_from:], field_name, format_spec, conversion)
Пример #40
0
    def save_params(self):
        f = Formatter()
        tokens = f.parse(self.command_string)

        params = []
        for (_ , param_name, _ , _) in tokens:
            if param_name is not None:
                if param_name in self.inputdict:
                    param = self.inputdict[param_name]
                else:
                    param = iobjs.Input(name=param_name)
                if param_name in self._defaults:
                    param.default = self._defaults[param_name]
                params += [param]
        self.inputs = params
Пример #41
0
def strfdelta(tdelta, fmt='{D:02}d {H:02}h {M:02}m {S:02}s', inputtype='timedelta'):
    """Convert a datetime.timedelta object or a regular number to a custom-
    formatted string, just like the stftime() method does for datetime.datetime
    objects.

    The fmt argument allows custom formatting to be specified.  Fields can 
    include seconds, minutes, hours, days, and weeks.  Each field is optional.

    Some examples:
        '{D:02}d {H:02}h {M:02}m {S:02}s' --> '05d 08h 04m 02s' (default)
        '{W}w {D}d {H}:{M:02}:{S:02}'     --> '4w 5d 8:04:02'
        '{D:2}d {H:2}:{M:02}:{S:02}'      --> ' 5d  8:04:02'
        '{H}h {S}s'                       --> '72h 800s'

    The inputtype argument allows tdelta to be a regular number instead of the  
    default, which is a datetime.timedelta object.  Valid inputtype strings: 
        's', 'seconds', 
        'm', 'minutes', 
        'h', 'hours', 
        'd', 'days', 
        'w', 'weeks'
    """

    # Convert tdelta to integer seconds.
    if inputtype == 'timedelta':
        remainder = int(tdelta.total_seconds())
    elif inputtype in ['s', 'seconds']:
        remainder = int(tdelta)
    elif inputtype in ['m', 'minutes']:
        remainder = int(tdelta)*60
    elif inputtype in ['h', 'hours']:
        remainder = int(tdelta)*3600
    elif inputtype in ['d', 'days']:
        remainder = int(tdelta)*86400
    elif inputtype in ['w', 'weeks']:
        remainder = int(tdelta)*604800

    f = Formatter()
    desired_fields = [field_tuple[1] for field_tuple in f.parse(fmt)]
    possible_fields = ('W', 'D', 'H', 'M', 'S')
    constants = {'W': 604800, 'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
    values = {}
    for field in possible_fields:
        if field in desired_fields and field in constants:
            values[field], remainder = divmod(remainder, constants[field])
    return f.format(fmt, **values)
Пример #42
0
 def _wrapped(pseudo_type, string, **kwargs):
     text = []
     formatter = Formatter()
     for (literal_text, field_name, format_spec, conversion) in formatter.parse(string):
         if literal_text:
             literal_text = next_splitter_or_func(
                 literal_text, self.splitters, func, pseudo_type)
             literal_text = literal_text.replace('{', '{{').replace('}', '}}')
             text.append(literal_text)
         if field_name is not None:
             fmt = field_name
             if conversion is not None:
                 fmt += '!' + conversion
             if format_spec:
                 fmt += ':' + format_spec
             text.append('{%s}' % (fmt, ))
     return "".join(text)
Пример #43
0
def strfdelta(tdelta, fmt=None):
    from string import Formatter
    if not fmt:
        # The standard, most human readable format.
        fmt = "{D} days {H:02} hours {M:02} minutes {S:02} seconds"
    if tdelta == timedelta():
        return "0 minutes"
    formatter = Formatter()
    return_map = {}
    div_by_map = {'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
    keys = map(lambda x: x[1], list(formatter.parse(fmt)))
    remainder = int(tdelta.total_seconds())
    for unit in ('D', 'H', 'M', 'S'):
        if unit in keys and unit in div_by_map.keys():
            return_map[unit], remainder = divmod(remainder, div_by_map[unit])

    return formatter.format(fmt, **return_map)
Пример #44
0
 def get_params(self):
     formatter = Formatter()
     format_iterator = formatter.parse(self.get_cleaned_content())
     params = {
         'args': list(),
         'kwargs': set()
     }
     for _tuple in format_iterator:
         field_name = _tuple[1]
         if field_name is not None:
             if field_name == '':
                 params['args'].append(field_name)
             elif field_name.isdigit():
                 if field_name not in params['args']:
                     params['args'].append(field_name)
             else:
                 params['kwargs'].add(field_name)
     return params
Пример #45
0
    def parse(self, fmt_string):
        for literal_txt, field_name, format_spec, conversion in Formatter.parse(self, fmt_string):

            # Find $foo patterns in the literal text.
            continue_from = 0
            txt = ""
            for m in self._dollar_pattern.finditer(literal_txt):
                new_txt, new_field = m.group(1, 2)
                # $$foo --> $foo
                if new_field.startswith("$"):
                    txt += new_txt + new_field
                else:
                    yield (txt + new_txt, new_field, "", None)
                    txt = ""
                continue_from = m.end()

            # Re-yield the {foo} style pattern
            yield (txt + literal_txt[continue_from:], field_name, format_spec, conversion)
Пример #46
0
def tokenize_format_str(fstr, resolve_pos=True):
    """Takes a format string, turns it into a list of alternating string
    literals and :class:`BaseFormatField` tokens. By default, also
    infers anonymous positional references into explict, numbered
    positional references. To disable this behavior set *resolve_pos*
    to ``False``.
    """
    ret = []
    if resolve_pos:
        fstr = infer_positional_format_args(fstr)
    formatter = Formatter()
    for lit, fname, fspec, conv in formatter.parse(fstr):
        if lit:
            ret.append(lit)
        if fname is None:
            continue
        ret.append(BaseFormatField(fname, fspec, conv))
    return ret
Пример #47
0
class BaseManager(object):
    """Base class for Endpoint Manager objects."""

    url = ''

    def __init__(self, api_client):
        self.api_client = api_client
        self._formatter = StringFormatter()

    def _get_format_kwargs(self, **kwargs):
        it = self._formatter.parse(self.url)
        output = {i[1]: '' for i in it}
        for key in output.keys():
            if kwargs.get(key):
                output[key] = kwargs[key]
        if 'endpoint' in output.keys():
            output.pop('endpoint')
        return output

    def get_url(self,
                endpoint,
                kwargs,
                authorized_args=[]):
        """Returns the required url for a request against CloudKitty's API.

        :param endpoint: The endpoint on which the request should be done
        :type endpoint: str
        :param kwargs: kwargs that will be used to build the query (part after
                       '?' in the url) and to format the url.
        :type kwargs: dict
        :param authorized_args: The arguments that are authorized in url
                                parameters
        :type authorized_args: list
        """
        query_kwargs = {
            key: kwargs[key] for key in authorized_args
            if kwargs.get(key, None)
        }
        kwargs = self._get_format_kwargs(**kwargs)
        url = self.url.format(endpoint=endpoint, **kwargs)
        query = urlencode(query_kwargs)
        if query:
            url += '?' + query
        return url
Пример #48
0
    def strfdelta(tsec, format_str="P", format_no_day="PT{H}H{M}M{S}S", format_zero="PT0S"):
        """Formatting the time duration.

        Duration ISO8601 format (PnYnMnDTnHnMnS): http://en.wikipedia.org/wiki/ISO_8601
        Choosing the format P[nD]TnHnMnS where days is the total number of days (if not 0), 0 values may be omitted,
        0 duration is PT0S

        :param tsec: float, number of seconds
        :param format_str: Format string, ISO 8601 is "P{D}DT{H}H{M}M{S}S". Default is a format string "P": will
            use ISO 8601 but skip elements that have 0 value, e.g. P1H7S instead of P1H0M7S
        :param format_no_day: Format string,  ISO 8601, default "PT{H}H{M}M{S}S"
        :param format_zero: format for when tsec is 0 or None, default "PT0S"
        :return: Formatted time duration
        """
        if not tsec:
            # 0 or None
            return format_zero

        f = Formatter()
        d = {}
        l = {'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
        rem = long(tsec)

        if format_str == "P":
            # variable format
            if 0 < tsec < 86400:
                format_str = "PT"
            for i in ('D', 'H', 'M', 'S'):
                if i in l.keys():
                    d[i], rem = divmod(rem, l[i])
                    if d[i] != 0:
                        format_str = "%s{%s}%s" % (format_str, i, i)
        else:
            if 0 < tsec < 86400:
                format_str = format_no_day
            k = map(lambda x: x[1], list(f.parse(format_str)))

            for i in ('D', 'H', 'M', 'S'):
                if i in k and i in l.keys():
                    d[i], rem = divmod(rem, l[i])

        return f.format(format_str, **d)
Пример #49
0
 def resolve_conf(unresolved):
     """take a config with values using string formatting; apply string formatting until they all don't;
        returns (dict of things that could be resolved, dict of things that couldn't be resolved)"""
     f = Formatter()
     resolved = {}
     while unresolved:
         changed_something, missing_defs = False, []
         for k, v in unresolved.items():
             if isinstance(v, basestring) and v and tuple(f.parse(v))[0][1] is not None:
                 try:
                     unresolved[k] = f.vformat(v, [], resolved)
                     changed_something = True
                 except KeyError, e: # missing a definition; but could in the next pass if we changed something
                     missing_defs.append(e.args[0])
             else:
                 # non strings are, by definition, resolved; no recursion into complex data structures here
                 # items without format specifiers are also resolved
                 del unresolved[k]
                 resolved[k] = v
                 changed_something = True
         if not changed_something:
             break
 def template_opts(self):
     """Returns the template key/values, if a key from the template
     does not exist raises an exception.
     """
     template_opts = {}
     formatter = Formatter()
     keys = [opt[1] for opt in formatter.parse(
         self.template) if opt[1] not in ['sequence']]
     template_opts.update(
         sequence=str(self.sequence_number).rjust(self.padding, '0'))
     for key in keys:
         try:
             value = getattr(self, key)
         except AttributeError:
             raise IdentifierMissingTemplateValue(
                 f'Required option not provided. Got \'{key}\'.')
         else:
             if value:
                 template_opts.update({key: value})
             else:
                 raise IdentifierMissingTemplateValue(
                     f'Required option cannot be None. Got \'{key}\'.')
     return template_opts
Пример #51
0
def main(argv):
    out = sys.stdout

    if len(argv) < 2:
        sys.stderr.write('''
usage: %(prog)s format
'''.lstrip() % {
            'prog': argv[0]
        })
        return 1

    if argv[1] == '--tools':
        out.write('\n'.join([
            tool.name for tool in TOOLS
        ]) + '\n')
        out.flush()
        return 0

    format = argv[1]
    formatter = Formatter()

    try:
        tool = get_tool()
    except NoToolError:
        return 0

    values = {}
    for null, field_name, null, null in formatter.parse(format):
        if not field_name:
            continue
        values[field_name] = getattr(tool, field_name)

    out.write(format.format(**values))
    out.flush()

    return 0
Пример #52
0
    def compute_one_task(self, itask, task):
        """
        Run the algorithm once, using the parameters specified by `task`,
        which is the `itask` iteration
    
        Parameters
        ----------
        itask : int
            the integer index of this task
        task : tuple
            a tuple of values representing this task value
        """
        # if you are the pool's root, write out the temporary parameter file
        this_config = None
        if self.workers.subcomm.rank == 0:
                
            # initialize a temporary file
            with tempfile.NamedTemporaryFile(delete=False) as ff:
                
                this_config = ff.name
                logger.debug("creating temporary file: %s" %this_config)
                
                # key/values for this task 
                if len(self.task_dims) == 1:
                    possible_kwargs = {self.task_dims[0] : task}
                else:
                    possible_kwargs = dict(zip(self.task_dims, task))
                    
                # any extra key/value pairs for this tasks
                if self.extras is not None:
                    for k in self.extras:
                        possible_kwargs[k] = self.extras[k][itask]
                        
                # use custom formatter that only formats the possible keys, ignoring other
                # occurences of curly brackets
                formatter = Formatter()
                formatter.parse = lambda l: SafeStringParse(formatter, l, list(possible_kwargs))
                kwargs = [kw for _, kw, _, _ in formatter.parse(self.template) if kw]
                        
                # do the string formatting if the key is present in template
                valid = {k:possible_kwargs[k] for k in possible_kwargs if k in kwargs}
                ff.write(formatter.format(self.template, **valid).encode())
        
        # bcast the file name to all in the worker pool
        this_config = self.workers.subcomm.bcast(this_config, root=0)

        # configuration file passed via -c
        params, extra = ReadConfigFile(open(this_config, 'r').read(), self.algorithm_class.schema)
        
        # output is required
        output = getattr(extra, 'output', None)
        if output is None:
            raise ValueError("argument `output` is required in config file")
            
        # initialize the algorithm and run
        alg = self.algorithm_class(**vars(params))
        result = alg.run()
        alg.save(output, result)

        # remove temporary files
        if self.workers.subcomm.rank == 0:
            if os.path.exists(this_config): 
                logger.debug("removing temporary file: %s" %this_config)
                os.remove(this_config)
                
        return 0
Пример #53
0
class RelayProtocol(LineOnlyReceiver):
    
    MAX_LENGTH = 65536
    
    def __init__(self, factory):
        self.factory = factory
        self._ids = set()
        self._format = Formatter()
    
    def error(self, s):
        return self.reply({
            'id': 0,
            'state': 'error',
            'message': s
        })
    
    def reply(self, msg={}):
        try:
            self.transport.write(json.dumps(msg) + self.delimiter)
            return True
        except (ValueError, TypeError):
            return self.error('unable to serialise response (internal error)')
    
    def parse(self, line):
        try:
            deserialised = json.loads(line)
        except (ValueError, TypeError):
            return self.error('unable to deserialise request (client error)')
        if 'request' not in deserialised:
            return self.error('missing required parameter: request')
        if 'id' not in deserialised:
            return self.error('missing required parameter: id')
        id = deserialised.get('id', '')
        request = deserialised.get('request', '')
        params = deserialised.get('params', {})
        data = deserialised.get('data', {})
        request_config = self.factory.get_request(request)
        if not request_config:
            return self.error('not a valid request: {}'.format(request))
        if len(request_config) != 5:
            return self.error('request tuple does not have three elements: {}'.format(request))
        request_method, request_url, expected_status, request_auth, parser = request_config
        if not request_auth:
            request_auth = NullAuth()
        if not parser:
            parser = NullParser()
        for (lit, field, spec, conv) in self._format.parse(request_url):
            if field and field not in params:
                return self.error('missing required parameter: {}'.format(field))
        try:
            parsed_url = request_url.format(**params)
        except KeyError:
            return self.error('unable to parse request url with provided paramters')
        self.send_request(
            id=id,
            method=request_method,
            url=parsed_url,
            auth=request_auth,
            data=data,
            expected=expected_status,
            parser=parser
        )
    
    def send_request(self, id='', method='GET', url='', auth=None, data='', expected=200, parser=None):
        request = HttpRequest(
            id=id,
            method=method,
            url=url,
            expected=expected,
            parser=parser
        )
        if data:
            request.set_body(data)
        request = auth.apply_auth(request)
        HttpTransport(request).go(self.got_response)
        self.reply({
            'id': str(request.id),
            'status': 'dispatched',
        })
    
    def got_response(self, response):
        self.reply({
            'id': response.request.id,
            'status': 'ok' if response.ok() else 'error',
            'response': response.data(),
            'time': round(time.time() - response.request.start_time, 5),
        })
    
    def lineReceived(self, line):
        self.parse(line)
Пример #54
0
def extract_used_fields(text):
    fmtr = Formatter()
    return [i[1] for i in fmtr.parse(text) if i[1]]
Пример #55
0
import polib
from string import Formatter
import glob

filelist = glob.glob("*.po")
pos = {filename: polib.pofile(filename) for filename in filelist}

formatter = Formatter()

for name, po in pos.iteritems():
    print "Testing", name
    for entry in po:
        if len(entry.msgstr) > 0:
            try:
                ids = [field_name
                       for literal_text, field_name, format_spec, conversion
                       in formatter.parse(entry.msgid)]
                tids = [field_name
                        for literal_text, field_name, format_spec, conversion
                        in formatter.parse(entry.msgstr)]
            except Exception as e:
                print "Got exception!", e, "for entry", entry.msgid
            else:
                if tids is not None:
                    missing = [name for name in tids
                               if name is not None and name not in ids]
                    if len(missing) > 0:
                        print "Missing parameters", missing, \
                              "in translation of", entry.msgid
def createScriptFile(script_fp,
                     xmlfile, 
                     nlogofile,
                     experiment,
                     combination_nr,
                     script_template,
                     csv_output_dir = "./"
                     ):
    """
    Create a script file from a template string.

    Parameters
    ----------

    script_fp : file pointer
       File opened for writing.    

    xmlfile : string
       File name and path of the xml experiment file.
       This string will be accessible through the key {setup}
       in the script_template string.

    nlogofile : string
       File name and path of the ,nlogo model file.
       This string will be accessible through the key {model}
       in the script_template string.

    experiment : string
       Name of the experiment.
       This string will be accessible through the key {experiment}
       in the script_template string.

    combination_nr : int
       The experiment combination number.
       This value will be accessible through the key {combination}
       in the script_template string.

    script_template : str
       The script template string. This string will be cloned for each script
       but the following keys can be used and will have individual values.
       {job} - Name of the job. Will be the name of the xml-file (minus extension).
       {combination} - The value of the parameter combination_nr.
       {experiment} - The value of the parameter experiment.
       {csv} - File name, including full path, of a experiment-unique csv-file.
       {setup} - The value of the parameter csvfile.
       {model} - The value of the parameter nlogofile.
       {csvfname} - Only the file name part of the {csv} key.
       {csvfpath} - Only the path part of the {csv} key.
       
    csv_output_dir : str, optional
       Path to the directory used when constructing the {csv} and {csvfpath} 
       keys.


    Returns
    -------

    file_name : str
       Name of the file name used for the script.

    """
    jobname = os.path.splitext(os.path.basename(xmlfile))[0]


    fname = jobname + ".csv"
    csvfile = os.path.join(csv_output_dir, fname)

    strformatter = Formatter()
    formatmap = {
        "job" : jobname, 
        "combination" : combination_nr, 
        "experiment" : experiment,
        "csv" : csvfile,
        "setup" : xmlfile,
        "model" : nlogofile,
        "csvfname" : fname,
        "csvfpath" : csv_output_dir
        }
    # Use string formatter to go through the script template and
    # look for unknown keys. Do not replace them, but print warning.
    for lt, fn, fs, co in strformatter.parse(script_template):
        if fn != None and fn not in formatmap.keys():
            print("Warning: Unsupported key '{{{0}}}' in script template. Ignoring."\
                      .format(fn))
            formatmap[fn] = "{" + fn + "}"
            
    script_fp.write(script_template.format(**formatmap))