def _compute_kanban_subtasks(self): for record in self: result_string1 = '' result_string2 = '' result_string3 = '' for subtask in record.subtask_ids: bounding_length = 25 tmp_list = (subtask.name).split() for index in range(len(tmp_list)): if len(tmp_list[index]) > bounding_length: tmp_list[ index] = tmp_list[index][:bounding_length] + '...' tmp_subtask_name = " ".join(tmp_list) if subtask.state == 'todo' and record.env.user == subtask.user_id and record.env.user == subtask.reviewer_id: tmp_string3 = escape(': {0}'.format(tmp_subtask_name)) result_string3 += '<li><b>TODO</b>{}</li>'.format( tmp_string3) elif subtask.state == 'todo' and record.env.user == subtask.user_id: tmp_string1_1 = escape('{0}'.format( subtask.reviewer_id.name)) tmp_string1_2 = escape('{0}'.format(tmp_subtask_name)) result_string1 += '<li><b>TODO</b> from <em>{0}</em>: {1}</li>'.format( tmp_string1_1, tmp_string1_2) elif subtask.state == 'todo' and record.env.user == subtask.reviewer_id: tmp_string2_1 = escape('{0}'.format(subtask.user_id.name)) tmp_string2_2 = escape('{0}'.format(tmp_subtask_name)) result_string2 += '<li>TODO for <em>{0}</em>: {1}</li>'.format( tmp_string2_1, tmp_string2_2) record.kanban_subtasks = '<ul>' + result_string1 + result_string3 + result_string2 + '</ul>'
def event_track_proposal_post(self, event, **post): if not event.can_access_from_current_website(): raise NotFound() tags = [] for tag in event.allowed_track_tag_ids: if post.get('tag_' + str(tag.id)): tags.append(tag.id) track = request.env['event.track'].sudo().create({ 'name': post['track_name'], 'partner_name': post['partner_name'], 'partner_email': post['email_from'], 'partner_phone': post['phone'], 'partner_biography': escape(post['biography']), 'event_id': event.id, 'tag_ids': [(6, 0, tags)], 'user_id': False, 'description': escape(post['description']) }) if request.env.user != request.website.user_id: track.sudo().message_subscribe(partner_ids=request.env.user.partner_id.ids) else: partner = request.env['res.partner'].sudo().search([('email', '=', post['email_from'])]) if partner: track.sudo().message_subscribe(partner_ids=partner.ids) return request.render("website_event_track.event_track_proposal_success", {'track': track, 'event': event})
def record_to_html(self, record, field_name, options): assert options['tagName'] != 'img',\ "Oddly enough, the root tag of an image field can not be img. " \ "That is because the image goes into the tag, or it gets the " \ "hose again." if options.get('qweb_img_raw_data', False): return super(Image, self).record_to_html(record, field_name, options) aclasses = ['img', 'img-fluid'] if options.get('qweb_img_responsive', True) else ['img'] aclasses += options.get('class', '').split() classes = ' '.join(map(escape, aclasses)) max_size = None if options.get('resize'): max_size = options.get('resize') else: max_width, max_height = options.get('max_width', 0), options.get('max_height', 0) if max_width or max_height: max_size = '%sx%s' % (max_width, max_height) sha = hashlib.sha1(str(getattr(record, '__last_update')).encode('utf-8')).hexdigest()[0:7] max_size = '' if max_size is None else '/%s' % max_size avoid_if_small = '&avoid_if_small=true' if options.get('avoid_if_small') else '' src = '/web/image/%s/%s/%s%s?unique=%s%s' % (record._name, record.id, options.get('preview_image', field_name), max_size, sha, avoid_if_small) alt = None if options.get('alt-field') and getattr(record, options['alt-field'], None): alt = escape(record[options['alt-field']]) elif options.get('alt'): alt = options['alt'] src_zoom = None if options.get('zoom') and getattr(record, options['zoom'], None): src_zoom = '/web/image/%s/%s/%s%s?unique=%s' % (record._name, record.id, options['zoom'], max_size, sha) elif options.get('zoom'): src_zoom = options['zoom'] atts = OrderedDict() atts["src"] = src atts["class"] = classes atts["style"] = options.get('style') atts["alt"] = alt atts["data-zoom"] = src_zoom and u'1' or None atts["data-zoom-image"] = src_zoom atts["data-no-post-process"] = options.get('data-no-post-process') atts = self.env['ir.qweb']._post_processing_att('img', atts, options.get('template_options')) img = ['<img'] for name, value in atts.items(): if value: img.append(' ') img.append(escape(pycompat.to_text(name))) img.append('="') img.append(escape(pycompat.to_text(value))) img.append('"') img.append('/>') return u''.join(img)
def event_track_proposal_post(self, event, **post): tags = [] for tag in event.allowed_track_tag_ids: if post.get('tag_' + str(tag.id)): tags.append(tag.id) track = request.env['event.track'].sudo().create({ 'name': post['track_name'], 'partner_name': post['partner_name'], 'partner_email': post['email_from'], 'partner_phone': post['phone'], 'partner_biography': escape(post['biography']), 'event_id': event.id, 'tag_ids': [(6, 0, tags)], 'user_id': False, 'description': escape(post['description']) }) return request.website.render( "website_event_track.event_track_proposal_success", { 'track': track, 'event': event })
def google_map(self, *arg, **post): clean_ids = [] for partner_id in post.get('partner_ids', "").split(","): try: clean_ids.append(int(partner_id)) except ValueError: pass partners = request.env['res.partner'].sudo().search([("id", "in", clean_ids), ('website_published', '=', True), ('is_company', '=', True)]) partner_data = { "counter": len(partners), "partners": [] } for partner in partners.with_context(show_address=True): # TODO in master, do not use `escape` but `t-esc` in the qweb template. partner_data["partners"].append({ 'id': partner.id, 'name': escape(partner.name), 'address': escape('\n'.join(partner.name_get()[0][1].split('\n')[1:])), 'latitude': escape(str(partner.partner_latitude)), 'longitude': escape(str(partner.partner_longitude)), }) if 'customers' in post.get('partner_url', ''): partner_url = '/customers/' else: partner_url = '/partners/' google_maps_api_key = request.env['ir.config_parameter'].sudo().get_param('google_maps_api_key') values = { 'partner_url': partner_url, 'partner_data': json.dumps(partner_data), 'google_maps_api_key': google_maps_api_key, } return request.render("website_google_map.google_map", values)
def google_map(self, *arg, **post): clean_ids = [] for partner_id in post.get('partner_ids', "").split(","): try: clean_ids.append(int(partner_id)) except ValueError: pass partners = request.env['res.partner'].sudo().search([("id", "in", clean_ids), ('website_published', '=', True), ('is_company', '=', True)]) partner_data = { "counter": len(partners), "partners": [] } for partner in partners.with_context({'show_address': True}): # TODO in master, do not use `escape` but `t-esc` in the qweb template. partner_data["partners"].append({ 'id': partner.id, 'name': escape(partner.name), 'address': escape('\n'.join(partner.name_get()[0][1].split('\n')[1:])), 'latitude': escape(str(partner.partner_latitude)), 'longitude': escape(str(partner.partner_longitude)), }) if 'customers' in post.get('partner_url', ''): partner_url = '/customers/' else: partner_url = '/partners/' values = { 'partner_url': partner_url, 'partner_data': json.dumps(partner_data) } return request.website.render("website_google_map.google_map", values)
def _compute_kanban_subtasks(self): for record in self: result_string1 = "" result_string2 = "" result_string3 = "" for subtask in record.subtask_ids: bounding_length = 25 tmp_list = (subtask.name).split() for index in range(len(tmp_list)): if len(tmp_list[index]) > bounding_length: tmp_list[ index] = tmp_list[index][:bounding_length] + "..." tmp_subtask_name = " ".join(tmp_list) if (subtask.state == "todo" and record.env.user == subtask.user_id and record.env.user == subtask.reviewer_id): tmp_string3 = escape(u": {}".format(tmp_subtask_name)) result_string3 += u"<li><b>TODO</b>{}</li>".format( tmp_string3) elif subtask.state == "todo" and record.env.user == subtask.user_id: tmp_string1_1 = escape(u"{}".format( subtask.reviewer_id.name)) tmp_string1_2 = escape(u"{}".format(tmp_subtask_name)) result_string1 += u"<li><b>TODO</b> from <em>{}</em>: {}</li>".format( tmp_string1_1, tmp_string1_2) elif subtask.state == "todo" and record.env.user == subtask.reviewer_id: tmp_string2_1 = escape(u"{}".format(subtask.user_id.name)) tmp_string2_2 = escape(u"{}".format(tmp_subtask_name)) result_string2 += u"<li>TODO for <em>{}</em>: {}</li>".format( tmp_string2_1, tmp_string2_2) record.kanban_subtasks = ("<ul>" + result_string1 + result_string3 + result_string2 + "</ul>")
def send_subtask_email(self, subtask_name, subtask_state, subtask_reviewer_id, subtask_user_id): for r in self: body = '' reviewer = self.env["res.users"].browse(subtask_reviewer_id) user = self.env["res.users"].browse(subtask_user_id) state = SUBTASK_STATES[subtask_state] reviewer_ids = [] subtype = 'project_task_subtask.subtasks_subtype' if user == self.env.user and reviewer == self.env.user: body = '<p><strong>' + state + '</strong>: ' + escape( subtask_name) + '</p>' subtype = False elif self.env.user == reviewer: body = '<p>' + escape( user.name ) + ', <br><strong>' + state + '</strong>: ' + escape( subtask_name) + '</p>' reviewer_ids = [user.create_uid.id] elif self.env.user == user: body = '<p>' + escape( reviewer.name ) + ', <br><strong>' + state + '</strong>: ' + escape( subtask_name) + '</p>' reviewer_ids = [reviewer.create_uid.id] r.message_post(type='comment', subtype=subtype, body=body, reviewer_ids=reviewer_ids)
def send_subtask_email( self, subtask_name, subtask_state, subtask_reviewer_id, subtask_user_id, old_name=None, ): for r in self: body = "" reviewer = self.env["res.users"].browse(subtask_reviewer_id) user = self.env["res.users"].browse(subtask_user_id) state = SUBTASK_STATES[subtask_state] if subtask_state == "done": state = '<span style="color:#080">' + state + "</span>" if subtask_state == "todo": state = '<span style="color:#A00">' + state + "</span>" if subtask_state == "cancelled": state = '<span style="color:#777">' + state + "</span>" if subtask_state == "waiting": state = '<span style="color:#b818ce">' + state + "</span>" partner_ids = [] subtype = "project_task_subtask.subtasks_subtype" if user == self.env.user and reviewer == self.env.user: body = "<p>" + "<strong>" + state + "</strong>: " + escape( subtask_name) subtype = False elif self.env.user == reviewer: body = ("<p>" + escape(user.name) + ", <br><strong>" + state + "</strong>: " + escape(subtask_name)) partner_ids = [user.partner_id.id] elif self.env.user == user: body = ( "<p>" + escape(reviewer.name) + ', <em style="color:#999">I updated checklist item assigned to me:</em> <br><strong>' + state + "</strong>: " + escape(subtask_name)) partner_ids = [reviewer.partner_id.id] else: body = ( "<p>" + escape(user.name) + ", " + escape(reviewer.name) + ', <em style="color:#999">I updated checklist item, now its assigned to ' + escape(user.name) + ": </em> <br><strong>" + state + "</strong>: " + escape(subtask_name)) partner_ids = [user.partner_id.id, reviewer.partner_id.id] if old_name: body = ( body + '<br><em style="color:#999">Updated from</em><br><strong>' + state + "</strong>: " + escape(old_name) + "</p>") else: body = body + "</p>" r.message_post( message_type="comment", subtype=subtype, body=body, partner_ids=partner_ids, )
def _compile_directive_snippet(self, el, options): el.set('t-call', el.attrib.pop('t-snippet')) name = self.env['ir.ui.view'].search([('key', '=', el.attrib.get('t-call'))]).display_name thumbnail = el.attrib.pop('t-thumbnail', "oe-thumbnail") div = u'<div name="%s" data-oe-type="snippet" data-oe-thumbnail="%s">' % ( escape(pycompat.to_text(name)), escape(pycompat.to_text(thumbnail)) ) return [self._append(ast.Str(div))] + self._compile_node(el, options) + [self._append(ast.Str(u'</div>'))]
def _compile_directive_snippet(self, el, options): el.set('t-call', el.attrib.pop('t-snippet')) View = self.env['ir.ui.view'] view_id = View.get_view_id(el.attrib.get('t-call')) name = View.browse(view_id).name thumbnail = el.attrib.pop('t-thumbnail', "oe-thumbnail") div = u'<div name="%s" data-oe-type="snippet" data-oe-thumbnail="%s">' % ( escape(pycompat.to_text(name)), escape( pycompat.to_text(thumbnail))) return [self._append(ast.Str(div))] + self._compile_node( el, options) + [self._append(ast.Str(u'</div>'))]
def record_to_html(self, record, field_name, options): assert options['tagName'] != 'img',\ "Oddly enough, the root tag of an image field can not be img. " \ "That is because the image goes into the tag, or it gets the " \ "hose again." if options.get('qweb_img_raw_data', False): return super(Image, self).record_to_html(record, field_name, options) aclasses = ['img', 'img-fluid'] if options.get('qweb_img_responsive', True) else ['img'] aclasses += options.get('class', '').split() classes = ' '.join(map(escape, aclasses)) src, src_zoom = self._get_src_urls(record, field_name, options) if options.get('alt-field') and getattr(record, options['alt-field'], None): alt = escape(record[options['alt-field']]) elif options.get('alt'): alt = options['alt'] else: alt = escape(record.display_name) itemprop = None if options.get('itemprop'): itemprop = options['itemprop'] atts = OrderedDict() atts["src"] = src atts["itemprop"] = itemprop atts["class"] = classes atts["style"] = options.get('style') atts["alt"] = alt atts["data-zoom"] = src_zoom and u'1' or None atts["data-zoom-image"] = src_zoom atts["data-no-post-process"] = options.get('data-no-post-process') atts = self.env['ir.qweb']._post_processing_att( 'img', atts, options.get('template_options')) img = ['<img'] for name, value in atts.items(): if value: img.append(' ') img.append(escape(pycompat.to_text(name))) img.append('="') img.append(escape(pycompat.to_text(value))) img.append('"') img.append('/>') return M(''.join(img))
def _compile_directive_install(self, el, compile_context, indent): key = el.attrib.pop('t-install') thumbnail = el.attrib.pop('t-thumbnail', 'oe-thumbnail') if self.user_has_groups('base.group_system'): module = self.env['ir.module.module'].search([('name', '=', key)]) if not module or module.state == 'installed': return [] name = el.attrib.get('string') or 'Snippet' div = '<div name="%s" data-oe-type="snippet" data-module-id="%s" data-oe-thumbnail="%s"><section/></div>' % ( escape(pycompat.to_text(name)), module.id, escape(pycompat.to_text(thumbnail))) self._append_text(div, compile_context) return []
def _compile_directive_snippet(self, el, options): key = el.attrib.pop('t-snippet') el.set('t-call', key) el.set('t-call-options', "{'snippet-key': '" + key + "'}") View = self.env['ir.ui.view'].sudo() view_id = View.get_view_id(key) name = View.browse(view_id).name thumbnail = el.attrib.pop('t-thumbnail', "oe-thumbnail") div = u'<div name="%s" data-oe-type="snippet" data-oe-thumbnail="%s" data-oe-snippet-id="%s" data-oe-keywords="%s">' % ( escape(pycompat.to_text(name)), escape( pycompat.to_text(thumbnail)), escape( pycompat.to_text(view_id)), escape(pycompat.to_text(el.findtext('keywords')))) return [self._append(ast.Str(div))] + self._compile_node( el, options) + [self._append(ast.Str(u'</div>'))]
def _compile_directive_install(self, el, options): if self.user_has_groups('base.group_system'): module = self.env['ir.module.module'].search([('name', '=', el.attrib.get('t-install'))]) if not module or module.state == 'installed': return [] name = el.attrib.get('string') or 'Snippet' thumbnail = el.attrib.pop('t-thumbnail', 'oe-thumbnail') div = u'<div name="%s" data-oe-type="snippet" data-module-id="%s" data-oe-thumbnail="%s"><section/></div>' % ( escape(pycompat.to_text(name)), module.id, escape(pycompat.to_text(thumbnail)) ) return [self._append(ast.Str(div))] else: return []
def value_to_html(self, value, options): res = super(Contact,self).value_to_html(value, options) if options.get('min_name', False): if not value.exists(): return False opf = options and options.get('fields') or ["name", "address", "phone", "mobile", "fax", "email"] value = value.sudo().with_context(show_address=True) phone = '' if value.phone: phone = value.phone elif options.get('parent_phone', False) and value.commercial_partner_id.phone: phone = value.commercial_partner_id.phone name_get = value.name or '' val = { 'name': name_get.split("\n")[0], 'address': escape("\n".join(value.name_get()[0][1].split("\n")[1:])).strip(), 'phone': phone, 'mobile': value.mobile, 'fax': value.fax, 'city': value.city, 'country_id': value.country_id.display_name, 'website': value.website, 'email': value.email, 'fields': opf, 'object': value, 'options': options } return self.env['ir.qweb'].render('base.contact', val) else: return res
def get_mapping_value(field_type, value, field_meta): if field_type == 'text': if value and field_meta.get('truncate', True): value = shorten(value, max_nb_chars, placeholder='...') if field_meta.get('match') and value and term: pattern = '|'.join(map(re.escape, term.split())) if pattern: parts = re.split(f'({pattern})', value, flags=re.IGNORECASE) if len(parts) > 1: value = request.env['ir.ui.view'].sudo( )._render_template( "website.search_text_with_highlight", {'parts': parts}) field_type = 'html' if field_type not in ('image', 'binary') and ( 'ir.qweb.field.%s' % field_type) in request.env: opt = {} if field_type == 'monetary': opt['display_currency'] = options['display_currency'] elif field_type == 'html': opt['template_options'] = {} value = request.env[('ir.qweb.field.%s' % field_type)].value_to_html(value, opt) return escape(value)
def record_to_html(self, record, field_name, options): assert options['tagName'] != 'img',\ "Oddly enough, the root tag of an image field can not be img. " \ "That is because the image goes into the tag, or it gets the " \ "hose again." aclasses = ['img', 'img-responsive'] + options.get('class', '').split() classes = ' '.join(itertools.imap(escape, aclasses)) max_size = None if options.get('resize'): max_size = options.get('resize') else: max_width, max_height = options.get('max_width', 0), options.get( 'max_height', 0) if max_width or max_height: max_size = '%sx%s' % (max_width, max_height) sha = hashlib.sha1(getattr(record, '__last_update')).hexdigest()[0:7] max_size = '' if max_size is None else '/%s' % max_size src = '/web/image/%s/%s/%s%s?unique=%s' % (record._name, record.id, field_name, max_size, sha) alt = None if options.get('alt-field') and getattr(record, options['alt-field'], None): alt = escape(record[options['alt-field']]) elif options.get('alt'): alt = options['alt'] img = '<img class="%s" src="%s" style="%s"%s/>' % \ (classes, src, options.get('style', ''), ' alt="%s"' % alt if alt else '') return ir_qweb.unicodifier(img)
def value_to_html(self, value, options): if not value: return '' opf = options and options.get('fields') or [ "name", "address", "phone", "mobile", "email" ] opsep = options and options.get('separator') or "\n" value = value.sudo().with_context(show_address=True) name_get = value.name_get()[0][1] val = { 'name': name_get.split("\n")[0], 'address': escape(opsep.join(name_get.split("\n")[1:])).strip(), 'phone': value.phone, 'mobile': value.mobile, 'city': value.city, 'country_id': value.country_id.display_name, 'website': value.website, 'email': value.email, 'fields': opf, 'object': value, 'options': options } return self.env['ir.qweb'].render( 'base.contact', val, **options.get('template_options', dict()))
def _compile_directive_snippet(self, el, compile_context, indent): key = el.attrib.pop('t-snippet') el.set('t-call', key) el.set('t-options', f"{{'snippet-key': {key!r}}}") view = self.env['ir.ui.view']._get_view(key).sudo() name = view.name thumbnail = el.attrib.pop('t-thumbnail', "oe-thumbnail") div = '<div name="%s" data-oe-type="snippet" data-oe-thumbnail="%s" data-oe-snippet-id="%s" data-oe-keywords="%s">' % ( escape(pycompat.to_text(name)), escape( pycompat.to_text(thumbnail)), escape(pycompat.to_text( view.id)), escape(pycompat.to_text( el.findtext('keywords')))) self._append_text(div, compile_context) code = self._compile_node(el, compile_context, indent) self._append_text('</div>', compile_context) return code
def record_to_html(self, record, field_name, options): assert options['tagName'] != 'img',\ "Oddly enough, the root tag of an image field can not be img. " \ "That is because the image goes into the tag, or it gets the " \ "hose again." aclasses = ['img', 'img-responsive'] + options.get('class', '').split() classes = ' '.join(itertools.imap(escape, aclasses)) max_size = None if options.get('resize'): max_size = options.get('resize') else: max_width, max_height = options.get('max_width', 0), options.get('max_height', 0) if max_width or max_height: max_size = '%sx%s' % (max_width, max_height) sha = hashlib.sha1(getattr(record, '__last_update')).hexdigest()[0:7] max_size = '' if max_size is None else '/%s' % max_size src = '/web/image/%s/%s/%s%s?unique=%s' % (record._name, record.id, field_name, max_size, sha) alt = None if options.get('alt-field') and getattr(record, options['alt-field'], None): alt = escape(record[options['alt-field']]) elif options.get('alt'): alt = options['alt'] img = '<img class="%s" src="%s" style="%s"%s/>' % \ (classes, src, options.get('style', ''), ' alt="%s"' % alt if alt else '') return ir_qweb.unicodifier(img)
def value_to_html(self, value, options): if not value.exists(): return False opf = options and options.get('fields') or [ "name", "address", "phone", "mobile", "fax", "email" ] value = value.sudo().with_context(show_address=True) name_get = value.name_get()[0][1] val = { 'name': value.company_name or name_get.split("\n")[0], 'address': escape("\n".join(name_get.split("\n")[1:])).strip(), 'phone': value.phone, 'mobile': value.mobile, 'fax': value.fax, 'city': value.city, 'country_id': value.country_id.display_name, 'website': value.website, 'email': value.email, 'fields': opf, 'object': value, 'options': options } return self.env['ir.qweb'].render('base.contact', val)
def html_escape(string, options): """ Automatically escapes content unless options['html-escape'] is set to False :param str string: :param dict options: """ return escape(string) if not options or options.get('html-escape', True) else string
def _get_website_file_count(self): count = 0 if self.website_file: url = escape(self.website_file_url) count = self.env['ir.ui.view'].search_count( ["|", ('arch', 'like', '"%s"' % url), ('arch', 'like', "'%s'" % url)]) self.website_file_count = count
def event_track_proposal_post(self, event, **post): tags = [] for tag in event.allowed_track_tag_ids: if post.get('tag_' + str(tag.id)): tags.append(tag.id) track = request.env['event.track'].sudo().create({ 'name': post['track_name'], 'partner_name': post['partner_name'], 'partner_email': post['email_from'], 'partner_phone': post['phone'], 'partner_biography': escape(post['biography']), 'event_id': event.id, 'tag_ids': [(6, 0, tags)], 'user_id': False, 'description': escape(post['description']) }) return request.website.render("website_event_track.event_track_proposal_success", {'track': track, 'event': event})
def _compute_kanban_subtasks(self): for record in self: result_string1 = '' result_string2 = '' result_string3 = '' for subtask in record.subtask_ids: if subtask.state == 'todo' and record.env.user == subtask.user_id and record.env.user == subtask.reviewer_id: tmp_string3 = escape(u': {0}'.format(subtask.name)) result_string3 += u'<li><b>TODO</b>{}</li>'.format( tmp_string3) elif subtask.state == 'todo' and record.env.user == subtask.user_id: tmp_string1 = escape(u'{0}: {1}'.format( subtask.reviewer_id.name, subtask.name)) result_string1 += u'<li><b>TODO</b> from {}</li>'.format( tmp_string1) elif subtask.state == 'todo' and record.env.user == subtask.reviewer_id: tmp_string2 = escape(u'{0}: {1}'.format( subtask.user_id.name, subtask.name)) result_string2 += u'<li>TODO for {}</li>'.format( tmp_string2) record.kanban_subtasks = '<ul>' + result_string1 + result_string3 + result_string2 + '</ul>'
def send_subtask_email(self, subtask_name, subtask_state, subtask_reviewer_id, subtask_user_id, old_name=None): for r in self: body = '' reviewer = self.env["res.users"].browse(subtask_reviewer_id) user = self.env["res.users"].browse(subtask_user_id) state = SUBTASK_STATES[subtask_state] if subtask_state == 'done': state = '<span style="color:#080">' + state + '</span>' if subtask_state == 'todo': state = '<span style="color:#A00">' + state + '</span>' if subtask_state == 'cancelled': state = '<span style="color:#777">' + state + '</span>' if subtask_state == 'waiting': state = '<span style="color:#b818ce">' + state + '</span>' partner_ids = [] subtype = 'project_task_subtask.subtasks_subtype' if user == self.env.user and reviewer == self.env.user: body = '<p>' + '<strong>' + state + '</strong>: ' + escape( subtask_name) subtype = False elif self.env.user == reviewer: body = '<p>' + escape( user.name ) + ', <br><strong>' + state + '</strong>: ' + escape( subtask_name) partner_ids = [user.partner_id.id] elif self.env.user == user: body = '<p>' + escape( reviewer.name ) + ', <em style="color:#999">I updated checklist item assigned to me:</em> <br><strong>' + state + '</strong>: ' + escape( subtask_name) partner_ids = [reviewer.partner_id.id] else: body = '<p>' + escape(user.name) + ', ' + escape( reviewer.name ) + ', <em style="color:#999">I updated checklist item, now its assigned to ' + escape( user.name ) + ': </em> <br><strong>' + state + '</strong>: ' + escape( subtask_name) partner_ids = [user.partner_id.id, reviewer.partner_id.id] if old_name: body = body + '<br><em style="color:#999">Updated from</em><br><strong>' + state + '</strong>: ' + escape( old_name) + '</p>' else: body = body + '</p>' r.message_post(message_type='comment', subtype=subtype, body=body, partner_ids=partner_ids)
def _compute_kanban_subtasks(self): for record in self: result_string_td = '' result_string_wt = '' if record.subtask_ids: task_todo_ids = record.subtask_ids.filtered( lambda x: x.state == 'todo' and x.user_id.id == record.env. user.id) task_waiting_ids = record.subtask_ids.filtered( lambda x: x.state == 'waiting' and x.user_id.id == record. env.user.id) if task_todo_ids: tmp_string_td = escape(': {0}'.format(len(task_todo_ids))) result_string_td += '<li><b>TODO{}</b></li>'.format( tmp_string_td) if task_waiting_ids: tmp_string_wt = escape(': {0}'.format( len(task_waiting_ids))) result_string_wt += '<li><b>Waiting{}</b></li>'.format( tmp_string_wt) record.kanban_subtasks = '<div class="kanban_subtasks"><ul>' + \ result_string_td + result_string_wt + '</ul></div>'
def _compute_kanban_subtasks(self): for record in self: result_string_td = "" result_string_wt = "" if record.subtask_ids: task_todo_ids = record.subtask_ids.filtered( lambda x: x.state == "todo" and x.user_id.id == record.env. user.id) task_waiting_ids = record.subtask_ids.filtered( lambda x: x.state == "waiting" and x.user_id.id == record. env.user.id) if task_todo_ids: tmp_string_td = escape(": {}".format(len(task_todo_ids))) result_string_td += "<li><b>TODO{}</b></li>".format( tmp_string_td) if task_waiting_ids: tmp_string_wt = escape(": {}".format( len(task_waiting_ids))) result_string_wt += "<li><b>Waiting{}</b></li>".format( tmp_string_wt) record.kanban_subtasks = ('<div class="kanban_subtasks"><ul>' + result_string_td + result_string_wt + "</ul></div>")
def record_to_html(self, record, field_name, options): assert options['tagName'] != 'img',\ "Oddly enough, the root tag of an image field can not be img. " \ "That is because the image goes into the tag, or it gets the " \ "hose again." if options.get('qweb_img_raw_data', False): return super(Image, self).record_to_html(record, field_name, options) aclasses = ['img', 'img-responsive'] if options.get( 'qweb_img_responsive', True) else ['img'] aclasses += options.get('class', '').split() classes = ' '.join(pycompat.imap(escape, aclasses)) max_size = None if options.get('resize'): max_size = options.get('resize') else: max_width, max_height = options.get('max_width', 0), options.get( 'max_height', 0) if max_width or max_height: max_size = '%sx%s' % (max_width, max_height) sha = hashlib.sha1(getattr( record, '__last_update').encode('utf-8')).hexdigest()[0:7] max_size = '' if max_size is None else '/%s' % max_size avoid_if_small = '&avoid_if_small=true' if options.get( 'avoid_if_small') else '' src = '/web/image/%s/%s/%s%s?unique=%s%s' % ( record._name, record.id, field_name, max_size, sha, avoid_if_small) alt = None if options.get('alt-field') and getattr(record, options['alt-field'], None): alt = escape(record[options['alt-field']]) elif options.get('alt'): alt = options['alt'] src_zoom = None if options.get('zoom') and getattr(record, options['zoom'], None): src_zoom = '/web/image/%s/%s/%s%s?unique=%s' % ( record._name, record.id, options['zoom'], max_size, sha) elif options.get('zoom'): src_zoom = options['zoom'] img = '<img class="%s" src="%s" style="%s"%s%s/>' % \ (classes, src, options.get('style', ''), ' alt="%s"' % alt if alt else '', ' data-zoom="1" data-zoom-image="%s"' % src_zoom if src_zoom else '') return pycompat.to_text(img)
def record_to_html(self, record, field_name, options): assert options['tagName'] != 'img',\ "Oddly enough, the root tag of an image field can not be img. " \ "That is because the image goes into the tag, or it gets the " \ "hose again." if options.get('qweb_img_raw_data', False): return super(Image, self).record_to_html(record, field_name, options) aclasses = ['img', 'img-responsive'] if options.get('qweb_img_responsive', True) else ['img'] aclasses += options.get('class', '').split() classes = ' '.join(pycompat.imap(escape, aclasses)) max_size = None if options.get('resize'): max_size = options.get('resize') else: max_width, max_height = options.get('max_width', 0), options.get('max_height', 0) if max_width or max_height: max_size = '%sx%s' % (max_width, max_height) sha = hashlib.sha1(getattr(record, '__last_update').encode('utf-8')).hexdigest()[0:7] max_size = '' if max_size is None else '/%s' % max_size avoid_if_small = '&avoid_if_small=true' if options.get('avoid_if_small') else '' src = '/web/image/%s/%s/%s%s?unique=%s%s' % (record._name, record.id, field_name, max_size, sha, avoid_if_small) alt = None if options.get('alt-field') and getattr(record, options['alt-field'], None): alt = escape(record[options['alt-field']]) elif options.get('alt'): alt = options['alt'] src_zoom = None if options.get('zoom') and getattr(record, options['zoom'], None): src_zoom = '/web/image/%s/%s/%s%s?unique=%s' % (record._name, record.id, options['zoom'], max_size, sha) elif options.get('zoom'): src_zoom = options['zoom'] img = '<img class="%s" src="%s" style="%s"%s%s/>' % \ (classes, src, options.get('style', ''), ' alt="%s"' % alt if alt else '', ' data-zoom="1" data-zoom-image="%s"' % src_zoom if src_zoom else '') return pycompat.to_text(img)
def try_remove_file(self): Views = self.env['ir.ui.view'] attachments_to_remove = [] # views blocking removal of the attachment removal_blocked_by = {} for attachment in self: # in-document URLs are html-escaped, a straight search will not # find them url = escape(attachment.website_file_url) views = Views.search( ["|", ('arch', 'like', '"%s"' % url), ('arch', 'like', "'%s'" % url)]) for v in views: removal_blocked_by[v.id] = v.name # probably incorrect update on porting else: attachments_to_remove.append(attachment.id) if attachments_to_remove: self.unlink(attachments_to_remove) return removal_blocked_by
def value_to_html(self, value, options): if not value.exists(): return False opf = options and options.get('fields') or ["name", "address", "phone", "mobile", "email"] value = value.sudo().with_context(show_address=True) name_get = value.name_get()[0][1] val = { 'name': name_get.split("\n")[0], 'address': escape("\n".join(name_get.split("\n")[1:])).strip(), 'phone': value.phone, 'mobile': value.mobile, 'city': value.city, 'country_id': value.country_id.display_name, 'website': value.website, 'email': value.email, 'fields': opf, 'object': value, 'options': options } return self.env['ir.qweb'].render('base.contact', val)
def create_email_for_interaction_resume(self, subject, body, partner): """ Creates a mail to make the new request appear on the interaction resume :param subject: subject of email :param body: body of email :param message: mail.message :param partner: partner making the request :return: None """ self.env["mail.mail"].create({ "state": "sent", "subject": subject, "body_html": body, "author_id": partner.id, "email_from": partner.email, "mail_message_id": self.env["mail.message"].create({ "model": "res.partner", "res_id": partner.id, "body": escape(body), "subject": subject, "author_id": partner.id, "subtype_id": self.env.ref("mail.mt_comment").id, "date": fields.Datetime.now(), }).id, })
def create_email_for_interaction_resume(self, subject, body, partner): """ Creates a mail to make the new request appear on the interaction resume :param subject: subject of email :param body: body of email :param message: mail.message :param partner: partner making the request :return: None """ self.env['mail.mail'].create({ 'state': 'sent', 'subject': subject, 'body_html': body, 'author_id': partner.id, 'email_from': partner.email, 'mail_message_id': self.env['mail.message'].create({ 'model': 'res.partner', 'res_id': partner.id, 'body': escape(body), 'subject': subject, 'author_id': partner.id, 'subtype_id': self.env.ref('mail.mt_comment').id, 'date': fields.Datetime.now(), }).id })
def value_to_html(self, value, options): if not value.exists(): return False opf = options and options.get("fields") or ["name", "address", "phone", "mobile", "fax", "email"] value = value.sudo().with_context(show_address=True) name_get = value.name_get()[0][1] val = { "name": name_get.split("\n")[0], "address": escape("\n".join(name_get.split("\n")[1:])).strip(), "phone": value.phone, "mobile": value.mobile, "fax": value.fax, "city": value.city, "country_id": value.country_id.display_name, "website": value.website, "email": value.email, "fields": opf, "object": value, "options": options, } return self.env["ir.qweb"].render("base.contact", val)