[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:
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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])}
|
||||
|
||||
@@ -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']
|
||||
|
||||
@@ -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']
|
||||
|
||||
@@ -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})
|
||||
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user