Example #1
0
    def transform(self, result, encoding):
        css = u''
        javascript = u''
        for parent in parents(self.published.context, iface=IFlowFolder):
            css = parent._v_css = getattr(  # noqa: P001
                parent,
                '_v_css',
                Scss().compile(parent.css or u''),
            )
            javascript =\
                (parent.javascript or u'').strip().replace(u'\r\n', u'\n')
            break

        root = result.tree.getroot()
        if css:
            head = root.find('head')
            # trick LXML to render styles with //<!CDATA[[
            style = builder.STYLE(u'\n/*', type='text/css')
            style.append(builder.S(CDATA(u'*/\n' + css + u'\n/*')))
            style.getchildren()[0].tail = u'*/\n'
            head.append(style)
            # head.append(builder.STYLE(
            #     css,
            #     type='text/css',
            # ))

        if javascript:
            body = root.find('body')
            # trick LXML to render script with //<!CDATA[[
            script = builder.SCRIPT(u'\n//', type='application/javascript')
            script.append(builder.S(CDATA(u'\n' + javascript + u'\n//')))
            script.getchildren()[0].tail = u'\n'
            body.append(script)

        return result
Example #2
0
    def to_element(self) -> ElementT:
        """Returns item element for xml."""
        item = create_element('item', children=[
            create_element('title', CDATA(self.title)),
            create_element('description', CDATA(self.description)),
        ])

        if self.url:
            item.append(create_element('link', self.url))

        item.append(create_element(
            'guid',
            attrib={
                'isPermaLink': str(bool(not self.guid and self.url)).lower()
            },
            text=(self.guid or self.url or CDATA(self.title))
        ))

        if self.author:
            item.append(create_element(
                '{http://purl.org/dc/elements/1.1/}creator',
                CDATA(self.author)
            ))

        for category in self.categories:
            item.append(create_element('category', CDATA(category)))
        if self.enclosure:
            item.append(self.enclosure.to_element())
        if self.pub_date:
            item.append(create_element('pubDate', self.pub_date))

        return item
Example #3
0
    def process_availability(self, root, tag, child, script_type, identifier):
        if tag:
            if child.text is None:
                child.text = CDATA(self.add_availability(script_type, identifier, False))
            else:
                if 'SchemeUtil_PMP' not in child.text:
                    new_var = ''
                    current_code_array = child.text.splitlines()
                    current_code = ''
                    for line_code in current_code_array:
                        if line_code.startswith('//'):
                            pass
                        else:
                            current_code = current_code + line_code + '\n'

                    if child.text.count('return ') > 1:
                        new_var = new_var + 'var actual : boolean'
                        new_var = new_var + str(current_code).replace('return', 'actual =').replace('"', '\"')
                    else:
                        new_var = str(current_code).replace('return', 'var actual =', 1).replace('"', '\"')
                    child.text = CDATA(new_var + '\n' + self.add_availability(script_type, identifier, True))
        else:
            new_element = etree.Element('AvailabilityScript')
            new_element.text = CDATA(self.add_availability(script_type, identifier, False))
            root.insert(0, new_element)
Example #4
0
 def process_initialize(self, root, tag, child):
     if tag:
         if child.text is None:
             child.text = CDATA(self.add_clause_initialize())
     else:
         new_element = etree.Element('InitializeScript')
         new_element.text = CDATA(self.add_clause_initialize())
         root.insert(0, new_element)
Example #5
0
 def process_existence(self, root, tag, child):
     if self.existence != '':
         del root.attrib['existence']
         if tag:
             if child.text is None:
                 child.text = CDATA(self.add_clause_existence())
         else:
             new_element = etree.Element('ExistenceScript')
             new_element.text = CDATA(self.add_clause_existence())
             root.insert(0, new_element)
Example #6
0
 def element_artwork(self, e, p):
     if e.text and e.text.strip() and not ']]>' in e.text:
         e.text = CDATA(
             e.text
         )  # prevent text from being mucked up by other processors
     stripattr(e, [
         'height',
         '{http://www.w3.org/XML/1998/namespace}space',
         'width',
     ])
     if e.text and re.search(r'^\s*<CODE BEGINS>', e.text):
         # We have source code.  Permitted attributes: anchor, name,
         # source, type.
         e = self.replace(e, 'sourcecode')
         e.set('markers', 'true')
         match = re.search(
             r'(?s)^\s*<CODE BEGINS>(\s+file\s+"([^"]*)")?(.*?)(<CODE ENDS>(.*))?$',
             e.text)
         file = match.group(1)
         name = match.group(2)
         body = match.group(3)
         ends = match.group(4)
         tail = match.group(5)
         if file and name:
             e.set('name', name)
         e.text = CDATA(body)
         if not ends:
             self.warn(e,
                       "Found <CODE BEGINS> without matching <CODE ENDS>")
         if ends and tail.strip() != "":
             self.warn(e, "Found non-whitespace content after <CODE ENDS>")
             e.tail = tail
         stripattr(e, [
             'align',
             'alt',
             'height',
             'suppress-title',
             'width',
         ])
     src = e.get('src')
     if e.text and e.text.strip() and src:
         # We have both text content and a src attribute -- convert to
         # <artset> with 2 <artwork)
         ext = os.path.splitext(src)[1][1:]
         artset = self.element('artset', line=e.sourceline)
         extart = self.copy(e, 'artwork')
         extart.text = None
         extart.tail = None
         extart.set('type', ext)
         artset.append(extart)
         stripattr(e, ['src'])
         e.set('type', 'ascii-art')
         artset.append(e)
         p.append(artset)
Example #7
0
def generate_rss_feed(repo, filename, me):
    generator = FeedGenerator()
    generator.id(repo.html_url)
    generator.title(f"RSS feed of {repo.owner.login}'s {repo.name}")
    generator.author(
        {"name": os.getenv("GITHUB_NAME"), "email": os.getenv("GITHUB_EMAIL")}
    )
    generator.link(href=repo.html_url)
    generator.link(
        href=f"https://raw.githubusercontent.com/{repo.full_name}/master/{filename}",
        rel="self",
    )
    for issue in repo.get_issues():
        if not issue.body or not is_me(issue, me) or issue.pull_request:
            continue
        item = generator.add_entry(order="append")
        item.id(issue.html_url)
        item.link(href=issue.html_url)
        item.title(issue.title)
        item.published(issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ"))
        for label in issue.labels:
            item.category({"term": label.name})
        body = "".join(c for c in issue.body if _valid_xml_char_ordinal(c))
        item.content(CDATA(marko.convert(body)), type="html")
    generator.atom_file(filename)
Example #8
0
    def _cdata(self, text):
        if isinstance(text, str):
            el = Element('a')
            el.text = CDATA(text)
            return dc(tostring(el)[3:-4])

        return smart_text(text)
Example #9
0
def generateNoteElement(html, enex):
    soup, noteProps = generateCData(html)
    note = etree.SubElement(enex, "note")
    title = etree.SubElement(note, 'title').text = noteProps['note-title']
    content = etree.SubElement(note, "content").text = CDATA(str(soup))
    etree.SubElement(
        note, "created"
    ).text = f"{dt.utcnow().strftime('%Y%m%dT%H%M%SZ')}"  #todo: replace dummy datetimes
    etree.SubElement(
        note, "updated").text = f"{dt.utcnow().strftime('%Y%m%dT%H%M%SZ')}"
    nattrs = etree.SubElement(note, "note-attributes")
    etree.SubElement(nattrs, 'author').text = "Jon Crump"

    for x in noteProps:
        d = noteProps[x]
        if x != 'note-title':
            resource = etree.SubElement(note, "resource")
            etree.SubElement(resource, "data",
                             encoding="base64").text = d['data']
            etree.SubElement(resource, "mime").text = d['type']
            etree.SubElement(resource, "width").text = d['width']
            etree.SubElement(resource, "height").text = d['height']

            rattrs = etree.SubElement(resource, "resource-attributes")
            etree.SubElement(rattrs, 'file-name').text = d['filename']
Example #10
0
def _add_text_elm(entry, data, name):
    """Add a text subelement to an entry"""
    if not data:
        return

    elm = xml_elem(name, entry)
    type_ = data.get('type')
    if data.get('src'):
        if name != 'content':
            raise ValueError("Only the 'content' element of an entry can "
                             "contain a 'src' attribute")
        elm.attrib['src'] = data['src']
    elif data.get(name):
        # Surround xhtml with a div tag, parse it and embed it
        if type_ == 'xhtml':
            xhtml = '<div xmlns="http://www.w3.org/1999/xhtml">' \
                    + data.get(name) + '</div>'
            elm.append(xml_fromstring(xhtml))
        elif type_ == 'CDATA':
            elm.text = CDATA(data.get(name))
        # Parse XML and embed it
        elif type_ and (type_.endswith('/xml') or type_.endswith('+xml')):
            elm.append(xml_fromstring(data[name]))
        # Embed the text in escaped form
        elif not type_ or type_.startswith('text') or type_ == 'html':
            elm.text = data.get(name)
        # Everything else should be included base64 encoded
        else:
            raise NotImplementedError(
                'base64 encoded {} is not supported at the moment. '
                'Pull requests adding support are welcome.'.format(name)
            )
    # Add type description of the content
    if type_:
        elm.attrib['type'] = type_
Example #11
0
def process_version(version, key, path, author):
    cpath = path
    vars = (version.get('vars') or {})
    xmlver = Element(
        'version', {
            'name': key,
            'author': version.get('author') or author,
            'time': get(version, 'time', prefix=path),
        })
    SubElement(xmlver,
               'changelog').text = CDATA(get(version, 'changelog', path))
    file_list = get(version, 'files', path)
    for i in range(len(file_list)):
        filedef = file_list[i]
        cpath = path + ['files', str(i + 1)]
        if isinstance(filedef, str):
            # Simple case: just a string
            SubElement(xmlver,
                       'source').text = replace_text(filedef, vars, cpath)
        else:
            # Complex case, dictionary with fields
            # TODO process variables
            attribs = filedef.copy()
            for k, v in attribs.items():
                attribs[k] = replace_text(str(v), vars, cpath)
            src = attribs.pop('src')
            SubElement(xmlver, 'source', attribs).text = src
    return xmlver
Example #12
0
    def encode_item(self, request, item, search_context):
        link_url = request.build_absolute_uri(
            "%s?%s" % (reverse("ows"),
                       urlencode(
                           dict(
                               service="WCS",
                               version="2.0.1",
                               request="DescribeCoverage",
                               coverageId=item.identifier,
                           ))))

        rss_item = RSS(
            "item",
            RSS("title", item.identifier),
            RSS("description", CDATA(item.identifier)),
            RSS("link", link_url),
        )

        if "geo" in search_context.parameters:
            rss_item.append(RSS("guid", request.build_absolute_uri()))
        else:
            rss_item.append(RSS("guid", item.identifier, isPermaLink="false"))

        rss_item.extend(self.encode_item_links(request, item))

        # TODO: remove this for the general dc:date?
        if item.begin_time and item.end_time:
            rss_item.append(
                GML("TimePeriod",
                    GML("beginPosition", isoformat(item.begin_time)),
                    GML("endPosition", isoformat(item.end_time)),
                    **{ns_gml("id"): item.identifier}))

        rss_item.extend(self.encode_spatio_temporal(item))
        return rss_item
    def makeLayers(self, root, mapp, mapkey):
        for l in mapp[mapkey]:
            layer = etree.SubElement(root, "Layer",
                                     name=l["name"].replace("\"", ""))
            for key in l.keys():
                if "include" == key:
                    # import the file?
                    pass
                elif "name" == key:
                    pass
                elif "status" == key:
                    layer.set("status", l[key])
                elif "type" == key:
                    layer.set("type", l[key])
                elif "classes" == key:

                    for s in l[key]:
                        class_ = etree.SubElement(layer, "Class")
                        for k in s.keys():
                            if k == 'name' or k == 'status':
                                class_.set(k, s[k].replace('"', '')
                                           .replace("'", ""))
                            elif k == 'styles':
                                st = s['styles']

                                for sty in st:
                                    stEl = etree.SubElement(class_, "Style")
                                    for key in sty.keys():
                                        self.makeSubElement(stEl, sty, key)
                                    stEl = self.sortChildren(stEl, stEl)
                            elif "labels" == k:
                                kx = self.makeLabels(s, class_, k)
                            else:
                                self.makeSubElement(class_, s, k)
                        class_ = self.sortChildren(class_, class_)

                elif "metadata" == key:
                    meta = etree.SubElement(layer, "Metadata")
                    c = l[key]

                    for kx in c:
                        item = etree.SubElement(meta, "item",
                                                name=kx.replace("'", "")
                                                .replace("\"", ""))
                    item.text = c[kx].replace("'", "").replace("\"", "")
                elif "validation" == key:
                    validation = etree.SubElement(layer, "Validation")
                    for k in l["validation"]:
                        item = etree.SubElement(validation, "item",
                                                name=k[0].replace("'", "")
                                                .replace("\"", ""))
                        item.text = k[1].replace("'", "").replace("\"", "")

                elif "data" == key:
                    data = etree.SubElement(layer, "Data")
                    data.text = CDATA(l["data"][0])
                else:
                    self.makeSubElement(layer, l, key)
            layer = self.sortChildren(layer, layer)
Example #14
0
    def to_element(self) -> ElementT:
        """Returns image element for xml."""
        image = create_element('image',
                               children=[
                                   create_element('url', self.url),
                                   create_element('link', self.link),
                                   create_element('title', CDATA(self.title))
                               ])

        if self.description:
            image.append(create_element('description',
                                        CDATA(self.description)))
        if self.height:
            image.append(create_element('height', self.height))
        if self.width:
            image.append(create_element('width', self.width))

        return image
Example #15
0
    def to_xml(self) -> Element:
        """Serialize the taskstore into a lxml element."""

        root = Element('tasklist')

        for task in self.lookup.values():
            element = SubElement(root, self.XML_TAG)
            element.set('id', str(task.id))
            element.set('status', task.status.value)

            title = SubElement(element, 'title')
            title.text = task.title

            tags = SubElement(element, 'tags')

            for t in task.tags:
                tag_tag = SubElement(tags, 'tag')
                tag_tag.text = str(t.id)

            dates = SubElement(element, 'dates')

            added_date = SubElement(dates, 'added')
            added_date.text = str(task.date_added)

            modified_date = SubElement(dates, 'modified')
            modified_date.text = str(task.date_modified)

            if task.status == Status.DONE:
                done_date = SubElement(dates, 'done')
                done_date.text = str(task.date_closed)

            if task.date_due:
                due = SubElement(dates, 'due')
                due.text = str(task.date_due)

            if task.date_start:
                start = SubElement(dates, 'start')
                start.text = str(task.date_start)

            subtasks = SubElement(element, 'subtasks')

            for subtask in task.children:
                sub = SubElement(subtasks, 'sub')
                sub.text = str(subtask.id)

            content = SubElement(element, 'content')
            text = task.content

            # Poor man's encoding.
            # CDATA's only poison is this combination of characters.
            text = text.replace(']]>', ']]&gt;')
            content.text = CDATA(text)

        return root
Example #16
0
 def process_package_covterms(self, child_element):
     for option_cov_term in child_element:
         if option_cov_term.tag == 'Packages':
             for cov_term_opt in option_cov_term:
                 for cov_term_opt_item in cov_term_opt:
                     if cov_term_opt_item.text is not None:
                         if cov_term_opt_item.tag == 'PackageTerms':
                             pass
                         else:
                             cov_term_opt_item.text = CDATA(cov_term_opt_item.text)
     return self
Example #17
0
    def encode_entry(self, request, item):
        entry = ATOM(
            "entry",
            ATOM("title", item.identifier),
            ATOM("id", item.identifier),
            ATOM("summary", CDATA(item.identifier)),
        )

        entry.extend(self.encode_item_links(request, item))
        entry.extend(self.encode_spatio_temporal(item))

        return entry
Example #18
0
    def _create_xml_content(self, export_data):
        """
        Creates an xml content based on the input data and the EDI report template and puts it into the 'body' field of the 'self'.

        :param export_data: a list of dictionaries with element names and values

        This method is called explicitly when the EDI document is created.
        """
        report_obj = self.env['report']
        self.body = report_obj.get_html(
            self, 'eintegration_edi_manager.edi_document_report_template')
        root = etree.fromstring(self.body.lstrip())
        message_body = root.find('.//MESSAGEBODY')
        element_list = []
        for export_data_item in export_data:
            top = None
            for exported_field in export_data_item['names']:
                element_names = exported_field.split('/')
                field_element = None
                parent_element = top
                for element_name in element_names:
                    if top is None:
                        field_element = etree.Element(element_name)
                        top = field_element
                    else:
                        field_element = parent_element.find(element_name)
                        if field_element is None:
                            field_element = parent_element if parent_element.tag == element_name else etree.SubElement(
                                parent_element, element_name)
                    parent_element = field_element
                data_value = export_data_item['data'].pop(0)
                if isinstance(data_value, (int, float)):
                    field_element.text = CDATA(str(data_value))
                else:
                    field_element.text = CDATA(data_value)
            element_list.append(top)
        for element in element_list:
            message_body.append(element)
        self.body = "<?xml version='1.0' encoding='ISO-8859-1'?>\n" + etree.tostring(
            root, pretty_print=True)
Example #19
0
    def cdata_wrap(text):
        if text is None:
            return None

        try:
            if re.search("[<>\'\"]", text) is not None:
                return CDATA(text)
                pass
            return text
        except ValueError as ve:
            raise
        except TypeError as te:
            raise
Example #20
0
 def element_artwork(self, e, p):
     if e.text and e.text.strip():
         e.text = CDATA(
             e.text
         )  # prevent text from being mucked up by other processors
     stripattr(e, [
         'height',
         '{http://www.w3.org/XML/1998/namespace}space',
         'width',
     ])
     if e.text and re.search(r'^\s*<CODE BEGINS>', e.text):
         # We have source code.  Permitted attributes: anchor, name,
         # source, type.
         e = self.replace(e, 'sourcecode')
         e.set('markers', 'true')
         match = re.search(
             r'(?s)^\s*<CODE BEGINS>(\s+file\s+"([^"]*)")?(.*?)(<CODE ENDS>(.*))?$',
             e.text)
         file = match.group(1)
         name = match.group(2)
         body = match.group(3)
         ends = match.group(4)
         tail = match.group(5)
         if file and name:
             e.set('name', name)
         e.text = CDATA(body)
         if not ends:
             self.warn(e,
                       "Found <CODE BEGINS> without matching <CODE ENDS>")
         if ends and tail.strip() != "":
             self.warn(e, "Found non-whitespace content after <CODE ENDS>")
             e.tail = tail
         stripattr(e, [
             'align',
             'alt',
             'height',
             'suppress-title',
             'width',
         ])
Example #21
0
 def new_dict_to_xml(self, indata):
     log.debug("new_dict_to_xml=%s", indata)
     from lxml import etree
     from lxml.etree import CDATA
     root = etree.Element("xml")
     for k, v in indata.items():
         field = etree.SubElement(root, str(k))
         nv = str(v) if type(v) not in types.StringTypes else v
         log.debug("new_dict_to_xml=%s", nv)
         if k == 'detail':
             field.text = CDATA(nv)
         else:
             field.text = nv
     xmlstr = etree.tostring(root, encoding='utf-8')
     return xmlstr
Example #22
0
    def _output(self, texts: Tuple[bytes, ...]) -> bytes:
        feed_type_desc = self._feed_type_desc
        items = [
            item for text in texts
            for item in self._hext_rule_extract(Html(text.decode()))
        ]
        items = list(unique_everseen(items, json.dumps))
        log.info('HTML inputs %s have %s items in all.', feed_type_desc,
                 len(items))

        feed = self._init_feed()
        is_debug_logged = self._is_debug_logged
        for item in items:
            if item["code_link"].startswith("https://github.com/"):
                item["code_author"] = item["code_link"].removeprefix(
                    "https://github.com/").split("/")[0]
                item[
                    "title"] = "/" + item["code_author"] + "/ " + item["title"]
            if 'categories' not in item:
                item['categories'] = []
            elif isinstance(item['categories'], str):
                item['categories'] = [item['categories']]

            entry = feed.add_entry(order='append')
            entry.title(item['title'])
            entry.link(href=item['link'])
            entry.guid(item['link'], permalink=True)
            # description = '\n\n'.join((item['description'], item['code_link']))
            description = f'{item["description"]} <p>Code: <a href="{item["code_link"]}">{item["code_link"]}</a></p>'
            entry.description(CDATA(description))
            entry.comments(item["code_link"])
            for category in item['categories']:
                if category.startswith(
                        '+') and category[1:].isdigit():  # Ex: +1, +2
                    continue
                category = category.capitalize() if category.isupper(
                ) else category
                entry.category(term=category)
            if is_debug_logged:
                log.debug('Added: %s', item['title'])

        text_: bytes = feed.rss_str(pretty=True)
        log.info('XML output %s has %s items.', feed_type_desc,
                 text_.count(b'<item>'))
        return text_
Example #23
0
def clozeQuestion(problemNumber):
    question = etree.SubElement(quiz, "question", type="cloze")
    name = etree.SubElement(question, "name")
    txt = etree.SubElement(name, "text")
    txt.text = problemID + str(problemNumber)
    questionText = etree.SubElement(question, "questiontext", format="html")
    txt = etree.SubElement(questionText, "text")
    cdatadiv = etree.Element("div")

    #############################################################################
    ## The following lines determine the values that are used in the question: ##
    #############################################################################

    amount = 1000 * int(
        5 * random() + 1)  # A random multiple of 1000 between 1000 and 5000.
    interest = int(13 * random() + 4)  # Random integer between 4 and 16.
    years = 2 + int(4 * random())  # Random integer between 2 and 5

    #########################################################################
    ## The following lines create the text for the question:               ##
    #########################################################################

    par = etree.SubElement(cdatadiv, "p")
    par.text = "If I invest R" + str(amount) + " in a fund that receives "
    par.text = par.text + str(interest) + " percent interest per year, "
    par.text = par.text + "compounded monthly, "
    par.text = par.text + "calculate the value of the account after "
    par.text = par.text + str(years) + " years."

    ################################################################################
    ## Lastly, these lines create the Cloze answer boxes with the data they need: ##
    ################################################################################

    par = etree.SubElement(cdatadiv, "p")  # Start a new paragraph
    par.text = clozeAnswerElement(1,
                                  amount * (1 + interest / 1200)**(12 * years),
                                  0.02)

    ########################################################################

    contentStr = etree.tostring(cdatadiv, pretty_print=True)
    txt.text = CDATA(contentStr)
    quiz.append(etree.Comment("New question."))

    return
Example #24
0
    def to_element(self) -> ElementT:
        """Returns root element for xml."""
        root = Element('rss', nsmap=self.root_nsmap, version=self.root_version)
        channel = create_element(
            'channel',
            children=[
                create_element('title', CDATA(self.title)),
                create_element('description', CDATA(self.description)),
                create_element('link', self.site_url),
                create_element('{http://www.w3.org/2005/Atom}link',
                               href=self.feed_url,
                               rel='self',
                               type='application/rss+xml'),
                create_element('generator', self.generator),
                create_element('lastBuildDate', datetime.utcnow())
            ])

        channel_image = self.image
        if not channel_image and self.image_url:
            channel_image = Image(self.image_url, self.site_url, self.title)
        if isinstance(channel_image, Image):
            channel.append(channel_image.to_element())

        for category in self.categories:
            channel.append(create_element('category', CDATA(category)))
        if self.pub_date:
            channel.append(create_element('pubDate', self.pub_date))
        if self.copyright:
            channel.append(create_element('copyright', CDATA(self.copyright)))
        if self.language:
            channel.append(create_element('language', CDATA(self.language)))
        if self.editor:
            channel.append(create_element('managingEditor',
                                          CDATA(self.editor)))
        if self.webmaster:
            channel.append(create_element('webMaster', CDATA(self.webmaster)))
        if self.docs_url:
            channel.append(create_element('docs', self.docs_url))

        for item in self.items:
            if isinstance(item, Item):
                channel.append(item.to_element())

        root.append(channel)
        return root
Example #25
0
    def export_post_comments(self, nid, base_url):
        wp = self.nsmap['wp']
        content = self.nsmap['content']
        dsq = self.nsmap['dsq']

        post = self.posts[nid]

        item_node = Element('item', nsmap=self.nsmap)
        SubElement(item_node, 'title').text = post['title']
        SubElement(item_node, 'link').text = base_url + self.get_post_path(post) + '/'
        SubElement(item_node, '{%s}encoded' % content).text = CDATA(post['body'])
        SubElement(item_node, '{%s}thread_identifier' % dsq).text = '/' + self.get_post_path(post) + '/'
        SubElement(item_node, '{%s}post_date_gmt' % wp).text = str(post['date'])
        SubElement(item_node, '{%s}comment_status' % wp).text = 'open'

        if nid in self.comments.keys():
            for comment in self.comments[nid]:
                item_node.append(self.export_comment(comment))

        return item_node
Example #26
0
def multiply_fracture_conductivity(origin_xml, new_xml, multiplier):
    """Function that generates a nex XML with some multiple of the conductivity
    -----------
    Parameters:
        origin_xml: String. Full path to the xml to edit
        new_xml: String. Full path to the new xml
        multipler: Float. Conductivity will be multipled by this parameter
        """

    parser = etree.XMLParser(strip_cdata=False)
    tree = etree.parse(origin_xml, parser)
    root = tree.getroot()

    # Read the relevant features
    data = root.find('Mesh').find('Data')
    aperture = data.find('.//DataSet[@TagName="APERTURE"]')
    conductivity = data.find(
        './/DataSet[@TagName="GMFACE_FRACTURE_CONDUCTIVITY"]')

    # Parse the text data as a pandas DataFrame
    cond_data = pn.read_csv(StringIO(conductivity.text),
                            sep='\t\t\t\t',
                            header=None,
                            names=['id_face', 'cond'])

    # Modify the data
    cond_data.loc[:, 'cond'] = cond_data.cond * multiplier
    # Enforce data types
    cond_data = cond_data.astype({'id_face': str, 'cond': str})

    pdb.set_trace()
    # Return the modified data to the text format
    b = cond_data.values.tolist()
    step_1 = ['\t\t\t\t'.join(elm) for elm in b]
    step_2 = '\n\t\t\t\n\t\t\t' + '\n\t\t\t'.join(step_1) + '\n\t\t\t\n\t\t\t'
    # Add the CDATA tag to the new string
    step_3 = CDATA(step_2)
    conductivity.text = step_3
    tree.write(new_xml)
    def create_question_xml(self, slides_lst):
        XHTML_NAMESPACE = xml_schema_url
        XHTML = "{%s}" % XHTML_NAMESPACE
        NSMAP = {
            None: XHTML_NAMESPACE,
            'xsi': 'http://www.w3.org/2001/XMLSchema-instance'
        }
        envelope = Element("HTMLQuestion", nsmap=NSMAP)

        index_path = Path.cwd() / 'docs' / 'index.html'
        index_html = index_path.read_text()

        index_html = index_html.replace(
            'var slides_to_test = [12];',
            'var slides_to_test = ' + str(slides_lst) + ';')

        html_content = SubElement(envelope, 'HTMLContent')
        html_content.text = CDATA(index_html)

        frame_height = SubElement(envelope, 'FrameHeight')
        frame_height.text = '0'

        return tostring(envelope, encoding='unicode')
Example #28
0
    def get_kml_for_fields(self,
                           scientific_name=None,
                           province_list=None,
                           provider_id_list=None,
                           latitude=None,
                           longitude=None,
                           start_date=None,
                           end_date=None,
                           page=None,
                           items_per_page=None,
                           start_latitude=None,
                           end_latitude=None,
                           start_longitude=None,
                           end_longitude=None,
                           is_simple_search=False):

        collection_filter = Collection.query.filter(
            Collection.full_scientific_name.like('%' + scientific_name + '%'),
            Collection.province.in_(province_list) if province_list else True,
            Collection.provider_id.in_(provider_id_list)
            if provider_id_list else True,
            Collection.latitude >= start_latitude if start_latitude else True,
            Collection.latitude <= end_latitude if end_latitude else True,
            Collection.longitude >= start_longitude
            if start_longitude else True,
            Collection.longitude <= end_longitude if end_longitude else True,
            Collection.last_date >= start_date if start_date else True,
            Collection.last_date <= end_date if end_date else True)

        if collection_filter.count() == 0:
            return None

        output = io.BytesIO()

        from lxml import etree as et

        root_el = et.Element("kml", xmlns="http://www.opengis.net/kml/2.2")

        document = et.SubElement(root_el, "Document", id="root_doc")
        folder = et.SubElement(document, "Folder")
        et.SubElement(folder, "name").text = "BioNoMo data"
        from unidecode import unidecode
        for collection in collection_filter:
            if collection.longitude and collection.latitude:
                placemark = et.SubElement(folder, "Placemark")
                _content = """
                <span style='font-weight: bold'>{}</span><br><br>
                {}: <span style='font-style: italic'>{}</span><br>
                {}: <span style='font-style: italic'>{}</span><br>
                {}: <span style='font-style: italic'>{}</span><br>
                <br>
                <span style='font-weight: bold'>{}</span><br>
                {}<br>
                """.format(
                    collection.full_scientific_name,
                    unidecode(collection.get_header('header.province')),
                    collection.province if collection.province else "---",
                    unidecode(collection.get_header('header.provider')),
                    collection.provider.name if collection.provider else "---",
                    unidecode(collection.get_header('header.last_date')),
                    collection.last_date if collection.last_date else "---",
                    unidecode(collection.get_header('header.taxonomy')),
                    self.get_taxonomical_tree_as_str_html(collection))
                point = et.SubElement(placemark, "Point")
                et.SubElement(point, "coordinates").text = "{},{}"\
                    .format(collection.longitude, collection.latitude)
                et.SubElement(placemark, "description").text = CDATA(_content)

        tree = et.ElementTree(root_el)
        tree.write(output,
                   pretty_print=False,
                   xml_declaration=True,
                   encoding='utf-8',
                   compression=1)

        return (output, 'zip')
Example #29
0
    def to_file(self):
        """ returns:
            - filename: STR
            - fsdb:     FSDB xml data, to be used in frontend."""

        formula = self.comp.formula
        pilots = self.comp.participants
        '''create dicts of attributes for each section'''
        comp_attr = {
            'id':
            '',  # still to do
            'name':
            self.comp.comp_name,
            'location':
            self.comp.comp_site,
            'from':
            self.comp.date_from,
            'to':
            self.comp.date_to,
            'utc_offset':
            self.comp.time_offset / 3600,
            'discipline':
            self.comp.comp_class.lower(),
            'ftv_factor':
            round(1 - formula.validity_param, 2),
            'fai_sanctioning': (1 if self.comp.sanction == 'FAI 1' else
                                2 if self.comp.sanction == 'FAI 2' else 0)
        }

        formula_attr = {
            'id':
            formula.formula_name,
            'min_dist':
            km(formula.min_dist, 1),
            'nom_dist':
            km(formula.nominal_dist, 1),
            'nom_time':
            formula.nominal_time / 3600,
            'nom_launch':
            formula.nominal_launch,
            'nom_goal':
            formula.nominal_goal,
            'day_quality_override':
            0,  # still to implement
            'bonus_gr':
            formula.glide_bonus,
            'jump_the_gun_factor': (0 if formula.max_JTG == 0 else round(
                1 / formula.JTG_penalty_per_sec, 1)),
            'jump_the_gun_max':
            formula.max_JTG,
            'normalize_1000_before_day_quality':
            0,  # still to implement
            'time_points_if_not_in_goal':
            round(1 - formula.no_goal_penalty, 1),
            'use_1000_points_for_max_day_quality':
            0,  # still to implement
            'use_arrival_position_points':
            1 if formula.formula_arrival == 'position' else 0,
            'use_arrival_time_points':
            1 if formula.formula_arrival == 'time' else 0,
            'use_departure_points':
            1 if formula.formula_departure == 'departure' else 0,
            'use_difficulty_for_distance_points':
            1 if formula.formula_distance == 'difficulty' else 0,
            'use_distance_points':
            1 if formula.formula_distance != 'off' else 0,
            'use_distance_squared_for_LC':
            1 if formula.comp_class == 'PG' else 0,  # still to implement
            'use_leading_points':
            1 if formula.formula_departure == 'leadout' else 0,
            'use_semi_circle_control_zone_for_goal_line':
            1,  # still to implement
            'use_time_points':
            1 if formula.formula_time == 'on' else 0,
            'scoring_altitude':
            'GPS' if formula.scoring_altitude == 'GPS' else 'QNH',
            'final_glide_decelerator':
            'none' if formula.arr_alt_bonus == 0 else 'aatb',
            'no_final_glide_decelerator_reason':
            '',
            'min_time_span_for_valid_task':
            60 if self.comp_class == 'PG' else 0,  # still to implement
            'score_back_time':
            formula.score_back_time / 60,
            'use_proportional_leading_weight_if_nobody_in_goal':
            '',  # still to implement
            'leading_weight_factor':
            (0 if formula.formula_departure != 'leadout' else round(
                formula.lead_factor, 3)),
            'turnpoint_radius_tolerance':
            formula.tolerance,
            'use_arrival_altitude_points':
            0 if formula.arr_alt_bonus == 0 else ''  # still to implement
        }
        if formula.arr_alt_bonus > 0:
            formula_attr['aatb_factor'] = round(formula.arr_alt_bonus, 3)
        '''create the file structure'''
        root = ET.Element('Fs')
        root.set('version', '3.5')
        root.set('comment', 'generated by AirScore')
        '''FsCompetition'''
        comp = ET.SubElement(root, 'FsCompetition')
        for k, v in comp_attr.items():
            comp.set(k, str(v))

        formula = ET.SubElement(comp, 'FsScoreFormula')
        for k, v in formula_attr.items():
            formula.set(k, str(v))

        notes = ET.SubElement(comp, 'FsCompetitionNotes')
        notes.text = CDATA('Generated by AirScore')
        # notes.text = '<![CDATA[Generated by AirScore]]>'
        '''FsParticipants'''
        participants = ET.SubElement(comp, 'FsParticipants')
        for p in pilots:
            pil = ET.SubElement(participants, 'FsParticipant')
            pilot_attr = {
                'id': p.ID or p.par_id,
                'name': p.name,
                'birthday': p.pilot_birthdate_str,
                'glider': p.glider,
                'glider_main_colors': '',
                'fai_licence': 1 if p.fai_id else 0,
                'female': p.female,
                'nat_code_3166_a3': p.nat,
                'sponsor': p.sponsor,
                'CIVLID': p.civl_id,
            }
            custom_attr = {
                'fai_n': p.fai_id,
                'class': p.glider_cert,
                'team': p.team,
                'LIVE': p.live_id
            }

            for k, v in pilot_attr.items():
                pil.set(k, str(v))
            cus = ET.SubElement(pil, 'FsCustomAttributes')
            for k, v in custom_attr.items():
                sub = ET.SubElement(cus, 'FsCustomAttribute')
                sub.set('name', k)
                sub.set('value', str(v))
        '''FsTasks'''
        tasks = ET.SubElement(comp, 'FsTasks')
        for idx, t in enumerate(self.tasks):
            task = ET.SubElement(tasks, 'FsTask')
            task.set('id', str(idx + 1))
            task.set('name', t.task_name)
            task.set('tracklog_folder', '')

            task_f = ET.SubElement(task, 'FsScoreFormula')
            task_d = ET.SubElement(task, 'FsTaskDefinition')
            task_s = ET.SubElement(task, 'FsTaskState')
            task_p = ET.SubElement(task, 'FsParticipants')
            task_sp = ET.SubElement(task, 'FsTaskScoreParams')

            # tf = dict(t.formula.to_dict(), **t.stats)
            '''FsTaskState'''
            task_s.set('task_state',
                       ('REGULAR' if not t.stopped_time else 'STOPPED'))  # ?
            task_s.set('score_back_time', str(t.formula.score_back_time / 60))
            task_s.set('cancel_reason', t.comment)
            '''FsScoreFormula'''
            # we permit just few changes in single tasks from comp formula, so we just update those
            tf_attr = formula_attr
            tf_attr.update({
                'jump_the_gun_factor':
                (0 if not t.formula.JTG_penalty_per_sec else round(
                    1 / t.formula.JTG_penalty_per_sec, 1)),
                'time_points_if_not_in_goal':
                1 - t.formula.no_goal_penalty,
                'use_arrival_position_points':
                1 if t.formula.arrival == 'position' else 0,
                'use_arrival_time_points':
                1 if t.formula.arrival == 'time' else 0,
                'use_departure_points':
                1 if t.formula.departure == 'departure' else 0,
                'use_difficulty_for_distance_points':
                1 if t.formula.distance == 'difficulty' else 0,
                'use_distance_points':
                0 if t.formula.distance == 'off' else 1,
                'use_leading_points':
                0 if t.formula.departure == 'off' else 1,
                'use_time_points':
                0 if t.formula.time == 'off' else 1,
                'scoring_altitude':
                'GPS' if t.formula.scoring_altitude == 'GPS' else 'QNH',
                'final_glide_decelerator':
                'none' if t.formula.arr_alt_bonus == 0 else 'aatb',
                'use_arrival_altitude_points':
                0 if t.formula.arr_alt_bonus == 0 else 1,
                'turnpoint_radius_tolerance':
                t.formula.tolerance,
            })

            for k, v in tf_attr.items():
                task_f.set(k, str(v))
            '''FsTaskDefinition'''
            tps = t.turnpoints
            td_attr = {
                'ss':
                [i + 1 for i, tp in enumerate(tps)
                 if tp.type == 'speed'].pop(0),
                'es':
                [i + 1 for i, tp in enumerate(tps)
                 if tp.type == 'endspeed'].pop(0),
                'goal':
                next(tp.shape for tp in tps if tp.type == 'goal').upper(),
                'groundstart':
                0,  # still to implement
                'qnh_setting':
                1013.25  # still to implement
            }

            for k, v in td_attr.items():
                task_d.set(k, str(v))

            t_open = get_isotime(t.date, t.window_open_time, t.time_offset)
            t_close = get_isotime(t.date, t.task_deadline, t.time_offset)
            ss_open = get_isotime(t.date, t.start_time, t.time_offset)
            if t.start_close_time:
                ss_close = get_isotime(t.date, t.start_close_time,
                                       t.time_offset)
            else:
                ss_close = t_close
            if t.window_close_time:
                w_close = get_isotime(t.date, t.window_close_time,
                                      t.time_offset)
            else:
                w_close = ss_close

            for i, tp in enumerate(tps):
                task_tp = ET.SubElement(task_d, 'FsTurnpoint')
                tp_attr = {
                    'id':
                    tp.name,
                    'lat':
                    round(tp.lat, 5),
                    'lon':
                    round(tp.lon, 5),
                    'altitude':
                    tp.altitude,
                    'radius':
                    tp.radius,
                    'open':
                    t_open if i < (td_attr['ss'] - 1) else ss_open,
                    'close':
                    w_close if i == 0 else ss_close if i == (td_attr['ss'] -
                                                             1) else t_close
                }
                for k, v in tp_attr.items():
                    task_tp.set(k, str(v))
                '''we add also FsTaskDistToTp during tp iteration'''
                sp_dist = ET.SubElement(task_sp, 'FsTaskDistToTp')
                sp_dist.set('tp_no', str(i + 1))
                sp_dist.set('distance', str(t.partial_distance[i]))
            '''add start gates'''
            gates = 1
            if t.SS_interval > 0:
                gates += t.start_iteration
            for i in range(gates):
                task_sg = ET.SubElement(task_d, 'FsStartGate')
                intv = 0 if not t.SS_interval else t.SS_interval * i
                i_time = get_isotime(t.date, (t.start_time + intv),
                                     t.time_offset)
                task_sg.set('open', str(i_time))
            '''FsTaskScoreParams'''
            launch_ess = [
                t.partial_distance[i] for i, tp in enumerate(t.turnpoints)
                if tp.type == 'endspeed'
            ].pop()
            sp_attr = {
                'ss_distance':
                km(t.SS_distance),
                'task_distance':
                km(t.opt_dist),
                'launch_to_ess_distance':
                km(launch_ess),
                'no_of_pilots_present':
                t.pilots_present,
                'no_of_pilots_flying':
                t.pilots_launched,
                'no_of_pilots_lo':
                t.pilots_launched - t.pilots_goal,
                'no_of_pilots_reaching_nom_dist':
                len([
                    x for x in t.valid_results
                    if x.distance_flown > t.formula.nominal_dist
                ]),
                'no_of_pilots_reaching_es':
                t.pilots_ess,
                'no_of_pilots_reaching_goal':
                t.pilots_goal,
                'sum_flown_distance':
                km(t.tot_distance_flown),
                'best_dist':
                km(t.max_distance or 0),
                'best_time':
                round((t.fastest or 0) / 3600, 14),
                'worst_time':
                round(
                    max((x.ESS_time or 0) - (x.SSS_time or 0)
                        for x in t.valid_results) / 3600, 14),
                'no_of_pilots_in_competition':
                len(self.comp.participants),
                'no_of_pilots_landed_before_stop':
                0 if not t.stopped_time else t.pilots_landed,
                'sum_dist_over_min':
                km(t.tot_dist_over_min),
                'sum_real_dist_over_min':
                km(t.tot_dist_over_min),  # not yet implemented
                'best_real_dist':
                km(t.max_distance),  # not yet implemented
                'last_start_time':
                get_isotime(
                    t.date,
                    max([
                        x.SSS_time for x in t.valid_results
                        if x.SSS_time is not None
                    ]), t.time_offset),
                'first_start_time':
                ('' if not t.min_dept_time else get_isotime(
                    t.date, t.min_dept_time, t.time_offset)),
                'first_finish_time':
                ('' if not t.min_ess_time else get_isotime(
                    t.date, t.min_ess_time, t.time_offset)),
                'max_time_to_get_time_points':
                round(0 / 3600, 14),  # not yet implemented
                'no_of_pilots_with_time_points':
                len([x for x in t.valid_results if x.time_score > 0]),
                'goal_ratio': (0 if t.pilots_launched == 0 else round(
                    t.pilots_goal / t.pilots_launched, 15)),
                'arrival_weight':
                0 if t.arrival == 0 else round(t.arr_weight, 3),
                'departure_weight':
                0 if t.departure != 'on' else round(t.dep_weight, 3),
                'leading_weight':
                0 if t.departure != 'leadout' else round(t.dep_weight, 3),
                'time_weight':
                0 if t.arrival == 'off' else round(t.time_weight, 3),
                'distance_weight':
                round(t.dist_weight, 3),  # not yet implemented
                'smallest_leading_coefficient':
                round(t.min_lead_coeff, 14),
                'available_points_distance':
                round(t.avail_dist_points, 14),
                'available_points_time':
                round(t.avail_time_points, 14),
                'available_points_departure':
                (0 if not t.formula.departure == 'departure' else round(
                    t.avail_dep_points, 14)),
                'available_points_leading':
                (0 if not t.formula.departure == 'leadout' else round(
                    t.avail_dep_points, 14)),
                'available_points_arrival':
                round(t.avail_arr_points, 14),
                'time_validity':
                round(t.time_validity, 3),
                'launch_validity':
                round(t.launch_validity, 3),
                'distance_validity':
                round(t.dist_validity, 3),
                'stop_validity':
                round(t.stop_validity, 3),
                'day_quality':
                round(t.day_quality, 3),
                'ftv_day_validity':
                t.ftv_validity,
                'time_points_stop_correction':
                0  # not yet implemented
            }
            for k, v in sp_attr.items():
                task_sp.set(k, str(v))
            '''FsParticipants'''
            for i, pil in enumerate(t.pilots):
                '''create pilot result for the task'''
                pil_p = ET.SubElement(task_p, 'FsParticipant')
                pil_p.set('id', str(pil.ID or pil.par_id))
                if not (pil.result_type in ('abs', 'dnf', 'nyp')):
                    '''only if pilot flew'''
                    pil_fd = ET.SubElement(pil_p, 'FsFlightData')
                    pil_r = ET.SubElement(pil_p, 'FsResult')
                    if not (pil.result_type in ['mindist', 'min_dist']):
                        fd_attr = {
                            'distance':
                            km(pil.distance_flown),
                            'bonus_distance':
                            km(pil.distance),
                            # ?? seems 0 for PG and more than dist for HG
                            'started_ss':
                            '' if not pil.real_start_time else get_isotime(
                                t.date, pil.real_start_time, t.time_offset),
                            'finished_ss':
                            '' if not pil.ESS_time else get_isotime(
                                t.date, pil.ESS_time, t.time_offset),
                            'altitude_at_ess':
                            pil.ESS_altitude,
                            'finished_task':
                            '' if not pil.goal_time else get_isotime(
                                t.date, pil.goal_time, t.time_offset),
                            'tracklog_filename':
                            pil.track_file,
                            'lc':
                            pil.lead_coeff,
                            'iv':
                            pil.fixed_LC or '',
                            'ts':
                            get_isotime(t.date, pil.first_time, t.time_offset),
                            'alt':
                            pil.last_altitude,  # ??
                            'bonus_alt':
                            '',  # ?? not implemented
                            'max_alt':
                            pil.max_altitude,
                            'last_tracklog_point_distance':
                            '',  # not implemented yet
                            'bonus_last_tracklog_point_distance':
                            '',  # ?? not implemented
                            'last_tracklog_point_time':
                            get_isotime(t.date, pil.landing_time,
                                        t.time_offset),
                            'last_tracklog_point_alt':
                            pil.landing_altitude,
                            'landed_before_deadline':
                            '1' if pil.landing_time <
                            (t.task_deadline if not t.stopped_time else
                             t.stopped_time) else '0',
                            'reachedGoal':
                            1 if pil.goal_time else 0
                            # only deadline?
                        }
                        for k, v in fd_attr.items():
                            pil_fd.set(k, str(v))

                    r_attr = {
                        'rank':
                        i + 1,  # not implemented, they should be ordered tho
                        # Rank IS NOT SAFE (I guess)
                        'points':
                        round(pil.score),
                        'distance':
                        km(pil.total_distance if pil.total_distance else pil.
                           distance_flown),
                        'ss_time':
                        '' if not pil.ss_time else sec_to_time(
                            pil.ss_time).strftime('%H:%M:%S'),
                        'finished_ss_rank':
                        ''
                        if not pil.ESS_time and pil.ESS_rank else pil.ESS_rank,
                        'distance_points':
                        0 if not pil.distance_score else round(
                            pil.distance_score, 1),
                        'time_points':
                        0 if not pil.time_score else round(pil.time_score, 1),
                        'arrival_points':
                        0 if not pil.arrival_score else round(
                            pil.arrival_score, 1),
                        'departure_points':
                        0 if not t.formula.departure == 'departure' else round(
                            pil.departure_score, 1),
                        'leading_points':
                        0 if not t.formula.departure == 'leadout' else round(
                            pil.departure_score, 1),
                        'penalty':
                        0 if not [
                            n for n in pil.notifications
                            if n.percentage_penalty > 0
                        ] else max(n.percentage_penalty
                                   for n in pil.notifications),
                        'penalty_points':
                        0 if not [
                            n for n in pil.notifications if n.flat_penalty > 0
                        ] else max(n.flat_penalty for n in pil.notifications),
                        'penalty_reason':
                        '; '.join([
                            n.comment for n in pil.notifications
                            if n.flat_penalty + n.percentage_penalty > 0
                            and not n.notification_type == 'jtg'
                        ]),
                        'penalty_points_auto':
                        sum(n.flat_penalty for n in pil.notifications
                            if n.notification_type == 'jtg'),
                        'penalty_reason_auto':
                        '' if not [
                            n for n in pil.notifications
                            if n.notification_type == 'jtg'
                        ] else next(
                            n for n in pil.notifications
                            if n.notification_type == 'jtg').flat_penalty,
                        'penalty_min_dist_points':
                        0,  # ??
                        'got_time_but_not_goal_penalty':
                        (pil.ESS_time or 0) > 0 and not pil.goal_time,
                        'started_ss':
                        '' if not pil.real_start_time else get_isotime(
                            t.date, pil.SSS_time, t.time_offset),
                        'finished_ss':
                        '' if not pil.ESS_time else get_isotime(
                            t.date, pil.ESS_time, t.time_offset),
                        'ss_time_dec_hours':
                        0 if not pil.ESS_time else round(
                            pil.ss_time / 3600, 14),
                        'ts':
                        get_isotime(t.date, pil.first_time,
                                    t.time_offset),  # flight origin time
                        'real_distance':
                        km(pil.distance_flown),
                        'last_distance':
                        '',  # ?? last fix distance?
                        'last_altitude_above_goal':
                        pil.last_altitude,
                        'altitude_bonus_seconds':
                        0,  # not implemented
                        'altitude_bonus_time':
                        sec_to_time(0).strftime('%H:%M:%S'),  # not implemented
                        'altitude_at_ess':
                        pil.ESS_altitude,
                        'scored_ss_time':
                        ('' if not pil.ss_time else sec_to_time(
                            pil.ss_time).strftime('%H:%M:%S')),
                        'landed_before_stop':
                        t.stopped_time and res.landing_time < t.stopped_time
                    }

                    for k, v in r_attr.items():
                        pil_r.set(k, str(v))
        '''creates the file to store'''
        fsdb = ET.tostring(root,
                           pretty_print=True,
                           xml_declaration=True,
                           encoding='UTF-8')

        return self.filename, fsdb
Example #30
0
    point.set('IsXOnly', 'False')
    point.set('Index', '329')
    positionScreen = SubElement(point, 'PositionScreen')
    positionScreen.set('X', '{}'.format(xScreen))
    positionScreen.set('Y', '{}'.format(yScreen))


document = Element('Document')
document.set('VersionNumber', '11.0')
document.set('AxesPointsRequired', '0')

image = SubElement(document, 'Image')
image.set('Width', '605')
image.set('Height', '340')
image.text = CDATA(
    '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'
)

coordSystem = SubElement(document, 'CoordSystem')
general = SubElement(coordSystem, 'General')
general.set('CursorSize', '3')
general.set('ExtraPrecision', '1')
coords = SubElement(coordSystem, 'Coords')
coords.set('Type', '0')
coords.set('TypeString', 'Cartesian')
coords.set('Coords', '0')
coords.set('ScaleXTheta', '0')
coords.set('ScaleXThetaString', 'Linear')
coords.set('ScaleYRadius', '0')
coords.set('ScaleYRadiusString', 'Linear')
coords.set('UnitsX', '0')