Exemple #1
0
    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", "mimetype", "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.move.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':
            template_ids = request.env['product.product'].sudo().browse(
                purchased_products).mapped('product_tmpl_id').ids
            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 = io.BytesIO(base64.standard_b64decode(attachment["datas"]))
            # we follow what is done in ir_http's binary_content for the extension management
            extension = os.path.splitext(attachment["name"] or '')[1]
            extension = extension if extension else mimetypes.guess_extension(
                attachment["mimetype"] or '')
            filename = attachment['name']
            filename = filename if os.path.splitext(
                filename)[1] else filename + extension
            return http.send_file(data, filename=filename, as_attachment=True)
        else:
            return request.not_found()
Exemple #2
0
 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()
Exemple #3
0
    def view(self, db, token, action, id, view='calendar'):
        registry = registry_get(db)
        with registry.cursor() as cr:
            # Since we are in auth=none, create an env with SUPERUSER_ID
            env = Environment(cr, SUPERUSER_ID, {})
            attendee = env['calendar.attendee'].search([('access_token', '=', token), ('event_id', '=', int(id))])
            if not attendee:
                return request.not_found()
            timezone = attendee.partner_id.tz
            lang = attendee.partner_id.lang or 'en_US'
            event = env['calendar.event'].with_context(tz=timezone, lang=lang).browse(int(id))

            # If user is internal and logged, redirect to form view of event
            # otherwise, display the simplifyed web page with event informations
            if request.session.uid and request.env['res.users'].browse(request.session.uid).user_has_groups('base.group_user'):
                return werkzeug.utils.redirect('/web?db=%s#id=%s&view_type=form&model=calendar.event' % (db, id))

            # NOTE : we don't use request.render() since:
            # - we need a template rendering which is not lazy, to render before cursor closing
            # - we need to display the template in the language of the user (not possible with
            #   request.render())
            response_content = env['ir.ui.view'].with_context(lang=lang).render_template(
                'calendar.invitation_page_anonymous', {
                    'event': event,
                    'attendee': attendee,
                })
            return request.make_response(response_content, headers=[('Content-Type', 'text/html')])
Exemple #4
0
 def download_document(self, file, filename):
     if not file:
         return request.not_found()
     else:
         return request.make_response(
             file, [('Content-Type', 'application/octet-stream'),
                    ('Content-Disposition', content_disposition(filename))])
Exemple #5
0
    def view_meeting(self, token, id, **kwargs):
        attendee = request.env['calendar.attendee'].sudo().search([
            ('access_token', '=', token), ('event_id', '=', int(id))
        ])
        if not attendee:
            return request.not_found()
        timezone = attendee.partner_id.tz
        lang = attendee.partner_id.lang or get_lang(request.env).code
        event = request.env['calendar.event'].with_context(
            tz=timezone, lang=lang).sudo().browse(int(id))

        # If user is internal and logged, redirect to form view of event
        # otherwise, display the simplifyed web page with event informations
        if request.session.uid and request.env['res.users'].browse(
                request.session.uid).user_has_groups('base.group_user'):
            return werkzeug.utils.redirect(
                '/web?db=%s#id=%s&view_type=form&model=calendar.event' %
                (request.env.cr.dbname, id))

        # NOTE : we don't use request.render() since:
        # - we need a template rendering which is not lazy, to render before cursor closing
        # - we need to display the template in the language of the user (not possible with
        #   request.render())
        response_content = request.env['ir.ui.view'].with_context(
            lang=lang)._render_template('calendar.invitation_page_anonymous', {
                'event': event,
                'attendee': attendee,
            })
        return request.make_response(response_content,
                                     headers=[('Content-Type', 'text/html')])
Exemple #6
0
 def action_submit_rating(self, token, **kwargs):
     rate = int(kwargs.get('rate'))
     assert rate in (1, 3, 5), "Incorrect rating"
     rating = request.env['helpdesk.ticket'].sudo().search([('access_token',
                                                             '=', token)])
     if not rating:
         return request.not_found()
     feedback = (kwargs.get('feedback'))
     rating.rating_last_value = float(rate)
     if feedback:
         message = plaintext2html(feedback)
     post_values = {
         'res_model': 'helpdesk.ticket',
         'res_id': rating.id,
         'message': feedback,
         'send_after_commit': False,
         'attachment_ids': False,  # will be added afterward
     }
     message = _message_post_helper(**post_values)
     lang = rating.partner_id.lang or get_lang(request.env).code
     return request.env['ir.ui.view'].with_context(
         lang=lang)._render_template(
             'helpdesk_basic.rating_external_page_view', {
                 'web_base_url':
                 request.env['ir.config_parameter'].sudo().get_param(
                     'web.base.url'),
                 'rating_value':
                 rating,
             })
Exemple #7
0
 def download_document(self, model, field, id, filename=None, **kw):
     """
     :param str filename: field holding the file's name, if any
     :returns: :class:`werkzeug.wrappers.Response`
     """
     Model = request.registry[model]
     cr, uid, context = request.cr, request.uid, request.context
     fields = [field]
     res = Model.read(cr, uid, [int(id)], fields, context)[0]
     # filecontent = base64.b64decode(res.get(field) or '')
     filecontent = res.get(field)
     print(filecontent)
     if not filecontent:
         return request.not_found()
     else:
         if not filename:
             filename = '%s_%s' % (model.replace('.', '_'), id)
         headers = [
             ('Content-Type', 'application/xml'),
             ('Content-Disposition', content_disposition(filename)),
             ('charset', 'utf-8'),
         ]
         return request.make_response(filecontent,
                                      headers=headers,
                                      cookies=None)
Exemple #8
0
 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(pycompat.to_text(content).encode('utf-8')).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)
             
Exemple #9
0
    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':
            template_ids = request.env['product.product'].sudo().browse(
                purchased_products).mapped('product_tmpl_id').ids
            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 = io.BytesIO(base64.standard_b64decode(attachment["datas"]))
            return http.send_file(data,
                                  filename=attachment['name'],
                                  as_attachment=True)
        else:
            return request.not_found()
Exemple #10
0
 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(
             'website.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()
Exemple #11
0
    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()
Exemple #12
0
    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()
Exemple #13
0
 def action_open_rating(self, token, rate, **kwargs):
     assert rate in (1, 3, 5), "Incorrect rating"
     rating = request.env['helpdesk.ticket'].sudo().search([('access_token',
                                                             '=', token)])
     if not rating:
         return request.not_found()
     rate_names = {
         5: _("satisfied"),
         3: _("not satisfied"),
         1: _("highly dissatisfied")
     }
     lang = rating.partner_id.lang or get_lang(request.env).code
     return request.env['ir.ui.view'].with_context(
         lang=lang)._render_template(
             'helpdesk_basic.rating_external_page_submit', {
                 'token': token,
                 'rate_names': rate_names,
                 'rate': rate
             })
Exemple #14
0
 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,
             })
Exemple #15
0
 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
             })
Exemple #16
0
 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.registry[model]
     cr, uid, context = request.cr, request.uid, request.context
     fields = [field]
     res = Model.read(cr, uid, [int(id)], fields, context)[0]
     filecontent = base64.b64decode(res.get(field) or '')
     if not filecontent:
         return request.not_found()
     else:
         if not filename:
             filename = '%s_%s' % (model.replace('.', '_'), id)
     return request.make_response(filecontent,
                         [('Content-Type', 'application/pdf'),
                          ('Content-Disposition', content_disposition(filename))])
Exemple #17
0
    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()

        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

            content = flectra.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







        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')
        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 content and (width or height):
            content = flectra.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        
Exemple #18
0
    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.sudo().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 = _(
                "%(car_name)s (driven from: %(date_start)s to %(date_end)s)",
                car_name=car_name,
                date_start=date_start,
                date_end=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)
Exemple #19
0
    def sitemap_xml_index(self, **kwargs):
        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': base64.b64encode(content),
                '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 = base64.b64decode(sitemap.datas)

        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.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-%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 = [
                    "%d-%d" % (current_website.id, p)
                    for p in 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)])