vanilla 19.0

This commit is contained in:
Ernad Husremovic 2025-10-08 10:49:46 +02:00
parent 991d2234ca
commit d1963a3c3a
3066 changed files with 1651266 additions and 922560 deletions

View file

@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
import json
from odoo.exceptions import UserError
from odoo.http import Controller, request, Response, route
from odoo.http import Controller, request, Response, route, content_disposition
class Profiling(Controller):
@ -20,15 +22,58 @@ class Profiling(Controller):
except UserError as e:
return Response(response='error: %s' % e, status=500, mimetype='text/plain')
@route(['/web/speedscope', '/web/speedscope/<model("ir.profile"):profile>'], type='http', sitemap=False, auth='user')
def speedscope(self, profile=None):
# don't server speedscope index if profiling is not enabled
if not request.env['ir.profile']._enabled_until():
return request.not_found()
@route([
'/web/speedscope/<profile>',
], type='http', sitemap=False, auth='user', readonly=True)
def speedscope(self, profile=None, action=False, **kwargs):
profiles = request.env['ir.profile'].browse(int(p) for p in profile.split(',')).exists()
profile_str = profile
if not profiles:
raise request.not_found()
params = kwargs or profiles._default_profile_params()
speedscope_result = profiles._generate_speedscope(profiles._parse_params(params))
if action == 'speedscope_download_json':
headers = [
('Content-Type', 'application/json'),
('X-Content-Type-Options', 'nosniff'),
('Content-Disposition', content_disposition(f'profile_{profile_str}.json')),
]
return request.make_response(speedscope_result, headers)
icp = request.env['ir.config_parameter']
context = {
'profile': profile,
'profiles': profiles,
'speedscope_base64': base64.b64encode(speedscope_result).decode('utf-8'),
'url_root': request.httprequest.url_root,
'cdn': icp.sudo().get_param('speedscope_cdn', "https://cdn.jsdelivr.net/npm/speedscope@1.13.0/dist/release/")
}
return request.render('web.view_speedscope_index', context)
response = request.render('web.view_speedscope_index', context)
if action == 'speedscope_download_html':
response.headers['Content-Disposition'] = content_disposition(f'profile_{profile_str}.html')
response.headers['X-Content-Type-Options'] = 'nosniff'
response.headers['Content-Type'] = 'text/html'
return response
@route([
'/web/profile_config/<profile>',
], type='http', sitemap=False, auth='user', readonly=True)
def profile_config(self, profile=None, action=False, **kwargs):
profile_str = profile
profiles = request.env['ir.profile'].browse(int(p) for p in profile_str.split(',')).exists()
if not profiles:
raise request.not_found()
if action == 'memory_open':
memory_profile = profiles._generate_memory_profile(profiles._parse_params(kwargs))
encoded_memory_profile = json.dumps(memory_profile).encode('utf_8')
context = {
'profile': profiles,
'memory_graph': base64.b64encode(encoded_memory_profile).decode('utf-8'),
}
return request.render('web.view_memory', context)
context = {
'default_params': profiles._default_profile_params(),
'profile_str': profile_str,
'profiles': profiles,
}
return request.render('web.config_speedscope_index', context)