[MERGE] web_*: reorganize files, finish migration and apply guidelines
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import openerp.addons.web.http as http
|
||||
from openerp.addons.web.http import request
|
||||
import openerp.http as http
|
||||
from openerp.http import request
|
||||
|
||||
|
||||
class google_calendar_controller(http.Controller):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import werkzeug
|
||||
|
||||
from openerp.addons.web import http
|
||||
from openerp import http
|
||||
from openerp.http import request
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ from odoo.exceptions import AccessError
|
||||
from odoo.sql_db import TestCursor
|
||||
from odoo.tools import config
|
||||
from odoo.tools.misc import find_in_path
|
||||
from odoo.addons.web.http import request
|
||||
from odoo.http import request
|
||||
from odoo.tools.safe_eval import safe_eval as eval
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import sys
|
||||
|
||||
# Mock deprecated openerp.addons.web.http module
|
||||
import openerp.http
|
||||
sys.modules['openerp.addons.web.http'] = openerp.http
|
||||
http = openerp.http
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import controllers
|
||||
import models
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'Web',
|
||||
'category': 'Hidden',
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import main, pivot
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import babel.messages.pofile
|
||||
import base64
|
||||
import csv
|
||||
import datetime
|
||||
import functools
|
||||
import glob
|
||||
import hashlib
|
||||
import imghdr
|
||||
import itertools
|
||||
import jinja2
|
||||
import json
|
||||
import logging
|
||||
import operator
|
||||
import datetime
|
||||
import hashlib
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
import werkzeug.utils
|
||||
import werkzeug.wrappers
|
||||
import zlib
|
||||
from xml.etree import ElementTree
|
||||
from cStringIO import StringIO
|
||||
|
||||
import babel.messages.pofile
|
||||
import werkzeug.utils
|
||||
import werkzeug.wrappers
|
||||
from openerp.api import Environment
|
||||
|
||||
try:
|
||||
import xlwt
|
||||
except ImportError:
|
||||
xlwt = None
|
||||
|
||||
import openerp
|
||||
import openerp.modules.registry
|
||||
from openerp.modules import get_resource_path
|
||||
from openerp.tools import topological_sort
|
||||
from openerp.tools.translate import _
|
||||
from openerp.tools import ustr
|
||||
from openerp.tools.misc import str2bool
|
||||
from openerp import http
|
||||
from openerp.http import request, serialize_exception as _serialize_exception
|
||||
from openerp.exceptions import AccessError
|
||||
import odoo
|
||||
import odoo.modules.registry
|
||||
from odoo.api import Environment
|
||||
from odoo.modules import get_resource_path
|
||||
from odoo.tools import topological_sort
|
||||
from odoo.tools.translate import _
|
||||
from odoo.tools.misc import str2bool
|
||||
from odoo import http
|
||||
from odoo.http import request, serialize_exception as _serialize_exception
|
||||
from odoo.exceptions import AccessError
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -48,7 +48,7 @@ if hasattr(sys, 'frozen'):
|
||||
path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'views'))
|
||||
loader = jinja2.FileSystemLoader(path)
|
||||
else:
|
||||
loader = jinja2.PackageLoader('openerp.addons.web', "views")
|
||||
loader = jinja2.PackageLoader('odoo.addons.web', "views")
|
||||
|
||||
env = jinja2.Environment(loader=loader, autoescape=True)
|
||||
env.filters["json"] = json.dumps
|
||||
@@ -57,7 +57,7 @@ env.filters["json"] = json.dumps
|
||||
BUNDLE_MAXAGE = 60 * 60 * 24 * 7
|
||||
|
||||
#----------------------------------------------------------
|
||||
# OpenERP Web helpers
|
||||
# Odoo Web helpers
|
||||
#----------------------------------------------------------
|
||||
|
||||
db_list = http.db_list
|
||||
@@ -163,16 +163,16 @@ def module_installed(environment):
|
||||
|
||||
def module_installed_bypass_session(dbname):
|
||||
try:
|
||||
registry = openerp.modules.registry.RegistryManager.get(dbname)
|
||||
registry = odoo.modules.registry.RegistryManager.get(dbname)
|
||||
with registry.cursor() as cr:
|
||||
return module_installed(
|
||||
environment=Environment(cr, openerp.SUPERUSER_ID, {}))
|
||||
environment=Environment(cr, odoo.SUPERUSER_ID, {}))
|
||||
except Exception:
|
||||
pass
|
||||
return {}
|
||||
|
||||
def module_boot(db=None):
|
||||
server_wide_modules = openerp.conf.server_wide_modules or ['web']
|
||||
server_wide_modules = odoo.conf.server_wide_modules or ['web']
|
||||
serverside = []
|
||||
dbside = []
|
||||
for i in server_wide_modules:
|
||||
@@ -245,7 +245,7 @@ def manifest_list(extension, mods=None, db=None, debug=None):
|
||||
db: a database name (return all installed modules in that database)
|
||||
"""
|
||||
if debug is not None:
|
||||
_logger.warning("openerp.addons.web.main.manifest_list(): debug parameter is deprecated")
|
||||
_logger.warning("odoo.addons.web.main.manifest_list(): debug parameter is deprecated")
|
||||
files = manifest_glob(extension, addons=mods, db=db, include_remotes=True)
|
||||
return [wp for _fp, wp in files]
|
||||
|
||||
@@ -345,7 +345,7 @@ def generate_views(action):
|
||||
action['views'] = [(view_id, view_modes[0])]
|
||||
|
||||
def fix_view_modes(action):
|
||||
""" For historical reasons, OpenERP has weird dealings in relation to
|
||||
""" For historical reasons, Odoo has weird dealings in relation to
|
||||
view_mode and the view_type attribute (on window actions):
|
||||
|
||||
* one of the view modes is ``tree``, which stands for both list views
|
||||
@@ -427,7 +427,7 @@ def binary_content(xmlid=None, model='ir.attachment', id=None, field='datas', un
|
||||
download=download, mimetype=mimetype, default_mimetype=default_mimetype, env=env)
|
||||
|
||||
#----------------------------------------------------------
|
||||
# OpenERP Web web Controllers
|
||||
# Odoo Web web Controllers
|
||||
#----------------------------------------------------------
|
||||
class Home(http.Controller):
|
||||
|
||||
@@ -462,12 +462,12 @@ class Home(http.Controller):
|
||||
return http.redirect_with_hash(redirect)
|
||||
|
||||
if not request.uid:
|
||||
request.uid = openerp.SUPERUSER_ID
|
||||
request.uid = odoo.SUPERUSER_ID
|
||||
|
||||
values = request.params.copy()
|
||||
try:
|
||||
values['databases'] = http.db_list()
|
||||
except openerp.exceptions.AccessDenied:
|
||||
except odoo.exceptions.AccessDenied:
|
||||
values['databases'] = None
|
||||
|
||||
if request.httprequest.method == 'POST':
|
||||
@@ -482,6 +482,7 @@ class Home(http.Controller):
|
||||
values['error'] = _("Wrong login/password")
|
||||
return request.render('web.login', values)
|
||||
|
||||
|
||||
class WebClient(http.Controller):
|
||||
|
||||
@http.route('/web/webclient/csslist', type='json', auth="none")
|
||||
@@ -494,21 +495,20 @@ class WebClient(http.Controller):
|
||||
|
||||
@http.route('/web/webclient/locale/<string:lang>', type='http', auth="none")
|
||||
def load_locale(self, lang):
|
||||
magic_file_finding = [lang.replace("_",'-').lower(), lang.split('_')[0]]
|
||||
magic_file_finding = [lang.replace("_", '-').lower(), lang.split('_')[0]]
|
||||
addons_path = http.addons_manifest['web']['addons_path']
|
||||
#load momentjs locale
|
||||
momentjs_locale_file = False
|
||||
# load momentjs locale
|
||||
momentjs_locale = ""
|
||||
for code in magic_file_finding:
|
||||
try:
|
||||
with open(os.path.join(addons_path, 'web', 'static', 'lib', 'moment', 'locale', code + '.js'), 'r') as f:
|
||||
momentjs_locale = f.read()
|
||||
#we found a locale matching so we can exit
|
||||
# we found a locale matching so we can exit
|
||||
break
|
||||
except IOError:
|
||||
continue
|
||||
|
||||
#return the content of the locale
|
||||
# return the content of the locale
|
||||
headers = [('Content-Type', 'application/javascript'), ('Cache-Control', 'max-age=%s' % (36000))]
|
||||
return request.make_response(momentjs_locale, headers)
|
||||
|
||||
@@ -551,47 +551,47 @@ class WebClient(http.Controller):
|
||||
@http.route('/web/webclient/translations', type='json', auth="none")
|
||||
def translations(self, mods=None, lang=None):
|
||||
request.disable_db = False
|
||||
uid = openerp.SUPERUSER_ID
|
||||
if mods is None:
|
||||
m = request.registry.get('ir.module.module')
|
||||
mods = [x['name'] for x in m.search_read(request.cr, uid,
|
||||
[('state','=','installed')], ['name'])]
|
||||
mods = [x['name'] for x in request.env['ir.module.module'].sudo().search_read(
|
||||
[('state', '=', 'installed')], ['name'])]
|
||||
if lang is None:
|
||||
lang = request.context["lang"]
|
||||
res_lang = request.registry.get('res.lang')
|
||||
ids = res_lang.search(request.cr, uid, [("code", "=", lang)])
|
||||
langs = request.env['res.lang'].sudo().search([("code", "=", lang)])
|
||||
lang_params = None
|
||||
if ids:
|
||||
lang_params = res_lang.read(request.cr, uid, ids[0],
|
||||
["name", "direction", "date_format", "time_format", "grouping", "decimal_point", "thousands_sep"])
|
||||
if langs:
|
||||
lang_params = langs.read([
|
||||
"name", "direction", "date_format", "time_format",
|
||||
"grouping", "decimal_point", "thousands_sep"])[0]
|
||||
|
||||
# Regional languages (ll_CC) must inherit/override their parent lang (ll), but this is
|
||||
# done server-side when the language is loaded, so we only need to load the user's lang.
|
||||
ir_translation = request.registry.get('ir.translation')
|
||||
translations_per_module = {}
|
||||
messages = ir_translation.search_read(request.cr, uid, [('module','in',mods),('lang','=',lang),
|
||||
('comments','like','openerp-web'),('value','!=',False),
|
||||
('value','!=','')],
|
||||
['module','src','value','lang'], order='module')
|
||||
messages = request.env['ir.translation'].sudo().search_read([
|
||||
('module', 'in', mods), ('lang', '=', lang),
|
||||
('comments', 'like', 'openerp-web'), ('value', '!=', False),
|
||||
('value', '!=', '')],
|
||||
['module', 'src', 'value', 'lang'], order='module')
|
||||
for mod, msg_group in itertools.groupby(messages, key=operator.itemgetter('module')):
|
||||
translations_per_module.setdefault(mod,{'messages':[]})
|
||||
translations_per_module[mod]['messages'].extend({'id': m['src'],
|
||||
'string': m['value']} \
|
||||
for m in msg_group)
|
||||
translations_per_module.setdefault(mod, {'messages': []})
|
||||
translations_per_module[mod]['messages'].extend({
|
||||
'id': m['src'],
|
||||
'string': m['value']}
|
||||
for m in msg_group)
|
||||
return {
|
||||
'lang_parameters': lang_params,
|
||||
'modules': translations_per_module,
|
||||
'multi_lang': len(res_lang.get_installed(request.cr, uid)) > 1,
|
||||
'multi_lang': len(request.env['res.lang'].sudo().get_installed()) > 1,
|
||||
}
|
||||
|
||||
@http.route('/web/webclient/version_info', type='json', auth="none")
|
||||
def version_info(self):
|
||||
return openerp.service.common.exp_version()
|
||||
return odoo.service.common.exp_version()
|
||||
|
||||
@http.route('/web/tests', type='http', auth="none")
|
||||
def index(self, mod=None, **kwargs):
|
||||
return request.render('web.qunit_suite')
|
||||
|
||||
|
||||
class Proxy(http.Controller):
|
||||
|
||||
@http.route('/web/proxy/post/<path:path>', type='http', auth='user', methods=['GET'])
|
||||
@@ -613,15 +613,15 @@ class Database(http.Controller):
|
||||
|
||||
def _render_template(self, **d):
|
||||
d.setdefault('manage',True)
|
||||
d['insecure'] = openerp.tools.config['admin_passwd'] == 'admin'
|
||||
d['list_db'] = openerp.tools.config['list_db']
|
||||
d['langs'] = openerp.service.db.exp_list_lang()
|
||||
d['countries'] = openerp.service.db.exp_list_countries()
|
||||
d['insecure'] = odoo.tools.config['admin_passwd'] == 'admin'
|
||||
d['list_db'] = odoo.tools.config['list_db']
|
||||
d['langs'] = odoo.service.db.exp_list_lang()
|
||||
d['countries'] = odoo.service.db.exp_list_countries()
|
||||
# databases list
|
||||
d['databases'] = []
|
||||
try:
|
||||
d['databases'] = http.db_list()
|
||||
except openerp.exceptions.AccessDenied:
|
||||
except odoo.exceptions.AccessDenied:
|
||||
monodb = db_monodb()
|
||||
if monodb:
|
||||
d['databases'] = [monodb]
|
||||
@@ -668,14 +668,14 @@ class Database(http.Controller):
|
||||
@http.route('/web/database/backup', type='http', auth="none", methods=['POST'], csrf=False)
|
||||
def backup(self, master_pwd, name, backup_format = 'zip'):
|
||||
try:
|
||||
openerp.service.db.check_super(master_pwd)
|
||||
odoo.service.db.check_super(master_pwd)
|
||||
ts = datetime.datetime.utcnow().strftime("%Y-%m-%d_%H-%M-%S")
|
||||
filename = "%s_%s.%s" % (name, ts, backup_format)
|
||||
headers = [
|
||||
('Content-Type', 'application/octet-stream; charset=binary'),
|
||||
('Content-Disposition', content_disposition(filename)),
|
||||
]
|
||||
dump_stream = openerp.service.db.dump_db(name, None, backup_format)
|
||||
dump_stream = odoo.service.db.dump_db(name, None, backup_format)
|
||||
response = werkzeug.wrappers.Response(dump_stream, headers=headers, direct_passthrough=True)
|
||||
return response
|
||||
except Exception, e:
|
||||
@@ -742,7 +742,7 @@ class Session(http.Controller):
|
||||
@http.route('/web/session/modules', type='json', auth="user")
|
||||
def modules(self):
|
||||
# return all installed modules. Web client is smart enough to not load a module twice
|
||||
return module_installed(environment=request.env(user=openerp.SUPERUSER_ID))
|
||||
return module_installed(environment=request.env(user=odoo.SUPERUSER_ID))
|
||||
|
||||
@http.route('/web/session/save_session_action', type='json', auth="user")
|
||||
def save_session_action(self, the_action):
|
||||
@@ -977,7 +977,7 @@ class Binary(http.Controller):
|
||||
width = 500
|
||||
if height > 500:
|
||||
height = 500
|
||||
content = openerp.tools.image_resize_image(base64_source=content, size=(width or None, height or None), encoding='base64', filetype='PNG')
|
||||
content = odoo.tools.image_resize_image(base64_source=content, size=(width or None, height or None), encoding='base64', filetype='PNG')
|
||||
|
||||
image_base64 = content and base64.b64decode(content) or self.placeholder()
|
||||
headers.append(('Content-Length', len(image_base64)))
|
||||
@@ -1054,14 +1054,14 @@ class Binary(http.Controller):
|
||||
dbname = db_monodb()
|
||||
|
||||
if not uid:
|
||||
uid = openerp.SUPERUSER_ID
|
||||
uid = odoo.SUPERUSER_ID
|
||||
|
||||
if not dbname:
|
||||
response = http.send_file(placeholder(imgname + imgext))
|
||||
else:
|
||||
try:
|
||||
# create an empty registry
|
||||
registry = openerp.modules.registry.Registry(dbname)
|
||||
registry = odoo.modules.registry.Registry(dbname)
|
||||
with registry.cursor() as cr:
|
||||
cr.execute("""SELECT c.logo_web, c.write_date
|
||||
FROM res_users u
|
||||
@@ -1155,7 +1155,7 @@ class Export(http.Controller):
|
||||
fields['.id'] = fields.pop('id', {'string': 'ID'})
|
||||
|
||||
fields_sequence = sorted(fields.iteritems(),
|
||||
key=lambda field: openerp.tools.ustr(field[1].get('string', '')))
|
||||
key=lambda field: odoo.tools.ustr(field[1].get('string', '')))
|
||||
|
||||
records = []
|
||||
for field_name, field in fields_sequence:
|
||||
@@ -1275,7 +1275,7 @@ class ExportFormat(object):
|
||||
raise NotImplementedError()
|
||||
|
||||
def from_data(self, fields, rows):
|
||||
""" Conversion method from OpenERP's export data to whatever the
|
||||
""" Conversion method from Odoo's export data to whatever the
|
||||
current export class outputs
|
||||
|
||||
:params list fields: a list of fields to export
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
from openerp import http
|
||||
import json
|
||||
from openerp.http import request, serialize_exception as _serialize_exception
|
||||
from cStringIO import StringIO
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from collections import deque
|
||||
import json
|
||||
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
||||
try:
|
||||
import xlwt
|
||||
except ImportError:
|
||||
xlwt = None
|
||||
|
||||
|
||||
class TableExporter(http.Controller):
|
||||
|
||||
@http.route('/web/pivot/check_xlwt', type='json', auth='none')
|
||||
def check_xlwt(self):
|
||||
return xlwt is not None
|
||||
|
||||
|
||||
@http.route('/web/pivot/export_xls', type='http', auth="user")
|
||||
def export_xls(self, data, token):
|
||||
jdata = json.loads(data)
|
||||
@@ -29,41 +32,41 @@ class TableExporter(http.Controller):
|
||||
# Step 1: writing headers
|
||||
headers = jdata['headers']
|
||||
|
||||
# x,y: current coordinates
|
||||
# x,y: current coordinates
|
||||
# carry: queue containing cell information when a cell has a >= 2 height
|
||||
# and the drawing code needs to add empty cells below
|
||||
x, y, carry = 1, 0, deque()
|
||||
x, y, carry = 1, 0, deque()
|
||||
for i, header_row in enumerate(headers):
|
||||
worksheet.write(i,0, '', header_plain)
|
||||
worksheet.write(i, 0, '', header_plain)
|
||||
for header in header_row:
|
||||
while (carry and carry[0]['x'] == x):
|
||||
cell = carry.popleft()
|
||||
for i in range(nbr_measures):
|
||||
worksheet.write(y, x+i, '', header_plain)
|
||||
if cell['height'] > 1:
|
||||
carry.append({'x': x, 'height':cell['height'] - 1})
|
||||
carry.append({'x': x, 'height': cell['height'] - 1})
|
||||
x = x + nbr_measures
|
||||
style = header_plain if 'expanded' in header else header_bold
|
||||
for i in range(header['width']):
|
||||
worksheet.write(y, x + i, header['title'] if i == 0 else '', style)
|
||||
if header['height'] > 1:
|
||||
carry.append({'x': x, 'height':header['height'] - 1})
|
||||
x = x + header['width'];
|
||||
carry.append({'x': x, 'height': header['height'] - 1})
|
||||
x = x + header['width']
|
||||
while (carry and carry[0]['x'] == x):
|
||||
cell = carry.popleft()
|
||||
for i in range(nbr_measures):
|
||||
worksheet.write(y, x+i, '', header_plain)
|
||||
if cell['height'] > 1:
|
||||
carry.append({'x': x, 'height':cell['height'] - 1})
|
||||
carry.append({'x': x, 'height': cell['height'] - 1})
|
||||
x = x + nbr_measures
|
||||
x, y = 1, y + 1
|
||||
|
||||
# Step 2: measure row
|
||||
if nbr_measures > 1:
|
||||
worksheet.write(y,0, '', header_plain)
|
||||
worksheet.write(y, 0, '', header_plain)
|
||||
for measure in jdata['measure_row']:
|
||||
style = header_bold if measure['is_bold'] else header_plain
|
||||
worksheet.write(y, x, measure['measure'], style);
|
||||
worksheet.write(y, x, measure['measure'], style)
|
||||
x = x + 1
|
||||
y = y + 1
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import ir_http
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import json
|
||||
|
||||
import openerp
|
||||
from openerp import models
|
||||
from openerp.http import request
|
||||
from odoo import models
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class Http(models.AbstractModel):
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import test_js
|
||||
import test_menu
|
||||
import test_serving_base
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import openerp.tests
|
||||
|
||||
|
||||
class WebSuite(openerp.tests.HttpCase):
|
||||
def test_01_js(self):
|
||||
self.phantom_js('/web/tests?mod=web',"","", login='admin')
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import unittest
|
||||
|
||||
from ..controllers import main
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import random
|
||||
import unittest
|
||||
|
||||
from openerp.tools import topological_sort
|
||||
from odoo.tools import topological_sort
|
||||
|
||||
|
||||
def sample(population):
|
||||
return random.sample(
|
||||
population,
|
||||
random.randint(0, min(len(population), 5)))
|
||||
|
||||
|
||||
class TestModulesLoading(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.mods = map(str, range(1000))
|
||||
|
||||
def test_topological_sort(self):
|
||||
random.shuffle(self.mods)
|
||||
modules = [
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'Web Calendar',
|
||||
'category': 'Hidden',
|
||||
@@ -10,7 +13,7 @@ Odoo Web Calendar view.
|
||||
'version': '2.0',
|
||||
'depends': ['web'],
|
||||
'data' : [
|
||||
'views/web_calendar.xml',
|
||||
'views/web_calendar_templates.xml',
|
||||
],
|
||||
'qweb': [
|
||||
'static/src/xml/*.xml',
|
||||
|
||||
+2
-4
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<template id="assets_backend" name="web_calendar assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<link rel="stylesheet" href="/web_calendar/static/src/less/web_calendar.less"/>
|
||||
@@ -11,5 +10,4 @@
|
||||
<script type="text/javascript" src="/web_calendar/static/src/js/web_calendar.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -1 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import controllers
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'Odoo Web Diagram',
|
||||
'category': 'Hidden',
|
||||
@@ -8,8 +11,8 @@ Openerp Web Diagram view.
|
||||
""",
|
||||
'version': '2.0',
|
||||
'depends': ['web'],
|
||||
'data' : [
|
||||
'views/web_diagram.xml',
|
||||
'data': [
|
||||
'views/web_diagram_templates.xml',
|
||||
],
|
||||
'qweb': [
|
||||
'static/src/xml/*.xml',
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import main
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
import openerp
|
||||
from openerp.tools.safe_eval import safe_eval as eval
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
class DiagramView(openerp.http.Controller):
|
||||
import odoo
|
||||
import odoo.http as http
|
||||
|
||||
@openerp.http.route('/web_diagram/diagram/get_diagram_info', type='json', auth='user')
|
||||
from odoo.tools.safe_eval import safe_eval as eval
|
||||
|
||||
|
||||
class DiagramView(http.Controller):
|
||||
|
||||
@http.route('/web_diagram/diagram/get_diagram_info', type='json', auth='user')
|
||||
def get_diagram_info(self, req, id, model, node, connector,
|
||||
src_node, des_node, label, **kw):
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<odoo>
|
||||
<data>
|
||||
<template id="assets_backend" name="web_diagram assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
@@ -10,4 +10,4 @@
|
||||
</xpath>
|
||||
</template>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -1,4 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import controllers
|
||||
import models
|
||||
import tests
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'Web Editor',
|
||||
'category': 'Hidden',
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import main
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from openerp.http import request, STATIC_CACHE
|
||||
from openerp.addons.web import http
|
||||
import json
|
||||
import io
|
||||
from PIL import Image, ImageFont, ImageDraw
|
||||
from openerp import tools
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import cStringIO
|
||||
import werkzeug.wrappers
|
||||
import time
|
||||
import io
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
import werkzeug.wrappers
|
||||
from PIL import Image, ImageFont, ImageDraw
|
||||
|
||||
from odoo.http import request
|
||||
from odoo import http, tools
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -25,8 +28,6 @@ class Web_Editor(http.Controller):
|
||||
#------------------------------------------------------
|
||||
@http.route('/web_editor/field/html', type='http', auth="user")
|
||||
def FieldTextHtml(self, model=None, res_id=None, field=None, callback=None, **kwargs):
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
|
||||
kwargs.update(
|
||||
model=model,
|
||||
res_id=res_id,
|
||||
@@ -39,17 +40,16 @@ class Web_Editor(http.Controller):
|
||||
kwargs[k] = int(kwargs[k])
|
||||
|
||||
trans = dict(
|
||||
lang=kwargs.get('lang', context.get('lang')),
|
||||
lang=kwargs.get('lang', request.env.context.get('lang')),
|
||||
translatable=kwargs.get('translatable'),
|
||||
edit_translations=kwargs.get('edit_translations'),
|
||||
editable=kwargs.get('enable_editor'))
|
||||
|
||||
context.update(trans)
|
||||
kwargs.update(trans)
|
||||
|
||||
record = None
|
||||
if model and kwargs.get('res_id'):
|
||||
record = request.registry[model].browse(cr, uid, kwargs.get('res_id'), context)
|
||||
record = request.env[model].with_context(trans).browse(kwargs.get('res_id'))
|
||||
|
||||
kwargs.update(content=record and getattr(record, field) or "")
|
||||
|
||||
@@ -141,23 +141,23 @@ class Web_Editor(http.Controller):
|
||||
# the upload argument doesn't allow us to access the files if more than
|
||||
# one file is uploaded, as upload references the first file
|
||||
# therefore we have to recover the files from the request object
|
||||
Attachments = request.registry['ir.attachment'] # registry for the attachment table
|
||||
Attachments = request.env['ir.attachment'] # registry for the attachment table
|
||||
|
||||
uploads = []
|
||||
message = None
|
||||
if not upload: # no image provided, storing the link and the image name
|
||||
name = url.split("/").pop() # recover filename
|
||||
attachment_id = Attachments.create(request.cr, request.uid, {
|
||||
attachment = Attachments.create({
|
||||
'name': name,
|
||||
'type': 'url',
|
||||
'url': url,
|
||||
'public': True,
|
||||
'res_model': 'ir.ui.view',
|
||||
}, request.context)
|
||||
uploads += Attachments.read(request.cr, request.uid, [attachment_id], ['name', 'mimetype', 'checksum', 'url'], request.context)
|
||||
})
|
||||
uploads += attachment.read(['name', 'mimetype', 'checksum', 'url'])
|
||||
else: # images provided
|
||||
try:
|
||||
attachment_ids = []
|
||||
attachments = request.env['ir.attachment']
|
||||
for c_file in request.httprequest.files.getlist('upload'):
|
||||
data = c_file.read()
|
||||
try:
|
||||
@@ -172,15 +172,15 @@ class Web_Editor(http.Controller):
|
||||
except IOError, e:
|
||||
pass
|
||||
|
||||
attachment_id = Attachments.create(request.cr, request.uid, {
|
||||
attachment = Attachments.create({
|
||||
'name': c_file.filename,
|
||||
'datas': data.encode('base64'),
|
||||
'datas_fname': c_file.filename,
|
||||
'public': True,
|
||||
'res_model': 'ir.ui.view',
|
||||
}, request.context)
|
||||
attachment_ids.append(attachment_id)
|
||||
uploads += Attachments.read(request.cr, request.uid, attachment_ids, ['name', 'mimetype', 'checksum', 'url'], request.context)
|
||||
})
|
||||
attachments += attachment
|
||||
uploads += attachments.read(['name', 'mimetype', 'checksum', 'url'])
|
||||
except Exception, e:
|
||||
logger.exception("Failed to upload image to attachment")
|
||||
message = unicode(e)
|
||||
@@ -199,25 +199,26 @@ class Web_Editor(http.Controller):
|
||||
Returns a dict mapping attachments which would not be removed (if any)
|
||||
mapped to the views preventing their removal
|
||||
"""
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
Attachment = request.registry['ir.attachment']
|
||||
Views = request.registry['ir.ui.view']
|
||||
Attachment = attachments_to_remove = request.env['ir.attachment']
|
||||
Views = request.env['ir.ui.view']
|
||||
|
||||
attachments_to_remove = []
|
||||
# views blocking removal of the attachment
|
||||
removal_blocked_by = {}
|
||||
|
||||
for attachment in Attachment.browse(cr, uid, ids, context=context):
|
||||
for attachment in Attachment.browse(ids):
|
||||
# in-document URLs are html-escaped, a straight search will not
|
||||
# find them
|
||||
url = tools.html_escape(attachment.local_url)
|
||||
ids = Views.search(cr, uid, ["|", ('arch_db', 'like', '"%s"' % url), ('arch_db', 'like', "'%s'" % url)], context=context)
|
||||
views = Views.search([
|
||||
"|",
|
||||
('arch_db', 'like', '"%s"' % url),
|
||||
('arch_db', 'like', "'%s'" % url)
|
||||
])
|
||||
|
||||
if ids:
|
||||
removal_blocked_by[attachment.id] = Views.read(
|
||||
cr, uid, ids, ['name'], context=context)
|
||||
if views:
|
||||
removal_blocked_by[attachment.id] = views.read(['name'])
|
||||
else:
|
||||
attachments_to_remove.append(attachment.id)
|
||||
attachments_to_remove += attachment
|
||||
if attachments_to_remove:
|
||||
Attachment.unlink(cr, uid, attachments_to_remove, context=context)
|
||||
attachments_to_remove.unlink()
|
||||
return removal_blocked_by
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import ir_attachment
|
||||
import ir_qweb
|
||||
import ir_ui_view
|
||||
|
||||
@@ -1,36 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import openerp
|
||||
from openerp.osv import osv, fields
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import contextlib
|
||||
from sys import maxint
|
||||
from openerp.addons.web.http import request
|
||||
import datetime
|
||||
import hashlib
|
||||
import time
|
||||
import os
|
||||
|
||||
from openerp.tools import html_escape as escape, ustr, image_resize_and_sharpen, image_save_for_web
|
||||
from PIL import Image
|
||||
import cStringIO
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
from odoo import api, models, fields
|
||||
|
||||
|
||||
class ir_attachment(osv.osv):
|
||||
class IrAttachment(models.Model):
|
||||
|
||||
_inherit = "ir.attachment"
|
||||
|
||||
def _local_url_get(self, cr, uid, ids, name, arg, context=None):
|
||||
result = {}
|
||||
for attach in self.browse(cr, uid, ids, context=context):
|
||||
if attach.url:
|
||||
result[attach.id] = attach.url
|
||||
else:
|
||||
result[attach.id] = '/web/image/%s?unique=%s' % (attach.id, attach.checksum)
|
||||
return result
|
||||
local_url = fields.Char("Attachment URL", compute='_compute_local_url')
|
||||
|
||||
_columns = {
|
||||
'local_url': fields.function(_local_url_get, string="Attachment URL", type='char'),
|
||||
}
|
||||
@api.one
|
||||
def _compute_local_url(self):
|
||||
if self.url:
|
||||
self.local_url = self.url
|
||||
else:
|
||||
self.local_url = '/web/image/%s?unique=%s' % (self.id, self.checksum)
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from openerp.osv import orm
|
||||
from openerp.http import request
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class ir_http(orm.AbstractModel):
|
||||
class IrHttp(models.AbstractModel):
|
||||
_inherit = 'ir.http'
|
||||
|
||||
def _dispatch(self):
|
||||
@@ -13,4 +15,4 @@ class ir_http(orm.AbstractModel):
|
||||
request.context['edit_translations'] = True
|
||||
if request.context.get('lang') != "en_US" and 'translatable' not in request.context:
|
||||
request.context['translatable'] = True
|
||||
return super(ir_http, self)._dispatch()
|
||||
return super(IrHttp, self)._dispatch()
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
"""
|
||||
Web_editor-context rendering needs to add some metadata to rendered and allow to edit fields,
|
||||
as well as render a few fields differently.
|
||||
|
||||
Also, adds methods to convert values back to openerp models.
|
||||
Also, adds methods to convert values back to Odoo models.
|
||||
"""
|
||||
|
||||
import ast
|
||||
@@ -22,22 +24,19 @@ import pytz
|
||||
from dateutil import parser
|
||||
from lxml import etree, html
|
||||
from PIL import Image as I
|
||||
import openerp.modules
|
||||
import odoo.modules
|
||||
|
||||
from odoo import api
|
||||
|
||||
import openerp
|
||||
from openerp.osv import orm, fields
|
||||
from openerp.tools import ustr, DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from openerp.tools import html_escape as escape
|
||||
from openerp.addons.base.ir import ir_qweb
|
||||
from odoo import api, models, fields
|
||||
from odoo.tools import ustr
|
||||
from odoo.tools import html_escape as escape
|
||||
from odoo.addons.base.ir import ir_qweb
|
||||
|
||||
REMOTE_CONNECTION_TIMEOUT = 2.5
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class QWeb(orm.AbstractModel):
|
||||
class QWeb(models.AbstractModel):
|
||||
""" QWeb object for rendering editor stuff
|
||||
"""
|
||||
_inherit = 'ir.qweb'
|
||||
@@ -69,7 +68,7 @@ class QWeb(orm.AbstractModel):
|
||||
#------------------------------------------------------
|
||||
|
||||
|
||||
class Field(orm.AbstractModel):
|
||||
class Field(models.AbstractModel):
|
||||
_name = 'ir.qweb.field'
|
||||
_inherit = 'ir.qweb.field'
|
||||
|
||||
@@ -98,14 +97,14 @@ class Field(orm.AbstractModel):
|
||||
return self.value_from_string(element.text_content().strip())
|
||||
|
||||
|
||||
class Integer(orm.AbstractModel):
|
||||
class Integer(models.AbstractModel):
|
||||
_name = 'ir.qweb.field.integer'
|
||||
_inherit = 'ir.qweb.field.integer'
|
||||
|
||||
value_from_string = int
|
||||
|
||||
|
||||
class Float(orm.AbstractModel):
|
||||
class Float(models.AbstractModel):
|
||||
_name = 'ir.qweb.field.float'
|
||||
_inherit = 'ir.qweb.field.float'
|
||||
|
||||
@@ -117,7 +116,7 @@ class Float(orm.AbstractModel):
|
||||
.replace(lang.decimal_point, '.'))
|
||||
|
||||
|
||||
class ManyToOne(orm.AbstractModel):
|
||||
class ManyToOne(models.AbstractModel):
|
||||
_name = 'ir.qweb.field.many2one'
|
||||
_inherit = 'ir.qweb.field.many2one'
|
||||
|
||||
@@ -146,7 +145,7 @@ class ManyToOne(orm.AbstractModel):
|
||||
return None
|
||||
|
||||
|
||||
class Contact(orm.AbstractModel):
|
||||
class Contact(models.AbstractModel):
|
||||
_name = 'ir.qweb.field.contact'
|
||||
_inherit = 'ir.qweb.field.contact'
|
||||
|
||||
@@ -165,18 +164,7 @@ class Contact(orm.AbstractModel):
|
||||
return node and node.__html__()
|
||||
|
||||
|
||||
def parse_fuzzy(in_format, value):
|
||||
day_first = in_format.find('%d') < in_format.find('%m')
|
||||
|
||||
if '%y' in in_format:
|
||||
year_first = in_format.find('%y') < in_format.find('%d')
|
||||
else:
|
||||
year_first = in_format.find('%Y') < in_format.find('%d')
|
||||
|
||||
return parser.parse(value, dayfirst=day_first, yearfirst=year_first)
|
||||
|
||||
|
||||
class Date(orm.AbstractModel):
|
||||
class Date(models.AbstractModel):
|
||||
_name = 'ir.qweb.field.date'
|
||||
_inherit = 'ir.qweb.field.date'
|
||||
|
||||
@@ -192,11 +180,10 @@ class Date(orm.AbstractModel):
|
||||
if not value:
|
||||
return False
|
||||
|
||||
datetime.datetime.strptime(value, DEFAULT_SERVER_DATE_FORMAT)
|
||||
return value
|
||||
|
||||
|
||||
class DateTime(orm.AbstractModel):
|
||||
class DateTime(models.AbstractModel):
|
||||
_name = 'ir.qweb.field.datetime'
|
||||
_inherit = 'ir.qweb.field.datetime'
|
||||
|
||||
@@ -205,13 +192,11 @@ class DateTime(orm.AbstractModel):
|
||||
attrs = super(DateTime, self).attributes(record, field_name, options, values)
|
||||
value = record[field_name]
|
||||
if isinstance(value, basestring):
|
||||
value = datetime.datetime.strptime(
|
||||
value, DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
value = fields.Datetime.from_string(value)
|
||||
if value:
|
||||
# convert from UTC (server timezone) to user timezone
|
||||
value = fields.datetime.context_timestamp(
|
||||
self._cr, self._uid, timestamp=value, context=self.env.context)
|
||||
value = value.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
value = fields.Datetime.context_timestamp(self, timestamp=value)
|
||||
value = fields.Datetime.to_string(value)
|
||||
attrs['data-oe-original'] = value
|
||||
return attrs
|
||||
|
||||
@@ -240,10 +225,10 @@ class DateTime(orm.AbstractModel):
|
||||
exc_info=True)
|
||||
|
||||
# format back to string
|
||||
return dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
return fields.Datetime.to_string(dt)
|
||||
|
||||
|
||||
class Text(orm.AbstractModel):
|
||||
class Text(models.AbstractModel):
|
||||
_name = 'ir.qweb.field.text'
|
||||
_inherit = 'ir.qweb.field.text'
|
||||
|
||||
@@ -252,7 +237,7 @@ class Text(orm.AbstractModel):
|
||||
return html_to_text(element)
|
||||
|
||||
|
||||
class Selection(orm.AbstractModel):
|
||||
class Selection(models.AbstractModel):
|
||||
_name = 'ir.qweb.field.selection'
|
||||
_inherit = 'ir.qweb.field.selection'
|
||||
|
||||
@@ -270,7 +255,7 @@ class Selection(orm.AbstractModel):
|
||||
value, selection))
|
||||
|
||||
|
||||
class HTML(orm.AbstractModel):
|
||||
class HTML(models.AbstractModel):
|
||||
_name = 'ir.qweb.field.html'
|
||||
_inherit = 'ir.qweb.field.html'
|
||||
|
||||
@@ -284,7 +269,7 @@ class HTML(orm.AbstractModel):
|
||||
return '\n'.join(content)
|
||||
|
||||
|
||||
class Image(orm.AbstractModel):
|
||||
class Image(models.AbstractModel):
|
||||
"""
|
||||
Widget options:
|
||||
|
||||
@@ -361,7 +346,7 @@ class Image(orm.AbstractModel):
|
||||
if sep and sep != '/':
|
||||
rest.replace(sep, '/')
|
||||
|
||||
path = openerp.modules.get_module_resource(
|
||||
path = odoo.modules.get_module_resource(
|
||||
match.group('module'), 'static', *(rest.split('/')))
|
||||
|
||||
if not path:
|
||||
@@ -403,7 +388,7 @@ class Image(orm.AbstractModel):
|
||||
return out.getvalue().encode('base64')
|
||||
|
||||
|
||||
class Monetary(orm.AbstractModel):
|
||||
class Monetary(models.AbstractModel):
|
||||
_name = 'ir.qweb.field.monetary'
|
||||
_inherit = 'ir.qweb.field.monetary'
|
||||
|
||||
@@ -417,7 +402,7 @@ class Monetary(orm.AbstractModel):
|
||||
.replace(lang.decimal_point, '.'))
|
||||
|
||||
|
||||
class Duration(orm.AbstractModel):
|
||||
class Duration(models.AbstractModel):
|
||||
_name = 'ir.qweb.field.duration'
|
||||
_inherit = 'ir.qweb.field.duration'
|
||||
|
||||
@@ -435,14 +420,14 @@ class Duration(orm.AbstractModel):
|
||||
return float(value)
|
||||
|
||||
|
||||
class RelativeDatetime(orm.AbstractModel):
|
||||
class RelativeDatetime(models.AbstractModel):
|
||||
_name = 'ir.qweb.field.relative'
|
||||
_inherit = 'ir.qweb.field.relative'
|
||||
|
||||
# get formatting from ir.qweb.field.relative but edition/save from datetime
|
||||
|
||||
|
||||
class QwebView(orm.AbstractModel):
|
||||
class QwebView(models.AbstractModel):
|
||||
_name = 'ir.qweb.field.qweb'
|
||||
_inherit = 'ir.qweb.field.qweb'
|
||||
|
||||
|
||||
@@ -3,14 +3,16 @@
|
||||
|
||||
from lxml import etree
|
||||
|
||||
from openerp import models, api
|
||||
from openerp.tools.translate import encode, xml_translate, html_translate
|
||||
from odoo import models, api
|
||||
from odoo.tools.translate import encode, xml_translate, html_translate
|
||||
|
||||
|
||||
def edit_translation_mapping(data):
|
||||
data = dict(data, model=data['name'].partition(',')[0])
|
||||
return '<span data-oe-model="%(model)s" data-oe-translation-id="%(id)s" data-oe-translation-state="%(state)s">%(value)s</span>' % data
|
||||
|
||||
class ir_translation(models.Model):
|
||||
|
||||
class IrTranslation(models.Model):
|
||||
_inherit = 'ir.translation'
|
||||
|
||||
@api.model
|
||||
@@ -18,7 +20,7 @@ class ir_translation(models.Model):
|
||||
if self._context.get('edit_translations'):
|
||||
self.insert_missing(field, records)
|
||||
return edit_translation_mapping
|
||||
return super(ir_translation, self)._get_terms_mapping(field, records)
|
||||
return super(IrTranslation, self)._get_terms_mapping(field, records)
|
||||
|
||||
@api.multi
|
||||
def save_html(self, value):
|
||||
|
||||
@@ -1,40 +1,33 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import copy
|
||||
import openerp
|
||||
from openerp.exceptions import AccessError
|
||||
from openerp.osv import osv
|
||||
from lxml import etree, html
|
||||
from openerp import api
|
||||
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class view(osv.osv):
|
||||
class IrUiView(models.Model):
|
||||
_inherit = 'ir.ui.view'
|
||||
|
||||
@api.cr_uid_ids_context
|
||||
def render(self, cr, uid, id_or_xml_id, values=None, engine='ir.qweb', context=None):
|
||||
if isinstance(id_or_xml_id, list):
|
||||
id_or_xml_id = id_or_xml_id[0]
|
||||
if not values:
|
||||
values = {}
|
||||
if values.get('editable'):
|
||||
@api.multi
|
||||
def render(self, values=None, engine='ir.qweb'):
|
||||
if values and values.get('editable'):
|
||||
try:
|
||||
if not isinstance(id_or_xml_id, (int, long)):
|
||||
if '.' not in id_or_xml_id:
|
||||
raise ValueError('Invalid template id: %r' % (id_or_xml_id,))
|
||||
id_or_xml_id = self.get_view_id(cr, uid, id_or_xml_id, context=context)
|
||||
self.check_access_rights(cr, uid, 'write')
|
||||
self.check_access_rule(cr, uid, [id_or_xml_id], 'write', context=context)
|
||||
|
||||
self.check_access_rights('write')
|
||||
self.check_access_rule('write')
|
||||
except AccessError:
|
||||
values['editable'] = False
|
||||
|
||||
return super(view, self).render(cr, uid, id_or_xml_id, values=values, engine=engine, context=context)
|
||||
return super(IrUiView, self).render(values=values, engine=engine)
|
||||
|
||||
#------------------------------------------------------
|
||||
# Save from html
|
||||
#------------------------------------------------------
|
||||
|
||||
def extract_embedded_fields(self, cr, uid, arch, context=None):
|
||||
@api.model
|
||||
def extract_embedded_fields(self, arch):
|
||||
return arch.xpath('//*[@data-oe-model != "ir.ui.view"]')
|
||||
|
||||
@api.model
|
||||
@@ -62,12 +55,12 @@ class view(osv.osv):
|
||||
return etree.tostring(
|
||||
arch_no_whitespace, encoding='unicode', pretty_print=True)
|
||||
|
||||
def replace_arch_section(self, cr, uid, view_id, section_xpath, replacement, context=None):
|
||||
@api.multi
|
||||
def replace_arch_section(self, section_xpath, replacement):
|
||||
# the root of the arch section shouldn't actually be replaced as it's
|
||||
# not really editable itself, only the content truly is editable.
|
||||
|
||||
[view] = self.browse(cr, uid, [view_id], context=context)
|
||||
arch = etree.fromstring(view.arch.encode('utf-8'))
|
||||
self.ensure_one()
|
||||
arch = etree.fromstring(self.arch.encode('utf-8'))
|
||||
# => get the replacement root
|
||||
if not section_xpath:
|
||||
root = arch
|
||||
@@ -84,7 +77,8 @@ class view(osv.osv):
|
||||
|
||||
return arch
|
||||
|
||||
def to_field_ref(self, cr, uid, el, context=None):
|
||||
@api.model
|
||||
def to_field_ref(self, el):
|
||||
# filter out meta-information inserted in the document
|
||||
attributes = dict((k, v) for k, v in el.items()
|
||||
if not k.startswith('data-oe-'))
|
||||
@@ -94,34 +88,28 @@ class view(osv.osv):
|
||||
out.tail = el.tail
|
||||
return out
|
||||
|
||||
def save(self, cr, uid, res_id, value, xpath=None, context=None):
|
||||
@api.multi
|
||||
def save(self, value, xpath=None):
|
||||
""" Update a view section. The view section may embed fields to write
|
||||
|
||||
:param str model:
|
||||
:param int res_id:
|
||||
:param str xpath: valid xpath to the tag to replace
|
||||
"""
|
||||
res_id = int(res_id)
|
||||
|
||||
arch_section = html.fromstring(
|
||||
value, parser=html.HTMLParser(encoding='utf-8'))
|
||||
|
||||
if xpath is None:
|
||||
# value is an embedded field on its own, not a view section
|
||||
self.save_embedded_field(cr, uid, arch_section, context=context)
|
||||
self.save_embedded_field(arch_section)
|
||||
return
|
||||
|
||||
for el in self.extract_embedded_fields(cr, uid, arch_section, context=context):
|
||||
self.save_embedded_field(cr, uid, el, context=context)
|
||||
for el in self.extract_embedded_fields(arch_section):
|
||||
self.save_embedded_field(el)
|
||||
|
||||
# transform embedded field back to t-field
|
||||
el.getparent().replace(el, self.to_field_ref(cr, uid, el, context=context))
|
||||
el.getparent().replace(el, self.to_field_ref(el))
|
||||
|
||||
arch = self.replace_arch_section(cr, uid, res_id, xpath, arch_section, context=context)
|
||||
self.write(cr, uid, res_id, {
|
||||
'arch': self._pretty_arch(arch)
|
||||
}, context=context)
|
||||
for view in self:
|
||||
arch = view.replace_arch_section(xpath, arch_section)
|
||||
view.write({'arch': view._pretty_arch(arch)})
|
||||
|
||||
view = self.browse(cr, openerp.SUPERUSER_ID, res_id, context=context)
|
||||
if view.model_data_id:
|
||||
view.model_data_id.write({'noupdate': True})
|
||||
self.sudo().mapped('model_data_id').write({'noupdate': True})
|
||||
|
||||
@@ -1,43 +1,41 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from openerp.osv import orm, fields
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
class test_converter(orm.Model):
|
||||
class ConverterTest(models.Model):
|
||||
_name = 'web_editor.converter.test'
|
||||
|
||||
# disable translation export for those brilliant field labels and values
|
||||
_translate = False
|
||||
|
||||
_columns = {
|
||||
'char': fields.char(),
|
||||
'integer': fields.integer(),
|
||||
'float': fields.float(),
|
||||
'numeric': fields.float(digits=(16, 2)),
|
||||
'many2one': fields.many2one('web_editor.converter.test.sub'),
|
||||
'binary': fields.binary(),
|
||||
'date': fields.date(),
|
||||
'datetime': fields.datetime(),
|
||||
'selection': fields.selection([
|
||||
(1, "réponse A"),
|
||||
(2, "réponse B"),
|
||||
(3, "réponse C"),
|
||||
(4, "réponse <D>"),
|
||||
]),
|
||||
'selection_str': fields.selection([
|
||||
('A', "Qu'il n'est pas arrivé à Toronto"),
|
||||
('B', "Qu'il était supposé arriver à Toronto"),
|
||||
('C', "Qu'est-ce qu'il fout ce maudit pancake, tabernacle ?"),
|
||||
('D', "La réponse D"),
|
||||
], string=u"Lorsqu'un pancake prend l'avion à destination de Toronto et "
|
||||
u"qu'il fait une escale technique à St Claude, on dit:"),
|
||||
'html': fields.html(),
|
||||
'text': fields.text(),
|
||||
}
|
||||
char = fields.Char()
|
||||
integer = fields.Integer()
|
||||
float = fields.Float()
|
||||
numeric = fields.Float(digits=(16, 2))
|
||||
many2one = fields.Many2one('web_editor.converter.test.sub')
|
||||
binary = fields.Binary()
|
||||
date = fields.Date()
|
||||
datetime = fields.Datetime()
|
||||
selection = fields.Selection([
|
||||
(1, "réponse A"),
|
||||
(2, "réponse B"),
|
||||
(3, "réponse C"),
|
||||
(4, "réponse <D>"),
|
||||
])
|
||||
selection_str = fields.Selection([
|
||||
('A', "Qu'il n'est pas arrivé à Toronto"),
|
||||
('B', "Qu'il était supposé arriver à Toronto"),
|
||||
('C', "Qu'est-ce qu'il fout ce maudit pancake, tabernacle ?"),
|
||||
('D', "La réponse D"),
|
||||
], string=u"Lorsqu'un pancake prend l'avion à destination de Toronto et "
|
||||
u"qu'il fait une escale technique à St Claude, on dit:")
|
||||
html = fields.Html()
|
||||
text = fields.Text()
|
||||
|
||||
|
||||
class test_converter_sub(orm.Model):
|
||||
class ConverterTestSub(models.Model):
|
||||
_name = 'web_editor.converter.test.sub'
|
||||
|
||||
_columns = {
|
||||
'name': fields.char(),
|
||||
}
|
||||
name = fields.Char()
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
<span class="text-muted">— or — </span>
|
||||
<label for="iamgeurl">Add an image URL</label>
|
||||
<div class="form-group btn-group">
|
||||
<input class="form-control url pull-left" id="iamgeurl" name="url" placeholder="http://openerp.com/logo.png" style="width: 320px;" type="text"/>
|
||||
<input class="form-control url pull-left" id="iamgeurl" name="url" placeholder="https://www.odoo.com/logo.png" style="width: 320px;" type="text"/>
|
||||
<button class="btn btn-default" type="submit">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -238,7 +238,7 @@
|
||||
<label class="control-label" for="link-external">URL or Email Address
|
||||
</label>
|
||||
</h4>
|
||||
<input class="form-control url email-address url-source" id="link-external" placeholder="http://openerp.com" type="text"/>
|
||||
<input class="form-control url email-address url-source" id="link-external" placeholder="https://www.odoo.com" type="text"/>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="form-horizontal link-style">
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import test_ui
|
||||
import test_converter
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import textwrap
|
||||
import unittest
|
||||
|
||||
from lxml import etree, html
|
||||
from lxml.builder import E
|
||||
|
||||
from openerp.tests import common
|
||||
from openerp.addons.web_editor.models.ir_qweb import html_to_text
|
||||
from odoo.tests import common
|
||||
from odoo.addons.web_editor.models.ir_qweb import html_to_text
|
||||
|
||||
|
||||
class TestHTMLToText(unittest.TestCase):
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import openerp.tests
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import odoo.tests
|
||||
|
||||
|
||||
class TestUi(openerp.tests.HttpCase):
|
||||
class TestUi(odoo.tests.HttpCase):
|
||||
|
||||
post_install = True
|
||||
at_install = False
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<odoo>
|
||||
|
||||
<template id="layout" name="Editor layout"><!DOCTYPE html>
|
||||
<html t-att-lang="lang and lang.replace('_', '-')"
|
||||
@@ -66,4 +66,4 @@
|
||||
</t>
|
||||
</template>
|
||||
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'Base Kanban',
|
||||
'category': 'Hidden',
|
||||
@@ -9,7 +12,7 @@ Odoo Web kanban view.
|
||||
'version': '2.0',
|
||||
'depends': ['web'],
|
||||
'data' : [
|
||||
'views/web_kanban.xml',
|
||||
'views/web_kanban_templates.xml',
|
||||
],
|
||||
'qweb' : [
|
||||
'static/src/xml/*.xml',
|
||||
|
||||
+2
-4
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<template id="assets_backend" name="web_kanban assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<link rel="stylesheet" href="/web_kanban/static/src/less/kanban_dashboard.less"/>
|
||||
@@ -15,5 +14,4 @@
|
||||
<script type="text/javascript" src="/web_kanban/static/src/js/compatibility.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -0,0 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'Gauge Widget for Kanban',
|
||||
'category': 'Hidden',
|
||||
@@ -7,7 +10,7 @@ This widget allows to display gauges using d3 library.
|
||||
'version': '1.0',
|
||||
'depends': ['web_kanban'],
|
||||
'data' : [
|
||||
'views/web_kanban_gauge.xml',
|
||||
'views/web_kanban_gauge_templates.xml',
|
||||
],
|
||||
'qweb': [
|
||||
],
|
||||
|
||||
+2
-4
@@ -1,10 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<template id="assets_backend" name="web_kanban_gauge assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/web_kanban_gauge/static/src/js/kanban_gauge.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -1,4 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'Planner',
|
||||
'category': 'Extra Tools',
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import web_planner
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from urllib import urlencode
|
||||
|
||||
from openerp import api, models, fields
|
||||
from odoo import api, models, fields
|
||||
|
||||
|
||||
class Planner(models.Model):
|
||||
@@ -11,8 +13,8 @@ class Planner(models.Model):
|
||||
Each Planner has link to ir.ui.menu record that is a top menu used to display the
|
||||
planner launcher(progressbar)
|
||||
|
||||
Method _prepare_<planner_application>_data(self, cr, uid, context) that
|
||||
generate the values used to display in specific planner pages
|
||||
Method _prepare_<planner_application>_data(self) (model method) that
|
||||
generates the values used to display in specific planner pages
|
||||
"""
|
||||
|
||||
_name = 'web.planner'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import controllers
|
||||
import models
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'Odoo Settings Dashboard',
|
||||
'version': '1.0',
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import main
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from openerp import http
|
||||
from openerp.exceptions import AccessError
|
||||
from openerp.http import request
|
||||
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from odoo import fields, http
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class WebSettingsDashboard(http.Controller):
|
||||
@@ -47,7 +48,7 @@ class WebSettingsDashboard(http.Controller):
|
||||
|
||||
# See update.py for this computation
|
||||
limit_date = datetime.now() - timedelta(15)
|
||||
enterprise_users = request.env['res.users'].search_count([("login_date", ">=", limit_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT)), ('share', '=', False)])
|
||||
enterprise_users = request.env['res.users'].search_count([("login_date", ">=", fields.Datetime.to_string(limit_date)), ('share', '=', False)])
|
||||
|
||||
return {
|
||||
'apps': {
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import res_users
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp import models, api
|
||||
from odoo import models, api
|
||||
|
||||
|
||||
class Users(models.Model):
|
||||
class ResUsers(models.Model):
|
||||
_inherit = 'res.users'
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import models
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'Tours',
|
||||
'category': 'Hidden',
|
||||
@@ -10,8 +12,8 @@ Odoo Web tours.
|
||||
'version': '0.1',
|
||||
'depends': ['web'],
|
||||
'data': [
|
||||
'assets.xml',
|
||||
'views/tour.xml'
|
||||
'views/tour_templates.xml',
|
||||
'views/tour_views.xml'
|
||||
],
|
||||
'qweb': [
|
||||
"static/src/xml/*.xml",
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import ir_http
|
||||
import ir_ui_menu
|
||||
import tour
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
from openerp import models
|
||||
from openerp.http import request
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class Http(models.AbstractModel):
|
||||
_inherit = 'ir.http'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<odoo>
|
||||
<data>
|
||||
<template id="assets_common" name="tours assets" inherit_id="web.assets_common">
|
||||
<xpath expr="." position="inside">
|
||||
@@ -17,4 +17,4 @@
|
||||
</xpath>
|
||||
</template>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -1,7 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<odoo>
|
||||
<record id="edit_tour_list" model="ir.ui.view">
|
||||
<field name="model">web_tour.tour</field>
|
||||
<field name="arch" type="xml">
|
||||
@@ -28,5 +26,4 @@
|
||||
<field name="search_view_id" ref="edit_tour_search"/>
|
||||
</record>
|
||||
<menuitem action="edit_tour_action" id="menu_tour_action" parent="base.next_id_2" sequence="5"/>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -13,7 +13,7 @@ import werkzeug.wrappers
|
||||
|
||||
import openerp
|
||||
from openerp.addons.web.controllers.main import WebClient, Binary
|
||||
from openerp.addons.web import http
|
||||
from openerp import http
|
||||
from openerp.http import request
|
||||
from openerp.osv.orm import browse_record
|
||||
from openerp.addons.website.models.website import slug
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.http import request
|
||||
from openerp.osv import orm
|
||||
import ast
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ from openerp.tools.translate import _
|
||||
from openerp.osv import orm, osv, fields
|
||||
from openerp.tools import html_escape as escape, ustr, image_resize_and_sharpen, image_save_for_web
|
||||
from openerp.tools.safe_eval import safe_eval
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.http import request
|
||||
from werkzeug.exceptions import NotFound
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -7,8 +7,11 @@ from lxml.html import builder as h
|
||||
|
||||
from openerp.tests import common
|
||||
|
||||
|
||||
def attrs(**kwargs):
|
||||
return dict(('data-oe-%s' % key, str(value)) for key, value in kwargs.iteritems())
|
||||
|
||||
|
||||
class TestViewSaving(common.TransactionCase):
|
||||
def eq(self, a, b):
|
||||
self.assertEqual(a.tag, b.tag)
|
||||
@@ -42,8 +45,7 @@ class TestViewSaving(common.TransactionCase):
|
||||
})
|
||||
|
||||
def test_embedded_extraction(self):
|
||||
fields = self.registry('ir.ui.view').extract_embedded_fields(
|
||||
self.cr, self.uid, self.arch, context=None)
|
||||
fields = self.env['ir.ui.view'].extract_embedded_fields(self.arch)
|
||||
|
||||
expect = [
|
||||
h.SPAN("My Company", attrs(model='res.company', id=1, field='name', type='char')),
|
||||
@@ -56,7 +58,7 @@ class TestViewSaving(common.TransactionCase):
|
||||
embedded = h.SPAN("+00 00 000 00 0 000", attrs(
|
||||
model='res.company', id=1, field='phone', type='char'))
|
||||
|
||||
self.registry('ir.ui.view').save_embedded_field(self.cr, self.uid, embedded)
|
||||
self.env['ir.ui.view'].save_embedded_field(embedded)
|
||||
|
||||
company = self.registry('res.company').browse(self.cr, self.uid, 1)
|
||||
self.assertEqual(company.phone, "+00 00 000 00 0 000")
|
||||
@@ -66,37 +68,37 @@ class TestViewSaving(common.TransactionCase):
|
||||
e1 = h.SPAN("My Company", attrs(model='res.company', id=1, field='name'))
|
||||
e2 = h.SPAN("Leeroy Jenkins", attrs(model='res.company', id=1, field='name'))
|
||||
|
||||
View = self.registry('ir.ui.view')
|
||||
View = self.env['ir.ui.view']
|
||||
|
||||
View.save_embedded_field(self.cr, self.uid, e1)
|
||||
View.save_embedded_field(e1)
|
||||
# FIXME: more precise exception
|
||||
with self.assertRaises(Exception):
|
||||
View.save_embedded_field(self.cr, self.uid, e2)
|
||||
View.save_embedded_field(e2)
|
||||
|
||||
def test_embedded_to_field_ref(self):
|
||||
View = self.registry('ir.ui.view')
|
||||
View = self.env['ir.ui.view']
|
||||
embedded = h.SPAN("My Company", attrs(expression="bob"))
|
||||
self.eq(
|
||||
View.to_field_ref(self.cr, self.uid, embedded, context=None),
|
||||
View.to_field_ref(embedded),
|
||||
h.SPAN({'t-field': 'bob'})
|
||||
)
|
||||
|
||||
def test_to_field_ref_keep_attributes(self):
|
||||
View = self.registry('ir.ui.view')
|
||||
View = self.env['ir.ui.view']
|
||||
|
||||
att = attrs(expression="bob", model="res.company", id=1, field="name")
|
||||
att['id'] = "whop"
|
||||
att['class'] = "foo bar"
|
||||
embedded = h.SPAN("My Company", att)
|
||||
|
||||
self.eq(View.to_field_ref(self.cr, self.uid, embedded, context=None),
|
||||
self.eq(View.to_field_ref(embedded),
|
||||
h.SPAN({'t-field': 'bob', 'class': 'foo bar', 'id': 'whop'}))
|
||||
|
||||
def test_replace_arch(self):
|
||||
replacement = h.P("Wheee")
|
||||
|
||||
result = self.registry('ir.ui.view').replace_arch_section(
|
||||
self.cr, self.uid, self.view_id, None, replacement)
|
||||
self.cr, self.uid, [self.view_id], None, replacement)
|
||||
|
||||
self.eq(result, h.DIV("Wheee"))
|
||||
|
||||
@@ -104,7 +106,7 @@ class TestViewSaving(common.TransactionCase):
|
||||
replacement = h.DIV(h.P("Wheee"))
|
||||
|
||||
result = self.registry('ir.ui.view').replace_arch_section(
|
||||
self.cr, self.uid, self.view_id, None, replacement)
|
||||
self.cr, self.uid, [self.view_id], None, replacement)
|
||||
|
||||
self.eq(result, replacement)
|
||||
|
||||
@@ -112,7 +114,7 @@ class TestViewSaving(common.TransactionCase):
|
||||
replacement = h.H1("I am the greatest title alive!")
|
||||
|
||||
result = self.registry('ir.ui.view').replace_arch_section(
|
||||
self.cr, self.uid, self.view_id, '/div/div[1]/h3',
|
||||
self.cr, self.uid, [self.view_id], '/div/div[1]/h3',
|
||||
replacement)
|
||||
|
||||
self.eq(result, h.DIV(
|
||||
@@ -134,12 +136,12 @@ class TestViewSaving(common.TransactionCase):
|
||||
def test_multiple_xpath_matches(self):
|
||||
with self.assertRaises(ValueError):
|
||||
self.registry('ir.ui.view').replace_arch_section(
|
||||
self.cr, self.uid, self.view_id, '/div/div/h3',
|
||||
self.cr, self.uid, [self.view_id], '/div/div/h3',
|
||||
h.H6("Lol nope"))
|
||||
|
||||
def test_save(self):
|
||||
Company = self.registry('res.company')
|
||||
View = self.registry('ir.ui.view')
|
||||
View = self.env['ir.ui.view']
|
||||
|
||||
replacement = ET.tostring(h.DIV(
|
||||
h.H3("Column 2"),
|
||||
@@ -149,14 +151,13 @@ class TestViewSaving(common.TransactionCase):
|
||||
h.LI(h.SPAN("+12 3456789", attrs(model='res.company', id=1, field='phone', expression="edmund", type='char'))),
|
||||
)
|
||||
), encoding='utf-8')
|
||||
View.save(self.cr, self.uid, res_id=self.view_id, value=replacement,
|
||||
xpath='/div/div[2]')
|
||||
View.browse(self.view_id).save(value=replacement, xpath='/div/div[2]')
|
||||
|
||||
company = Company.browse(self.cr, self.uid, 1)
|
||||
self.assertEqual(company.name, "Acme Corporation")
|
||||
self.assertEqual(company.phone, "+12 3456789")
|
||||
self.eq(
|
||||
ET.fromstring(View.browse(self.cr, self.uid, self.view_id).arch.encode('utf-8')),
|
||||
ET.fromstring(View.browse(self.view_id).arch.encode('utf-8')),
|
||||
h.DIV(
|
||||
h.DIV(
|
||||
h.H3("Column 1"),
|
||||
@@ -180,7 +181,7 @@ class TestViewSaving(common.TransactionCase):
|
||||
'arch':'<t><p><h1>hello world</h1></p></t>',
|
||||
'type':'qweb'
|
||||
})
|
||||
view = self.registry('ir.ui.view').browse(self.cr, self.uid, view_id)
|
||||
view = self.env['ir.ui.view'].browse(view_id)
|
||||
# script and style text nodes should not escaped client side
|
||||
replacement = '<script>1 && "hello & world"</script>'
|
||||
view.save(replacement, xpath='/t/p/h1')
|
||||
@@ -212,26 +213,25 @@ class TestViewSaving(common.TransactionCase):
|
||||
node = html.tostring(h.SPAN(
|
||||
"Acme Corporation",
|
||||
attrs(model='res.company', id=company_id, field="name", expression='bob', type='char')))
|
||||
|
||||
self.registry('ir.ui.view').save(self.cr, self.uid, res_id=company_id,value=node)
|
||||
View = self.env['ir.ui.view']
|
||||
View.browse(company_id).save(value=node)
|
||||
|
||||
company = Company.browse(self.cr, self.uid, company_id)
|
||||
self.assertEqual(company.name, "Acme Corporation")
|
||||
|
||||
|
||||
def test_field_tail(self):
|
||||
View = self.registry('ir.ui.view')
|
||||
View = self.env['ir.ui.view']
|
||||
replacement = ET.tostring(
|
||||
h.LI(h.SPAN("+12 3456789", attrs(
|
||||
model='res.company', id=1, type='char',
|
||||
field='phone', expression="edmund")),
|
||||
"whop whop"
|
||||
), encoding="utf-8")
|
||||
View.save(self.cr, self.uid, res_id = self.view_id, value=replacement,
|
||||
xpath='/div/div[2]/ul/li[3]')
|
||||
View.browse(self.view_id).save(value=replacement, xpath='/div/div[2]/ul/li[3]')
|
||||
|
||||
self.eq(
|
||||
ET.fromstring(View.browse(self.cr, self.uid, self.view_id).arch.encode('utf-8')),
|
||||
ET.fromstring(View.browse(self.view_id).arch.encode('utf-8')),
|
||||
h.DIV(
|
||||
h.DIV(
|
||||
h.H3("Column 1"),
|
||||
|
||||
@@ -5,8 +5,8 @@ import json
|
||||
import werkzeug
|
||||
|
||||
from openerp import tools
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp import http
|
||||
from openerp.http import request
|
||||
from openerp.addons.website.models.website import slug, unslug
|
||||
from odoo.addons.website.controllers.main import QueryURL
|
||||
from openerp.exceptions import UserError
|
||||
|
||||
@@ -7,8 +7,8 @@ import werkzeug
|
||||
from collections import OrderedDict
|
||||
|
||||
from odoo import fields
|
||||
from odoo.addons.web import http
|
||||
from odoo.addons.web.http import request
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
from odoo.addons.website.models.website import slug, unslug
|
||||
from odoo.addons.website_partner.controllers.main import WebsitePartnerPage
|
||||
from odoo.tools.translate import _
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
|
||||
import openerp
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.addons.web import http
|
||||
from openerp import http
|
||||
from openerp.addons.website.models.website import unslug
|
||||
from openerp.tools.translate import _
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.http import request
|
||||
import werkzeug.urls
|
||||
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ import base64
|
||||
|
||||
import openerp
|
||||
from openerp import tools, _
|
||||
from openerp.addons.web import http
|
||||
from openerp import http
|
||||
from openerp.addons.web.controllers.main import binary_content
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.http import request
|
||||
from openerp.addons.website.models.website import slug
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
import json
|
||||
|
||||
from odoo.addons.web import http
|
||||
from odoo.addons.web.http import request
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
from odoo.tools import html_escape as escape
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import werkzeug
|
||||
|
||||
from openerp.addons.web import http
|
||||
from openerp import http
|
||||
from openerp.http import request
|
||||
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ import werkzeug.urls
|
||||
|
||||
from odoo import fields
|
||||
|
||||
from odoo.addons.web import http
|
||||
from odoo.addons.web.http import request
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
from odoo.addons.website.models.website import unslug
|
||||
from odoo.tools.translate import _
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp import http
|
||||
from openerp.http import request
|
||||
import werkzeug
|
||||
import datetime
|
||||
import time
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp import http
|
||||
from openerp.http import request
|
||||
|
||||
import datetime
|
||||
from werkzeug.exceptions import NotFound
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import urlparse
|
||||
|
||||
from odoo import http
|
||||
from odoo.addons.web.http import request
|
||||
from odoo.http import request
|
||||
|
||||
from odoo.addons.website_mail.controllers.main import WebsiteMail
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import base64
|
||||
import logging
|
||||
import werkzeug
|
||||
|
||||
from openerp.addons.web import http
|
||||
from openerp import http
|
||||
from openerp.exceptions import AccessError, UserError
|
||||
from openerp.http import request
|
||||
from openerp.tools.translate import _
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
import json
|
||||
from odoo import _
|
||||
from odoo.addons.web import http
|
||||
from odoo.addons.web.http import request
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class Twitter(http.Controller):
|
||||
|
||||
@@ -10,7 +10,7 @@ from collections import OrderedDict
|
||||
|
||||
from openerp import api, models, tools
|
||||
from openerp.tools import safe_eval
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.http import request
|
||||
from odoo.modules.module import get_resource_path
|
||||
import json
|
||||
from time import time
|
||||
|
||||
Reference in New Issue
Block a user