[IMP] website*: clean sitemap + add method to declare sitemap function.

Don't add useless routes or route that will return 404.
Improve generate function from ModelConverter to have a better management of
query_string.

Now we have an helper sitemap_qs2dom that will analyse the current route and
check if query string is plausible and if yes, generate a domain, when the
query_string don't seems to match the route, we return a Falsy domain.

Before this commit, if qs was /product/ipad, enumerate_page check for each
modelconverter of the route a name ilike '/product/ipad'.

Now we check all routes that contains product and one converter that match ipad
or routes that contains ipad and one converter that match product.

This commit a new way to declare the sitemap for a route.
    def sitemap_xx(env, rule, query_string):
        yield {'loc': '/my_url'}
    @http.route(..., sitemap=sitemap_xx)

    In this case, only the loc returned by this function will be in the sitemap
    for all rules.

    You can pass sitempa=False, if you don't want that route are into the sitemap
This commit is contained in:
Jeremy Kersten
2017-09-27 21:33:49 +02:00
parent 3d0d8b89d1
commit 1b52b00d2a
12 changed files with 168 additions and 61 deletions
+2 -2
View File
@@ -24,7 +24,7 @@ class AuthSignupHome(Home):
return http.redirect_with_hash(request.params.get('redirect'))
return response
@http.route('/web/signup', type='http', auth='public', website=True)
@http.route('/web/signup', type='http', auth='public', website=True, sitemap=False)
def web_auth_signup(self, *args, **kw):
qcontext = self.get_auth_signup_qcontext()
@@ -56,7 +56,7 @@ class AuthSignupHome(Home):
return request.render('auth_signup.signup', qcontext)
@http.route('/web/reset_password', type='http', auth='public', website=True)
@http.route('/web/reset_password', type='http', auth='public', website=True, sitemap=False)
def web_auth_reset_password(self, *args, **kw):
qcontext = self.get_auth_signup_qcontext()
+1 -1
View File
@@ -460,7 +460,7 @@ class Home(http.Controller):
def _login_redirect(self, uid, redirect=None):
return redirect if redirect else '/web'
@http.route('/web/login', type='http', auth="none")
@http.route('/web/login', type='http', auth="none", sitemap=False)
def web_login(self, redirect=None, **kw):
ensure_db()
request.params['login_success'] = False
+21 -6
View File
@@ -3,8 +3,8 @@
import logging
import traceback
import datetime
import os
import unittest
import werkzeug
import werkzeug.routing
@@ -17,12 +17,28 @@ from odoo.http import request
from odoo.tools import config
from odoo.exceptions import QWebException
from odoo.tools.safe_eval import safe_eval
from odoo.osv.expression import FALSE_DOMAIN
from odoo.addons.http_routing.models.ir_http import ModelConverter, _guess_mimetype
logger = logging.getLogger(__name__)
def sitemap_qs2dom(qs, route, field='name'):
""" Convert a query_string (can contains a path) to a domain"""
dom = []
if qs and qs.lower() not in route:
needles = qs.strip('/').split('/')
# needles will be altered and keep only element which one is not in route
# diff(from=['shop', 'product'], to=['shop', 'product', 'product']) => to=['product']
unittest.util.unorderable_list_difference(route.strip('/').split('/'), needles)
if len(needles) == 1:
dom = [(field, 'ilike', needles[0])]
else:
dom = FALSE_DOMAIN
return dom
class Http(models.AbstractModel):
_inherit = 'ir.http'
@@ -68,7 +84,7 @@ class Http(models.AbstractModel):
super(Http, cls)._add_dispatch_parameters(func)
if request.is_frontend and request.routing_iteration == 1:
request.website = request.website.with_context(request.context)
request.website = request.website.with_context(context)
@classmethod
def _get_languages(cls):
@@ -134,7 +150,6 @@ class Http(models.AbstractModel):
return False
@classmethod
def _handle_exception(cls, exception):
code = 500 # default code
@@ -223,11 +238,11 @@ class Http(models.AbstractModel):
class ModelConverter(ModelConverter):
def generate(self, uid, query=None, args=None):
def generate(self, uid, dom=None, args=None):
Model = request.env[self.model].sudo(uid)
domain = safe_eval(self.domain, (args or {}).copy())
if query:
domain.append((Model._rec_name, 'ilike', '%' + query + '%'))
if dom:
domain += dom
for record in Model.search_read(domain=domain, fields=['write_date', Model._rec_name]):
if record.get(Model._rec_name, False):
yield {'loc': (record['id'], record[Model._rec_name])}
+37 -13
View File
@@ -5,16 +5,17 @@ import inspect
import logging
import hashlib
import re
import unicodedata
from werkzeug import urls
from werkzeug.exceptions import NotFound
from odoo import api, fields, models, tools
from odoo.addons.http_routing.models.ir_http import slugify
from odoo.addons.website.models.ir_http import sitemap_qs2dom
from odoo.addons.portal.controllers.portal import pager
from odoo.tools import pycompat
from odoo.http import request
from odoo.osv.expression import FALSE_DOMAIN
from odoo.tools.translate import _
logger = logging.getLogger(__name__)
@@ -360,9 +361,25 @@ class Website(models.Model):
router = request.httprequest.app.get_db_router(request.db)
# Force enumeration to be performed as public user
url_set = set()
sitemap_endpoint_done = set()
for rule in router.iter_rules():
if 'sitemap' in rule.endpoint.routing:
if rule.endpoint in sitemap_endpoint_done:
continue
sitemap_endpoint_done.add(rule.endpoint)
func = rule.endpoint.routing['sitemap']
if func is False:
continue
for loc in func(self.env, rule, query_string):
yield loc
continue
if not self.rule_is_enumerable(rule):
continue
converters = rule._converters or {}
if query_string and not converters and (query_string not in rule.build([{}], append_unknown=False)[1]):
continue
@@ -370,12 +387,18 @@ class Website(models.Model):
# converters with a domain are processed after the other ones
convitems = sorted(
converters.items(),
key=lambda x: hasattr(x[1], 'domain') and (x[1].domain != '[]'))
key=lambda x: (hasattr(x[1], 'domain') and (x[1].domain != '[]'), rule._trace.index((True, x[0]))))
for (i, (name, converter)) in enumerate(convitems):
newval = []
for val in values:
query = i == len(convitems)-1 and query_string
for value_dict in converter.generate(uid=self.env.uid, query=query, args=val):
if query:
r = "".join([x[1] for x in rule._trace[1:] if not x[0]]) # remove model converter from route
query = sitemap_qs2dom(query, r)
if query == FALSE_DOMAIN:
continue
for value_dict in converter.generate(uid=self.env.uid, dom=query, args=val):
newval.append(val.copy())
value_dict[name] = value_dict['loc']
del value_dict['loc']
@@ -384,17 +407,18 @@ class Website(models.Model):
for value in values:
domain_part, url = rule.build(value, append_unknown=False)
page = {'loc': url}
for key, val in value.items():
if key.startswith('__'):
page[key[2:]] = val
if url in ('/sitemap.xml',):
continue
if url in url_set:
continue
url_set.add(url)
if not query_string or query_string.lower() in url.lower():
page = {'loc': url}
for key, val in value.items():
if key.startswith('__'):
page[key[2:]] = val
if url in ('/sitemap.xml',):
continue
if url in url_set:
continue
url_set.add(url)
yield page
yield page
# '/' already has a http.route & is in the routing_map so it will already have an entry in the xml
domain = [('url', '!=', '/')]
@@ -11,6 +11,7 @@ from odoo import fields
from odoo import http
from odoo.http import request
from odoo.addons.http_routing.models.ir_http import slug, unslug
from odoo.addons.website.models.ir_http import sitemap_qs2dom
from odoo.addons.portal.controllers.portal import CustomerPortal
from odoo.addons.website_partner.controllers.main import WebsitePartnerPage
@@ -179,6 +180,26 @@ class WebsiteAccount(CustomerPortal):
class WebsiteCrmPartnerAssign(WebsitePartnerPage):
_references_per_page = 40
def sitemap_partners(env, rule, qs):
if not qs or qs.lower() in '/partners':
yield {'loc': '/partners'}
Grade = env['res.partner.grade']
dom = [('website_published', '=', True)]
dom += sitemap_qs2dom(qs=qs, route='/partners/grade/', field=Grade._rec_name)
for grade in env['res.partner.grade'].search(dom):
loc = '/partners/grade/%s' % slug(grade)
if not qs or qs.lower() in loc:
yield {'loc': loc}
partners_dom = [('is_company', '=', True), ('grade_id', '!=', False), ('website_published', '=', True), ('grade_id.website_published', '=', True)]
dom += sitemap_qs2dom(qs=qs, route='/partners/country/')
countries = env['res.partner'].sudo().read_group(partners_dom, fields=['id', 'country_id'], groupby='country_id')
for country in countries:
loc = '/partners/country/%s' % slug(country['country_id'])
if not qs or qs.lower() in loc:
yield {'loc': loc}
@http.route([
'/partners',
'/partners/page/<int:page>',
@@ -191,7 +212,7 @@ class WebsiteCrmPartnerAssign(WebsitePartnerPage):
'/partners/grade/<model("res.partner.grade"):grade>/country/<model("res.country"):country>',
'/partners/grade/<model("res.partner.grade"):grade>/country/<model("res.country"):country>/page/<int:page>',
], type='http', auth="public", website=True)
], type='http', auth="public", website=True, sitemap=sitemap_partners)
def partners(self, country=None, grade=None, page=0, **post):
country_all = post.pop('country_all', False)
partner_obj = request.env['res.partner']
+22 -2
View File
@@ -4,7 +4,8 @@
import werkzeug.urls
from odoo import http
from odoo.addons.http_routing.models.ir_http import unslug
from odoo.addons.http_routing.models.ir_http import unslug, slug
from odoo.addons.website.models.ir_http import sitemap_qs2dom
from odoo.tools.translate import _
from odoo.http import request
@@ -12,6 +13,25 @@ from odoo.http import request
class WebsiteCustomer(http.Controller):
_references_per_page = 20
def sitemap_industry(env, rule, qs):
if not qs or qs.lower() in '/customers':
yield {'loc': '/customers'}
Industry = env['res.partner.industry']
dom = sitemap_qs2dom(qs, '/customers/industry', Industry._rec_name)
for industry in Industry.search(dom):
loc = '/customers/industry/%s' % slug(industry)
if not qs or qs.lower() in loc:
yield {'loc': loc}
dom = [('website_published', '=', True), ('assigned_partner_id', '!=', False)]
dom += sitemap_qs2dom(qs, '/customers/country')
countries = env['res.partner'].sudo().read_group(dom, ['id', 'country_id'], groupby='country_id')
for country in countries:
loc = '/customers/country/%s' % slug(country['country_id'])
if not qs or qs.lower() in loc:
yield {'loc': loc}
@http.route([
'/customers',
'/customers/page/<int:page>',
@@ -21,7 +41,7 @@ class WebsiteCustomer(http.Controller):
'/customers/industry/<model("res.partner.industry"):industry>/page/<int:page>',
'/customers/industry/<model("res.partner.industry"):industry>/country/<model("res.country"):country>',
'/customers/industry/<model("res.partner.industry"):industry>/country/<model("res.country"):country>/page/<int:page>',
], type='http', auth="public", website=True)
], type='http', auth="public", website=True, sitemap=sitemap_industry)
def customers(self, country=None, industry=None, page=0, **post):
Tag = request.env['res.partner.tag']
Partner = request.env['res.partner']
+7 -3
View File
@@ -13,7 +13,11 @@ from odoo.http import request
class WebsiteEventController(http.Controller):
@http.route(['/event', '/event/page/<int:page>', '/events', '/events/page/<int:page>'], type='http', auth="public", website=True)
def sitemap_event(env, rule, qs):
if not qs or qs.lower() in '/events':
yield {'loc': '/events'}
@http.route(['/event', '/event/page/<int:page>', '/events', '/events/page/<int:page>'], type='http', auth="public", website=True, sitemap=sitemap_event)
def events(self, page=1, **searches):
Event = request.env['event.event']
EventType = request.env['event.type']
@@ -133,7 +137,7 @@ class WebsiteEventController(http.Controller):
return request.render("website_event.index", values)
@http.route(['/event/<model("event.event"):event>/page/<path:page>'], type='http', auth="public", website=True)
@http.route(['/event/<model("event.event"):event>/page/<path:page>'], type='http', auth="public", website=True, sitemap=False)
def event_page(self, event, page, **post):
values = {
'event': event,
@@ -163,7 +167,7 @@ class WebsiteEventController(http.Controller):
target_url += '?enable_editor=1'
return request.redirect(target_url)
@http.route(['/event/<model("event.event"):event>/register'], type='http', auth="public", website=True)
@http.route(['/event/<model("event.event"):event>/register'], type='http', auth="public", website=True, sitemap=False)
def event_register(self, event, **post):
values = {
'event': event,
@@ -65,7 +65,7 @@ class WebsiteEventTrackController(http.Controller):
'dates': dates
}
@http.route(['''/event/<model("event.event", "[('website_track','=',1)]"):event>/agenda'''], type='http', auth="public", website=True)
@http.route(['''/event/<model("event.event"):event>/agenda'''], type='http', auth="public", website=True, sitemap=False)
def event_agenda(self, event, tag=None, **post):
days_tracks = collections.defaultdict(lambda: [])
for track in event.track_ids.sorted(lambda track: (track.date or '', bool(track.location_id))):
@@ -87,9 +87,9 @@ class WebsiteEventTrackController(http.Controller):
})
@http.route([
'''/event/<model("event.event", "[('website_track','=',1)]"):event>/track''',
'''/event/<model("event.event", "[('website_track','=',1)]"):event>/track/tag/<model("event.track.tag"):tag>'''
], type='http', auth="public", website=True)
'''/event/<model("event.event"):event>/track''',
'''/event/<model("event.event"):event>/track/tag/<model("event.track.tag"):tag>'''
], type='http', auth="public", website=True, sitemap=False)
def event_tracks(self, event, tag=None, **post):
searches = {}
if tag:
@@ -108,7 +108,7 @@ class WebsiteEventTrackController(http.Controller):
}
return request.render("website_event_track.tracks", values)
@http.route(['''/event/<model("event.event", "[('website_track_proposal','=',1)]"):event>/track_proposal'''], type='http', auth="public", website=True)
@http.route(['''/event/<model("event.event"):event>/track_proposal'''], type='http', auth="public", website=True, sitemap=False)
def event_track_proposal(self, event, **post):
return request.render("website_event_track.event_track_proposal", {'event': event})
+16 -7
View File
@@ -13,6 +13,7 @@ from datetime import datetime
from odoo import http, modules, SUPERUSER_ID, tools, _
from odoo.addons.http_routing.models.ir_http import slug
from odoo.addons.web.controllers.main import binary_content
from odoo.addons.website.models.ir_http import sitemap_qs2dom
from odoo.http import request
@@ -56,7 +57,7 @@ class WebsiteForum(http.Controller):
request.session['validation_email_sent'] = True
return True
@http.route('/forum/validate_email', type='http', auth='public', website=True)
@http.route('/forum/validate_email', type='http', auth='public', website=True, sitemap=False)
def validate_email(self, token, id, email, forum_id=None, **kwargs):
if forum_id:
try:
@@ -100,11 +101,19 @@ class WebsiteForum(http.Controller):
request.env['mail.message'].browse([int(kwargs.get('notification_id'))]).set_message_done()
return True
def sitemap_forum(env, rule, qs):
Forum = env['forum.forum']
dom = sitemap_qs2dom(qs, '/forum', Forum._rec_name)
for f in Forum.search(dom):
loc = '/forum/%s' % slug(f)
if not qs or qs.lower() in loc:
yield {'loc': loc}
@http.route(['/forum/<model("forum.forum"):forum>',
'/forum/<model("forum.forum"):forum>/page/<int:page>',
'''/forum/<model("forum.forum"):forum>/tag/<model("forum.tag", "[('forum_id','=',forum[0])]"):tag>/questions''',
'''/forum/<model("forum.forum"):forum>/tag/<model("forum.tag", "[('forum_id','=',forum[0])]"):tag>/questions/page/<int:page>''',
], type='http', auth="public", website=True)
'''/forum/<model("forum.forum"):forum>/tag/<model("forum.tag"):tag>/questions''',
'''/forum/<model("forum.forum"):forum>/tag/<model("forum.tag"):tag>/questions/page/<int:page>''',
], type='http', auth="public", website=True, sitemap=sitemap_forum)
def questions(self, forum, tag=None, page=1, filters='all', sorting=None, search='', post_type=None, **post):
Post = request.env['forum.post']
@@ -170,7 +179,7 @@ class WebsiteForum(http.Controller):
values = self._prepare_forum_values(forum=forum, searches=dict(), header={'is_guidelines': True}, **post)
return request.render("website_forum.faq", values)
@http.route('/forum/get_tags', type='http', auth="public", methods=['GET'], website=True)
@http.route('/forum/get_tags', type='http', auth="public", methods=['GET'], website=True, sitemap=False)
def tag_read(self, q='', l=25, **post):
data = request.env['forum.tag'].search_read(
domain=[('name', '=ilike', (q or '') + "%")],
@@ -179,7 +188,7 @@ class WebsiteForum(http.Controller):
)
return json.dumps(data)
@http.route(['/forum/<model("forum.forum"):forum>/tag', '/forum/<model("forum.forum"):forum>/tag/<string:tag_char>'], type='http', auth="public", website=True)
@http.route(['/forum/<model("forum.forum"):forum>/tag', '/forum/<model("forum.forum"):forum>/tag/<string:tag_char>'], type='http', auth="public", website=True, sitemap=False)
def tags(self, forum, tag_char=None, **post):
# build the list of tag first char, with their value as tag_char param Ex : [('All', 'all'), ('C', 'c'), ('G', 'g'), ('Z', z)]
first_char_tag = forum.get_tags_first_char()
@@ -569,7 +578,7 @@ class WebsiteForum(http.Controller):
return werkzeug.utils.redirect("/forum/%s/user/%d" % (slug(forum), partner.user_ids[0].id))
return werkzeug.utils.redirect("/forum/%s" % slug(forum))
@http.route(['/forum/user/<int:user_id>/avatar'], type='http', auth="public", website=True)
@http.route(['/forum/user/<int:user_id>/avatar'], type='http', auth="public", website=True, sitemap=False)
def user_avatar(self, user_id=0, **post):
status, headers, content = binary_content(model='res.users', id=user_id, field='image_medium', default_mimetype='image/png', env=request.env(user=SUPERUSER_ID))
@@ -7,6 +7,10 @@ from odoo.http import request
class WebsiteHrRecruitment(http.Controller):
def sitemap_jobs(env, rule, qs):
if not qs or qs.lower() in '/jobs':
yield {'loc': '/jobs'}
@http.route([
'/jobs',
'/jobs/country/<model("res.country"):country>',
@@ -16,7 +20,7 @@ class WebsiteHrRecruitment(http.Controller):
'/jobs/country/<model("res.country"):country>/office/<int:office_id>',
'/jobs/department/<model("hr.department"):department>/office/<int:office_id>',
'/jobs/country/<model("res.country"):country>/department/<model("hr.department"):department>/office/<int:office_id>',
], type='http', auth="public", website=True)
], type='http', auth="public", website=True, sitemap=sitemap_jobs)
def jobs(self, country=None, department=None, office_id=None, **kwargs):
env = request.env(context=dict(request.env.context, show_address=True, no_tag_br=True))
@@ -116,10 +116,9 @@ class MailGroup(http.Controller):
channel.sudo()._send_confirmation_email(partner_ids, unsubscribe)
return "email"
@http.route([
"/groups/<model('mail.channel'):group>",
"/groups/<model('mail.channel'):group>/page/<int:page>"
'''/groups/<model('mail.channel', "[('channel_type', '=', 'channel')]"):group>''',
'''/groups/<model('mail.channel'):group>/page/<int:page>'''
], type='http', auth="public", website=True)
def thread_headers(self, group, page=1, mode='thread', date_begin=None, date_end=None, **post):
if group.channel_type != 'channel':
@@ -154,7 +153,7 @@ class MailGroup(http.Controller):
return request.render('website_mail_channel.group_messages', values)
@http.route([
'''/groups/<model('mail.channel'):group>/<model('mail.message', "[('model','=','mail.channel'), ('res_id','=',group[0])]"):message>''',
'''/groups/<model('mail.channel', "[('channel_type', '=', 'channel')]"):group>/<model('mail.message', "[('model','=','mail.channel'), ('res_id','=',group[0])]"):message>''',
], type='http', auth="public", website=True)
def thread_discussion(self, group, message, mode='thread', date_begin=None, date_end=None, **post):
if group.channel_type != 'channel':
@@ -181,7 +180,7 @@ class MailGroup(http.Controller):
return request.render('website_mail_channel.group_message', values)
@http.route(
'''/groups/<model('mail.channel'):group>/<model('mail.message', "[('model','=','mail.channel'), ('res_id','=',group[0])]"):message>/get_replies''',
'''/groups/<model('mail.channel', "[('channel_type', '=', 'channel')]"):group>/<model('mail.message', "[('model','=','mail.channel'), ('res_id','=',group[0])]"):message>/get_replies''',
type='json', auth="public", methods=['POST'], website=True)
def render_messages(self, group, message, **post):
if group.channel_type != 'channel':
+26 -15
View File
@@ -8,6 +8,8 @@ import werkzeug
from odoo import http, _
from odoo.exceptions import AccessError, UserError
from odoo.http import request
from odoo.addons.http_routing.models.ir_http import slug
from odoo.addons.website.models.ir_http import sitemap_qs2dom
_logger = logging.getLogger(__name__)
@@ -66,22 +68,30 @@ class WebsiteSlides(http.Controller):
'is_public_user': request.env.user == request.website.user_id
})
def sitemap_slide(env, rule, qs):
Channel = env['slide.channel']
dom = sitemap_qs2dom(qs=qs, route='/slides/', field=Channel._rec_name)
for channel in Channel.search(dom):
loc = '/slides/%s' % slug(channel)
if qs.lower() in loc:
yield {'loc': loc}
@http.route([
'''/slides/<model("slide.channel", "[('can_see', '=', True)]"):channel>''',
'''/slides/<model("slide.channel", "[('can_see', '=', True)]"):channel>/page/<int:page>''',
'''/slides/<model("slide.channel"):channel>''',
'''/slides/<model("slide.channel):channel>/page/<int:page>''',
'''/slides/<model("slide.channel", "[('can_see', '=', True)]"):channel>/<string:slide_type>''',
'''/slides/<model("slide.channel", "[('can_see', '=', True)]"):channel>/<string:slide_type>/page/<int:page>''',
'''/slides/<model("slide.channel"):channel>/<string:slide_type>''',
'''/slides/<model("slide.channel"):channel>/<string:slide_type>/page/<int:page>''',
'''/slides/<model("slide.channel", "[('can_see', '=', True)]"):channel>/tag/<model("slide.tag"):tag>''',
'''/slides/<model("slide.channel", "[('can_see', '=', True)]"):channel>/tag/<model("slide.tag"):tag>/page/<int:page>''',
'''/slides/<model("slide.channel"):channel>/tag/<model("slide.tag"):tag>''',
'''/slides/<model("slide.channel"):channel>/tag/<model("slide.tag"):tag>/page/<int:page>''',
'''/slides/<model("slide.channel", "[('can_see', '=', True)]"):channel>/category/<model("slide.category"):category>''',
'''/slides/<model("slide.channel", "[('can_see', '=', True)]"):channel>/category/<model("slide.category"):category>/page/<int:page>''',
'''/slides/<model("slide.channel"):channel>/category/<model("slide.category"):category>''',
'''/slides/<model("slide.channel"):channel>/category/<model("slide.category"):category>/page/<int:page>''',
'''/slides/<model("slide.channel", "[('can_see', '=', True)]"):channel>/category/<model("slide.category"):category>/<string:slide_type>''',
'''/slides/<model("slide.channel", "[('can_see', '=', True)]"):channel>/category/<model("slide.category"):category>/<string:slide_type>/page/<int:page>'''],
type='http', auth="public", website=True)
'''/slides/<model("slide.channel"):channel>/category/<model("slide.category"):category>/<string:slide_type>''',
'''/slides/<model("slide.channel"):channel>/category/<model("slide.category"):category>/<string:slide_type>/page/<int:page>'''],
type='http', auth="public", website=True, sitemap=sitemap_slide)
def channel(self, channel, category=None, tag=None, page=1, slide_type=None, sorting='creation', search=None, **kw):
user = request.env.user
Slide = request.env['slide.slide']
@@ -161,15 +171,16 @@ class WebsiteSlides(http.Controller):
self._set_viewed_slide(slide, 'slide')
return request.render('website_slides.slide_detail_view', values)
@http.route('''/slides/slide/<model("slide.slide", "[('channel_id.can_see', '=', True), ('datas', '!=', False), ('slide_type', '=', 'presentation')]"):slide>/pdf_content''', type='http', auth="public", website=True)
@http.route('''/slides/slide/<model("slide.slide"):slide>/pdf_content''',
type='http', auth="public", website=True, sitemap=False)
def slide_get_pdf_content(self, slide):
response = werkzeug.wrappers.Response()
response.data = slide.datas and base64.b64decode(slide.datas) or b''
response.mimetype = 'application/pdf'
return response
@http.route('''/slides/slide/<model("slide.slide", "[('channel_id.can_see', '=', True), ('download_security', '=', 'public')]"):slide>/download''', type='http', auth="public", website=True)
def slide_download(self, slide):
@http.route('''/slides/slide/<model("slide.slide"):slide>/download''', type='http', auth="public", website=True)
def slide_download(self, slide, sitemap=False):
if slide.download_security == 'public' or (slide.download_security == 'user' and request.session.uid):
filecontent = base64.b64decode(slide.datas)
disposition = 'attachment; filename=%s.pdf' % werkzeug.urls.url_quote(slide.name)
@@ -279,7 +290,7 @@ class WebsiteSlides(http.Controller):
# --------------------------------------------------
# EMBED IN THIRD PARTY WEBSITES
# --------------------------------------------------
@http.route('/slides/embed/<int:slide_id>', type='http', auth='public', website=True)
@http.route('/slides/embed/<int:slide_id>', type='http', auth='public', website=True, sitemap=False)
def slides_embed(self, slide_id, page="1", **kw):
# Note : don't use the 'model' in the route (use 'slide_id'), otherwise if public cannot access the embedded
# slide, the error will be the website.403 page instead of the one of the website_slides.embed_slide.