[MERGE] forward port of branch 9.0 up to f7432ef
This commit is contained in:
@@ -687,7 +687,7 @@ class AccountTax(models.Model):
|
|||||||
partner = partner_id and self.pool.get('res.partner').browse(cr, uid, partner_id, context=context) or None
|
partner = partner_id and self.pool.get('res.partner').browse(cr, uid, partner_id, context=context) or None
|
||||||
ids = isinstance(ids, (int, long)) and [ids] or ids
|
ids = isinstance(ids, (int, long)) and [ids] or ids
|
||||||
recs = self.browse(cr, uid, ids, context=context)
|
recs = self.browse(cr, uid, ids, context=context)
|
||||||
return recs.compute_all(price_unit, currency, quantity, product, partner)
|
return AccountTax.compute_all(recs, price_unit, currency, quantity, product, partner)
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _fix_tax_included_price(self, price, prod_taxes, line_taxes):
|
def _fix_tax_included_price(self, price, prod_taxes, line_taxes):
|
||||||
|
|||||||
@@ -796,4 +796,4 @@ class report_xml(osv.osv):
|
|||||||
if object_id:
|
if object_id:
|
||||||
model = self.pool.get('ir.model').browse(cr, uid, object_id, context=context).model
|
model = self.pool.get('ir.model').browse(cr, uid, object_id, context=context).model
|
||||||
args.append(('model', '=', model))
|
args.append(('model', '=', model))
|
||||||
return super(report_xml, self).search(cr, uid, args, offset, limit, order, context, count)
|
return super(report_xml, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ function connect () {
|
|||||||
WPA_PASS_FILE="/tmp/wpa_pass.txt"
|
WPA_PASS_FILE="/tmp/wpa_pass.txt"
|
||||||
PERSISTENT_WIFI_NETWORK_FILE="/home/pi/wifi_network.txt"
|
PERSISTENT_WIFI_NETWORK_FILE="/home/pi/wifi_network.txt"
|
||||||
CURRENT_WIFI_NETWORK_FILE="/tmp/current_wifi_network.txt" # used to repair connection when we lose it
|
CURRENT_WIFI_NETWORK_FILE="/tmp/current_wifi_network.txt" # used to repair connection when we lose it
|
||||||
|
LOST_WIFI_FILE="/tmp/lost_wifi.txt"
|
||||||
ESSID="${1}"
|
ESSID="${1}"
|
||||||
PASSWORD="${2}"
|
PASSWORD="${2}"
|
||||||
PERSIST="${3}"
|
PERSIST="${3}"
|
||||||
@@ -15,6 +16,7 @@ function connect () {
|
|||||||
sleep 3
|
sleep 3
|
||||||
|
|
||||||
sudo pkill -f keep_wifi_alive.sh
|
sudo pkill -f keep_wifi_alive.sh
|
||||||
|
WIFI_WAS_LOST=$?
|
||||||
|
|
||||||
# make network choice persistent
|
# make network choice persistent
|
||||||
if [ -n "${ESSID}" ] ; then
|
if [ -n "${ESSID}" ] ; then
|
||||||
@@ -54,13 +56,24 @@ function connect () {
|
|||||||
|
|
||||||
# give dhcp some time
|
# give dhcp some time
|
||||||
timeout 30 sh -c 'until ifconfig wlan0 | grep "inet addr:" ; do sleep 0.1 ; done'
|
timeout 30 sh -c 'until ifconfig wlan0 | grep "inet addr:" ; do sleep 0.1 ; done'
|
||||||
|
TIMEOUT_RETURN=$?
|
||||||
|
|
||||||
if [ $? -eq 124 ] && [ -z "${NO_AP}" ] ; then
|
if [ ${TIMEOUT_RETURN} -eq 124 ] && [ -z "${NO_AP}" ] ; then
|
||||||
logger -t posbox_connect_to_wifi "Failed to connect, forcing Posbox AP"
|
logger -t posbox_connect_to_wifi "Failed to connect, forcing Posbox AP"
|
||||||
sudo /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/wireless_ap.sh "force" &
|
sudo /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/wireless_ap.sh "force" &
|
||||||
else
|
else
|
||||||
logger -t posbox_connect_to_wifi "Restarting odoo"
|
if [ ${TIMEOUT_RETURN} -ne 124 ] ; then
|
||||||
sudo service odoo restart
|
rm -f "${LOST_WIFI_FILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "${LOST_WIFI_FILE}" ] ; then
|
||||||
|
logger -t posbox_connect_to_wifi "Restarting odoo"
|
||||||
|
sudo service odoo restart
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ${WIFI_WAS_LOST} -eq 0 ] ; then
|
||||||
|
touch "${LOST_WIFI_FILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
logger -t posbox_connect_to_wifi "Starting wifi keep alive script"
|
logger -t posbox_connect_to_wifi "Starting wifi keep alive script"
|
||||||
/home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/keep_wifi_alive.sh &
|
/home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/keep_wifi_alive.sh &
|
||||||
|
|||||||
@@ -131,8 +131,8 @@ class Report(osv.Model):
|
|||||||
|
|
||||||
@api.v8
|
@api.v8
|
||||||
def get_html(self, records, report_name, data=None):
|
def get_html(self, records, report_name, data=None):
|
||||||
return self._model.get_html(self._cr, self._uid, records.ids, report_name,
|
return Report.get_html(self._model, self._cr, self._uid, records.ids,
|
||||||
data=data, context=self._context)
|
report_name, data=data, context=self._context)
|
||||||
|
|
||||||
@api.v7
|
@api.v7
|
||||||
def get_pdf(self, cr, uid, ids, report_name, html=None, data=None, context=None):
|
def get_pdf(self, cr, uid, ids, report_name, html=None, data=None, context=None):
|
||||||
@@ -245,8 +245,8 @@ class Report(osv.Model):
|
|||||||
|
|
||||||
@api.v8
|
@api.v8
|
||||||
def get_pdf(self, records, report_name, html=None, data=None):
|
def get_pdf(self, records, report_name, html=None, data=None):
|
||||||
return self._model.get_pdf(self._cr, self._uid, records.ids, report_name,
|
return Report.get_pdf(self._model, self._cr, self._uid, records.ids,
|
||||||
html=html, data=data, context=self._context)
|
report_name, html=html, data=data, context=self._context)
|
||||||
|
|
||||||
@api.v7
|
@api.v7
|
||||||
def get_action(self, cr, uid, ids, report_name, data=None, context=None):
|
def get_action(self, cr, uid, ids, report_name, data=None, context=None):
|
||||||
@@ -279,8 +279,8 @@ class Report(osv.Model):
|
|||||||
|
|
||||||
@api.v8
|
@api.v8
|
||||||
def get_action(self, records, report_name, data=None):
|
def get_action(self, records, report_name, data=None):
|
||||||
return self._model.get_action(self._cr, self._uid, records.ids, report_name,
|
return Report.get_action(self._model, self._cr, self._uid, records.ids,
|
||||||
data=data, context=self._context)
|
report_name, data=data, context=self._context)
|
||||||
|
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
# Report generation helpers
|
# Report generation helpers
|
||||||
@@ -326,8 +326,8 @@ class Report(osv.Model):
|
|||||||
|
|
||||||
@api.v8
|
@api.v8
|
||||||
def _check_attachment_use(self, records, report):
|
def _check_attachment_use(self, records, report):
|
||||||
return self._model._check_attachment_use(
|
return Report._check_attachment_use(
|
||||||
self._cr, self._uid, records.ids, report, context=self._context)
|
self._model, self._cr, self._uid, records.ids, report, context=self._context)
|
||||||
|
|
||||||
def _check_wkhtmltopdf(self):
|
def _check_wkhtmltopdf(self):
|
||||||
return wkhtmltopdf_state
|
return wkhtmltopdf_state
|
||||||
|
|||||||
@@ -603,7 +603,7 @@ class WebsiteForum(http.Controller):
|
|||||||
if (user_id != request.session.uid and not
|
if (user_id != request.session.uid and not
|
||||||
(user.website_published or
|
(user.website_published or
|
||||||
(count_user_questions and current_user.karma > forum.karma_unlink_all))):
|
(count_user_questions and current_user.karma > forum.karma_unlink_all))):
|
||||||
return request.website.render("website_forum.private_profile", values)
|
return request.render("website_forum.private_profile", values, status=404)
|
||||||
|
|
||||||
# limit length of visible posts by default for performance reasons, except for the high
|
# limit length of visible posts by default for performance reasons, except for the high
|
||||||
# karma users (not many of them, and they need it to properly moderate the forum)
|
# karma users (not many of them, and they need it to properly moderate the forum)
|
||||||
|
|||||||
@@ -768,7 +768,7 @@
|
|||||||
<i t-if="question.post_type == 'discussion'" t-attf-class="fa fa-comments-o" t-att-title="question.post_type.capitalize()" />
|
<i t-if="question.post_type == 'discussion'" t-attf-class="fa fa-comments-o" t-att-title="question.post_type.capitalize()" />
|
||||||
<i t-if="question.post_type == 'link'" t-attf-class="fa fa-link" t-att-title="question.post_type.capitalize()" />
|
<i t-if="question.post_type == 'link'" t-attf-class="fa fa-link" t-att-title="question.post_type.capitalize()" />
|
||||||
<span>By </span>
|
<span>By </span>
|
||||||
<a t-attf-href="/forum/#{ slug(forum) }/user/#{ question.create_uid.id }"
|
<a t-att-href="(question.create_uid.id == request.session.uid or question.create_uid.sudo().website_published) and '/forum/%s/user/%s' % (slug(forum), question.create_uid.id) or '#'"
|
||||||
t-field="question.create_uid"
|
t-field="question.create_uid"
|
||||||
t-field-options='{"widget": "contact", "country_image": true, "fields": ["name", "country_id"]}'
|
t-field-options='{"widget": "contact", "country_image": true, "fields": ["name", "country_id"]}'
|
||||||
style="display: inline-block;"/>
|
style="display: inline-block;"/>
|
||||||
@@ -916,13 +916,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="question-block">
|
<div class="question-block">
|
||||||
<div class="pull-right author-box">
|
<div class="pull-right author-box">
|
||||||
|
<t t-set="user_profile_url" t-attf-value="#"/>
|
||||||
|
<t t-if="answer.create_uid.id == request.session.uid or answer.create_uid.sudo().website_published">
|
||||||
|
<t t-set="user_profile_url" t-value="'/forum/%s/user/%s' % (slug(forum), answer.create_uid.id)"/>
|
||||||
|
</t>
|
||||||
<div class="o_forum_user_bio_expand" t-if="answer.can_display_biography">
|
<div class="o_forum_user_bio_expand" t-if="answer.can_display_biography">
|
||||||
<t t-call="website_forum.forum_user_tooltip"/>
|
<t t-call="website_forum.forum_user_tooltip"/>
|
||||||
</div>
|
</div>
|
||||||
<a t-attf-href="/forum/#{ slug(forum) }/user/#{ answer.create_uid.id }" class="o_forum_user_info">
|
<a t-att-href="user_profile_url" class="o_forum_user_info">
|
||||||
<img class="pull-left img img-rounded o_forum_avatar" t-attf-src="/forum/user/#{answer.create_uid.id}/avatar"/>
|
<img class="pull-left img img-rounded o_forum_avatar" t-attf-src="/forum/user/#{answer.create_uid.id}/avatar"/>
|
||||||
</a>
|
</a>
|
||||||
<a t-attf-href="/forum/#{ slug(forum) }/user/#{ answer.create_uid.id }"
|
<a t-att-href="user_profile_url"
|
||||||
t-field="answer.create_uid"
|
t-field="answer.create_uid"
|
||||||
t-field-options='{"widget": "contact", "country_image": true, "fields": ["name", "country_id"]}'
|
t-field-options='{"widget": "contact", "country_image": true, "fields": ["name", "country_id"]}'
|
||||||
style="display: inline-block;"/>
|
style="display: inline-block;"/>
|
||||||
@@ -1006,11 +1010,11 @@
|
|||||||
<!-- Template for user tooltip -->
|
<!-- Template for user tooltip -->
|
||||||
<template id="forum_user_tooltip">
|
<template id="forum_user_tooltip">
|
||||||
<div class="o_forum_user_bio text-left panel panel-body">
|
<div class="o_forum_user_bio text-left panel panel-body">
|
||||||
<a t-attf-href="/forum/#{ slug(forum) }/user/#{ answer.create_uid.id }">
|
<a t-att-href="user_profile_url">
|
||||||
<img class="pull-left img img-rounded o_forum_avatar_big" t-attf-src="/forum/user/#{answer.create_uid.id}/avatar"/>
|
<img class="pull-left img img-rounded o_forum_avatar_big" t-attf-src="/forum/user/#{answer.create_uid.id}/avatar"/>
|
||||||
</a>
|
</a>
|
||||||
<div class="o_forum_tooltip_header">
|
<div class="o_forum_tooltip_header">
|
||||||
<h4 class="o_forum_tooltip_heading"><a t-attf-href="/forum/#{ slug(forum) }/user/#{ answer.create_uid.id }"
|
<h4 class="o_forum_tooltip_heading"><a t-att-href="user_profile_url"
|
||||||
t-field="answer.create_uid"
|
t-field="answer.create_uid"
|
||||||
t-field-options='{"widget": "contact", "country_image": true, "fields": ["name", "country_id"]}'
|
t-field-options='{"widget": "contact", "country_image": true, "fields": ["name", "country_id"]}'
|
||||||
style="display: inline-block;"/>
|
style="display: inline-block;"/>
|
||||||
|
|||||||
@@ -1104,22 +1104,23 @@ class ir_model_data(osv.osv):
|
|||||||
else:
|
else:
|
||||||
if mode=='init' or (mode=='update' and xml_id):
|
if mode=='init' or (mode=='update' and xml_id):
|
||||||
inherit_xml_ids = []
|
inherit_xml_ids = []
|
||||||
for table, field_name in model_obj._inherits.items():
|
if xml_id:
|
||||||
xml_ids = self.pool['ir.model.data'].search(cr, uid, [
|
for table, field_name in model_obj._inherits.items():
|
||||||
('module', '=', module),
|
xml_ids = self.pool['ir.model.data'].search(cr, uid, [
|
||||||
('name', '=', xml_id + '_' + table.replace('.', '_')),
|
('module', '=', module),
|
||||||
], context=context)
|
('name', '=', xml_id + '_' + table.replace('.', '_')),
|
||||||
# XML ID found in the database, try to recover an existing record
|
], context=context)
|
||||||
if xml_ids:
|
# XML ID found in the database, try to recover an existing record
|
||||||
found_xml_id = self.pool['ir.model.data'].browse(cr, uid, xml_ids[0], context=context)
|
if xml_ids:
|
||||||
record = self.pool[found_xml_id.model].browse(cr, uid, [found_xml_id.res_id], context=context)[0]
|
found_xml_id = self.pool['ir.model.data'].browse(cr, uid, xml_ids[0], context=context)
|
||||||
# The record exists, store the id and don't recreate the XML ID
|
record = self.pool[found_xml_id.model].browse(cr, uid, [found_xml_id.res_id], context=context)[0]
|
||||||
if record.exists():
|
# The record exists, store the id and don't recreate the XML ID
|
||||||
inherit_xml_ids.append(found_xml_id.model)
|
if record.exists():
|
||||||
values[field_name] = found_xml_id.res_id
|
inherit_xml_ids.append(found_xml_id.model)
|
||||||
# Orphan XML ID, delete it
|
values[field_name] = found_xml_id.res_id
|
||||||
else:
|
# Orphan XML ID, delete it
|
||||||
found_xml_id.unlink()
|
else:
|
||||||
|
found_xml_id.unlink()
|
||||||
|
|
||||||
res_id = model_obj.create(cr, uid, values, context=context)
|
res_id = model_obj.create(cr, uid, values, context=context)
|
||||||
if xml_id:
|
if xml_id:
|
||||||
|
|||||||
@@ -532,13 +532,24 @@ class ir_translation(osv.osv):
|
|||||||
records.check_field_access_rights(fmode, model_fields[mname])
|
records.check_field_access_rights(fmode, model_fields[mname])
|
||||||
records.check_access_rule(fmode)
|
records.check_access_rule(fmode)
|
||||||
|
|
||||||
|
@api.constrains('type', 'name', 'value')
|
||||||
|
def _check_value(self):
|
||||||
|
for trans in self.with_context(lang=None):
|
||||||
|
if trans.type == 'model' and trans.value:
|
||||||
|
mname, fname = trans.name.split(',')
|
||||||
|
record = trans.env[mname].browse(trans.res_id)
|
||||||
|
field = record._fields[fname]
|
||||||
|
if callable(field.translate):
|
||||||
|
# check whether applying (trans.src -> trans.value) then
|
||||||
|
# (trans.value -> trans.src) gives the original value back
|
||||||
|
value0 = field.translate(lambda term: None, record[fname])
|
||||||
|
value1 = field.translate({trans.src: trans.value}.get, value0)
|
||||||
|
value2 = field.translate({trans.value: trans.src}.get, value1)
|
||||||
|
if value2 != value0:
|
||||||
|
raise ValueError(_("Translation is not valid:\n%s") % trans.value)
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def create(self, vals):
|
def create(self, vals):
|
||||||
if vals.get('type') == 'model' and vals.get('value'):
|
|
||||||
# check and sanitize value
|
|
||||||
mname, fname = vals['name'].split(',')
|
|
||||||
field = self.env[mname]._fields[fname]
|
|
||||||
vals['value'] = field.check_trans_value(vals['value'])
|
|
||||||
record = super(ir_translation, self.sudo()).create(vals).with_env(self.env)
|
record = super(ir_translation, self.sudo()).create(vals).with_env(self.env)
|
||||||
record.check('create')
|
record.check('create')
|
||||||
self.clear_caches()
|
self.clear_caches()
|
||||||
@@ -548,13 +559,6 @@ class ir_translation(osv.osv):
|
|||||||
def write(self, vals):
|
def write(self, vals):
|
||||||
if vals.get('value'):
|
if vals.get('value'):
|
||||||
vals.setdefault('state', 'translated')
|
vals.setdefault('state', 'translated')
|
||||||
ttype = vals.get('type') or self[:1].type
|
|
||||||
if ttype == 'model':
|
|
||||||
# check and sanitize value
|
|
||||||
name = vals.get('name') or self[:1].name
|
|
||||||
mname, fname = name.split(',')
|
|
||||||
field = self.env[mname]._fields[fname]
|
|
||||||
vals['value'] = field.check_trans_value(vals['value'])
|
|
||||||
elif vals.get('src') or not vals.get('value', True):
|
elif vals.get('src') or not vals.get('value', True):
|
||||||
vals.setdefault('state', 'to_translate')
|
vals.setdefault('state', 'to_translate')
|
||||||
self.check('write')
|
self.check('write')
|
||||||
|
|||||||
@@ -644,6 +644,16 @@ def v7(method_v7):
|
|||||||
def foo(self):
|
def foo(self):
|
||||||
...
|
...
|
||||||
|
|
||||||
|
Special care must be taken if one method calls the other one, because
|
||||||
|
the method may be overridden! In that case, one should call the method
|
||||||
|
from the current class (say ``MyClass``), for instance::
|
||||||
|
|
||||||
|
@api.v7
|
||||||
|
def foo(self, cr, uid, ids, context=None):
|
||||||
|
# Beware: records.foo() may call an overriding of foo()
|
||||||
|
records = self.browse(cr, uid, ids, context)
|
||||||
|
return MyClass.foo(records)
|
||||||
|
|
||||||
Note that the wrapper method uses the docstring of the first method.
|
Note that the wrapper method uses the docstring of the first method.
|
||||||
"""
|
"""
|
||||||
# retrieve method_v8 from the caller's frame
|
# retrieve method_v8 from the caller's frame
|
||||||
|
|||||||
+5
-5
@@ -3915,7 +3915,7 @@ class BaseModel(object):
|
|||||||
if column._classic_write and not hasattr(column, '_fnct_inv'):
|
if column._classic_write and not hasattr(column, '_fnct_inv'):
|
||||||
if single_lang or not (has_trans and column.translate and not callable(column.translate)):
|
if single_lang or not (has_trans and column.translate and not callable(column.translate)):
|
||||||
# vals[field] is not a translation: update the table
|
# vals[field] is not a translation: update the table
|
||||||
updates.append((field, '%s', column._symbol_set[1](vals[field])))
|
updates.append((field, column._symbol_set[0], column._symbol_set[1](vals[field])))
|
||||||
direct.append(field)
|
direct.append(field)
|
||||||
else:
|
else:
|
||||||
upd_todo.append(field)
|
upd_todo.append(field)
|
||||||
@@ -4235,7 +4235,7 @@ class BaseModel(object):
|
|||||||
for field in vals:
|
for field in vals:
|
||||||
column = self._columns[field]
|
column = self._columns[field]
|
||||||
if column._classic_write:
|
if column._classic_write:
|
||||||
updates.append((field, '%s', column._symbol_set[1](vals[field])))
|
updates.append((field, column._symbol_set[0], column._symbol_set[1](vals[field])))
|
||||||
|
|
||||||
#for the function fields that receive a value, we set them directly in the database
|
#for the function fields that receive a value, we set them directly in the database
|
||||||
#(they may be required), but we also need to trigger the _fct_inv()
|
#(they may be required), but we also need to trigger the _fct_inv()
|
||||||
@@ -4469,7 +4469,7 @@ class BaseModel(object):
|
|||||||
value[v] = value[v][0]
|
value[v] = value[v][0]
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
updates.append((v, '%s', column._symbol_set[1](value[v])))
|
updates.append((v, column._symbol_set[0], column._symbol_set[1](value[v])))
|
||||||
if updates:
|
if updates:
|
||||||
query = 'UPDATE "%s" SET %s WHERE id = %%s' % (
|
query = 'UPDATE "%s" SET %s WHERE id = %%s' % (
|
||||||
self._table, ','.join('"%s"=%s' % u[:2] for u in updates),
|
self._table, ','.join('"%s"=%s' % u[:2] for u in updates),
|
||||||
@@ -4493,8 +4493,8 @@ class BaseModel(object):
|
|||||||
value = value[0]
|
value = value[0]
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
query = 'UPDATE "%s" SET "%s"=%%s WHERE id = %%s' % (
|
query = 'UPDATE "%s" SET "%s"=%s WHERE id = %%s' % (
|
||||||
self._table, f,
|
self._table, f, column._symbol_set[0],
|
||||||
)
|
)
|
||||||
cr.execute(query, (column._symbol_set[1](value), id))
|
cr.execute(query, (column._symbol_set[1](value), id))
|
||||||
|
|
||||||
|
|||||||
@@ -219,6 +219,12 @@ class XMLTranslator(object):
|
|||||||
text = text.replace(term, trans)
|
text = text.replace(term, trans)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
def process_attr(self, attr):
|
||||||
|
""" Translate the given node attribute value. """
|
||||||
|
term = attr.strip()
|
||||||
|
trans = term and self.callback(term)
|
||||||
|
return attr.replace(term, trans) if trans else attr
|
||||||
|
|
||||||
def process(self, node):
|
def process(self, node):
|
||||||
""" Process the given xml `node`: collect `todo` and `done` items. """
|
""" Process the given xml `node`: collect `todo` and `done` items. """
|
||||||
if (
|
if (
|
||||||
@@ -249,7 +255,7 @@ class XMLTranslator(object):
|
|||||||
# complete translations and serialize result as done
|
# complete translations and serialize result as done
|
||||||
for attr in TRANSLATED_ATTRS:
|
for attr in TRANSLATED_ATTRS:
|
||||||
if node.get(attr):
|
if node.get(attr):
|
||||||
node.set(attr, self.process_text(node.get(attr)))
|
node.set(attr, self.process_attr(node.get(attr)))
|
||||||
self.done(self.serialize(node.tag, node.attrib, child_trans.get_done()))
|
self.done(self.serialize(node.tag, node.attrib, child_trans.get_done()))
|
||||||
|
|
||||||
# add node tail as todo
|
# add node tail as todo
|
||||||
|
|||||||
Reference in New Issue
Block a user