You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
3.9 KiB
93 lines
3.9 KiB
import logging
|
|
import datetime
|
|
import base64
|
|
import copy
|
|
|
|
from odoo import http, fields, _
|
|
from odoo.http import request
|
|
|
|
from odoo.addons.website.controllers.main import Website
|
|
|
|
SITEMAP_CACHE_TIME = datetime.timedelta(hours=12)
|
|
LOC_PER_SITEMAP = 45000
|
|
|
|
|
|
class WebsiteExtended(Website):
|
|
|
|
@http.route('/sitemap.xml', type='http', auth="public", website=True, multilang=False, sitemap=False)
|
|
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({
|
|
'raw': content.encode(),
|
|
'mimetype': mimetype,
|
|
'type': 'binary',
|
|
'name': url,
|
|
'url': url,
|
|
})
|
|
dom = [('url', '=', '/sitemap-%d.xml' % current_website.id), ('type', '=', 'binary')]
|
|
sitemap = Attachment.search(dom, limit=1)
|
|
seos = request.env['seo.seo'].sudo().search([('is_indexed', '=', False)])
|
|
if sitemap and not seos:
|
|
# 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.with_user(request.website.user_id)._enumerate_pages()
|
|
locs = list(locs)
|
|
for rec in request.env['seo.seo'].sudo().search([]):
|
|
# for item in enumerate(locs):
|
|
# if rec.url_containing in item['loc']:
|
|
# del locs[n]
|
|
locs = [item for item in locs if rec.url_containing not in item['loc']]
|
|
rec.is_indexed = True
|
|
while True:
|
|
values = {
|
|
'locs': locs,
|
|
'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)
|
|
if len(locs) * pages < LOC_PER_SITEMAP:
|
|
break
|
|
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)])
|
|
|