Exemplo n.º 1
0
def emit_yin(ctx, module, fd):
    fd.write('<?xml version="1.0" encoding="UTF-8"?>\n')
    fd.write('<%s name="%s"\n' % (module.keyword, module.arg))
    fd.write(' ' * len(module.keyword) + '  xmlns="%s"' % yin_namespace)

    prefix = module.search_one('prefix')
    if prefix is not None:
        namespace = module.search_one('namespace')
        fd.write('\n')
        fd.write(' ' * len(module.keyword))
        fd.write('  xmlns:' + prefix.arg + '=' +
                 quoteattr(namespace.arg))
    for imp in module.search('import'):
        prefix = imp.search_one('prefix')
        if prefix is not None:
            rev = None
            r = imp.search_one('revision-date')
            if r is not None:
                rev = r.arg
            mod = statements.modulename_to_module(module, imp.arg, rev)
            if mod is not None:
                ns = mod.search_one('namespace')
                if ns is not None:
                    fd.write('\n')
                    fd.write(' ' * len(module.keyword))
                    fd.write('  xmlns:' + prefix.arg + '=' +
                             quoteattr(ns.arg))
    fd.write('>\n')
    if ctx.opts.yin_canonical:
        substmts = grammar.sort_canonical(module.keyword, module.substmts)
    else:
        substmts = module.substmts
    for s in substmts:
        emit_stmt(ctx, module, s, fd, '  ', '  ')
    fd.write('</%s>\n' % module.keyword)
Exemplo n.º 2
0
def render_report_group(group, request, css_class=''):
    """Produce the HTML for a report group on a section index page"""
    if not (IPeopleSectionColumn.providedBy(group) or
            IPeopleReportGroup.providedBy(group)):
        return ''
    result = []
    title = getattr(group, 'title', '')
    if title:
        result.append('<h3>%s</h3>' % escape(group.title))
    if css_class:
        result.append('<ul class=%s>' % quoteattr(css_class))
    else:
        result.append('<ul>')
    for obj in group.values():
        if IPeopleReport.providedBy(obj):
            url = resource_url(obj, request)
            result.append('<li><a href=%s class=%s>%s</a></li>' % (
                quoteattr(url),
                quoteattr(obj.css_class),
                escape(obj.link_title)))
        elif IPeopleReportGroup.providedBy(obj):
            html = render_report_group(obj, request)
            result.append('<li>')
            result.append(html)
            result.append('</li>')
    result.append('</ul>')
    return '\n'.join(result)
Exemplo n.º 3
0
    def export_purchaseorders(self):
        '''
Send all open purchase orders to frePPLe, using the purchase.order and
purchase.order.line models.

Only purchase order lines in state 'confirmed' are extracted. The state of the
purchase order header must be "approved".

Mapping:
'Purchase ' purchase.order.line.product.name ' @ ' purchase.order.location_id.name -> operationplan.operation
convert purchase.order.line.product_uom_qty and purchase.order.line.product_uom -> operationplan.quantity
purchase.order.date_planned -> operationplan.end
purchase.order.date_planned -> operationplan.start
'1' -> operationplan.locked
'''
        m = self.req.session.model('purchase.order.line')
        ids = m.search([('state', '=', 'confirmed')], context=self.req.session.context)
        fields = ['name', 'date_planned', 'product_id', 'product_qty', 'product_uom', 'order_id']
        po_line = [i for i in m.read(ids, fields, self.req.session.context)]

        # Get all purchase orders
        m = self.req.session.model('purchase.order')
        ids = [i['order_id'][0] for i in po_line]
        fields = ['name', 'location_id', 'partner_id', 'state', 'shipped']
        # for python 2.7:
        # po = { j['id']: j for j in m.read(ids, fields, self.req.session.context) }
        po = {}
        for i in m.read(ids, fields, self.req.session.context):
            po[i['id']] = i

        # Create purchasing operations
        dd = []
        deliveries = set()
        yield '<!-- purchase operations -->\n'
        yield '<operations>\n'
        for i in po_line:
            if not i['product_id']:
                continue
            item = self.product_product.get(i['product_id'][0], None)
            j = po[i['order_id'][0]]
            location = j['location_id'] and self.map_locations.get(j['location_id'][0], None) or None
            if location and item and j['state'] == 'approved' and not j['shipped']:
                operation = u'Purchase %s @ %s' % (item['name'], location)
                buf = u'%s @ %s' % (item['name'], location)
                due = i['date_planned']
                qty = self.convert_qty_uom(i['product_qty'], i['product_uom'][0], i['product_id'][0])
                if not buf in deliveries and not buf in self.procured_buffers:
                    yield '<operation name=%s><flows><flow xsi:type="flow_end" quantity="1"><buffer name=%s><item name=%s/><location name=%s/></buffer></flow></flows></operation>\n' % (
                        quoteattr(operation), quoteattr(buf), quoteattr(item['name']), quoteattr(location)
                    )
                    deliveries.update([buf])
                dd.append((quoteattr(operation), due, due, qty))
        yield '</operations>\n'

        # Create purchasing operationplans
        yield '<!-- open purchase order lines -->\n'
        yield '<operationplans>\n'
        #for i in dd:
        #    yield '<operationplan operation=%s start="%sT00:00:00" end="%sT00:00:00" quantity="%f" locked="true"/>\n' % i
        yield '</operationplans>\n'
Exemplo n.º 4
0
    def export_orderpoints(self):
        '''
        Defining order points for frePPLe, based on the stock.warehouse.orderpoint
        model.

        Mapping:
        stock.warehouse.orderpoint.product.name ' @ ' stock.warehouse.orderpoint.location_id.name -> buffer.name
        stock.warehouse.orderpoint.location_id.name -> buffer.location
        stock.warehouse.orderpoint.product.name -> buffer.item
        convert stock.warehouse.orderpoint.product_min_qty -> buffer.mininventory
        convert stock.warehouse.orderpoint.product_max_qty -> buffer.maxinventory
        convert stock.warehouse.orderpoint.qty_multiple -> buffer->size_multiple
        '''
        m = self.req.session.model('stock.warehouse.orderpoint')
        ids = m.search([], context=self.req.session.context)
        fields = ['warehouse_id', 'product_id', 'product_min_qty', 'product_max_qty', 'product_uom', 'qty_multiple']
        if ids:
            yield '<!-- order points -->\n'
            yield '<buffers>\n'
            for i in m.read(ids, fields, self.req.session.context):
                item = self.product_product.get(i['product_id'] and i['product_id'][0] or 0, None)
                if not item:
                    continue
                uom_factor = self.convert_qty_uom(1.0, i['product_uom'][0], i['product_id'][0])
                name = u'%s @ %s' % (item['name'], i['warehouse_id'][1])
                yield '<buffer name=%s><item name=%s/><location name=%s/>\n' \
                  '%s%s%s<booleanproperty name="ip_flag" value="true"/>\n' \
                  '<stringproperty name="roq_type" value="quantity"/>\n<stringproperty name="ss_type" value="quantity"/>\n' \
                  '</buffer>\n' % (
                        quoteattr(name), quoteattr(item['name']), quoteattr(i['warehouse_id'][1]),
                        '<doubleproperty name="ss_min_qty" value="%s"/>\n' % (i['product_min_qty'] * uom_factor) if i['product_min_qty'] else '',
                        '<doubleproperty name="roq_min_qty" value="%s"/>\n' % ((i['product_max_qty']-i['product_min_qty']) * uom_factor) if (i['product_max_qty']-i['product_min_qty']) else '',
                        '<doubleproperty name="roq_multiple_qty" value="%s"/>\n' % (i['qty_multiple'] * uom_factor) if i['qty_multiple'] else '',
                    )
            yield '</buffers>\n'
Exemplo n.º 5
0
    def export_onhand(self):
        '''
Extracting all on hand inventories to frePPLe.

We're bypassing the ORM for performance reasons.

Mapping:
stock.report.prodlots.product_id.name @ stock.report.prodlots.location_id.name -> buffer.name
stock.report.prodlots.product_id.name -> buffer.item
stock.report.prodlots.location_id.name -> buffer.location
sum(stock.report.prodlots.qty) -> buffer.onhand
'''
        yield '<!-- inventory -->\n'
        yield '<buffers>\n'
        cr = RegistryManager.get(self.database).cursor()
        try:
            cr.execute('SELECT product_id, location_id, sum(qty) '
                       'FROM stock_quant '
                       'WHERE qty > 0 '
                       'GROUP BY product_id, location_id')
            for i in cr.fetchall():
                item = self.product_product.get(i[0], None)
                location = self.map_locations.get(i[1], None)
                if location and item:
                    yield '<buffer name=%s onhand="%f"><item name=%s/><location name=%s/></buffer>\n' % (
                        quoteattr(u'%s @ %s' % (item['name'], location)),
                        i[2], quoteattr(item['name']), quoteattr(location)
                    )
        finally:
            cr.close()
        yield '</buffers>\n'
Exemplo n.º 6
0
    def export_onhand(self):
        """
    Extracting all on hand inventories to frePPLe.

    We're bypassing the ORM for performance reasons.

    Mapping:
    stock.report.prodlots.product_id.name @ stock.report.prodlots.location_id.name -> buffer.name
    stock.report.prodlots.product_id.name -> buffer.item
    stock.report.prodlots.location_id.name -> buffer.location
    sum(stock.report.prodlots.qty) -> buffer.onhand
    """
        yield "<!-- inventory -->\n"
        yield "<buffers>\n"
        cr = RegistryManager.get(self.database).db.cursor()
        try:
            cr.execute(
                "SELECT product_id, location_id, sum(qty) "
                "FROM stock_report_prodlots "
                "WHERE qty > 0 "
                "GROUP BY product_id, location_id"
            )
            for i in cr.fetchall():
                item = self.product_product.get(i[0], None)
                location = self.map_locations.get(i[1], None)
                if location and item:
                    yield '<buffer name=%s onhand="%f"><item name=%s/><location name=%s/></buffer>\n' % (
                        quoteattr(u"%s @ %s" % (item["name"], location)),
                        i[2],
                        quoteattr(item["name"]),
                        quoteattr(location),
                    )
        finally:
            cr.close()
        yield "</buffers>\n"
Exemplo n.º 7
0
    def export_workcenters(self):
        '''
Send the workcenter list to frePPLe, based one the mrp.workcenter model.

We assume the workcenter name is unique. Odoo does NOT guarantuee that.

Mapping:
mrp.workcenter.name -> resource.name
mrp.workcenter.costs_hour -> resource.cost
mrp.workcenter.capacity_per_cycle / mrp.workcenter.time_cycle -> resource.maximum
'''
        self.map_workcenters = {}
        m = self.req.session.model('mrp.workcenter')
        ids = m.search([], context=self.req.session.context)
        fields = ['name', 'costs_hour', 'capacity_per_cycle', 'time_cycle']
        if ids:
            yield '<!-- workcenters -->\n'
            yield '<resources>\n'
            for i in m.read(ids, fields, self.req.session.context):
                name = i['name']
                self.map_workcenters[i['id']] = name
                yield '<resource name=%s maximum="%s" cost="%f"><location name=%s/></resource>\n' % (
                    quoteattr(name), i['capacity_per_cycle'] / (i['time_cycle'] or 1),
                    i['costs_hour'], quoteattr(self.mfg_location)
                )
            yield '</resources>\n'
Exemplo n.º 8
0
def get_xunit_content(report, testname, elapsed):
    test_count = sum(max(len(r[1]), 1) for r in report)
    error_count = sum(len(r[1]) for r in report)
    data = {
        'testname': testname,
        'test_count': test_count,
        'error_count': error_count,
        'time': '%.3f' % round(elapsed, 3),
    }
    xml = """<?xml version="1.0" encoding="UTF-8"?>
<testsuite
  name="%(testname)s"
  tests="%(test_count)d"
  failures="%(error_count)d"
  time="%(time)s"
>
""" % data

    for (filename, errors) in report:

        if errors:
            # report each cpplint error as a failing testcase
            for error in errors:
                data = {
                    'quoted_name': quoteattr(
                        '%s [%s] (%s:%d)' % (
                            error['category'], error['confidence'],
                            filename, error['linenum'])),
                    'testname': testname,
                    'quoted_message': quoteattr(error['message']),
                }
                xml += """  <testcase
    name=%(quoted_name)s
    classname="%(testname)s"
  >
      <failure message=%(quoted_message)s/>
  </testcase>
""" % data

        else:
            # if there are no cpplint errors report a single successful test
            data = {
                'quoted_location': quoteattr(filename),
                'testname': testname,
            }
            xml += """  <testcase
    name=%(quoted_location)s
    classname="%(testname)s"
    status="No problems found"/>
""" % data

    # output list of checked files
    data = {
        'escaped_files': escape(''.join(['\n* %s' % r[0] for r in report])),
    }
    xml += """  <system-out>Checked files:%(escaped_files)s</system-out>
""" % data

    xml += '</testsuite>\n'
    return xml
Exemplo n.º 9
0
    def export_workcenters(self):
        """
    Send the workcenter list to frePPLe, based one the mrp.workcenter model.

    We assume the workcenter name is unique. Odoo does NOT guarantuee that.

    Mapping:
    mrp.workcenter.name -> resource.name
    mrp.workcenter.costs_hour -> resource.cost
    mrp.workcenter.capacity_per_cycle / mrp.workcenter.time_cycle -> resource.maximum
    """
        self.map_workcenters = {}
        m = self.req.session.model("mrp.workcenter")
        ids = m.search([], context=self.req.session.context)
        fields = ["name", "costs_hour", "capacity_per_cycle", "time_cycle"]
        if ids:
            yield "<!-- workcenters -->\n"
            yield "<resources>\n"
            for i in m.read(ids, fields, self.req.session.context):
                name = i["name"]
                self.map_workcenters[i["id"]] = name
                yield '<resource name=%s maximum="%s" cost="%f"><location name=%s/></resource>\n' % (
                    quoteattr(name),
                    i["capacity_per_cycle"] / (i["time_cycle"] or 1),
                    i["costs_hour"],
                    quoteattr(self.mfg_location),
                )
            yield "</resources>\n"
Exemplo n.º 10
0
Arquivo: opml.py Projeto: cool-RR/Miro
 def _open_folder_entry(self, folder):
     if self.current_folder is not None:
         self._close_folder_entry()
     self.current_folder = folder
     self.io.write(u'\t<outline text=%s miro:section=%s>\n' % (
         saxutils.quoteattr(folder.get_title()),
         saxutils.quoteattr(folder.section)))
Exemplo n.º 11
0
def plugin_to_index(plugin):
    title = '<h3><img src="http://icons.iconarchive.com/icons/oxygen-icons.org/oxygen/32/Apps-preferences-plugin-icon.png"><a href=%s title="Plugin forum thread">%s</a></h3>' % (  # noqa
        quoteattr(plugin['thread_url']), escape(plugin['name']))
    released = datetime(*tuple(map(int, re.split(r'\D', plugin['last_modified'])))[:6]).strftime('%e %b, %Y').lstrip()
    details = [
        'Version: <b>%s</b>' % escape('.'.join(map(str, plugin['version']))),
        'Released: <b>%s</b>' % escape(released),
        'Author: %s' % escape(plugin['author']),
        'History: %s' % escape('Yes' if plugin['history'] else 'No'),
        'calibre: %s' % escape('.'.join(map(str, plugin['minimum_calibre_version']))),
        'Platforms: %s' % escape(', '.join(sorted(plugin['supported_platforms']) or ['all'])),
    ]
    if plugin['uninstall']:
        details.append('Uninstall: %s' % escape(', '.join(plugin['uninstall'])))
    if plugin['donate']:
        details.append('<a href=%s title="Donate">Donate</a>' % quoteattr(plugin['donate']))
    block = []
    for li in details:
        if li.startswith('calibre:'):
            block.append('<br>')
        block.append('<li>%s</li>' % li)
    block = '<ul>%s</ul>' % ('\n'.join(block))
    zipfile = '<div class="end"><a href=%s title="Download plugin" download=%s>Download plugin \u2193</a></div>' % (
        quoteattr(plugin['file']), quoteattr(plugin['name'] + '.zip'))
    desc = plugin['description'] or ''
    if desc:
        desc = '<p>%s</p>' % desc
    return '%s\n%s\n%s\n%s\n\n' % (title, desc, block, zipfile)
Exemplo n.º 12
0
	def CreateNode(self, cid, lat, lon, tags):

		xml = u"<?xml version='1.0' encoding='UTF-8'?>\n"
		xml += u'<osmChange version="0.6" generator="py">\n<create>\n<node id="-1" lat="{0}" lon="{1}" changeset="{2}">\n'.format(lat, lon, cid)
		for k in tags:
			xml += u'<tag k={0} v={1}/>\n'.format(saxutils.quoteattr(k), saxutils.quoteattr(tags[k]))
		xml += u'</node>\n</create>\n</osmChange>\n'
		if self.verbose >= 2: print (xml)
		newId = None
		newVersion = None

		if self.exe:
			r = requests.post(self.baseurl+"/0.6/changeset/"+str(cid)+"/upload", data=xml.encode('utf-8'), 
				auth=HTTPBasicAuth(self.user, self.passw),
				headers=self.xmlHeaders)

			if self.verbose >= 1: print (r.content)
			if r.status_code != 200: return None

			respRoot = ET.fromstring(r.content)
			for obj in respRoot:
				newId = obj.attrib['new_id']
				newVersion = obj.attrib['new_version']

		return int(newId), int(newVersion)
Exemplo n.º 13
0
    def __add(self, lst, fields):
        lst.append(u'<doc>')
        for field, value in fields.items():
            # Handle multi-valued fields if values
            # is passed in as a list/tuple
            if not isinstance(value, (list, tuple)): 
                values = [value]
            else: 
                values = value 

            for val in values: 
                # Do some basic data conversion
                if isinstance(val, datetime.datetime): 
                    val = utc_to_string(val)
                elif isinstance(val, bool): 
                    val = val and 'true' or 'false'

                try:
                    lst.append('<field name=%s>%s</field>' % (
                        (quoteattr(field), 
                        escape(unicode(val)))))
                except UnicodeDecodeError:
                    lst.append('<field name=%s> </field>' % (
                        (quoteattr(field))))
        lst.append('</doc>')
Exemplo n.º 14
0
	def ModifyRelation(self, cid, members, tags, rid, existingVersion):

		xml = u"<?xml version='1.0' encoding='UTF-8'?>\n"
		xml += u'<osmChange version="0.6" generator="py">\n<modify>\n<relation id="{0}" changeset="{1}" version="{2}">\n'.format(rid, cid, existingVersion)
		for mem in members:
			xml += u'<member type="{}" role={} ref="{}"/>\n'.format(mem['type'], saxutils.quoteattr(mem['role']), int(mem['ref']))
		for k in tags:
			xml += u'<tag k={0} v={1}/>\n'.format(saxutils.quoteattr(k), saxutils.quoteattr(tags[k]))
		xml += u'</relation>\n</modify>\n</osmChange>\n'
		if self.verbose >= 2: print (xml)
		newId = None
		newVersion = None

		if self.exe:
			r = requests.post(self.baseurl+"/0.6/changeset/"+str(cid)+"/upload", data=xml.encode('utf-8'), 
				auth=HTTPBasicAuth(self.user, self.passw),
				headers=self.xmlHeaders)

			if self.verbose >= 1: print (r.content)
			if r.status_code != 200: return None

			respRoot = ET.fromstring(r.content)
			for obj in respRoot:
				newId = obj.attrib['new_id']
				newVersion = obj.attrib['new_version']

		return int(newId), int(newVersion)
Exemplo n.º 15
0
	def CreateChangeSet(self, tags):
		#Create a changeset
		createChangeset = u"<?xml version='1.0' encoding='UTF-8'?>\n" +\
		u"<osm version='0.6' generator='py'>\n" +\
		u"  <changeset>\n"
		for k in tags:
			createChangeset += u'<tag k={0} v={1}/>\n'.format(saxutils.quoteattr(k), saxutils.quoteattr(tags[k]))
		createChangeset += u"  </changeset>\n" +\
		u"</osm>\n"

		if self.verbose >= 2:
			print (createChangeset)

		if self.exe:
			
			r = requests.put(self.baseurl+"/0.6/changeset/create", data=createChangeset.encode('utf-8'), 
				auth=HTTPBasicAuth(self.user, self.passw),
				headers=self.xmlHeaders)

			if r.status_code != 200: 
				print (r.content)
				return (0,"Error creating changeset")
			if self.verbose >= 1: print (r.content)
			if len(r.content) == 0:
				return (0,"Error creating changeset")
			cid = int(r.content)
		else:
			cid = 1001
		return (cid, "Done")
Exemplo n.º 16
0
 def getVars(self):
     vars = wcomponents.WTemplated.getVars(self)
     urlGen = vars.get("modAuthorURLGen", None)
     l = []
     for author in self._list:
         authCaption = author.getFullName()
         if author.getAffiliation() != "":
             authCaption = "%s (%s)" % (authCaption, author.getAffiliation())
         if urlGen:
             authCaption = """<a href=%s>%s</a>""" % (urlGen(author), self.htmlText(authCaption))
         href = "\"\""
         if author.getEmail() != "":
             mailtoSubject = """[%s] _("Contribution") %s: %s""" % (self._conf.getTitle(), self._contrib.getId(), self._contrib.getTitle())
             mailtoURL = "mailto:%s?subject=%s" % (author.getEmail(), urllib.quote(mailtoSubject))
             href = quoteattr(mailtoURL)
         emailHtml = """ <a href=%s><img src="%s" style="border:0px" alt="email"></a> """ % (href, Config.getInstance().getSystemIconURL("smallEmail"))
         upURLGen = vars.get("upAuthorURLGen", None)
         up = ""
         if upURLGen is not None:
             up = """<a href=%s><img src=%s border="0" alt="up"></a>""" % (quoteattr(str(upURLGen(author))), quoteattr(str(Config.getInstance().getSystemIconURL("upArrow"))))
         downURLGen = vars.get("downAuthorURLGen", None)
         down = ""
         if downURLGen is not None:
             down = """<a href=%s><img src=%s border="0" alt="down"></a>""" % (quoteattr(str(downURLGen(author))), quoteattr(str(Config.getInstance().getSystemIconURL("downArrow"))))
         l.append("""<input type="checkbox" name="selAuthor" value=%s>%s%s%s %s""" % (quoteattr(author.getId()), up, down, emailHtml, authCaption))
     vars["authors"] = "<br>".join(l)
     vars["remAuthorsURL"] = vars.get("remAuthorsURL", "")
     vars["addAuthorsURL"] = vars.get("addAuthorsURL", "")
     vars["searchAuthorURL"] = vars.get("searchAuthorURL", "")
     return vars
Exemplo n.º 17
0
    def _make_ns_declarations(declarations, declared_prefixes):
        """Build namespace declarations and remove obsoleted mappings
        from `declared_prefixes`.

        :Parameters:
            - `declarations`: namespace to prefix mapping of the new
              declarations
            - `declared_prefixes`: namespace to prefix mapping of already
              declared prefixes.
        :Types:
            - `declarations`: `unicode` to `unicode` dictionary
            - `declared_prefixes`: `unicode` to `unicode` dictionary

        :Return: string of namespace declarations to be used in a start tag
        :Returntype: `unicode`
        """
        result = []
        for namespace, prefix in declarations.items():
            if prefix:
                result.append(u" xmlns:{0}={1}".format(prefix, quoteattr(namespace)))
            else:
                result.append(u" xmlns={1}".format(prefix, quoteattr(namespace)))
            for d_namespace, d_prefix in declared_prefixes.items():
                if (not prefix and not d_prefix) or d_prefix == prefix:
                    if namespace != d_namespace:
                        del declared_prefixes[d_namespace]
        return u" ".join(result)
Exemplo n.º 18
0
 def _log_response_error(self, url, rtype, description, time_start, time_stop):
     """Log a response that raise an unexpected exception."""
     self.total_responses += 1
     self.page_responses += 1
     info = {}
     info["cycle"] = self.cycle
     info["cvus"] = self.cvus
     info["thread_id"] = self.thread_id
     info["suite_name"] = self.suite_name
     info["test_name"] = self.test_name
     info["step"] = self.steps
     info["number"] = self.page_responses
     info["type"] = rtype
     info["url"] = quoteattr(url)
     info["code"] = -1
     info["description"] = description and quoteattr(description) or '""'
     info["time_start"] = time_start
     info["duration"] = time_stop - time_start
     info["result"] = "Error"
     info["traceback"] = quoteattr(" ".join(traceback.format_exception(*sys.exc_info())))
     message = (
         """<response cycle="%(cycle).3i" cvus="%(cvus).3i" thread="%(thread_id).3i" suite="%(suite_name)s" name="%(test_name)s" step="%(step).3i" number="%(number).3i" type="%(type)s" result="%(result)s" url=%(url)s code="%(code)s" description=%(description)s time="%(time_start)s" duration="%(duration)s" traceback=%(traceback)s />"""
         % info
     )
     self._logr(message)
Exemplo n.º 19
0
 def render_cat(c):
     for k, v in c.items():
         if not v:
             yield '<itunes:category text=%s />' % quoteattr(k)
         else:
             yield '<itunes:category text=%s>%s</itunes:category>' % (
                 quoteattr(k), '\n'.join(render_cat(v)))
Exemplo n.º 20
0
def plugin_to_index(plugin, count):
    title = '<h3><img src="/plugin-icon.png"><a href=%s title="Plugin forum thread">%s</a></h3>' % (  # noqa
        quoteattr(plugin["thread_url"]),
        escape(plugin["name"]),
    )
    released = datetime(*tuple(map(int, re.split(r"\D", plugin["last_modified"])))[:6]).strftime("%e %b, %Y").lstrip()
    details = [
        "Version: <b>%s</b>" % escape(".".join(map(str, plugin["version"]))),
        "Released: <b>%s</b>" % escape(released),
        "Author: %s" % escape(plugin["author"]),
        "History: %s" % escape("Yes" if plugin["history"] else "No"),
        "calibre: %s" % escape(".".join(map(str, plugin["minimum_calibre_version"]))),
        "Platforms: %s" % escape(", ".join(sorted(plugin["supported_platforms"]) or ["all"])),
    ]
    if plugin["uninstall"]:
        details.append("Uninstall: %s" % escape(", ".join(plugin["uninstall"])))
    if plugin["donate"]:
        details.append('<a href=%s title="Donate">Donate</a>' % quoteattr(plugin["donate"]))
    block = []
    for li in details:
        if li.startswith("calibre:"):
            block.append("<br>")
        block.append("<li>%s</li>" % li)
    block = "<ul>%s</ul>" % ("\n".join(block))
    downloads = ('\xa0<span class="download-count">[%d total downloads]</span>' % count) if count else ""
    zipfile = '<div class="end"><a href=%s title="Download plugin" download=%s>Download plugin \u2193</a>%s</div>' % (
        quoteattr(plugin["file"]),
        quoteattr(plugin["name"] + ".zip"),
        downloads,
    )
    desc = plugin["description"] or ""
    if desc:
        desc = "<p>%s</p>" % desc
    return "%s\n%s\n%s\n%s\n\n" % (title, desc, block, zipfile)
Exemplo n.º 21
0
def tigerxml(tree, stream, **params):
    """A single sentence as TIGER XML. The IDs should probably
    be more fancy.
    """
    compute_export_numbering(tree)
    stream.write(u"<s id=\"%d\">\n" % tree.data['sid'])
    stream.write(u"<graph root=\"%s\">\n" % tree.data['num'])
    stream.write(u"  <terminals>\n")
    for terminal in trees.terminals(tree):
        stream.write(u"    <t id=\"%d\" " % terminal.data['num'])
        for field in ['word', 'lemma', 'label', 'morph']:
            terminal.data[field] = quoteattr(terminal.data[field])
        stream.write(u"%s=%s " % ('word', terminal.data['word']))
        stream.write(u"%s=%s " % ('lemma', terminal.data['lemma']))
        stream.write(u"%s=%s " % ('pos', terminal.data['label']))
        stream.write(u"%s=%s " % ('morph', terminal.data['morph']))
        stream.write(u"/>\n")
    stream.write(u"  </terminals>\n")
    stream.write(u"  <nonterminals>\n")
    for subtree in trees.postorder(tree):
        if trees.has_children(subtree):
            stream.write(u"    <nt id=\"%d\" cat=%s>\n"
                         % (subtree.data['num'],
                            quoteattr(subtree.data['label'])))
            for child in trees.children(subtree):
                stream.write(u"      <edge label=%s idref=\"%d\" />\n"
                             % (quoteattr(child.data['edge']),
                                child.data['num']))
            stream.write(u"    </nt>\n")
    stream.write(u"  </nonterminals>\n")
    stream.write(u"</graph>\n")
    stream.write(u"</s>\n")
Exemplo n.º 22
0
    def getVars( self ):
        vars = wcomponents.WTemplated.getVars( self )
        vars["types"] = "<br>".join( self._getTypeFilterItemList() )
        vars["status"] = "<br>".join( self._getStatusFilterItemList() )
        vars["others"] = "<br>".join( self._getOthersFilterItemList() )
        vars["accTypes"] = "<br>".join( self._getAccTypeFilterItemList() )
        f = filters.SimpleFilter(self._filterCrit,self._sortingCrit)
        al = []
        abstractsToPrint = []
        self._checked = ""
        if vars["selectAll"]:
            self._checked = " checked"
        abstractList = f.apply( self._track.getAbstractList() )
        for abstract in abstractList:
            al.append( self._getAbstractHTML( abstract ) )
            abstractsToPrint.append("""<input type="hidden" name="abstracts" value="%s">"""%abstract.getId())
        vars["filteredNumberAbstracts"] = str(len(abstractList))
        vars["totalNumberAbstracts"] = str(len(self._track.getAbstractList()))
        if self._order == "up":
            al.reverse()
        vars["abstracts"] = "".join( al )
        vars["abstractsToPrint"] = "\n".join(abstractsToPrint)

        sortingField = self._sortingCrit.getField()
        vars["currentSorting"] = ""

        for crit in ["type", "status", "number", "date", "rating"]:
            url = self._getURL()

            vars["%sImg" % crit] = ""
            url.addParam("sortBy", crit)

            if sortingField.getId() == crit:
                vars["currentSorting"] = '<input type="hidden" name="sortBy" value="%s">' % crit
                if self._order == "down":
                    vars["%sImg" % crit] = """<img src="%s" alt="">"""%(Config.getInstance().getSystemIconURL("downArrow"))
                    url.addParam("order","up")
                elif self._order == "up":
                    vars["%sImg" % crit] = """<img src="%s" alt="">"""%(Config.getInstance().getSystemIconURL("upArrow"))
                    url.addParam("order","down")
            vars["%sSortingURL" % crit] = str(url)

        url = urlHandlers.UHTrackModifAbstracts.getURL( self._track )
        url.addParam("order", self._order)
        url.addParam("OK", "1")
        url.setSegment( "abstracts" )
        vars["filterPostURL"]=quoteattr(str(url))
        vars["accessAbstract"] = quoteattr(str(urlHandlers.UHTrackAbstractDirectAccess.getURL(self._track)))
        vars["allAbstractsURL"] = str(urlHandlers.UHConfAbstractManagment.getURL(self._conf))
        l = []
        for tpl in self._conf.getAbstractMgr().getNotificationTplList():
            l.append("""<option value="%s">%s</option>"""%(tpl.getId(), tpl.getName()))
        vars["notifTpls"] = "\n".join(l)
        vars["actionURL"]=quoteattr(str(urlHandlers.UHAbstractsTrackManagerAction.getURL(self._track)))
        vars["selectURL"]=quoteattr(str(urlHandlers.UHTrackModifAbstracts.getURL(self._track)))
        vars["filterUsed"] = self._filterUsed
        vars["resetFiltersURL"] = str(urlHandlers.UHTrackModifAbstracts.getURL(self._track))
        vars["pdfIconURL"] = quoteattr(str(Config.getInstance().getSystemIconURL("pdf")))
        vars["canModify"] = self._canModify
        return vars
Exemplo n.º 23
0
 def _getContribHTML(self,contrib):
     sdate = ""
     if contrib.getAdjustedStartDate() is not None:
         sdate=contrib.getAdjustedStartDate().strftime("%Y-%b-%d %H:%M" )
     strdur = ""
     if contrib.getDuration() is not None and contrib.getDuration().seconds != 0:
         strdur = (datetime(1900,1,1)+ contrib.getDuration()).strftime("%Hh%M'")
         dur = contrib.getDuration()
         self._totaldur = self._totaldur + dur
     title = """<a href=%s>%s</a>"""%( quoteattr( str( urlHandlers.UHContributionModification.getURL( contrib ) ) ), self.htmlText( contrib.getTitle() ))
     l = []
     for spk in contrib.getSpeakerList():
         l.append( self.htmlText( spk.getFullName() ) )
     speaker = "<br>".join( l )
     track = ""
     if contrib.getTrack():
         track = self.htmlText( contrib.getTrack().getCode() )
     cType=""
     if contrib.getType() is not None:
         cType=contrib.getType().getName()
     status=ContribStatusList().getCode(contrib.getCurrentStatus().__class__)
     attached_items = contrib.attached_items
     materials = None
     if attached_items:
         num_files = len(attached_items['files']) + sum(len(f.attachments) for f in attached_items['folders'])
         materials = '<a href="{}">{}</a>'.format(
             url_for('attachments.management', contrib),
             ngettext('1 file', '{num} files', num_files).format(num=num_files)
         )
     editURL=urlHandlers.UHSessionModContribListEditContrib.getURL(contrib)
     if self._currentSorting!="":
         editURL.addParam("sortBy",self._currentSorting)
     editIconURL=Config.getInstance().getSystemIconURL("modify")
     html = """
         <tr>
             <td><input type="checkbox" name="contributions" value=%s></td>
             <td valign="top" class="abstractLeftDataCell" nowrap>%s</td>
             <td valign="top" nowrap class="abstractDataCell">%s</td>
             <td valign="top" class="abstractDataCell">%s</td>
             <td valign="top" class="abstractDataCell">%s</td>
             <td valign="top" class="abstractDataCell"><a href=%s><img src=%s border="0" alt=""></a>%s</td>
             <td valign="top" class="abstractDataCell">%s</td>
             <td valign="top" class="abstractDataCell">%s</td>
             <td valign="top" class="abstractDataCell">%s</td>
             <td valign="top" class="abstractDataCell">%s</td>
             <td valign="top" class="abstractDataCell">%s</td>
         </tr>
             """%(quoteattr(str(contrib.getId())),
                 self.htmlText(contrib.getId()),
                 sdate or "&nbsp;",
                 strdur or "&nbsp;",
                 cType or "&nbsp;",
                 quoteattr(str(editURL)),
                 quoteattr(str(editIconURL)),title or "&nbsp;",
                 speaker or "&nbsp;",
                 track or "&nbsp;",
                 status or "&nbsp;",
                 materials or "&nbsp;",
                 self.htmlText(contrib.getBoardNumber()) or "&nbsp;")
     return html
Exemplo n.º 24
0
def attributes(data):
    if isinstance(data, basestring):
        return data
    elif isinstance(data, dict):
        return ' '.join(['{}={}'.format(k, quoteattr(v)) for k,v in data.items()])
    else:
        return ' '.join(['{}={}'.format(k, quoteattr(v)) for k,v in data])
Exemplo n.º 25
0
 def getVars( self ):
     vars = wcomponents.WTemplated.getVars(self)
     modPay=self._conf.getModPay()
     vars["setStatusURL"]=urlHandlers.UHConfModifEPaymentChangeStatus.getURL(self._conf)
     vars["enablePic"]=quoteattr(str(Configuration.Config.getInstance().getSystemIconURL( "enabledSection" )))
     vars["disablePic"]=quoteattr(str(Configuration.Config.getInstance().getSystemIconURL( "disabledSection" )))
     if modPay.isActivated():
         vars["changeTo"] = "False"
         vars["status"] = _("ENABLED")
         vars["changeStatus"] = _("DISABLE")
         vars["disabled"] = ""
         vars["detailPayment"] = self._conf.getModPay().getPaymentDetails()
         vars["conditionsPayment"] = self._conf.getModPay().getPaymentConditions()
         vars["specificConditionsPayment"] = self._conf.getModPay().getPaymentSpecificConditions()
         vars["successMsgPayment"] = self._conf.getModPay().getPaymentSuccessMsg()
         vars["receiptMsgPayment"] = self._conf.getModPay().getPaymentReceiptMsg()
         vars["conditionsEnabled"] = "DISABLED"
         if self._conf.getModPay().arePaymentConditionsEnabled():
             vars["conditionsEnabled"] = "ENABLED"
         vars["Currency"]=self._conf.getRegistrationForm().getCurrency() or _("not selected")
     else:
         vars["changeTo"] = "True"
         vars["status"] = _("DISABLED")
         vars["changeStatus"] = _("ENABLE")
         vars["disabled"] = "disabled"
         vars["detailPayment"] = ""
         vars["conditionsPayment"] = ""
         vars["conditionsEnabled"] = "DISABLED"
         vars["specificConditionsPayment"] = ""
         vars["successMsgPayment"] = ""
         vars["receiptMsgPayment"] = ""
         vars["Currency"] = ""
     vars["dataModificationURL"]=urlHandlers.UHConfModifEPaymentdetailPaymentModification.getURL(self._conf)
     vars["sections"] = self._getSectionsHTML()
     return vars
Exemplo n.º 26
0
    def add_dict_entry_internal(self, formatted_head_word, forms, formatted_desc):
        self.n_expanded_entries += 1
        self.index_size += len(forms)

        if self.entries_in_curr_dict_html >= self.max_entries_per_dict_html:
            self.close_dict_html()
            self.start_dict_html()

        self.entries_in_curr_dict_html += 1
                                                    
        self.curr_dict_f.write("""
        <idx:entry scriptable="yes" spell="yes">
          <idx:short>
            <idx:orth value=%s>%s
        """ % (quoteattr(forms[0]), formatted_head_word))

        if len(forms[1:]) > 0:
            self.curr_dict_f.write("""
            <idx:infl>
            """)

            for infl in forms[1:]:
                self.curr_dict_f.write("""<idx:iform value=%s exact="yes"/>\n""" % quoteattr(infl))

            self.curr_dict_f.write("""
            </idx:infl>
            """)

        self.curr_dict_f.write("""
           </idx:orth>
           %s
         </idx:short>
	</idx:entry>
        """ % formatted_desc)
Exemplo n.º 27
0
 def append_item(self, item, outfile, tabs):
     write = outfile.write
     if item.name == '---': # item is a separator
         write('    '*tabs + '<object class="separator"/>\n')
     else:
         if item.children:
             name = self.get_name(item)
             if name:
                 write('    '*tabs + '<object class="wxMenu" ' \
                       'name=%s>\n' % quoteattr(name))
             else:
                 write('    '*tabs + '<object class="wxMenu">\n')
         else:
             name = self.get_name(item)
             if name:
                 write('    '*tabs + '<object class="wxMenuItem" ' \
                       'name=%s>\n' % quoteattr(name))
             else:
                 write('    '*tabs + '<object class="wxMenuItem">\n')  
         if item.label:
             # translate & into _ as accelerator marker
             val = item.label.replace('&', '_')
             write('    '*(tabs+1) + '<label>%s</label>\n' % \
                   escape(val))
         if item.help_str:
             write('    '*(tabs+1) + '<help>%s</help>\n' % \
                   escape(item.help_str))
         if item.children:
             for c in item.children:
                 self.append_item(c, outfile, tabs+1)
         elif item.checkable == '1':
             write('    '*(tabs+1) + '<checkable>1</checkable>\n')
         elif item.radio == '1':
             write('    '*(tabs+1) + '<radio>1</radio>\n')
         write('    '*tabs + '</object>\n')
Exemplo n.º 28
0
 def getVars(self):
     vars=wcomponents.WTemplated.getVars(self)
     vars["code"]=quoteattr(str(self._track.getCode()))
     vars["title"]=quoteattr(str(self._track.getTitle()))
     vars["description"]=self.htmlText(self._track.getDescription())
     vars["postURL"]=quoteattr(str(urlHandlers.UHTrackPerformDataModification.getURL(self._track)))
     return vars
Exemplo n.º 29
0
    def export_onhand(self):
        '''
        Extracting all on hand inventories to frePPLe.

        We're bypassing the ORM for performance reasons.

        Mapping:
        stock.report.prodlots.product_id.name @ stock.report.prodlots.location_id.name -> buffer.name
        stock.report.prodlots.product_id.name -> buffer.item
        stock.report.prodlots.location_id.name -> buffer.location
        sum(stock.report.prodlots.qty) -> buffer.onhand
        '''
        yield '<!-- inventory -->\n'
        yield '<buffers>\n'
        cr = RegistryManager.get(self.database).cursor()
        try:
            cr.execute('SELECT product_id, location_id, sum(qty) '
                       'FROM stock_quant '
                       'WHERE qty > 0 '
                       'GROUP BY product_id, location_id '
                       'ORDER BY location_id ASC')
            inventory = {}
            for i in cr.fetchall():
                item = self.product_product.get(i[0], None)
                location = self.map_locations.get(i[1], None)
                if item and location:
                    inventory[ (item['name'], location) ] = i[2] + inventory.get( (item['name'], location), 0)
            for key, val in inventory.items():
                buf = "%s @ %s" % (key[0], key[1])
                yield '<buffer name=%s onhand="%f"><item name=%s/><location name=%s/></buffer>\n' % (
                    quoteattr(buf), val, quoteattr(key[0]), quoteattr(key[1])
                    )
        finally:
            cr.close()
        yield '</buffers>\n'
Exemplo n.º 30
0
 def getPendingNamespaces(self):
     parts = []
     if self.pendingDefault is not None:
         parts.append("xmlns=%s" % quoteattr(self.pendingDefault))
     for prefix, uri in self.pending.items():
         parts.append("xmlns:%s=%s" % (prefix, quoteattr(uri)))
     return parts
Exemplo n.º 31
0
    def export_items(self):
        """
        Send the list of products to frePPLe, based on the product.product model.
        For purchased items we also create a procurement buffer in each warehouse.

        Mapping:
        [product.product.code] product.product.name -> item.name
        product.product.product_tmpl_id.list_price -> item.cost
        product.product.id , product.product.product_tmpl_id.uom_id -> item.subcategory

        If product.product.product_tmpl_id.purchase_ok
        and product.product.product_tmpl_id.routes contains the buy route
        we collect the suppliers as product.product.product_tmpl_id.seller_ids
        [product.product.code] product.product.name -> itemsupplier.item
        res.partner.id res.partner.name -> itemsupplier.supplier.name
        supplierinfo.delay -> itemsupplier.leadtime
        supplierinfo.min_qty -> itemsupplier.size_minimum
        supplierinfo.date_start -> itemsupplier.effective_start
        supplierinfo.date_end -> itemsupplier.effective_end
        product.product.product_tmpl_id.delay -> itemsupplier.leadtime
        '1' -> itemsupplier.priority
        """
        # Read the product templates
        self.product_product = {}
        self.product_template_product = {}
        m = self.env["product.template"]
        fields = [
            "purchase_ok",
            "route_ids",
            "bom_ids",
            "produce_delay",
            "list_price",
            "uom_id",
            "seller_ids",
            "standard_price",
        ]
        recs = m.search([])
        self.product_templates = {}
        for i in recs.read(fields):
            self.product_templates[i["id"]] = i

        # Read the stock location routes
        rts = self.env["stock.location.route"]
        fields = ["name"]
        recs = rts.search([])
        stock_location_routes = {}
        buy_route = None
        mfg_route = None
        for i in recs.read(fields):
            stock_location_routes[i["id"]] = i
            if i["name"] and i["name"].lower().startswith("buy"):
                # Recognize items that can be purchased
                buy_route = i["id"]
            if i["name"] and i["name"].lower().startswith("manufacture"):
                mfg_route = i["id"]

        # Read the products
        m = self.env["product.product"]
        recs = m.search([])
        s = self.env["product.supplierinfo"]
        s_fields = ["name", "delay", "min_qty", "date_end", "date_start", "price"]
        supplier = {}
        if recs:
            yield "<!-- products -->\n"
            yield "<items>\n"
            fields = ["id", "name", "code", "product_tmpl_id", "seller_ids"]
            for i in recs.read(fields):
                tmpl = self.product_templates[i["product_tmpl_id"][0]]
                if i["code"]:
                    name = u"[%s] %s" % (i["code"], i["name"])
                else:
                    name = i["name"]
                prod_obj = {"name": name, "template": i["product_tmpl_id"][0]}
                self.product_product[i["id"]] = prod_obj
                self.product_template_product[i["product_tmpl_id"][0]] = prod_obj
                yield '<item name=%s cost="%f" subcategory="%s,%s">\n' % (
                    quoteattr(name),
                    (tmpl["list_price"] or 0)
                    / self.convert_qty_uom(1.0, tmpl["uom_id"][0], i["id"]),
                    self.uom_categories[self.uom[tmpl["uom_id"][0]]["category"]],
                    i["id"],
                )
                # Export suppliers for the item, if the item is allowed to be purchased
                if (
                    tmpl["purchase_ok"]
                    and buy_route in tmpl["route_ids"]
                    and tmpl["seller_ids"]
                ):
                    yield "<itemsuppliers>\n"
                    for sup in s.browse(tmpl["seller_ids"]).read(s_fields):
                        name = "%d %s" % (sup["name"][0], sup["name"][1])
                        yield '<itemsupplier leadtime="P%dD" priority="1" size_minimum="%f" cost="%f"%s%s><supplier name=%s/></itemsupplier>\n' % (
                            sup["delay"],
                            sup["min_qty"],
                            sup["price"],
                            ' effective_end="%s"' % sup["date_end"]
                            if sup["date_end"]
                            else "",
                            ' effective_start="%s"' % sup["date_start"]
                            if sup["date_start"]
                            else "",
                            quoteattr(name),
                        )
                    yield "</itemsuppliers>\n"
                yield "</item>\n"
            yield "</items>\n"
def test_double_quoteattr():
    return (quoteattr("Includes 'single' quotes") ==
            "\"Includes 'single' quotes\"")
def test_single_quoteattr():
    return (quoteattr('Includes "double" quotes') ==
            '\'Includes "double" quotes\'')
def test_quoteattr_basic():
    return quoteattr("Donald Duck & Co") == '"Donald Duck &amp; Co"'
Exemplo n.º 35
0
    def export_purchaseorders(self):
        """
        Send all open purchase orders to frePPLe, using the purchase.order and
        purchase.order.line models.

        Only purchase order lines in state 'confirmed' are extracted. The state of the
        purchase order header must be "approved".

        Mapping:
        purchase.order.line.product_id -> operationplan.item
        purchase.order.company.mfg_location -> operationplan.location
        purchase.order.partner_id -> operationplan.supplier
        convert purchase.order.line.product_uom_qty - purchase.order.line.qty_received and purchase.order.line.product_uom -> operationplan.quantity
        purchase.order.date_planned -> operationplan.end
        purchase.order.date_planned -> operationplan.start
        'PO' -> operationplan.ordertype
        'confirmed' -> operationplan.status
        """
        m = self.env["purchase.order.line"]
        recs = m.search(
            [
                "|",
                ("order_id.state", "not in", ("draft", "sent", "bid", "confirmed")),
                ("order_id.state", "=", False),
            ]
        )
        fields = [
            "name",
            "date_planned",
            "product_id",
            "product_qty",
            "qty_received",
            "product_uom",
            "order_id",
        ]
        po_line = [i for i in recs.read(fields)]

        # Get all purchase orders
        m = self.env["purchase.order"]
        ids = [i["order_id"][0] for i in po_line]
        fields = ["name", "company_id", "partner_id", "state", "date_order"]
        po = {}
        for i in m.browse(ids).read(fields):
            po[i["id"]] = i

        # Create purchasing operations
        yield "<!-- open purchase orders -->\n"
        yield "<operationplans>\n"
        for i in po_line:
            if not i["product_id"]:
                continue
            item = self.product_product.get(i["product_id"][0], None)
            j = po[i["order_id"][0]]
            #
            location = self.mfg_location
            if location and item and i["product_qty"] > i["qty_received"]:
                start = j["date_order"].replace(" ", "T")
                end = i["date_planned"].replace(" ", "T")
                qty = self.convert_qty_uom(
                    i["product_qty"] - i["qty_received"],
                    i["product_uom"][0],
                    i["product_id"][0],
                )
                yield '<operationplan reference=%s ordertype="PO" start="%s" end="%s" quantity="%f" status="confirmed">' "<item name=%s/><location name=%s/><supplier name=%s/>" % (
                    quoteattr(j["name"]),
                    start,
                    end,
                    qty,
                    quoteattr(item["name"]),
                    quoteattr(location),
                    quoteattr("%d %s" % (j["partner_id"][0], j["partner_id"][1])),
                )
                yield "</operationplan>\n"
        yield "</operationplans>\n"
Exemplo n.º 36
0
    def export_salesorders(self):
        """
        Send confirmed sales order lines as demand to frePPLe, using the
        sale.order and sale.order.line models.

        Each order is linked to a warehouse, which is used as the location in
        frePPLe.

        Only orders in the status 'draft' and 'sale' are extracted.

        The picking policy 'complete' is supported at the sales order line
        level only in frePPLe. FrePPLe doesn't allow yet to coordinate the
        delivery of multiple lines in a sales order (except with hacky
        modeling construct).
        The field requested_date is only available when sale_order_dates is
        installed.

        Mapping:
        sale.order.name ' ' sale.order.line.id -> demand.name
        sales.order.requested_date -> demand.due
        '1' -> demand.priority
        [product.product.code] product.product.name -> demand.item
        sale.order.partner_id.name -> demand.customer
        convert sale.order.line.product_uom_qty and sale.order.line.product_uom  -> demand.quantity
        stock.warehouse.name -> demand->location
        (if sale.order.picking_policy = 'one' then same as demand.quantity else 1) -> demand.minshipment
        """
        # Get all sales order lines
        m = self.env["sale.order.line"]
        recs = m.search([])
        fields = [
            "qty_delivered",
            "state",
            "product_id",
            "product_uom_qty",
            "product_uom",
            "order_id",
        ]
        so_line = [i for i in recs.read(fields)]

        # Get all sales orders
        m = self.env["sale.order"]
        ids = [i["order_id"][0] for i in so_line]
        fields = [
            "state",
            "partner_id",
            "requested_date",
            "date_order",
            "picking_policy",
            "warehouse_id",
            "picking_ids",
        ]
        so = {}
        for i in m.browse(ids).read(fields):
            so[i["id"]] = i

        # Generate the demand records
        yield "<!-- sales order lines -->\n"
        yield "<demands>\n"

        for i in so_line:
            name = u"%s %d" % (i["order_id"][1], i["id"])
            product = self.product_product.get(i["product_id"][0], None)
            j = so[i["order_id"][0]]
            location = j["warehouse_id"][1]
            customer = self.map_customers.get(j["partner_id"][0], None)
            if not customer or not location or not product:
                # Not interested in this sales order...
                continue
            due = j.get("requested_date", False) or j["date_order"]
            priority = 1  # We give all customer orders the same default priority

            # Possible sales order status are 'draft', 'sent', 'sale', 'done' and 'cancel'
            state = j.get("state", "sale")
            if state == "draft":
                status = "quote"
                qty = self.convert_qty_uom(
                    i["product_uom_qty"], i["product_uom"][0], i["product_id"][0]
                )
            elif state == "sale":
                qty = i["product_uom_qty"] - i["qty_delivered"]
                if qty <= 0:
                    status = "closed"
                    qty = self.convert_qty_uom(
                        i["product_uom_qty"], i["product_uom"][0], i["product_id"][0]
                    )
                else:
                    status = "open"
                    qty = self.convert_qty_uom(
                        qty, i["product_uom"][0], i["product_id"][0]
                    )
            elif state in ("done", "sent"):
                status = "closed"
                qty = self.convert_qty_uom(
                    i["product_uom_qty"], i["product_uom"][0], i["product_id"][0]
                )
            elif state == "cancel":
                status = "canceled"
                qty = self.convert_qty_uom(
                    i["product_uom_qty"], i["product_uom"][0], i["product_id"][0]
                )

            #           pick = self.req.session.model('stock.picking')
            #           p_fields = ['move_lines', 'sale_id', 'state']
            #           move = self.req.session.model('stock.move')
            #           m_fields = ['product_id', 'product_uom_qty']
            #           if j['picking_ids']:
            #                 # The code below only works in specific situations.
            #                 # If activated incorrectly it can lead to duplicate demands.
            #                 # Here to export sale order line based that is closed by stock moves.
            #                 # if DO line is done then demand status is closed
            #                 # if DO line is cancel, it will skip the current DO line
            #                 # else demand status is open
            #                 pick_number = 0
            #                 for p in pick.read(j['picking_ids'], p_fields, self.req.session.context):
            #                     p_ids = p['move_lines']
            #                     product_id = i['product_id'][0]
            #                     mv_ids = move.search([('id', 'in', p_ids), ('product_id','=', product_id)], context=self.req.session.context)
            #
            #                     status = ''
            #                     if p['state'] == 'done':
            #                         if self.mode == 1:
            #                           # Closed orders aren't transferred during a small run of mode 1
            #                           continue
            #                         status = 'closed'
            #                     elif p['state'] == 'cancel':
            #                         continue
            #                     else:
            #                         status = 'open'
            #
            #                     for mv in move.read(mv_ids, m_fields, self.req.session.context):
            #                         logger.error("     C sales order line %s  %s " % (i, mv))
            #                         pick_number = pick_number + 1
            #                         name = u'%s %d %d' % (i['order_id'][1], i['id'], pick_number)
            #                         yield '<demand name=%s quantity="%s" due="%s" priority="%s" minshipment="%s" status="%s"><item name=%s/><customer name=%s/><location name=%s/></demand>\n' % (
            #                             quoteattr(name), mv['product_uom_qty'], due.replace(' ', 'T'),  # TODO find a better way around this ugly hack (maybe get the datetime object from the database)
            #                             priority, minship,status, quoteattr(product['name']),
            #                             quoteattr(customer), quoteattr(location)
            #                         )
            yield '<demand name=%s quantity="%s" due="%s" priority="%s" minshipment="%s" status="%s"><item name=%s/><customer name=%s/><location name=%s/></demand>\n' % (
                quoteattr(name),
                qty,
                due.replace(
                    " ", "T"
                ),  # TODO find a better way around this ugly hack (maybe get the datetime object from the database)
                priority,
                j["picking_policy"] == "one" and qty or 1.0,
                status,
                quoteattr(product["name"]),
                quoteattr(customer),
                quoteattr(location),
            )

        yield "</demands>\n"
Exemplo n.º 37
0
    def export_boms(self):
        """
        Exports mrp.routings, mrp.routing.workcenter and mrp.bom records into
        frePPLe operations, flows and loads.

        Not supported yet: a) parent boms, b) phantom boms.
        """
        yield "<!-- bills of material -->\n"
        yield "<operations>\n"
        self.operations = set()

        # Read all active manufacturing routings
        m = self.env["mrp.routing"]
        recs = m.search([])
        fields = ["location_id"]
        mrp_routings = {}
        for i in recs.read(fields):
            mrp_routings[i["id"]] = i["location_id"]

        # Read all workcenters of all routings
        mrp_routing_workcenters = {}
        m = self.env["mrp.routing.workcenter"]
        recs = m.search([], order="routing_id, sequence asc")
        fields = ["routing_id", "workcenter_id", "sequence", "time_cycle"]
        for i in recs.read(fields):
            if i["routing_id"][0] in mrp_routing_workcenters:
                # If the same workcenter is used multiple times in a routing,
                # we add the times together.
                exists = False
                if not self.manage_work_orders:
                    for r in mrp_routing_workcenters[i["routing_id"][0]]:
                        if r[0] == i["workcenter_id"][1]:
                            r[1] += i["time_cycle"]
                            exists = True
                            break
                if not exists:
                    mrp_routing_workcenters[i["routing_id"][0]].append(
                        [i["workcenter_id"][1], i["time_cycle"], i["sequence"]]
                    )
            else:
                mrp_routing_workcenters[i["routing_id"][0]] = [
                    [i["workcenter_id"][1], i["time_cycle"], i["sequence"]]
                ]

        # Models used in the bom-loop below
        bom_lines_model = self.env["mrp.bom.line"]
        bom_lines_fields = ["product_qty", "product_uom_id", "product_id", "routing_id"]
        try:
            subproduct_model = self.env["mrp.subproduct"]
            subproduct_fields = [
                "product_id",
                "product_qty",
                "product_uom",
                "subproduct_type",
            ]
        except Exception:
            subproduct_model = None

        # Loop over all bom records
        bom_recs = self.env["mrp.bom"].search([])
        bom_fields = [
            "product_qty",
            "product_uom_id",
            "product_tmpl_id",
            "routing_id",
            "type",
            "bom_line_ids",
            "sub_products",
        ]
        for i in bom_recs.read(bom_fields):
            # Determine the location
            if i["routing_id"]:
                location = mrp_routings.get(i["routing_id"][0], None)
                if not location:
                    location = self.mfg_location
                else:
                    location = location[1]
            else:
                location = self.mfg_location

            # Determine operation name and item
            product_buf = self.product_template_product.get(
                i["product_tmpl_id"][0], None
            )  # TODO avoid multiple bom on single template
            if not product_buf:
                logger.warn(
                    "skipping %s %s" % (i["product_tmpl_id"][0], i["routing_id"])
                )
                continue
            buf_name = u"%s @ %s" % (product_buf["name"], location)
            uom_factor = self.convert_qty_uom(
                1.0, i["product_uom_id"][0], i["product_tmpl_id"][0]
            )
            operation = u"%d %s @ %s" % (i["id"], product_buf["name"], location)
            self.operations.add(operation)

            # Build operation. The operation can either be a summary operation or a detailed
            # routing.
            if (
                not self.manage_work_orders
                or not i["routing_id"]
                or not mrp_routing_workcenters.get(i["routing_id"][0], [])
            ):
                #
                # CASE 1: A single operation used for the BOM
                # All routing steps are collapsed in a single operation.
                #
                yield '<operation name=%s size_multiple="1" duration="%s" posttime="P%dD" xsi:type="operation_fixed_time">\n' "<item name=%s/><location name=%s/>\n" % (
                    quoteattr(operation),
                    self.convert_float_time(
                        self.product_templates[i["product_tmpl_id"][0]]["produce_delay"]
                    ),
                    self.manufacturing_lead,
                    quoteattr(product_buf["name"]),
                    quoteattr(location),
                )
                yield '<flows>\n<flow xsi:type="flow_end" quantity="%f"><item name=%s/></flow>\n' % (
                    i["product_qty"] * uom_factor,
                    quoteattr(product_buf["name"]),
                )

                # Build consuming flows.
                # If the same component is consumed multiple times in the same BOM
                # we sum up all quantities in a single flow. We assume all of them
                # have the same effectivity.
                fl = {}
                for j in bom_lines_model.browse(i["bom_line_ids"]).read(
                    bom_lines_fields
                ):
                    product = self.product_product.get(j["product_id"][0], None)
                    if not product:
                        continue
                    if j["product_id"][0] in fl:
                        fl[j["product_id"][0]].append(j)
                    else:
                        fl[j["product_id"][0]] = [j]
                for j in fl:
                    product = self.product_product[j]
                    qty = sum(
                        self.convert_qty_uom(
                            k["product_qty"], k["product_uom_id"][0], k["product_id"][0]
                        )
                        for k in fl[j]
                    )
                    yield '<flow xsi:type="flow_start" quantity="-%f"><item name=%s/></flow>\n' % (
                        qty,
                        quoteattr(product["name"]),
                    )

                # Build byproduct flows
                if i.get("sub_products", None) and subproduct_model:
                    for j in subproduct_model.browse(i["sub_products"]).read(
                        subproduct_fields
                    ):
                        product = self.product_product.get(j["product_id"][0], None)
                        if not product:
                            continue
                        yield '<flow xsi:type="%s" quantity="%f"><item name=%s/></flow>\n' % (
                            "flow_fixed_end"
                            if j["subproduct_type"] == "fixed"
                            else "flow_end",
                            self.convert_qty_uom(
                                j["product_qty"],
                                j["product_uom"][0],
                                j["product_id"][0],
                            ),
                            quoteattr(product["name"]),
                        )
                yield "</flows>\n"

                # Create loads
                if i["routing_id"]:
                    yield "<loads>\n"
                    for j in mrp_routing_workcenters.get(i["routing_id"][0], []):
                        yield '<load quantity="%f"><resource name=%s/></load>\n' % (
                            j[1],
                            quoteattr(j[0]),
                        )
                    yield "</loads>\n"
            else:
                #
                # CASE 2: A routing operation is created with a suboperation for each
                # routing step.
                #
                yield '<operation name=%s size_multiple="1" posttime="P%dD" xsi:type="operation_routing">' "<item name=%s/><location name=%s/>\n" % (
                    quoteattr(operation),
                    self.manufacturing_lead,
                    quoteattr(product_buf["name"]),
                    quoteattr(location),
                )

                yield "<suboperations>"
                steplist = mrp_routing_workcenters[i["routing_id"][0]]
                for step in steplist:
                    yield '<suboperation priority="%s">' '<operation name=%s duration="%s" xsi:type="operation_fixed_time">\n' "<location name=%s/>\n" '<loads><load quantity="%f"><resource name=%s/></load></loads>\n' % (
                        step[2],
                        quoteattr("%s - %s" % (operation, step[2])),
                        self.convert_float_time(step[1]),
                        quoteattr(location),
                        step[1],
                        quoteattr(step[0]),
                    )
                    if step[2] == steplist[-1][2]:
                        # Add producing flows on the last routing step
                        yield '<flows>\n<flow xsi:type="flow_end" quantity="%f"><item name=%s/></flow>\n' % (
                            i["product_qty"]
                            * getattr(i, "product_efficiency", 1.0)
                            * uom_factor,
                            quoteattr(product_buf["name"]),
                        )
                        # Add byproduct flows
                        if i.get("sub_products", None):
                            for j in subproduct_model.browse(i["sub_products"]).read(
                                subproduct_fields
                            ):
                                product = self.product_product.get(
                                    j["product_id"][0], None
                                )
                                if not product:
                                    continue
                                yield '<flow xsi:type="%s" quantity="%f"><item name=%s/></flow>\n' % (
                                    "flow_fixed_end"
                                    if j["subproduct_type"] == "fixed"
                                    else "flow_end",
                                    self.convert_qty_uom(
                                        j["product_qty"],
                                        j["product_uom"][0],
                                        j["product_id"][0],
                                    ),
                                    quoteattr(product["name"]),
                                )
                        yield "</flows>\n"
                    if step[2] == steplist[0][2]:
                        # All consuming flows on the first routing step.
                        # If the same component is consumed multiple times in the same BOM
                        # we sum up all quantities in a single flow. We assume all of them
                        # have the same effectivity.
                        fl = {}
                        for j in bom_lines_model.browse(i["bom_line_ids"]).read(
                            bom_lines_fields
                        ):
                            product = self.product_product.get(j["product_id"][0], None)
                            if not product:
                                continue
                            if j["product_id"][0] in fl:
                                fl[j["product_id"][0]].append(j)
                            else:
                                fl[j["product_id"][0]] = [j]
                        yield "<flows>\n"
                        for j in fl:
                            product = self.product_product[j]
                            qty = sum(
                                self.convert_qty_uom(
                                    k["product_qty"],
                                    k["product_uom_id"][0],
                                    k["product_id"][0],
                                )
                                for k in fl[j]
                            )
                            yield '<flow xsi:type="flow_start" quantity="-%f"><item name=%s/></flow>\n' % (
                                qty,
                                quoteattr(product["name"]),
                            )
                        yield "</flows>\n"
                    yield "</operation></suboperation>\n"
                yield "</suboperations>\n"
            yield "</operation>\n"
        yield "</operations>\n"
Exemplo n.º 38
0
    def export_calendar(self):
        """
        Build a calendar with a) holidays and b) working hours.

        The holidays are obtained from the hr.holidays.public.line model.
        If the hr module isn't installed, no public holidays will be defined.

        The working hours are extracted from a resource.calendar model.
        The calendar to use is configured with the company parameter "calendar".
        If left unspecified we assume 24*7 working hours.

        The odoo model is not ideal and nice for frePPLe, and the current mapping
        is an as-good-as-it-gets workaround.

        Mapping:
        res.company.calendar  -> calendar.name
        (if no working hours are defined then 1 else 0) -> calendar.default_value

        resource.calendar.attendance.date_from -> calendar_bucket.start
        '1' -> calendar_bucket.value
        resource.calendar.attendance.dayofweek -> calendar_bucket.days
        resource.calendar.attendance.hour_from -> calendar_bucket.startime
        resource.calendar.attendance.hour_to -> calendar_bucket.endtime
        computed -> calendar_bucket.priority

        hr.holidays.public.line.start -> calendar_bucket.start
        hr.holidays.public.line.start + 1 day -> calendar_bucket.end
        '0' -> calendar_bucket.value
        '1' -> calendar_bucket.priority
        """
        yield "<!-- calendar -->\n"
        yield "<calendars>\n"
        try:
            m = self.env["resource.calendar"]
            recs = m.search([("name", "=", self.calendar)])
            rec = m.read(recs, ["attendance_ids"], limit=1)
            fields = ["dayofweek", "date_from", "hour_from", "hour_to"]
            buckets = []
            for i in rec["attendance_ids"].read(fields):
                strt = datetime.strptime(i["date_from"] or "2000-01-01", "%Y-%m-%d")
                buckets.append(
                    (
                        strt,
                        '<bucket start="%sT00:00:00" value="1" days="%s" priority="%%s" starttime="%s" endtime="%s"/>\n'
                        % (
                            strt.strftime("%Y-%m-%d"),
                            2 ** ((int(i["dayofweek"]) + 1) % 7),
                            # In odoo, monday = 0. In frePPLe, sunday = 0.
                            "PT%dM" % round(i["hour_from"] * 60),
                            "PT%dM" % round(i["hour_to"] * 60),
                        ),
                    )
                )
            if len(buckets) > 0:
                # Sort by start date.
                # Required to assure that records with a later start date get a
                # lower priority in frePPLe.
                buckets.sort(key=itemgetter(0))
                priority = 1000
                yield '<calendar name=%s default="0"><buckets>\n' % quoteattr(
                    self.calendar
                )
                for i in buckets:
                    yield i[1] % priority
                    priority -= 1
            else:
                # No entries. We'll assume 24*7 availability.
                yield '<calendar name=%s default="1"><buckets>\n' % quoteattr(
                    self.calendar
                )
        except Exception:
            # Exception happens if the resource module isn't installed.
            yield "<!-- Working hours are assumed to be 24*7. -->\n"
            yield '<calendar name=%s default="1"><buckets>\n' % quoteattr(self.calendar)
        try:
            m = self.env["hr.holidays.public.line"]
            recs = m.search([])
            fields = ["date"]
            for i in recs.read(fields):
                nd = datetime.strptime(i["date"], "%Y-%m-%d") + timedelta(days=1)
                yield '<bucket start="%sT00:00:00" end="%sT00:00:00" value="0" priority="1"/>\n' % (
                    i["date"],
                    nd.strftime("%Y-%m-%d"),
                )
        except Exception:
            # Exception happens if the hr module is not installed
            yield "<!-- No holidays since the HR module is not installed -->\n"
        yield "</buckets></calendar></calendars>\n"
Exemplo n.º 39
0
    def add_bookmark(self):
        """Return the file like 'f' that leo_interface.send_head makes

        """
        parsed_url = urlparse.urlparse(self.request_handler.path)
        query = urlparse.parse_qs(parsed_url.query)
        # print(parsed_url.query)
        # print(query)
        name = query.get('name', ['NO TITLE'])[0]
        url = query['url'][0]
        one_tab_links = []
        if 'www.one-tab.com' in url.lower():
            one_tab_links = query.get('ln', [''])[0]
            one_tab_links = json.loads(one_tab_links)  # type:ignore
        c = None  # outline for bookmarks
        previous = None  # previous bookmark for adding selections
        parent = None  # parent node for new bookmarks
        using_root = False
        path = self.bookmark_unl
        if path:
            parsed = urlparse.urlparse(path)
            leo_path = os.path.expanduser(parsed.path)
            c = g.openWithFileName(leo_path, old_c=None)
            if c:
                g.es_print("Opened '%s' for bookmarks" % path)
                if parsed.fragment:
                    g.findUNL(parsed.fragment.split("-->"), c)
                parent = c.currentPosition()
                if parent.hasChildren():
                    previous = parent.getFirstChild()
            else:
                g.es_print("Failed to open '%s' for bookmarks" %
                           self.bookmark_unl)
        if c is None:
            using_root = True
            c = g.app.commanders()[0]
            parent = c.rootPosition()
            previous = c.rootPosition()
        f = StringIO()
        if previous and url == previous.b.split('\n', 1)[0]:
            # another marking of the same page, just add selection
            self.add_bookmark_selection(previous,
                                        query.get('selection', [''])[0])
            c.selectPosition(previous)  # required for body text redraw
            c.redraw()
            f.write("""
    <body onload="setTimeout('window.close();', 350);" style='font-family:mono'>
    <p>Selection added</p></body>""")
            return f
        if '_form' in query:
            # got extra details, save to new node
            f.write("""
    <body onload="setTimeout('window.close();', 350);" style='font-family:mono'>
    <p>Bookmark saved</p></body>""")
            if using_root:
                nd = parent.insertAfter()
                nd.moveToRoot(c.rootPosition())
            else:
                nd = parent.insertAsNthChild(0)
            if g.pluginIsLoaded('leo.plugins.bookmarks'):
                nd.h = name
            else:
                nd.h = '@url ' + name
            selection = query.get('selection', [''])[0]
            if selection:
                selection = '\n\n"""\n' + selection + '\n"""'
            tags = query.get('tags', [''])[0]
            if one_tab_links:
                if tags:
                    tags += ', OneTabList'
                else:
                    tags = 'OneTabList'
                self.get_one_tab(one_tab_links, nd)
            nd.b = "%s\n\nTags: %s\n\n%s\n\nCollected: %s%s\n\n%s" % (
                url,
                tags,
                query.get('_name', [''])[0],
                time.strftime("%c"),
                selection,
                query.get('description', [''])[0],
            )
            c.setChanged()
            c.selectPosition(nd)  # required for body text redraw
            c.redraw()
            return f
        # send form to collect extra details
        f.write("""
    <html>
    <head>
        <style>
            body {font-family:mono; font-size: 80%%;}
            th {text-align:right}
        </style>
        <style>%s</style>
    <title>Leo Add Bookmark</title>
    </head>
    <body onload='document.getElementById("tags").focus();'>
        <form method='GET' action='/_/add/bkmk/'>
            <input type='hidden' name='_form' value='1'/>
            <input type='hidden' name='_name' value=%s/>
            <input type='hidden' name='selection' value=%s/>
            <input type='hidden' name='ln' value=%s/>
            <table>
            <tr><th>Tags:</th><td><input id='tags' name='tags' size='60'/>(comma sep.)</td></tr>
            <tr><th>Title:</th><td><input name='name' value=%s size='60'/></td></tr>
            <tr><th>URL:</th><td><input name='url' value=%s size='60'/></td></tr>
            <tr><th>Notes:</th><td><textarea name='description' cols='60' rows='6'></textarea></td></tr>
            </table>
            <input type='submit' value='Save'/><br/>
        </form>
    </body>
    </html>""" % (
            getData(
                'user_bookmark_stylesheet'),  # EKR: Add config.css to style.
            quoteattr(name),
            quoteattr(query.get('selection', [''])[0]),
            quoteattr(json.dumps(one_tab_links)),
            quoteattr(name),
            quoteattr(url)))
        return f
Exemplo n.º 40
0
    def export_locations(self):
        """
        Generate a list of warehouse locations to frePPLe, based on the
        stock.warehouse model.

        We assume the location name to be unique. This is NOT guarantueed by Odoo.

        The field subategory is used to store the id of the warehouse. This makes
        it easier for frePPLe to send back planning results directly with an
        odoo location identifier.

        FrePPLe is not interested in the locations odoo defines with a warehouse.
        This methods also populates a map dictionary between these locations and
        warehouse they belong to.

        Mapping:
        stock.warehouse.name -> location.name
        stock.warehouse.id -> location.subcategory
        """
        self.map_locations = {}
        self.warehouses = set()
        childlocs = {}
        m = self.env["stock.warehouse"]
        recs = m.search([])
        if recs:
            yield "<!-- warehouses -->\n"
            yield "<locations>\n"
            fields = [
                "name",
                "wh_input_stock_loc_id",
                "wh_output_stock_loc_id",
                "wh_pack_stock_loc_id",
                "wh_qc_stock_loc_id",
                "view_location_id",
            ]
            for i in recs.read(fields):
                yield '<location name=%s subcategory="%s"><available name=%s/></location>\n' % (
                    quoteattr(i["name"]),
                    i["id"],
                    quoteattr(self.calendar),
                )
                childlocs[i["wh_input_stock_loc_id"][0]] = i["name"]
                childlocs[i["wh_output_stock_loc_id"][0]] = i["name"]
                childlocs[i["wh_pack_stock_loc_id"][0]] = i["name"]
                childlocs[i["wh_qc_stock_loc_id"][0]] = i["name"]
                childlocs[i["view_location_id"][0]] = i["name"]
                self.warehouses.add(i["name"])
            yield "</locations>\n"

            # Populate a mapping location-to-warehouse name for later lookups
            parent_loc = {}
            m = self.env["stock.location"]
            recs = m.search([])
            for i in recs.read(["location_id"]):
                if i["location_id"]:
                    parent_loc[i["id"]] = i["location_id"][0]

            marked = {}

            def fnd_parent(loc_id):  # go up the parent chain to find the warehouse
                if not marked.get(loc_id):  # ensures O(N) iterations instead of O(N^2)
                    if childlocs.get(loc_id):
                        return childlocs[loc_id]
                    if parent_loc.get(loc_id):
                        parent = fnd_parent(parent_loc[loc_id])
                        if parent > 0:
                            return parent
                marked[loc_id] = True
                return -1

            for loc_id in recs:
                parent = fnd_parent(loc_id)
                if parent > 0:
                    self.map_locations[loc_id] = parent
Exemplo n.º 41
0
from xml.sax.saxutils import escape, quoteattr

from django.utils.safestring import mark_safe
from django.template import Library

register = Library()
register.filter('xmlescape', lambda o: mark_safe(escape(o)))
register.filter('quoteattr', lambda o: mark_safe(quoteattr(o)))
Exemplo n.º 42
0
 def _quoteattr(self, attr):
     """Escape an XML attribute. Value can be unicode."""
     attr = xml_safe(attr)
     if isinstance(attr, unicode) and not UNICODE_STRINGS:
         attr = attr.encode(self.encoding)
     return saxutils.quoteattr(attr)
Exemplo n.º 43
0
 def lookup(attr, val):
     return self.formattersDom.find('format[@%s=%s]' %
                                    (attr, quoteattr(val)))
Exemplo n.º 44
0
def get_xunit_content(report, testname, elapsed):
    test_count = sum(max(len(r), 1) for r in report.values())
    error_count = sum(len(r) for r in report.values())
    data = {
        'testname': testname,
        'test_count': test_count,
        'error_count': error_count,
        'time': '%.3f' % round(elapsed, 3),
    }
    xml = """<?xml version="1.0" encoding="UTF-8"?>
<testsuite
  name="%(testname)s"
  tests="%(test_count)d"
  failures="%(error_count)d"
  time="%(time)s"
>
""" % data

    for filename in sorted(report.keys()):
        errors = report[filename]

        if errors:
            # report each pclint error as a failing testcase
            for error in errors:
                data = {
                    'quoted_name': quoteattr(
                        '%s: %s (%s:%d)' % (
                            error['severity'], error['id'],
                            filename, error['line'])),
                    'testname': testname,
                    'quoted_message': quoteattr(error['msg']),
                }
                xml += """  <testcase
    name=%(quoted_name)s
    classname="%(testname)s"
  >
      <failure message=%(quoted_message)s/>
  </testcase>
""" % data

        else:
            # if there are no pclint errors report a single successful test
            data = {
                'quoted_location': quoteattr(filename),
                'testname': testname,
            }
            xml += """  <testcase
    name=%(quoted_location)s
    classname="%(testname)s"
    status="No errors"/>
""" % data

    # output list of checked files
    data = {
        'escaped_files': escape(''.join(['\n* %s' % r
                                         for r in sorted(report.keys())])),
    }
    xml += """  <system-out>Checked files:%(escaped_files)s</system-out>
""" % data

    xml += '</testsuite>\n'
    return xml
Exemplo n.º 45
0
 def format_my_phrase(self):
     if self.phrase:
         return ' phrase=%s' % quoteattr(self.phrase)
     else:
         return ''
Exemplo n.º 46
0
 def lookup(attr, val):
     return self.formattersDom.find('aggregators/aggregator[@%s=%s]' %
                                    (attr, quoteattr(val)))
Exemplo n.º 47
0
 def test_single_double_quoteattr(self):
     self.assertEqual(quoteattr("Includes 'single' and \"double\" quotes"),
                      "\"Includes 'single' and &quot;double&quot; quotes\"")
Exemplo n.º 48
0
 def _quoteattr(self, attr):
     """Escape an XML attribute. Value can be unicode."""
     attr = xml_safe(attr)
     return saxutils.quoteattr(attr)
Exemplo n.º 49
0
 def test_single_quoteattr(self):
     self.assertEqual(quoteattr('Includes "double" quotes'),
                      '\'Includes "double" quotes\'')
Exemplo n.º 50
0
 def format_my_body(self):
     return "<exists field=%s/>" % quoteattr(self.exists)
Exemplo n.º 51
0
    def rna2xml_node(ident, value, parent):
        ident_next = ident + ident_val

        # divide into attrs and nodes.
        node_attrs = []
        nodes_items = []
        nodes_lists = []

        value_type = type(value)

        if issubclass(value_type, skip_classes):
            return

        # XXX, fixme, pointcache has eternal nested pointer to its self.
        if value == parent:
            return

        value_type_name = value_type.__name__
        for prop in property_typemap[value_type_name]:

            subvalue = getattr(value, prop)
            subvalue_type = type(subvalue)

            if subvalue_type in {int, bool, float}:
                node_attrs.append("%s=\"%s\"" % (prop, number_to_str(subvalue, subvalue_type)))
            elif subvalue_type is str:
                node_attrs.append("%s=%s" % (prop, quoteattr(subvalue)))
            elif subvalue_type is set:
                node_attrs.append("%s=%s" % (prop, quoteattr("{" + ",".join(list(subvalue)) + "}")))
            elif subvalue is None:
                node_attrs.append("%s=\"NONE\"" % prop)
            elif issubclass(subvalue_type, referenced_classes):
                # special case, ID's are always referenced.
                node_attrs.append("%s=%s" % (prop, quoteattr(subvalue_type.__name__ + "::" + subvalue.name)))
            else:
                try:
                    subvalue_ls = list(subvalue)
                except:
                    subvalue_ls = None

                if subvalue_ls is None:
                    nodes_items.append((prop, subvalue, subvalue_type))
                else:
                    # check if the list contains native types
                    subvalue_rna = value.path_resolve(prop, False)
                    if type(subvalue_rna).__name__ == "bpy_prop_array":
                        # check if this is a 0-1 color (rgb, rgba)
                        # in that case write as a hexadecimal
                        prop_rna = value.bl_rna.properties[prop]
                        if (prop_rna.subtype == 'COLOR_GAMMA' and
                                prop_rna.hard_min == 0.0 and
                                prop_rna.hard_max == 1.0 and
                                prop_rna.array_length in {3, 4}):
                            # -----
                            # color
                            array_value = "#" + "".join(("%.2x" % int(v * 255) for v in subvalue_rna))

                        else:
                            # default
                            def str_recursive(s):
                                subsubvalue_type = type(s)
                                if subsubvalue_type in {int, float, bool}:
                                    return number_to_str(s, subsubvalue_type)
                                else:
                                    return " ".join([str_recursive(si) for si in s])

                            array_value = " ".join(str_recursive(v) for v in subvalue_rna)

                        node_attrs.append("%s=\"%s\"" % (prop, array_value))
                    else:
                        nodes_lists.append((prop, subvalue_ls, subvalue_type))

        # declare + attributes
        if pretty_format:
            if node_attrs:
                fw("%s<%s\n" % (ident, value_type_name))
                for node_attr in node_attrs:
                    fw("%s%s\n" % (ident_next, node_attr))
                fw("%s>\n" % (ident_next,))
            else:
                fw("%s<%s>\n" % (ident, value_type_name))
        else:
            fw("%s<%s %s>\n" % (ident, value_type_name, " ".join(node_attrs)))

        # unique members
        for prop, subvalue, subvalue_type in nodes_items:
            fw("%s<%s>\n" % (ident_next, prop))  # XXX, this is awkward, how best to solve?
            rna2xml_node(ident_next + ident_val, subvalue, value)
            fw("%s</%s>\n" % (ident_next, prop))  # XXX, need to check on this.

        # list members
        for prop, subvalue, subvalue_type in nodes_lists:
            fw("%s<%s>\n" % (ident_next, prop))
            for subvalue_item in subvalue:
                if subvalue_item is not None:
                    rna2xml_node(ident_next + ident_val, subvalue_item, value)
            fw("%s</%s>\n" % (ident_next, prop))

        fw("%s</%s>\n" % (ident, value_type_name))
Exemplo n.º 52
0
 def test_double_quoteattr(self):
     self.assertEqual(quoteattr("Includes 'single' quotes"),
                      "\"Includes 'single' quotes\"")
Exemplo n.º 53
0
    def getVars(self):
        vars = wcomponents.WTemplated.getVars(self)
        defaultDefinePlace = defaultDefineRoom = ""
        defaultInheritPlace = defaultInheritRoom = "checked"
        locationName, locationAddress, roomName, defaultExistRoom = "", "", "", ""
        vars["conference"] = self._conf
        vars["boardNumber"] = quoteattr(str(self._contrib.getBoardNumber()))
        vars["contrib"] = self._contrib
        vars["title"] = quoteattr(self._contrib.getTitle())
        vars["description"] = self.htmlText(self._contrib.getDescription())
        vars["additionalFields"] = self._getAdditionalFieldsHTML()
        vars["day"], vars["month"], vars["year"] = "", "", ""
        vars["sHour"], vars["sMinute"] = "", ""
        sDate = self._contrib.getStartDate()
        if sDate is not None:
            vars["day"] = quoteattr(str(sDate.day))
            vars["month"] = quoteattr(str(sDate.month))
            vars["year"] = quoteattr(str(sDate.year))
            vars["sHour"] = quoteattr(str(sDate.hour))
            vars["sMinute"] = quoteattr(str(sDate.minute))
        if self._contrib.getStartDate():
            vars["dateTime"] = formatDateTime(
                self._contrib.getAdjustedStartDate())
        else:
            vars["dateTime"] = ""
        vars["duration"] = self._contrib.getDuration().seconds / 60
        if self._contrib.getDuration() is not None:
            vars["durationHours"] = quoteattr(
                str((datetime(1900, 1, 1) + self._contrib.getDuration()).hour))
            vars["durationMinutes"] = quoteattr(
                str((datetime(1900, 1, 1) +
                     self._contrib.getDuration()).minute))
        if self._contrib.getOwnLocation():
            defaultDefinePlace = "checked"
            defaultInheritPlace = ""
            locationName = self._contrib.getLocation().getName()
            locationAddress = self._contrib.getLocation().getAddress()

        if self._contrib.getOwnRoom():
            defaultDefineRoom = "checked"
            defaultInheritRoom = ""
            defaultExistRoom = ""
            roomName = self._contrib.getRoom().getName()
        vars["defaultInheritPlace"] = defaultInheritPlace
        vars["defaultDefinePlace"] = defaultDefinePlace
        vars["confPlace"] = ""
        confLocation = self._owner.getLocation()
        if self._contrib.isScheduled():
            confLocation = self._contrib.getSchEntry().getSchedule().getOwner(
            ).getLocation()
        if self._contrib.getSession(
        ) and not self._contrib.getConference().getEnableSessionSlots():
            confLocation = self._contrib.getSession().getLocation()
        if confLocation:
            vars["confPlace"] = confLocation.getName()
        vars["locationName"] = locationName
        vars["locationAddress"] = locationAddress
        vars["defaultInheritRoom"] = defaultInheritRoom
        vars["defaultDefineRoom"] = defaultDefineRoom
        vars["defaultExistRoom"] = defaultExistRoom
        vars["confRoom"] = ""
        confRoom = self._owner.getRoom()
        rx = []
        roomsexist = self._conf.getRoomList()
        roomsexist.sort()
        for room in roomsexist:
            sel = ""
            rx.append("""<option value=%s%s>%s</option>""" %
                      (quoteattr(str(room)), sel, self.htmlText(room)))
        vars["roomsexist"] = "".join(rx)
        if self._contrib.isScheduled():
            confRoom = self._contrib.getSchEntry().getSchedule().getOwner(
            ).getRoom()
        if self._contrib.getSession(
        ) and not self._contrib.getConference().getEnableSessionSlots():
            confRoom = self._contrib.getSession().getRoom()
        if confRoom:
            vars["confRoom"] = confRoom.getName()
        vars["roomName"] = quoteattr(roomName)
        vars["parentType"] = "conference"
        if self._contrib.getSession() is not None:
            vars["parentType"] = "session"
            if self._contrib.isScheduled() and self._contrib.getConference(
            ).getEnableSessionSlots():
                vars["parentType"] = "session slot"
        vars["postURL"] = urlHandlers.UHContributionDataModif.getURL(
            self._contrib)
        vars["types"] = self._getTypeItemsHTML()
        vars["keywords"] = self._contrib.getKeywords()
        import MaKaC.webinterface.webFactoryRegistry as webFactoryRegistry
        wr = webFactoryRegistry.WebFactoryRegistry()
        wf = wr.getFactory(self._conf)
        if wf != None:
            type = wf.getId()
        else:
            type = "conference"
        if type == "conference":
            vars["Type"] = WContributionDataModificationType().getHTML(vars)
            vars["Board"] = WContributionDataModificationBoard().getHTML(vars)
        else:
            vars["Type"] = ""
            vars["Board"] = ""

        minfo = info.HelperMaKaCInfo.getMaKaCInfoInstance()
        vars["useRoomBookingModule"] = minfo.getRoomBookingModuleActive()
        if self._contrib.getSession():
            vars["sessionType"] = self._contrib.getSession().getScheduleType()
        else:
            vars["sessionType"] = 'none'
        return vars
Exemplo n.º 54
0
 def test_quoteattr_basic(self):
     self.assertEqual(quoteattr("Donald Duck & Co"),
                      '"Donald Duck &amp; Co"')
Exemplo n.º 55
0
 def getVars(self):
     vars = wcomponents.WTemplated.getVars(self)
     vars["eventType"] = self._eventType
     vars["withdrawnNotice"] = self._getWithdrawnNoticeHTML()
     vars["locator"] = self._contrib.getLocator().getWebForm()
     vars["title"] = self._contrib.getTitle()
     if isStringHTML(self._contrib.getDescription()):
         vars["description"] = self._contrib.getDescription()
     else:
         vars[
             "description"] = """<table class="tablepre"><tr><td><pre>%s</pre></td></tr></table>""" % self._contrib.getDescription(
             )
     vars["additionalFields"] = self._getAdditionalFieldsHTML()
     vars["rowspan"] = "6"
     vars["place"] = ""
     if self._contrib.getLocation():
         vars["place"] = self.htmlText(
             self._contrib.getLocation().getName())
     room = self._contrib.getRoom()
     if room is not None and room.getName().strip() != "":
         vars["place"] = i18nformat("""%s <br> _("Room"): %s""") % (
             vars["place"], self.htmlText(room.getName()))
     if self._eventType == "conference" and self._contrib.getBoardNumber(
     ) != "" and self._contrib.getBoardNumber() is not None:
         vars["place"] = i18nformat("""%s<br> _("Board #")%s""") % (
             vars["place"], self.htmlText(self._contrib.getBoardNumber()))
     vars["id"] = self.htmlText(self._contrib.getId())
     vars["dataModificationURL"] = str(
         urlHandlers.UHContributionDataModification.getURL(self._contrib))
     vars["duration"] = ""
     if self._contrib.getDuration() is not None:
         vars["duration"] = (datetime(1900, 1, 1) +
                             self._contrib.getDuration()).strftime("%Hh%M'")
     vars["type"] = ""
     if self._contrib.getType():
         vars["type"] = self.htmlText(self._contrib.getType().getName())
     vars["track"] = i18nformat("""--_("none")--""")
     if self._contrib.getTrack():
         vars["track"] = """<a href=%s>%s</a>""" % (
             quoteattr(
                 str(
                     urlHandlers.UHTrackModification.getURL(
                         self._contrib.getTrack()))),
             self.htmlText(self._contrib.getTrack().getTitle()))
     vars["session"] = ""
     if self._contrib.getSession():
         vars["session"] = """<a href=%s>%s</a>""" % (
             quoteattr(
                 str(
                     urlHandlers.UHSessionModification.getURL(
                         self._contrib.getSession()))),
             self.htmlText(self._contrib.getSession().getTitle()))
     vars["abstract"] = ""
     if isinstance(self._contrib, conference.AcceptedContribution):
         vars["abstract"] = self._getAbstractHTML()
     vars["contrib"] = self._contrib
     vars["selTracks"] = self._getChangeTracksHTML()
     vars["setTrackURL"] = quoteattr(
         str(urlHandlers.UHContribModSetTrack.getURL(self._contrib)))
     vars["selSessions"] = self._getChangeSessionsHTML()
     vars["setSessionURL"] = quoteattr(
         str(urlHandlers.UHContribModSetSession.getURL(self._contrib)))
     vars["contribXML"] = urlHandlers.UHContribToXMLConfManager.getURL(
         self._contrib)
     vars["contribPDF"] = urlHandlers.UHContribToPDFConfManager.getURL(
         self._contrib)
     vars["printIconURL"] = Config.getInstance().getSystemIconURL("pdf")
     vars["xmlIconURL"] = Config.getInstance().getSystemIconURL("xml")
     vars["withdrawURL"] = quoteattr(
         str(urlHandlers.UHContribModWithdraw.getURL(self._contrib)))
     vars["withdrawnInfo"] = self._getWithdrawnInfoHTML()
     vars["withdrawDisabled"] = False
     if isinstance(self._contrib.getCurrentStatus(),
                   conference.ContribStatusWithdrawn):
         vars["withdrawDisabled"] = True
     vars["reportNumbersTable"] = wcomponents.WReportNumbersTable(
         self._contrib, "contribution").getHTML()
     vars["keywords"] = self._contrib.getKeywords()
     if self._contrib.getSession():
         vars["sessionType"] = self._contrib.getSession().getScheduleType()
     else:
         vars["sessionType"] = 'none'
     vars["primaryAuthors"] = self._getParticipantsList(
         self._contrib.getPrimaryAuthorList())
     vars["coAuthors"] = self._getParticipantsList(
         self._contrib.getCoAuthorList())
     vars["speakers"] = self._getParticipantsList(
         self._contrib.getSpeakerList())
     return vars
Exemplo n.º 56
0
def _display_xml_host(h, out=sys.stdout):
    out.write('<host')
    for k in ["timedout", "timeoutcounter"]:
        if k in h:
            out.write(' %s=%s' % (k, saxutils.quoteattr(h[k])))
    for k in ["starttime", "endtime"]:
        if k in h:
            out.write(' %s=%s' % (k, saxutils.quoteattr(h[k].strftime('%s'))))
    out.write('>')
    if 'state' in h:
        out.write('<status state="%s"' % h['state'])
        for k in ["reason", "reason_ttl"]:
            kk = "state_%s" % k
            if kk in h:
                out.write(' %s="%s"' % (k, h[kk]))
        out.write('/>')
    out.write('\n')
    if 'addr' in h:
        out.write('<address addr="%s" addrtype="ipv4"/>\n' % h['addr'])
    for t in h.get('addresses', []):
        for a in h['addresses'][t]:
            out.write('<address addr="%s" addrtype="%s"/>\n' % (a, t))
    if 'hostnames' in h:
        out.write('<hostnames>\n')
        for hostname in h['hostnames']:
            out.write('<hostname')
            for k in ['name', 'type']:
                if k in hostname:
                    out.write(' %s="%s"' % (k, hostname[k]))
            out.write('/>\n')
        out.write('</hostnames>\n')
    out.write('<ports>')
    for state, counts in viewitems(h.get('extraports', {})):
        out.write('<extraports state="%s" count="%d">\n' %
                  (state, counts['total']))
        for reason, count in viewitems(counts['reasons']):
            out.write('<extrareasons reason="%s" count="%d"/>\n' %
                      (reason, count))
        out.write('</extraports>\n')
    for p in h.get('ports', []):
        if p.get('port') == -1:
            h['scripts'] = p['scripts']
            continue
        out.write('<port')
        if 'protocol' in p:
            out.write(' protocol="%s"' % p['protocol'])
        if 'port' in p:
            out.write(' portid="%s"' % p['port'])
        out.write('><state')
        for k in ['state', 'reason', 'reason_ttl']:
            kk = 'state_%s' % k
            if kk in p:
                out.write(' %s=%s' % (k, saxutils.quoteattr(str(p[kk]))))
        out.write('/>')
        if 'service_name' in p:
            out.write('<service name="%s"' % p['service_name'])
            for k in [
                    'servicefp', 'product', 'version', 'extrainfo', 'ostype',
                    'method', 'conf'
            ]:
                kk = "service_%s" % k
                if kk in p:
                    if isinstance(p[kk], basestring):
                        out.write(' %s=%s' % (k, saxutils.quoteattr(p[kk])))
                    else:
                        out.write(' %s="%s"' % (k, p[kk]))
            # TODO: CPE
            out.write('></service>')
        for s in p.get('scripts', []):
            _display_xml_script(s, out=out)
        out.write('</port>\n')
    out.write('</ports>\n')
    if 'scripts' in h:
        out.write('<hostscript>')
        for s in h['scripts']:
            _display_xml_script(s, out=out)
        out.write('</hostscript>')
    for trace in h.get('traces', []):
        out.write('<trace')
        if 'port' in trace:
            out.write(' port=%s' % (saxutils.quoteattr(str(trace['port']))))
        if 'protocol' in trace:
            out.write(' proto=%s' % (saxutils.quoteattr(trace['protocol'])))
        out.write('>\n')
        for hop in sorted(trace.get('hops', []), key=lambda hop: hop['ttl']):
            out.write('<hop')
            if 'ttl' in hop:
                out.write(' ttl=%s' % (saxutils.quoteattr(str(hop['ttl']))))
            if 'ipaddr' in hop:
                out.write(' ipaddr=%s' %
                          (saxutils.quoteattr(utils.int2ip(hop['ipaddr']))))
            if 'rtt' in hop:
                out.write(
                    ' rtt=%s' %
                    (saxutils.quoteattr('%.2f' % hop['rtt'] if isinstance(
                        hop['rtt'], float) else hop['rtt'])))
            if 'host' in hop:
                out.write(' host=%s' % (saxutils.quoteattr(hop['host'])))
            out.write('/>\n')
        out.write('</trace>\n')
    out.write('</host>\n')
Exemplo n.º 57
0
                    created_at += ".000000"
                if content_type is None:
                    xml_output.append('<subdir name="%s"><name>%s</name>'
                                      '</subdir>' % (name, name))
                else:
                    content_type, size = self.derive_content_type_metadata(
                        content_type, size)
                    content_type = saxutils.escape(content_type)
                    xml_output.append(
                        '<object><name>%s</name><hash>%s</hash>'
                        '<bytes>%d</bytes><content_type>%s</content_type>'
                        '<last_modified>%s</last_modified></object>' %
                        (name, etag, size, content_type, created_at))
            container_list = ''.join([
                '<?xml version="1.0" encoding="UTF-8"?>\n',
                '<container name=%s>' % saxutils.quoteattr(container),
                ''.join(xml_output), '</container>'
            ])
        else:
            if not container_list:
                return HTTPNoContent(request=req, headers=resp_headers)
            container_list = '\n'.join(r[0] for r in container_list) + '\n'
        ret = Response(body=container_list, request=req, headers=resp_headers)
        ret.content_type = out_content_type
        ret.charset = 'utf-8'
        return ret

    @public
    @timing_stats(sample_rate=0.01)
    def REPLICATE(self, req):
        """
Exemplo n.º 58
0
 def getVars(self):
     vars = wcomponents.WTemplated.getVars(self)
     vars["postURL"] = quoteattr(
         str(urlHandlers.UHContribModWithdraw.getURL(self._contrib)))
     vars["comment"] = self.htmlText("")
     return vars
Exemplo n.º 59
0
def get_xunit_content(report, testname, elapsed):
    test_count = sum(max(len(r[1]), 1) for r in report)
    error_count = sum(len(r[1]) for r in report)
    data = {
        'testname': testname,
        'test_count': test_count,
        'error_count': error_count,
        'time': '%.3f' % round(elapsed, 3),
    }
    xml = """<?xml version="1.0" encoding="UTF-8"?>
<testsuite
  name="%(testname)s"
  tests="%(test_count)d"
  failures="%(error_count)d"
  errors="0"
  time="%(time)s"
>
""" % data

    for (filename, errors) in report:

        if errors:
            # report each cpplint error as a failing testcase
            for error in errors:
                data = {
                    'quoted_name':
                    quoteattr('%s [%s] (%s:%d)' %
                              (error['category'], error['confidence'],
                               filename, error['linenum'])),
                    'testname':
                    testname,
                    'quoted_message':
                    quoteattr(error['message']),
                }
                xml += """  <testcase
    name=%(quoted_name)s
    classname="%(testname)s"
  >
      <failure message=%(quoted_message)s/>
  </testcase>
""" % data

        else:
            # if there are no cpplint errors report a single successful test
            data = {
                'quoted_location': quoteattr(filename),
                'testname': testname,
            }
            xml += """  <testcase
    name=%(quoted_location)s
    classname="%(testname)s"/>
""" % data

    # output list of checked files
    data = {
        'escaped_files': escape(''.join(['\n* %s' % r[0] for r in report])),
    }
    xml += """  <system-out>Checked files:%(escaped_files)s</system-out>
""" % data

    xml += '</testsuite>\n'
    return xml
Exemplo n.º 60
0
def get_xunit_content(report, testname, elapsed):
    test_count = sum(max(len(r), 1) for r in report.values())
    error_count = sum(len(r) for r in report.values())
    data = {
        "testname": testname,
        "test_count": test_count,
        "error_count": error_count,
        "time": "%.3f" % round(elapsed, 3),
    }
    xml = ("""<?xml version="1.0" encoding="UTF-8"?>
<testsuite
  name="%(testname)s"
  tests="%(test_count)d"
  errors="0"
  failures="%(error_count)d"
  time="%(time)s"
>
""" % data)

    for filename in sorted(report.keys()):
        hunks = report[filename]

        if hunks:
            for hunk in hunks:
                data = {
                    "quoted_location":
                    quoteattr("%s:%d" % (filename, hunk.source_start)),
                    "testname":
                    testname,
                    "quoted_message":
                    quoteattr(str(hunk)),
                }
                xml += ("""  <testcase
    name=%(quoted_location)s
    classname="%(testname)s"
  >
      <failure message=%(quoted_message)s></failure>
  </testcase>
""" % data)

        else:
            # if there are no replacements report a single successful test
            data = {
                "quoted_location": quoteattr(filename),
                "testname": testname,
            }
            xml += ("""  <testcase
    name=%(quoted_location)s
    classname="%(testname)s"/>
""" % data)

    # output list of checked files
    data = {
        "escaped_files":
        escape("".join(["\n* %s" % r for r in sorted(report.keys())])),
    }
    xml += ("""  <system-out>Checked files:%(escaped_files)s</system-out>
""" % data)

    xml += "</testsuite>\n"
    return xml