Exemple #1
0
    def __init__(self, name, nexpected, ngiven):
        """
        """

        mark = name.mark
        TemplateError.__init__(self, self.message.format(
            name, mark.name, mark.line + 1, mark.column + 1, nexpected, ngiven
        ))
    def check_duplicate_attr(self, d, attr=None, mandatory=False):
        seen = {}
        stat = []

        def get_value(value):
            def get_single_value(v, k):
                if not (k in v):
                    if mandatory:
                        raise TemplateError(
                            "Missing mandatory attribute %s in %s" % (k, v))
                    else:
                        return None
                return v[k]

            if type(attr) is list:
                retval = ""
                for a in attr:
                    item = get_single_value(value, a)
                    retval += " " if retval else ""
                    retval += "%s=%s" % (a, item)
                return retval
            else:
                return get_single_value(value, attr)

        def check_unique_value(key, value):
            if key is not None:
                value['key'] = key
            v = get_value(value)
            if v in seen:
                stat.append(
                    "Duplicate value %s of attribute %s found in %s and %s" %
                    (v, attr, seen[v]['key'] if
                     ('key' in seen[v]) else seen[v], value['key'] if
                     ('key' in value) else value))
            else:
                seen[v] = value

        # sanity check: do we know which attribute to check?
        #
        if attr is None:
            raise TemplateError("You have to specify attr=name in checkunique")

        # iterate over a list or a dictionary, fail otherwise
        #
        if type(d) is list:
            for value in d:
                check_unique_value(None, value)
        elif type(d) is dict:
            for key in d:
                check_unique_value(key, d[key])
        else:
            raise TemplateError("")

        if len(stat) == 0:
            return None
        else:
            return stat
Exemple #3
0
    def _get_templated_body(self) -> str:
        """Assemble and return the body of the message using the template.

        Any captcha data is automatically removed, if present.
        """
        tmpl_path = settings.MAIL_TEMPLATE_PATH
        data = self.data.copy()
        if self.captcha_client.key:
            data.pop(self.captcha_client.key)
        if tmpl_path:
            try:
                with open(tmpl_path) as fd:
                    tmpl = Template(fd.read())
                    try:
                        return tmpl.render(data=data, metadata=self.metadata)
                    except UndefinedError as exc:
                        raise TemplateError(
                            f"The template did not define the required fields:"
                            f" {exc.message}")
            except IOError:
                err = (f"Cannot open template file. "
                       f"Check if it exists and is readable.")
                log.error(err)
                raise exceptions.ConfigError(err)
        else:
            return json.dumps(self.data)
Exemple #4
0
def markdown(env, value):
    """
    Markdown filter with support for extensions.
    """
    try:
        import markdown as md
    except ImportError:
        log.error(u"Cannot load the markdown library.")
        raise TemplateError(u"Cannot load the markdown library")
    output = value

    extensions = [
        'markdown.extensions.meta', 'markdown.extensions.headerid',
        'markdown.extensions.attr_list', 'markdown.extensions.toc',
        'markdown.extensions.def_list', 'digital_logic.ext.passthrough',
        'digital_logic.ext.sections'
    ]

    d = dict()
    d['extensions'] = list()
    d['extensions'].extend(extensions)

    marked = md.Markdown(**d)

    return marked.convert(output)
Exemple #5
0
    def generate_file(self, p: Path):
        try:
            template = Template(p.read_text())
            text = template.render(**self.ctx)
        except TemplateError as e:
            raise TemplateError('error in {}'.format(p)) from e
        text = text.strip('\n\t ')
        new_path = self.project_root / p.relative_to(self.template_dir)
        if len(text) < 3:
            # empty files don't get created, in case a few characters get left behind
            logger.debug('not creating "%s", as it would be empty', new_path)
            return
        logger.debug('creating "%s"', new_path)

        if p.name == 'requirements.txt':
            packages = {
                p.strip()
                for p in text.split('\n') if p.strip() and p.strip() != '#'
            }
            text = '\n'.join(sorted(packages))
        else:
            # helpful when debugging: print(text.replace(' ', '·').replace('\n', '⏎\n'))
            if p.suffix == '.py':
                text = SortImports(file_contents=text).output

            regexes = FILES_REGEXES.get(p.suffix, [])
            for regex, repl in regexes:
                text = regex.sub(repl, text)

        # re-add a trailing newline accounting for newlines added by PY_REGEXES
        text = re.sub('\n*$', '\n', text)
        new_path.parent.mkdir(parents=True, exist_ok=True)
        new_path.write_text(text)
        self.files_created += 1
Exemple #6
0
    def get_source(self, environment, template):
        parts = template.split(":")
        module = None
        templatePath = None
        if len(parts) == 1:
            module = self.baseModule
            templatePath = parts[0]
        elif len(parts) == 2:
            module = parts[0]
            templatePath = parts[1]
        else:
            raise TemplateError("Invalid syntax " + template)

        if module == "__main__":
            module = self.baseModule

        decode = 'utf-8'
        parts = templatePath.split("#")
        if len(parts) > 1:
            templatePath = parts[0]
            decode = parts[1]

        path = self.path + "/" + templatePath
        data = None
        if decode == "base64":
            myLogger.debug("Loading base64 resource from {0}:{1}".format(
                module, path))
            with pkg_resources.resource_stream(module, path) as res:
                data = base64.b64encode(res.read()).decode("utf-8")
        else:
            data = pkg_resources.resource_string(module, path).decode(decode)

        return data, templatePath, lambda: False
    def device_type(self, show_ver, *deftype):
        if "Cisco IOS" in show_ver: return "ios"
        if "NX-OS" in show_ver: return "nx-os"
        if len(deftype) > 0: return deftype[0]

        raise TemplateError(
            "Unknown device type - did you pass me show version?")
Exemple #8
0
    def status():

        if request.args.get('json'):
            payload = this_node.abridged_node_details()
            response = jsonify(payload)
            return response

        else:
            headers = {"Content-Type": "text/html", "charset": "utf-8"}
            previous_states = list(reversed(this_node.known_nodes.states.values()))[:5]
            # Mature every known node before rendering.
            for node in this_node.known_nodes:
                node.mature()

            try:
                content = status_template.render(this_node=this_node,
                                                 known_nodes=this_node.known_nodes,
                                                 previous_states=previous_states,
                                                 domains=serving_domains,
                                                 version=nucypher.__version__,
                                                 checksum_address=this_node.checksum_address)
            except Exception as e:
                log.debug("Template Rendering Exception: ".format(str(e)))
                raise TemplateError(str(e)) from e
            return Response(response=content, headers=headers)
 def get_single_value(v, k):
     if not (k in v):
         if mandatory:
             raise TemplateError(
                 "Missing mandatory attribute %s in %s" % (k, v))
         else:
             return None
     return v[k]
Exemple #10
0
  def dict_to_list(self,o):
    if type(o) is not dict:
      raise TemplateError("dict_to_list can only be used on dictionaries")

    l = []
    for k,v in o.items():
      v['id'] = k
      l.append(v)

    return l
Exemple #11
0
  def list_append(self,l,*argv):
    if type(l) is not list:
      raise TemplateError("First argument of append filter must be a list")

    for element in argv:
      if type(element) is list:
        l.extend(element)
      else:
        l.append(element)
    return l
Exemple #12
0
def render_to_pdf(template_name,
                  params,
                  font_resolver=font_resolver,
                  image_resolver=image_resolver):
    """Renders PDF from RML, which is rendered from a Django template.
    """
    rml = render_to_string(template_name, params).encode('utf-8')
    try:
        pdf = rml2pdf(rml, font_resolver, image_resolver)
    except Exception, e:
        raise TemplateError(str(e))
Exemple #13
0
    def status():
        headers = {"Content-Type": "text/html", "charset": "utf-8"}
        previous_states = list(reversed(this_node.known_nodes.states.values()))[:5]

        try:
            content = status_template.render(this_node=this_node,
                                             known_nodes=this_node.known_nodes,
                                             previous_states=previous_states)
        except Exception as e:
            log.debug("Template Rendering Exception: ".format(str(e)))
            raise TemplateError(str(e)) from e

        return Response(response=content, headers=headers)
    def list_flatten(self, l):
        if type(l) is not list:
            raise TemplateError("flatten filter takes a list")

        def recurse_flatten(l):
            if type(l) is not list:
                return [l]
            r = []
            for i in l:
                r.extend(recurse_flatten(i))
            return r

        return recurse_flatten(l)
Exemple #15
0
def Jinja2Process(flines, dir, inputs=[], inputs_file=None, verbose=False):
    env = Environment(loader=FileSystemLoader(dir),
                      undefined=StrictUndefined,
                      extensions=['jinja2.ext.do'])

    # Load any custom Jinja2 filters in the suite definition directory
    # Example: a filter to pad integer values some fill character:
    #|(file SUITE_DEFINIION_DIRECTORY/Jinja2/foo.py)
    #|  #!/usr/bin/env python
    #|  def foo( value, length, fillchar ):
    #|     return str(value).rjust( int(length), str(fillchar) )
    fdirs = [
        os.path.join(os.environ['CYLC_DIR'], 'lib', 'Jinja2Filters'),
        os.path.join(dir, 'Jinja2Filters'),
        os.path.join(os.path.join(os.environ['HOME'], '.cylc',
                                  'Jinja2Filters'))
    ]
    usedfdirs = []
    for fdir in fdirs:
        if os.path.isdir(fdir):
            usedfdirs.append(fdir)
    for filterdir in usedfdirs:
        sys.path.append(os.path.abspath(filterdir))
        for f in glob.glob(os.path.join(filterdir, '*.py')):
            fname = os.path.basename(f).rstrip('.py')
            # TODO - EXCEPTION HANDLING FOR LOADING CUSTOM FILTERS
            m = __import__(fname)
            env.filters[fname] = getattr(m, fname)

    # Import SUITE HOST USER ENVIRONMENT into template:
    # (usage e.g.: {{environ['HOME']}}).
    env.globals['environ'] = os.environ

    # load file lines into a template, excluding '#!jinja2' so
    # that '#!cylc-x.y.z' rises to the top.
    # CALLERS SHOULD HANDLE JINJA2 TEMPLATESYNTAXERROR AND TEMPLATEERROR
    # try:
    template = env.from_string('\n'.join(flines[1:]))
    # except Exception, x:
    #     # This happens if we use an unknown Jinja2 filter, for example.
    ##     # TODO - THIS IS CAUGHT BY VALIDATE BUT NOT BY VIEW COMMAND...
    #     raise TemplateError( x )
    try:
        template_vars = load_template_vars(inputs, inputs_file, verbose)
    except Exception, x:
        raise TemplateError(x)
Exemple #16
0
def _validate_randomizable_source(
        name: str, source: Union[str, List[Union[str, int, float]]]) -> None:
    """Validate that a randomizable template source has the proper format.

    Raises a TemplateError when one of the items of a list source has an
    invalid format, which can easily happen when one forgets to quote a complex
    string.
    """
    for val in source:
        if not isinstance(val, str):
            if not (isinstance(val, list) and len(val) == 2
                    and isinstance(val[1], (int, float))):
                raise TemplateError(
                    f'Invalid format on randomizable template {name}. The '
                    f'individual items of a randomizable template must be '
                    f'strings or 2-item lists, where the second item is a '
                    f'number. Perhaps you forgot to enclose a complex string '
                    f'in quotes?')
Exemple #17
0
    def status():
        # TODO: Seems very strange to deserialize *this node* when we can just pass it in.
        #       Might be a sign that we need to rethnk this composition.

        headers = {"Content-Type": "text/html", "charset": "utf-8"}
        this_node = _node_class.from_bytes(node_bytes_caster(), federated_only=federated_only)

        previous_states = list(reversed(node_tracker.states.values()))[:5]

        try:
            content = status_template.render(this_node=this_node,
                                             known_nodes=node_tracker,
                                             previous_states=previous_states)
        except Exception as e:
            log.debug("Template Rendering Exception: ".format(str(e)))
            raise TemplateError(str(e)) from e

        return Response(response=content, headers=headers)
Exemple #18
0
def raise_template_error(message):
    raise TemplateError(message)
Exemple #19
0
    def render(self,
               template=None,
               output="./out/spec.html",
               foreign_sources={},
               local=None,
               local_sources=None):
        """
        With no parameters render will update the info.json with the transformation information
        with params we'll render a html inline.
        """

        # base data sources
        raw_data = self._create_output_dict()
        info_json = self._update_transform_stage(raw_data)

        # we also need some basic jenkins details
        # Jenkins is case sensitive, and the pattern si different for covid
        family = info_json["families"][0].lower()
        if "COVID" in family.upper():
            family = family.upper()
        else:
            family = "-".join([x.capitalize() for x in family.split("-")])

        # Jenkins Job ---------
        # TODO - this bits very unlikely to be robust, but only matters for running
        # locaally.... sometimes is better than never
        jenkins_title = info_json["title"].replace(",", "").replace(" ", "-")
        pub_name = info_json["publisher"].split(" ")
        try:
            jenkins_title = pub_name[0] + "-" + pub_name[
                1][:1] + "-" + jenkins_title
        except IndexError:
            jenkins_title = pub_name[0] + jenkins_title

        jenkins_job = pathify(
            os.environ.get('JOB_NAME',
                           f'replace-with-family-name/job/')) + jenkins_title
        jenkins_job = jenkins_job.replace("replace-with-family-name", family)
        jenkins = {"job": jenkins_job, "family": family}

        # Jenkins Build Status ---------
        jenkins_build = f"https://ci.floop.org.uk/buildStatus/icon?job=GSS_data%2F{family}%2F{jenkins_title}/"
        jenkins["build"] = jenkins_build

        if local is not None and template is not None:
            raise Exception(
                "You can only pass EITHER local= or a remote template url/name, not both"
            )

        # Templating, going to wrap this in case something goes bang
        try:

            if local is not None:
                try:
                    with open(local, "r") as f:
                        localTemplate = f.read()
                except Exception as e:
                    raise Exception(
                        "Unable to open template from location {}.".format(
                            local)) from e
            elif template is None:
                # Exit immediately if no local template and we don't want to render
                return
            elif "/" not in template:
                # If it's just a file name so it's a template from the standard library
                template = "https://raw.githubusercontent.com/GSS-Cogs/frontend-template-resources/master/templates/jinja2/" + template
            else:
                pass
            """
            A foreign source is where we want to call in a little more data for the renderer,
            We'll add them to the two existing data sources we always make availible, which are:

            info_json: the info.json
            raw_data: the dictionary that is the tracer store (similar but with a little extra info)
            """
            kwargs = {
                "info_json": info_json,
                "raw_data": raw_data,
                "jenkins": jenkins
            }
            for template_referal, url in foreign_sources.items():

                # template_referal is how we want to refer to this exta data
                # in the template. Make sure it's not overwriting a standard data key
                if template_referal in ["info_json", "raw_data"]:
                    raise Exception("Aborting, you cannot pass a data source with the protected " \
                                    "label of {}.".format(template_referal))

                r = requests.get(url)
                if r.status_code != 200:
                    raise Exception(
                        "Unable to additional data from: {}, status code {}".
                        format(url, r.status_code))

                kwargs[template_referal] = r.json()

            # the user might also pass in some additional dictionaries
            if local_sources is not None:
                for template_referal, extra_dict in local_sources.items():

                    # template_referal is how we want to refer to this exta data
                    # in the template. Make sure it's not overwriting a standard data key
                    if template_referal in ["info_json", "raw_data"]:
                        raise Exception("Aborting, you cannot pass a data source with the protected " \
                                        "label of {}.".format(template_referal))

                    kwargs[template_referal] = extra_dict

            if local is None:
                r = requests.get(template)
                if r.status_code != 200:
                    raise Exception(
                        "Unable to http get template from: {}, status code {}".
                        format(template, r.status_code))
                templateRenderer = Template(r.text)
            else:
                templateRenderer = Template(localTemplate)
            outputText = templateRenderer.render(**kwargs)

            with open(output, "w") as f:
                f.write(outputText)

            print("Template {} rendered as {}".format(template, output))

        except Exception as e:
            raise TemplateError(
                "Problem encountered attmepting to render template") from e
Exemple #20
0
def Jinja2Process( flines, dir, inputs=[], inputs_file=None ):
    env = Environment( loader=FileSystemLoader(dir), undefined=StrictUndefined, extensions=['jinja2.ext.do'] )

    # Load any custom Jinja2 filters in the suite definition directory
    # Example: a filter to pad integer values some fill character:
    #|(file SUITE_DEFINIION_DIRECTORY/Jinja2/foo.py)
    #|  #!/usr/bin/env python
    #|  def foo( value, length, fillchar ):
    #|     return str(value).rjust( int(length), str(fillchar) )
    fdirs = [os.path.join( os.environ['CYLC_DIR'], 'lib', 'Jinja2Filters' ),
            os.path.join( dir, 'Jinja2Filters' ),
            os.path.join( os.path.join( os.environ['HOME'], '.cylc', 'Jinja2Filters' ))]
    usedfdirs = []
    for fdir in fdirs:
        if os.path.isdir( fdir ):
            usedfdirs.append( fdir )
    for filterdir in usedfdirs:
        sys.path.append( os.path.abspath( filterdir ))
        for f in glob.glob( os.path.join( filterdir, '*.py' )):
            fname = os.path.splitext(os.path.basename(f))[0]
            # TODO - EXCEPTION HANDLING FOR LOADING CUSTOM FILTERS
            m = __import__( fname )
            env.filters[ fname ] = getattr( m, fname )

    # Import SUITE HOST USER ENVIRONMENT into template:
    # (usage e.g.: {{environ['HOME']}}).
    env.globals['environ'] = os.environ

    # load file lines into a template, excluding '#!jinja2' so
    # that '#!cylc-x.y.z' rises to the top.
    # CALLERS SHOULD HANDLE JINJA2 TEMPLATESYNTAXERROR AND TEMPLATEERROR
    # try:
    template = env.from_string( '\n'.join(flines[1:]) )
    # except Exception as exc:
    #     # This happens if we use an unknown Jinja2 filter, for example.
    ##     # TODO - THIS IS CAUGHT BY VALIDATE BUT NOT BY VIEW COMMAND...
    #     raise TemplateError(exc)
    try:
        template_vars = load_template_vars( inputs, inputs_file )
    except Exception as exc:
        if isinstance(exc, TemplateError):
            raise
        raise TemplateError(exc)

    # CALLERS SHOULD HANDLE JINJA2 TEMPLATESYNTAXERROR AND TEMPLATEERROR
    # AND TYPEERROR (e.g. for not using "|int" filter on number inputs.
    # Convert unicode to plain str, ToDo - still needed for parsec?)
    #try:
    rendered = str( template.render( template_vars ) )
    #except Exception, x:
    #    raise TemplateError( x )

    xlines = rendered.split('\n')
    suiterc = []
    for line in xlines:
        # Jinja2 leaves blank lines where source lines contain
        # only Jinja2 code; this matters if line continuation
        # markers are involved, so we remove blank lines here.
        if re.match( '^\s*$', line ):
            continue
            # restoring newlines here is only necessary for display by
        # the cylc view command:
        ###suiterc.append(line + '\n')
        suiterc.append(line)

    return suiterc