def get_claim_report_user(self, employee_id, **post): if not request.env.user.has_group('fleet.fleet_group_manager'): return request.not_found() employee = request.env['hr.employee'].search([('id', '=', employee_id)], limit=1) partner_ids = (employee.user_id.partner_id | employee.address_home_id).ids if not employee or not partner_ids: return request.not_found() car_assignation_logs = request.env['fleet.vehicle.assignation.log'].search([('driver_id', 'in', partner_ids)]) doc_list = request.env['ir.attachment'].search([ ('res_model', '=', 'fleet.vehicle.assignation.log'), ('res_id', 'in', car_assignation_logs.ids)], order='create_date') writer = PdfFileWriter() font = "Helvetica" normal_font_size = 14 for document in doc_list: car_line_doc = request.env['fleet.vehicle.assignation.log'].browse(document.res_id) try: reader = PdfFileReader(io.BytesIO(base64.b64decode(document.datas)), strict=False, overwriteWarnings=False) except Exception: continue width = float(reader.getPage(0).mediaBox.getUpperRight_x()) height = float(reader.getPage(0).mediaBox.getUpperRight_y()) header = io.BytesIO() can = canvas.Canvas(header) can.setFont(font, normal_font_size) can.setFillColorRGB(1, 0, 0) car_name = car_line_doc.vehicle_id.display_name date_start = car_line_doc.date_start date_end = car_line_doc.date_end or '...' text_to_print = _("%s (driven from: %s to %s)") % (car_name, date_start, date_end) can.drawCentredString(width / 2, height - normal_font_size, text_to_print) can.save() header_pdf = PdfFileReader(header, overwriteWarnings=False) for page_number in range(0, reader.getNumPages()): page = reader.getPage(page_number) page.mergePage(header_pdf.getPage(0)) writer.addPage(page) _buffer = io.BytesIO() writer.write(_buffer) merged_pdf = _buffer.getvalue() _buffer.close() pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(merged_pdf))] return request.make_response(merged_pdf, headers=pdfhttpheaders)
def fast_launch(self, branch_name=False, repo=False, **post): Build = request.env['runbot.build'] domain = [('branch_id.branch_name', '=', branch_name)] if repo: domain.extend([('branch_id.repo_id', '=', repo.id)]) order = "sequence desc" else: order = 'repo_id ASC, sequence DESC' # Take the 10 lasts builds to find at least 1 running... Else no luck builds = Build.search(domain, order=order, limit=10) if builds: last_build = False for build in builds: if build.state == 'running' or (build.state == 'duplicate' and build.duplicate_id.state == 'running'): last_build = build if build.state == 'running' else build.duplicate_id break if not last_build: # Find the last build regardless the state to propose a rebuild last_build = builds[0] if last_build.state != 'running': url = "/runbot/build/%s?ask_rebuild=1" % last_build.id else: url = build.branch_id._get_branch_quickconnect_url(last_build.domain, last_build.dest)[build.branch_id.id] else: return request.not_found() return werkzeug.utils.redirect(url)
def open_rating(self, token, rate, **kwargs): assert rate in (1, 5, 10), "Incorrect rating" rating = request.env['rating.rating'].sudo().search([('access_token', '=', token)]) if not rating: return request.not_found() rate_names={ 5: _("not satisfied"), 1: _("highly dissatisfied"), 10: _("satisfied") } rating.sudo().write({'rating': rate, 'consumed': True}) return request.render('rating.rating_external_page_submit', { 'rating': rating, 'token': token, 'rate_name': rate_names[rate], 'rate': rate }) return request.not_found()
def build(self, build_id=None, search=None, **post): Build = request.env['runbot.build'] Logging = request.env['ir.logging'] build = Build.browse([int(build_id)]) if not build.exists(): return request.not_found() real_build = build.duplicate_id if build.state == 'duplicate' else build # other builds other_builds = Build.search([('branch_id', '=', build.branch_id.id)]) domain = ['|', ('dbname', '=like', '%s-%%' % real_build.dest), ('build_id', '=', real_build.id)] #if type: # domain.append(('type', '=', type)) #if level: # domain.append(('level', '=', level)) if search: domain.append(('name', 'ilike', search)) loggings = Logging.sudo().search(domain) context = { 'repo': build.repo_id, 'build': self.build_info(build), 'br': {'branch': build.branch_id}, 'logs': loggings, 'other_builds': other_builds } #context['type'] = type #context['level'] = level return request.render("runbot.build", context)
def _response_by_status(self, status, headers, content): if status == 304: return werkzeug.wrappers.Response(status=status, headers=headers) elif status == 301: return werkzeug.utils.redirect(content, code=301) elif status != 200: return request.not_found()
def sitemap_xml_index(self): Attachment = request.env['ir.attachment'].sudo() View = request.env['ir.ui.view'].sudo() mimetype = 'application/xml;charset=utf-8' content = None def create_sitemap(url, content): return Attachment.create({ 'datas': content.encode('base64'), 'mimetype': mimetype, 'type': 'binary', 'name': url, 'url': url, }) sitemap = Attachment.search([('url', '=', '/sitemap.xml'), ('type', '=', 'binary')], limit=1) if sitemap: # Check if stored version is still valid create_date = fields.Datetime.from_string(sitemap.create_date) delta = datetime.datetime.now() - create_date if delta < SITEMAP_CACHE_TIME: content = sitemap.datas.decode('base64') if not content: # Remove all sitemaps in ir.attachments as we're going to regenerated them sitemaps = Attachment.search([('url', '=like', '/sitemap%.xml'), ('type', '=', 'binary')]) sitemaps.unlink() pages = 0 locs = request.website.sudo(user=request.website.user_id.id).enumerate_pages() while True: values = { 'locs': islice(locs, 0, LOC_PER_SITEMAP), 'url_root': request.httprequest.url_root[:-1], } urls = View.render_template('website.sitemap_locs', values) if urls.strip(): content = View.render_template('website.sitemap_xml', {'content': urls}) pages += 1 last_sitemap = create_sitemap('/sitemap-%d.xml' % pages, content) else: break if not pages: return request.not_found() elif pages == 1: last_sitemap.write({ 'url': "/sitemap.xml", 'name': "/sitemap.xml" }) else: # Sitemaps must be split in several smaller files with a sitemap index content = View.render_template('website.sitemap_index_xml', { 'pages': range(1, pages + 1), 'url_root': request.httprequest.url_root, }) create_sitemap('/sitemap.xml', content) return request.make_response(content, [('Content-Type', mimetype)])
def make_event_ics_file(self, event, **kwargs): if not event or not event.registration_ids: return request.not_found() files = event._get_ics_file() content = files[event.id] return request.make_response(content, [ ('Content-Type', 'application/octet-stream'), ('Content-Length', len(content)), ('Content-Disposition', content_disposition('%s.ics' % event.name)) ])
def submit_rating(self, token, rate, **kwargs): rating = request.env["rating.rating"].sudo().search([("access_token", "=", token)]) if not rating: return request.not_found() record_sudo = request.env[rating.res_model].sudo().browse(rating.res_id) record_sudo.rating_apply(rate, token=token, feedback=kwargs.get("feedback")) # redirect to the form view if logged person if request.session.uid: return werkzeug.utils.redirect("/web#model=%s&id=%s&view_type=form" % (record_sudo._name, record_sudo.id)) return request.render("rating.rating_external_page_view")
def download_attachment(self, attachment_id): # Check if this is a valid attachment id attachment = request.env['ir.attachment'].sudo().search_read( [('id', '=', int(attachment_id))], ["name", "datas", "file_type", "res_model", "res_id", "type", "url"] ) if attachment: attachment = attachment[0] else: return redirect(self.orders_page) # Check if the user has bought the associated product res_model = attachment['res_model'] res_id = attachment['res_id'] purchased_products = request.env['account.invoice.line'].get_digital_purchases() if res_model == 'product.product': if res_id not in purchased_products: return redirect(self.orders_page) # Also check for attachments in the product templates elif res_model == 'product.template': P = request.env['product.product'] template_ids = map(lambda x: P.browse(x).product_tmpl_id.id, purchased_products) if res_id not in template_ids: return redirect(self.orders_page) else: return redirect(self.orders_page) # The client has bought the product, otherwise it would have been blocked by now if attachment["type"] == "url": if attachment["url"]: return redirect(attachment["url"]) else: return request.not_found() elif attachment["datas"]: data = StringIO(base64.standard_b64decode(attachment["datas"])) return http.send_file(data, filename=attachment['name'], as_attachment=True) else: return request.not_found()
def submit_rating(self, token, rate, **kwargs): rating = request.env['rating.rating'].sudo().search([('access_token', '=', token)]) if not rating: return request.not_found() record_sudo = request.env[rating.res_model].sudo().browse(rating.res_id) record_sudo.rating_apply(rate, token=token, feedback=kwargs.get('feedback')) lang = rating.partner_id.lang or 'en_US' return request.env['ir.ui.view'].with_context(lang=lang).render_template('rating.rating_external_page_view', { 'web_base_url': request.env['ir.config_parameter'].sudo().get_param('web.base.url'), 'rating': rating, })
def make_event_ics_file(self, event, **kwargs): if not event or not event.registration_ids: return request.not_found() attendee_ids = list(json.loads(kwargs.get('attendees', '{}').replace("'", '"')).values()) files = event.get_ics_file(attendee_ids) content = files[event.id] return request.make_response(content, [ ('Content-Type', 'application/octet-stream'), ('Content-Length', len(content)), ('Content-Disposition', 'attachment; filename=' + event.name + '.ics') ])
def open_rating(self, token, rate, **kwargs): assert rate in (1, 5, 10), "Incorrect rating" rating = request.env["rating.rating"].sudo().search([("access_token", "=", token)]) if not rating: return request.not_found() rate_names = {5: _("not satisfied"), 1: _("highly dissatisfied"), 10: _("satisfied")} rating.sudo().write({"rating": rate, "consumed": True}) return request.render( "rating.rating_external_page_submit", {"rating": rating, "token": token, "rate_name": rate_names[rate], "rate": rate}, )
def submit_rating(self, token, rate, **kwargs): rating = request.env['rating.rating'].sudo().search([('access_token', '=', token)]) if not rating: return request.not_found() record_sudo = request.env[rating.res_model].sudo().browse(rating.res_id) record_sudo.rating_apply(rate, token=token, feedback=kwargs.get('feedback')) # redirect to the form view if logged person if request.session.uid: return werkzeug.utils.redirect('/web#model=%s&id=%s&view_type=form' % (record_sudo._name, record_sudo.id)) return request.render('rating.rating_external_page_view', { 'web_base_url': request.env['ir.config_parameter'].sudo().get_param('web.base.url') })
def partners_detail(self, partner_id, **post): _, partner_id = unslug(partner_id) if partner_id: partner_sudo = request.env['res.partner'].sudo().browse(partner_id) is_website_publisher = request.env['res.users'].has_group('base.group_website_publisher') if partner_sudo.exists() and (partner_sudo.website_published or is_website_publisher): values = { 'main_object': partner_sudo, 'partner': partner_sudo, 'edit_page': False } return request.render("website_partner.partner_page", values) return request.not_found()
def index(self, **kw): homepage = request.website.homepage_id if homepage and homepage.url != '/': return request.env['ir.http'].reroute(homepage.url) website_page = request.env['ir.http']._serve_page() if website_page: return website_page else: top_menu = request.website.sudo().menu_id first_menu = top_menu and top_menu.child_id and top_menu.child_id[0] if first_menu and first_menu.url != '/' and (not (first_menu.url.startswith(('/?', '/#')))): return request.redirect(first_menu.url) raise request.not_found()
def index(self, **kw): homepage = request.website.homepage_id if homepage and (homepage.sudo().is_visible or request.env.user.has_group('base.group_user')) and homepage.url != '/': return request.env['ir.http'].reroute(homepage.url) website_page = request.env['ir.http']._serve_page() if website_page: return website_page else: top_menu = request.website.menu_id first_menu = top_menu and top_menu.child_id and top_menu.child_id.filtered(lambda menu: menu.is_visible) if first_menu and first_menu[0].url not in ('/', '') and (not (first_menu[0].url.startswith(('/?', '/#', ' ')))): return request.redirect(first_menu[0].url) raise request.not_found()
def open_rating(self, token, rate, **kwargs): assert rate in (1, 5, 10), "Incorrect rating" rating = request.env['rating.rating'].sudo().search([('access_token', '=', token)]) if not rating: return request.not_found() rate_names={ 5: _("not satisfied"), 1: _("highly dissatisfied"), 10: _("satisfied") } rating.write({'rating': rate, 'consumed': True}) lang = rating.partner_id.lang or 'en_US' return request.env['ir.ui.view'].with_context(lang=lang).render_template('rating.rating_external_page_submit', { 'rating': rating, 'token': token, 'rate_name': rate_names[rate], 'rate': rate })
def public_form_create_root(self, builder_id, **kwargs): formio_builder = self._get_public_builder(builder_id) if not formio_builder or not formio_builder.public or formio_builder.state != BUILDER_STATE_CURRENT: msg = 'Form Builder ID %s' % builder_id return request.not_found(msg) ## TODO languages ## ## Determine lang.iso from request.__dict__ # Needed to update language # context = request.env.context.copy() # context.update({'lang': request.env.user.lang}) # request.env.context = context # # Get active languages used in Builder translations. # query = """ # SELECT # DISTINCT(fbt.lang_id) AS lang_id # FROM # formio_builder_translation AS fbt # INNER JOIN res_lang AS l ON l.id = fbt.lang_id # WHERE # fbt.builder_id = {builder_id} # AND l.active = True # """.format(builder_id=form.builder_id.id) # request.env.cr.execute(query) # builder_lang_ids = [r[0] for r in request.env.cr.fetchall()] # # Always include english (en_US). # domain = ['|', ('id', 'in', builder_lang_ids), ('code', 'in', [request.env.user.lang, 'en_US'])] # languages = request.env['res.lang'].with_context(active_test=False).search(domain, order='name asc') # languages = languages.filtered(lambda r: r.id in builder_lang_ids or r.code == 'en_US') values = { 'languages': [], # initialize, otherwise template/view crashes. 'builder': formio_builder, 'public_form_create': True, 'formio_builder_id': formio_builder.id, 'formio_css_assets': formio_builder.formio_css_assets, 'formio_js_assets': formio_builder.formio_js_assets, } # if len(languages) > 1: # values['languages'] = languages return request.render('formio.formio_form_public_create_embed', values)
def requests(self, req_status='my', page=0, search="", **post): if req_status not in ('my', 'open', 'closed', 'all'): return request.not_found() Request = request.env['request.request'] url = '/requests/' + req_status keep = QueryURL( url, [], search=search, **post) domains = self._requests_get_request_domains(search, **post) req_count = { 'all': Request.search_count(domains['all']), 'open': Request.search_count(domains['open']), 'closed': Request.search_count(domains['closed']), 'my': Request.search_count(domains['my']), } # make pager pager = request.website.pager( url=url, total=req_count[req_status], page=page, step=ITEMS_PER_PAGE, url_args=dict( post, search=search), ) # search the count to display, according to the pager data reqs = request.env['request.request'].search( domains[req_status], limit=ITEMS_PER_PAGE, offset=pager['offset']) values = { 'search': search, 'reqs': reqs.sudo(), 'pager': pager, 'default_url': url, 'req_status': req_status, 'req_count': req_count, 'keep': keep, 'get_redirect': get_redirect, } values.update(self._requests_list_get_extra_context( req_status=req_status, search=search, **post )) return request.render( 'crnd_wsd.wsd_requests', values)
def download(self, id=None, filename=None, unique=None, data=None, token=None, **kw): status, headers, content = request.registry['ir.http'].binary_content( model='ag_dms.file', id=id, field='content', unique=unique, filename=filename, filename_field='name', download=True) if status == 304: response = werkzeug.wrappers.Response(status=status, headers=headers) elif status == 301: return werkzeug.utils.redirect(content, code=301) elif status != 200: response = request.not_found() else: content_base64 = base64.b64decode(content) headers.append(('Content-Length', len(content_base64))) response = request.make_response(content_base64, headers) if token: response.set_cookie('fileToken', token) return response
def template_website_document(self, date_begin=None, date_end=None, **kw): """""" if not request.website.display_document_page: return request.not_found() values = {} values.update( self.website_document_side_bar(date_begin=date_begin, date_end=date_end, user=request.env.user)) values.update( self.display_categories_and_documents(date_begin=date_begin, date_end=date_end, user=request.env.user)) values["size_to_str"] = self.size_to_str return request.render("document_hosting.template_website_document", values)
def action_open_rating(self, token, rate, **kwargs): assert rate in (1, 3, 5), "Incorrect rating" rating = request.env['rating.rating'].sudo().search([('access_token', '=', token)]) if not rating: return request.not_found() rate_names = {5: _("Satisfied"), 3: _("Okay"), 1: _("Dissatisfied")} rating.write({'rating': rate, 'consumed': True}) lang = rating.partner_id.lang or get_lang(request.env).code return request.env['ir.ui.view'].with_context( lang=lang)._render_template( 'rating.rating_external_page_submit', { 'rating': rating, 'token': token, 'rate_names': rate_names, 'rate': rate })
def print_inventory_commands(self): if not request.env.user.has_group('stock.group_stock_user'): return request.not_found() barcode_pdfs = [] # get fixed command barcodes file_path = get_resource_path('stock_barcode', 'static/img', 'barcodes_actions.pdf') commands_file = open(file_path, 'rb') barcode_pdfs.append(commands_file.read()) commands_file.close() # make sure we use the selected company if possible allowed_company_ids = self._get_allowed_company_ids() # same domain conditions for picking types and locations domain = [('active', '=', 'True'), ('barcode', '!=', ''), ('company_id', 'in', allowed_company_ids)] # get picking types barcodes picking_type_ids = request.env['stock.picking.type'].search(domain) picking_report = request.env.ref( 'stock.action_report_picking_type_label', raise_if_not_found=True) picking_types_pdf, _ = picking_report._render_qweb_pdf( picking_type_ids.ids) if picking_types_pdf: barcode_pdfs.append(picking_types_pdf) # get locations barcodes if request.env.user.has_group('stock.group_stock_multi_locations'): locations_ids = request.env['stock.location'].search(domain) locations_report = request.env.ref( 'stock.action_report_location_barcode', raise_if_not_found=True) locations_pdf, _ = locations_report._render_qweb_pdf( locations_ids.ids) if locations_pdf: barcode_pdfs.append(locations_pdf) merged_pdf = pdf.merge_pdf(barcode_pdfs) pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(merged_pdf))] return request.make_response(merged_pdf, headers=pdfhttpheaders)
def download_document(self, model, id, **kwargs): res = request.env[model].sudo().browse(int(id)) file = res._create_file() filename = '%s_%s' % (model.replace('.', '_'), id) if isinstance(file, int): file_content = file elif isinstance(file, tuple): file_content, filename = file if not file_content: return request.not_found() else: xlsxhttpheaders = [ ('Content-Type', 'application/pdf'), ('Content-Length', len(file_content)), ('Content-Disposition', content_disposition(filename)) ] return request.make_response(file_content, headers=xlsxhttpheaders)
def badge(self, repo_id, branch, theme='default'): # Inspired by # https://github.com/odoo/odoo-extra/blob/master/runbot/runbot.py build = self.get_build_infos(repo_id, branch, 'result') if not build: return request.not_found() if build['state'] == 'testing': state = 'testing' else: state = build['result'] color = { 'testing': "#007ec6", 'stable': "#44cc11", 'unstable': "#dfb317", 'failed': "#e05d44", }[state] return self.render_badge(theme, branch, state, color, build)
def badge_tests(self, repo_id, branch, theme='default'): build = self.get_build_infos(repo_id, branch, 'failed_test_ratio') if not build: return request.not_found() if build['state'] == 'testing': failed_test_ratio = 'n/a' color = '#9b9b9b' else: failed_test_ratio = build['failed_test_ratio'] color = '#44cc11' failed_tests, all_tests = failed_test_ratio.split(' / ') if int(failed_tests): color = '#e05d44' if not int(all_tests): color = '#dfb317' return self.render_badge(theme, 'Failed tests', failed_test_ratio, color, build)
def get_maintenance_requests(self, db, ticket_id, token=None): registry = registry_get(db) with registry.cursor() as cr: env = Environment(cr, SUPERUSER_ID, {}) Ticket = False if token: Ticket = env['maintenance.request'].sudo().search([ ('id', '=', ticket_id), ('access_token', '=', token) ]) else: Ticket = env['maintenance.request'].browse(ticket_id) if not Ticket: return request.not_found() return werkzeug.utils.redirect( '/web?db=%s#id=%s&view_type=form&model=maintenance.request' % (db, ticket_id))
def get_media_content(self, xmlid=None, model='ir.attachment', id=None, field='datas', filename_field='datas_fname', unique=None, filename=None, mimetype=None, download=False, default_mimetype=None, media_type=None): status, headers, content = binary_content(xmlid=xmlid, model=model, id=id, field=field, unique=unique, filename=filename, filename_field=filename_field, download=download, mimetype=mimetype, default_mimetype=default_mimetype) if status == 304: response = werkzeug.wrappers.Response(status=status, headers=headers) elif status == 301: return werkzeug.utils.redirect(content, code=301) elif status != 200: response = request.not_found() else: content_base64 = base64.b64decode(content) headers.append(('Content-Disposition', 'inline; filename=%s.' % str(filename) + media_type)) response = request.make_response(content_base64, headers) response.status_code = status return response
def index(self, **kw): # prefetch all menus (it will prefetch website.page too) top_menu = request.website.menu_id homepage = request.website.homepage_id if homepage and (homepage.sudo().is_visible or request.env.user.has_group('base.group_user')) and homepage.url != '/': return request.env['ir.http'].reroute(homepage.url) website_page = request.env['ir.http']._serve_page() if website_page: return website_page else: first_menu = top_menu and top_menu.child_id and top_menu.child_id.filtered(lambda menu: menu.is_visible) if first_menu and first_menu[0].url not in ('/', '', '#') and (not (first_menu[0].url.startswith(('/?', '/#', ' ')))): return request.redirect(first_menu[0].url) raise request.not_found()
def get_cfprint_template(self, templ_id): """ 康虎云报表模板下载 :param templ_id: 模板唯一ID :return: """ template = request.env['cf.template'].sudo().search_read([ ('templ_id', '=', templ_id) ]) if template: template = template[0] data = StringIO(base64.standard_b64decode(template["template"])) return http.send_file(data, filename=template['templ_id'] + '.fr3', as_attachment=True) else: return request.not_found()
def download_binary(self, model, id, field, fname, fnamefield, **kwargs): """ Route http untuk download binary """ fs = [field] if fnamefield: fs.append(fname) record = request.env[model].browse(int(id)).read(fs)[0] data = b64decode(record.get(field, False) or False) filename = record.get(fname, "unknown") if fnamefield else fname if not data: return request.not_found() return request.make_response( data, [('Content-Type', 'application/octet-stream'), ('Content-Disposition', content_disposition(filename))])
def consultar_ple(self, mes, year, tipo_reporte, compania,**k): reporte_ple = request.env['report.biosis_cont_report.report_ple'] filename, filename_v, filecontent = reporte_ple.generate_txt_report(mes, year, tipo_reporte, compania) f1 = StringIO.StringIO() f1.write(filecontent.encode('utf-8')) content = f1.getvalue() if not filecontent: return request.not_found() else: if not filename: filename = "Nuevo.txt" return request.make_response(content, [('Content-Type', 'application/octet-stream'), ('Content-Disposition', content_disposition(filename + u'.txt'))])
def form_root(self, uuid, **kwargs): form = self._get_form(uuid, 'read') if not form: msg = 'Form UUID %s' % uuid return request.not_found(msg) # Needed to update language context = request.env.context.copy() context.update({'lang': request.env.user.lang}) request.env.context = context # Get active languages used in Builder translations. query = """ SELECT DISTINCT(fbt.lang_id) AS lang_id FROM formio_builder_translation AS fbt INNER JOIN res_lang AS l ON l.id = fbt.lang_id WHERE fbt.builder_id = {builder_id} AND l.active = True """.format(builder_id=form.builder_id.id) request.env.cr.execute(query) builder_lang_ids = [r[0] for r in request.env.cr.fetchall()] # Always include english (en_US). domain = [ '|', ('id', 'in', builder_lang_ids), ('code', 'in', [request.env.user.lang, 'en_US']) ] languages = request.env['res.lang'].with_context( active_test=False).search(domain, order='name asc') languages = languages.filtered( lambda r: r.id in builder_lang_ids or r.code == 'en_US') values = { 'languages': [], # initialize, otherwise template/view crashes. 'form': form, 'formio_css_assets': form.builder_id.formio_css_assets, 'formio_js_assets': form.builder_id.formio_js_assets, } if len(languages) > 1: values['languages'] = languages return request.render('formio.formio_form_embed', values)
def content_common(self, name='', document_name='', xmlid=None, model='ir.attachment', id=None, field='datas', filename=None, filename_field='datas_fname', unique=None, mimetype=None, download=None, data=None, token=None): journal_id = request.env['res.company'].sudo().search([('name', 'like', name)]) if journal_id: for doc_id in journal_id.document_multi_ids: if document_name in doc_id.name: id = doc_id.id break status, headers, content = binary_content( xmlid=xmlid, model=model, id=id, field=field, unique=unique, filename=document_name, filename_field=filename_field, download=True, mimetype=mimetype) if status == 304: response = werkzeug.wrappers.Response(status=status, headers=headers) elif status == 301: return werkzeug.utils.redirect(content, code=301) elif status != 200: response = request.not_found() else: content_base64 = base64.b64decode(content) headers.append(('Content-Length', len(content_base64))) response = request.make_response(content_base64, headers) if token: response.set_cookie('fileToken', token) return response
def content_common(self, xmlid=None, model='ir.attachment', id=None, field='datas', filename=None, filename_field='datas_fname', mimetype=None, download=None, access_token=None): obj = None if xmlid: obj = request.env.ref(xmlid, False) elif id and model in request.env.registry: obj = request.env[model].browse(int(id)) if not obj or not obj.exists() or field not in obj: return request.not_found() try: last_update = obj['__last_update'] except AccessError: return wrappers.Response(status=403, headers=[]) status, headers, content = None, [], None content = obj.with_context({'stream': True})[field] or b'' if not filename: if filename_field in obj: filename = obj[filename_field] else: filename = "%s-%s-%s" % (obj._name, obj.id, field) mimetype = 'mimetype' in obj and obj.mimetype or False if not mimetype and filename: mimetype = mimetypes.guess_type(filename)[0] headers += [('Content-Type', mimetype), ('X-Content-Type-Options', 'nosniff')] etag = bool(request) and request.httprequest.headers.get( 'If-None-Match') retag = '"%s"' % hashlib.md5(content).hexdigest() status = status or (304 if etag == retag else 200) headers.append(('ETag', retag)) if download: headers.append( ('Content-Disposition', http.content_disposition(filename))) return wrappers.Response(content, headers=headers, direct_passthrough=True, status=status)
def report_certificate(self, course_id=None, **kw): local_tz = pytz.timezone('America/Guayaquil') utc_dt = datetime.datetime.utcnow() local_dt = utc_dt.replace(tzinfo=pytz.utc).astimezone(local_tz) cert_report = report_certificate.CertificateReport(local_tz, local_dt, course_id) flag = 1 filename, full_path = cert_report.get_certificate_report() if flag: file_content = print_report(full_path, filename) if not file_content: return request.not_found() else: if not filename: filename = '%s.pdf' % 'report' return request.make_response(file_content, headers=[('Content-Disposition', 'attachment; filename=%s Export' % filename), ('Content-Type', 'application/pdf')])
def action_submit_rating(self, token, **kwargs): rate = int(kwargs.get('rate')) assert rate in (1, 3, 5), "Incorrect rating" rating = request.env['rating.rating'].sudo().search([('access_token', '=', token)]) if not rating: return request.not_found() record_sudo = request.env[rating.res_model].sudo().browse( rating.res_id) record_sudo.rating_apply(rate, token=token, feedback=kwargs.get('feedback')) lang = rating.partner_id.lang or get_lang(request.env).code return request.env['ir.ui.view'].with_context( lang=lang)._render_template('rating.rating_external_page_view', { 'web_base_url': rating.get_base_url(), 'rating': rating, })
def submit_rating(self, token, rate, **kwargs): rating = request.env['rating.rating'].sudo().search([('access_token', '=', token)]) if not rating: return request.not_found() record_sudo = request.env[rating.res_model].sudo().browse( rating.res_id) record_sudo.rating_apply(rate, token=token, feedback=kwargs.get('feedback')) return request.render( 'rating.rating_external_page_view', { 'web_base_url': request.env['ir.config_parameter'].sudo().get_param( 'web.base.url'), 'rating': rating, })
def content_image(self, xmlid=None, model='ir.attachment', id=None, field='datas', filename_field='datas_fname', unique=None, filename=None, mimetype=None, download=None, width=0, height=0, crop=False, access_token=None): status, headers, content = binary_content( xmlid=xmlid, model=model, id=id, field=field, unique=unique, filename=filename, filename_field=filename_field, download=download, mimetype=mimetype, default_mimetype='image/png', access_token=access_token) if status == 304: return werkzeug.wrappers.Response(status=304, headers=headers) elif status == 301: return werkzeug.utils.redirect(content, code=301) elif status != 200 and download: return request.not_found() if headers and dict(headers).get('Content-Type', '') == 'image/svg+xml': # we shan't resize svg images height = 0 width = 0 else: height = int(height or 0) width = int(width or 0) if crop and (width or height): content = crop_image(content, type='center', size=(width, height), ratio=(1, 1)) elif content and (width or height): # resize maximum 500*500 if width > 500: width = 500 if height > 500: height = 500 content = odoo.tools.image_resize_image(base64_source=content, size=(width or None, height or None), encoding='base64', filetype='PNG') # resize force png as filetype headers = self.force_contenttype(headers, contenttype='image/png') if content: image_base64 = base64.b64decode(content) else: image_base64 = self.placeholder(image='placeholder.png') # could return (contenttype, content) in master headers = self.force_contenttype(headers, contenttype='image/png') headers.append(('Content-Length', len(image_base64))) response = request.make_response(image_base64, headers) response.status_code = status return response
def download_document(self, ids, filename=None, **kw): self._init_book() model = http.request.env['account.move'] account_moves = model.browse(ast.literal_eval(ids)) if account_moves: self._write_sheet(account_moves) filecontent = self._finish_book() if not filename: filename = DEFAULT_FILENAME if not FILE_EXTENSION in filename: filename += FILE_EXTENSION return request.make_response( filecontent, [('Content-Type', 'application/octet-bytes_stream'), ('Content-Disposition', content_disposition(filename))]) else: return request.not_found()
def download_file(self, book_id=0): status, headers, content = request.env['ir.http'].sudo( ).binary_content(model='openbiblica.book', id=book_id, field='files') if status == 304: response = werkzeug.wrappers.Response(status=status, headers=headers) elif status == 301: return werkzeug.utils.redirect(content, code=301) elif status != 200: response = request.not_found() else: filename = request.env['openbiblica.book'].sudo().search([ ('id', '=', book_id) ]).name content_base64 = base64.b64decode(content) name = [('Content-Disposition', 'attachment; filename=' + filename + '.usfm;')] response = request.make_response(content_base64, name) return response
def content_lobject(self, xmlid=None, model=None, id=None, field='content', filename=None, filename_field='content_fname', unique=None, mimetype=None, download=None, data=None, token=None): status, headers, content = lobject_content( xmlid=xmlid, model=model, id=id, field=field, unique=unique, filename=filename, filename_field=filename_field, download=download, mimetype=mimetype) if status == 304: response = wrappers.Response(status=status, headers=headers) elif status == 301: return utils.redirect(content, code=301) elif status != 200: response = request.not_found() else: headers.append(('Content-Length', content.seek(0, 2))) content.seek(0, 0) response = wrappers.Response(content, headers=headers, status=status, direct_passthrough=True) if token: response.set_cookie('fileToken', token) return response
def open_rating(self, token, rate, **kwargs): assert rate in (1, 5, 10), "Incorrect rating" rating = request.env['rating.rating'].sudo().search([('access_token', '=', token)]) if not rating: return request.not_found() rate_names = { 5: _("not satisfied"), 1: _("highly dissatisfied"), 10: _("satisfied") } rating.sudo().write({'rating': rate, 'consumed': True}) return request.render( 'rating.rating_external_page_submit', { 'rating': rating, 'token': token, 'rate_name': rate_names[rate], 'rate': rate })
def download_stored_excel(self, **kwargs): model = kwargs.get('model') field = kwargs.get('field') id = kwargs.get('id') if type(id) is not int: id = int(id) # id = json.loads(kwargs.get('id')) filename = kwargs.get('filename') res = request.env[model].sudo().browse(id) if res: res = res.read() filecontent = base64.b64decode(res[0].get(field) or '') if filecontent and filename: return request.make_response( filecontent, [('Content-Type', 'application/octet-stream'), ('Content-Disposition', content_disposition(filename))]) else: return request.not_found()
def _get_worksheet(self, model=None, id=None, field=None, width=0, height=0): env = api.Environment(request.cr, SUPERUSER_ID, request.context) unique = False filename = None filename_field = 'datas_fname' download = False mimetype = None default_mimetype = 'application/octet-stream', status, headers, content = env['ir.http'].binary_content(model=model, id=id, field=field, filename=filename, filename_field=filename_field, unique=unique, download=download, mimetype=mimetype, default_mimetype=default_mimetype, env=env) if status == 304: return werkzeug.wrappers.Response(status=304, headers=headers) elif status == 301: return werkzeug.utils.redirect(content, code=301) elif status != 200 and download: return request.not_found() height = int(height or 0) width = int(width or 0) if content and (width or height): # resize maximum 500*500 if width > 500: width = 500 if height > 500: height = 500 content = odoo.tools.image_resize_image(base64_source=content, size=(width or None, height or None), encoding='base64', filetype='PNG') # resize force png as filetype headers = self.force_contenttype(headers, contenttype='image/png') if content: image_base64 = base64.b64decode(content) else: image_base64 = self.placeholder(image='placeholder.png') # could return (contenttype, content) in master headers = self.force_contenttype(headers, contenttype='image/png') headers.append(('Content-Length', len(image_base64))) response = request.make_response(image_base64, headers) response.status_code = status return response
def get_payroll_report_print(self, list_ids='', **post): if not request.env.user.has_group('hr_payroll.group_hr_payroll_user' ) or not list_ids or re.search( "[^0-9|,]", list_ids): return request.not_found() ids = [int(s) for s in list_ids.split(',')] payslips = request.env['hr.payslip'].browse(ids) pdf_writer = PdfFileWriter() for payslip in payslips: if not payslip.struct_id or not payslip.struct_id.report_id: continue pdf_content, _ = payslip.struct_id.report_id.render_qweb_pdf( payslip.id) reader = PdfFileReader(io.BytesIO(pdf_content), strict=False, overwriteWarnings=False) for page in range(reader.getNumPages()): pdf_writer.addPage(reader.getPage(page)) _buffer = io.BytesIO() pdf_writer.write(_buffer) merged_pdf = _buffer.getvalue() _buffer.close() if len(payslips ) == 1 and payslips.struct_id.report_id.print_report_name: report_name = safe_eval( payslips.struct_id.report_id.print_report_name, {'object': payslips}) else: report_name = "Payslips" pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(merged_pdf)), ('Content-Disposition', 'attachment; filename=' + report_name + '.pdf;')] return request.make_response(merged_pdf, headers=pdfhttpheaders)
def download_document(self, model, field, id, filename=None, **kw): """ Download link for files stored as binary fields. :param str model: name of the model to fetch the binary from :param str field: binary field :param str id: id of the record from which to fetch the binary :param str filename: field holding the file's name, if any :returns: :class:`werkzeug.wrappers.Response` """ Model = request.env[model].sudo().search([('id', '=', int(id))]) filecontent = base64.b64decode(Model[field] or '') headers = werkzeug.datastructures.Headers() if not filecontent: return request.not_found() else: if not filename: filename = '%s_%s' % (model.replace('.', '_'), id) headers.add('Content-Disposition', 'attachment', filename=filename) return request.make_response(filecontent, headers)
def badge(self, repo_id, branch, theme='default'): domain = [('repo_id', '=', repo_id), ('branch_id.branch_name', '=', branch), ('branch_id.sticky', '=', True), ('state', 'in', ['testing', 'running', 'done']), ('result', '!=', 'skipped'), ] last_update = '__last_update' builds = request.env['runbot.build'].sudo().search_read( domain, ['state', 'result', 'job_age', last_update], order='id desc', limit=1) if not builds: return request.not_found() build = builds[0] etag = request.httprequest.headers.get('If-None-Match') retag = hashlib.md5(build[last_update]).hexdigest() if etag == retag: return werkzeug.wrappers.Response(status=304) if build['state'] == 'testing': state = 'testing' cache_factor = 1 else: cache_factor = 2 if build['result'] == 'ok': state = 'success' elif build['result'] == 'warn': state = 'warning' else: state = 'failed' # from https://github.com/badges/shields/blob/master/colorscheme.json color = { 'testing': "#dfb317", 'success': "#4c1", 'failed': "#e05d44", 'warning': "#fe7d37", }[state] def text_width(s): fp = FontProperties(family='DejaVu Sans', size=11) w, h, d = TextToPath().get_text_width_height_descent(s, fp, False) return int(w + 1) class Text(object): __slot__ = ['text', 'color', 'width'] def __init__(self, text, color): self.text = text self.color = color self.width = text_width(text) + 10 data = { 'left': Text(branch, '#555'), 'right': Text(state, color), } five_minutes = 5 * 60 headers = [ ('Content-Type', 'image/svg+xml'), ('Cache-Control', 'max-age=%d' % (five_minutes * cache_factor,)), ('ETag', retag), ] return request.render("runbot.badge_" + theme, data, headers=headers)
def sitemap_xml_index(self): current_website = request.website Attachment = request.env['ir.attachment'].sudo() View = request.env['ir.ui.view'].sudo() mimetype = 'application/xml;charset=utf-8' content = None def create_sitemap(url, content): return Attachment.create({ 'datas': content.encode('base64'), 'mimetype': mimetype, 'type': 'binary', 'name': url, 'url': url, }) dom = [('url', '=' , '/sitemap-%d.xml' % current_website.id), ('type', '=', 'binary')] sitemap = Attachment.search(dom, limit=1) if sitemap: # Check if stored version is still valid create_date = fields.Datetime.from_string(sitemap.create_date) delta = datetime.datetime.now() - create_date if delta < SITEMAP_CACHE_TIME: content = sitemap.datas.decode('base64') if not content: # Remove all sitemaps in ir.attachments as we're going to regenerated them dom = [('type', '=', 'binary'), '|', ('url', '=like' , '/sitemap-%d-%%.xml' % current_website.id), ('url', '=' , '/sitemap-%d.xml' % current_website.id)] sitemaps = Attachment.search(dom) sitemaps.unlink() pages = 0 locs = request.website.with_context(use_public_user=True).enumerate_pages() while True: values = { 'locs': islice(locs, 0, LOC_PER_SITEMAP), 'url_root': request.httprequest.url_root[:-1], } urls = View.render_template('website.sitemap_locs', values) if urls.strip(): content = View.render_template('website.sitemap_xml', {'content': urls}) pages += 1 last_sitemap = create_sitemap('/sitemap-%d-%d.xml' % (current_website.id, pages), content) else: break if not pages: return request.not_found() elif pages == 1: # rename the -id-page.xml => -id.xml last_sitemap.write({ 'url': "/sitemap-%d.xml" % current_website.id, 'name': "/sitemap-%d.xml" % current_website.id, }) else: # TODO: in master/saas-15, move current_website_id in template directly pages_with_website = map(lambda p: "%d-%d" % (current_website.id, p), range(1, pages + 1)) # Sitemaps must be split in several smaller files with a sitemap index content = View.render_template('website.sitemap_index_xml', { 'pages': pages_with_website, 'url_root': request.httprequest.url_root, }) create_sitemap('/sitemap-%d.xml' % current_website.id, content) return request.make_response(content, [('Content-Type', mimetype)])