[MERGE]Trunk.

bzr revid: vme@tinyerp.com-20130823052005-1ecpnw0590g8tzir
This commit is contained in:
Vidhin Mehta 2013-08-23 10:50:05 +05:30
commit 476e30f869
612 changed files with 44730 additions and 39499 deletions

View File

@ -1,21 +1,15 @@
.*.swp
.bzrignore
.idea
.project
.pydevproject
.ropeproject
.settings
.DS_Store
openerp/addons/*
openerp/filestore*
.Python
*.pyc
*.pyo
bin/*
.*
*.egg-info
*.orig
*.vim
build/
include/
lib/
share/
doc/_build/*
win32/*.bat
win32/meta.py
RE:^bin/
RE:^dist/
RE:^include/
RE:^share/
RE:^man/
RE:^lib/
RE:^addons/\w+/doc/_build/
RE:^.*?/node_modules

3
addons/web/.bowerrc Normal file
View File

@ -0,0 +1,3 @@
{
"directory": "static/lib/"
}

40
addons/web/Gruntfile.js Normal file
View File

@ -0,0 +1,40 @@
module.exports = function(grunt) {
grunt.initConfig({
jshint: {
src: ['static/src/**/*.js', 'static/test/**/*.js'],
options: {
sub: true, //[] instead of .
evil: true, //eval
laxbreak: true, //unsafe line breaks
},
},
sass: {
dev: {
options: {
style: "expanded",
},
files: {
"static/src/css/base.css": "static/src/css/base.sass",
}
}
},
watch: {
sass: {
files: ["static/src/css/base.sass"],
tasks: ['sass']
},
}
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('gen', ["sass"]);
grunt.registerTask('watcher', ["gen", "watch"]);
grunt.registerTask('test', []);
grunt.registerTask('default', ['jshint']);
};

View File

@ -1,7 +1,7 @@
{
'name': 'Web',
'category': 'Hidden',
'version': '7.0.1.0',
'version': '1.0',
'description':
"""
OpenERP Web core module.
@ -9,17 +9,16 @@ OpenERP Web core module.
This module provides the core of the OpenERP Web Client.
""",
'depends': [],
'depends': ['base'],
'auto_install': True,
'post_load': 'wsgi_postload',
'js' : [
"static/src/fixbind.js",
"static/lib/datejs/globalization/en-US.js",
"static/lib/datejs/core.js",
"static/lib/datejs/parser.js",
"static/lib/datejs/sugarpak.js",
"static/lib/datejs/extras.js",
"static/lib/jquery/jquery-1.8.3.js",
"static/lib/jquery/jquery.js",
"static/lib/jquery.MD5/jquery.md5.js",
"static/lib/jquery.form/jquery.form.js",
"static/lib/jquery.validate/jquery.validate.js",
@ -39,24 +38,23 @@ This module provides the core of the OpenERP Web Client.
"static/lib/jquery.timeago/jquery.timeago.js",
"static/lib/qweb/qweb2.js",
"static/lib/underscore/underscore.js",
"static/lib/underscore/underscore.string.js",
"static/lib/underscore.string/lib/underscore.string.js",
"static/lib/backbone/backbone.js",
"static/lib/cleditor/jquery.cleditor.js",
"static/lib/py.js/lib/py.js",
"static/src/js/openerpframework.js",
"static/src/js/boot.js",
"static/src/js/testing.js",
"static/src/js/pyeval.js",
"static/src/js/corelib.js",
"static/src/js/coresetup.js",
"static/src/js/dates.js",
"static/src/js/core.js",
"static/src/js/formats.js",
"static/src/js/chrome.js",
"static/src/js/views.js",
"static/src/js/data.js",
"static/src/js/data_export.js",
"static/src/js/search.js",
"static/src/js/view_form.js",
"static/src/js/view_list.js",
"static/src/js/view_form.js",
"static/src/js/view_list_editable.js",
"static/src/js/view_tree.js",
],
@ -75,16 +73,16 @@ This module provides the core of the OpenERP Web Client.
],
'test': [
"static/test/testing.js",
"static/test/class.js",
"static/test/framework.js",
"static/test/registry.js",
"static/test/form.js",
"static/test/data.js",
"static/test/list-utils.js",
"static/test/formats.js",
"static/test/rpc.js",
"static/test/jsonrpc.js",
"static/test/rpc-misordered.js",
"static/test/evals.js",
"static/test/search.js",
"static/test/Widget.js",
"static/test/list.js",
"static/test/list-editable.js",
"static/test/mutex.js"

17
addons/web/bower.json Normal file
View File

@ -0,0 +1,17 @@
{
"name": "web",
"version": "0.0.0",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"jquery": "1.8.3",
"underscore": "1.3.1",
"underscore.string": "2.2.1",
"qweb": "git@github.com:OpenERP/qweb.git#~1.0.0"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,8 @@ from openerp.modules import module
from .main import module_topological_sort
from .. import http
from ..http import request
NOMODULE_TEMPLATE = Template(u"""<!DOCTYPE html>
<html>
<head>
@ -86,9 +88,8 @@ TESTING = Template(u"""<!DOCTYPE html>
""", default_filters=['h'])
class TestRunnerController(http.Controller):
_cp_path = '/web/tests'
@http.httprequest
@http.route('/web/tests', type='http', auth="none")
def index(self, req, mod=None, **kwargs):
ms = module.get_modules()
manifests = dict(
@ -163,3 +164,11 @@ class TestRunnerController(http.Controller):
for path in glob.glob(normalized_pattern):
# replace OS path separators (from join & normpath) by URI ones
yield path[len(root):].replace(os.path.sep, '/')
@http.route('/web/tests/set_session_value', type='json', auth="none")
def set_session_value(self, value):
request.session.some_test_value = value
@http.route('/web/tests/get_session_value', type='json', auth="none")
def get_session_value(self):
return request.session.some_test_value

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -6,32 +6,49 @@
Welcome to OpenERP Web's documentation!
=======================================
Contents:
Basics
------
.. toctree::
:maxdepth: 1
module
widget
changelog-7.0
Server-Side Web Framework
-------------------------
async
rpc
qweb
client_action
.. toctree::
:maxdepth: 1
web_controllers
Javascript
----------
.. toctree::
:maxdepth: 1
guidelines
widget
rpc
async
qweb
client_action
testing
Views
-----
.. toctree::
:maxdepth: 1
search_view
list_view
form_view
changelog-7.0
Indices and tables
==================
------------------
* :ref:`genindex`
* :ref:`modindex`

View File

@ -0,0 +1,173 @@
Web Controllers
===============
Web controllers are classes in OpenERP able to catch the http requests sent by any browser. They allow to generate
html pages to be served like any web server, implement new methods to be used by the Javascript client, etc...
Controllers File
----------------
By convention the controllers should be placed in the controllers directory of the module. Example:
.. code-block:: text
web_example
├── controllers
│ ├── __init__.py
│ └── my_controllers.py
├── __init__.py
└── __openerp__.py
In ``__init__.py`` you must add:
::
import controllers
And here is the content of ``controllers/__init__.py``:
::
import my_controllers
Now you can put the following content in ``controllers/my_controllers.py``:
::
import openerp.addons.web.http as http
from openerp.addons.web.http import request
Controller Declaration
----------------------
In your controllers file, you can now declare a controller this way:
::
class MyController(http.Controller):
@http.route('/my_url/some_html', type="http")
def some_html(self):
return "<h1>This is a test</h1>"
@http.route('/my_url/some_json', type="json")
def some_json(self):
return {"sample_dictionary": "This is a sample JSON dictionary"}
A controller must inherit from ``http.Controller``. Each time you define a method with ``@http.route()`` it defines a
url to match. As example, the ``some_html()`` method will be called a client query the ``/my_url/some_html`` url.
Pure HTTP Requests
------------------
You can define methods to get any normal http requests by passing ``'http'`` to the ``type`` argument of
``http.route()``. When doing so, you get the HTTP parameters as named parameters of the method:
::
@http.route('/say_hello', type="http")
def say_hello(self, name):
return "<h1>Hello %s</h1>" % name
This url could be contacted by typing this url in a browser: ``http://localhost:8069/say_hello?name=Nicolas``.
JSON Requests
-------------
Methods that received JSON can be defined by passing ``'json'`` to the ``type`` argument of ``http.route()``. The
OpenERP Javascript client can contact these methods using the JSON-RPC protocol. JSON methods must return JSON. Like the
HTTP methods they receive arguments as named parameters (except these arguments are JSON-RPC parameters).
::
@http.route('/division', type="json")
def division(self, i, j):
return i / j # returns a number
URL Patterns
------------
Any URL passed to ``http.route()`` can contain patterns. Example:
::
@http.route('/files/<path:file_path>', type="http")
def files(self, file_path):
... # return a file identified by the path store in the 'my_path' variable
When such patterns are used, the method will received additional parameters that correspond to the parameters defined in
the url. For exact documentation about url patterns, see Werkzeug's documentation:
http://werkzeug.pocoo.org/docs/routing/ .
Also note you can pass multiple urls to ``http.route()``:
::
@http.route(['/files/<path:file_path>', '/other_url/<path:file_path>'], type="http")
def files(self, file_path):
...
Contacting Models
-----------------
To use the database you must access the OpenERP models. The global ``request`` object provides the necessary objects:
::
@http.route('/my_name', type="http")
def my_name(self):
my_user_record = request.registry.get("res.users").browse(request.cr, request.uid, request.uid)
return "<h1>Your name is %s</h1>" % my_user_record.name
``request.registry`` is the registry that gives you access to the models. It is the equivalent of ``self.pool`` when
working inside OpenERP models.
``request.cr`` is the cursor object. This is the ``cr`` parameter you have to pass as first argument of every model
method in OpenERP.
``request.uid`` is the id of the current logged in user. This is the ``uid`` parameter you have to pass as second
argument of every model method in OpenERP.
Authorization Levels
--------------------
By default, all access to the models will use the rights of the currently logged in user (OpenERP uses cookies to track
logged users). It is also impossible to reach an URL without being logged (the user's browser will receive an HTTP
error).
There are some cases when the current user is not relevant, and we just want to give access to anyone to an URL. A
typical example is be the generation of a home page for a website. The home page should be visible by anyone, whether
they have an account or not. To do so, add the ``'admin'`` value to the ``auth`` parameter of ``http.route()``:
::
@http.route('/hello', type="http", auth="admin")
def hello(self):
return "<div>Hello unknown user!</div>"
When using the ``admin`` authentication the access to the OpenERP models will be performed with the ``Administrator``
user and ``request.uid`` will be equal to ``openerp.SUPERUSER_ID`` (the id of the administrator).
It is important to note that when using the ``Administrator`` user all security is bypassed. So the programmers
implementing such methods should take great care of not creating security issues in the application.
Overriding Controllers
----------------------
Existing routes can be overridden. To do so, create a controller that inherit the controller containing the route you
want to override. Example that redefine the home page of your OpenERP application.
::
import openerp.addons.web.controllers.main as main
class Home2(main.Home):
@http.route('/', type="http", auth="db")
def index(self):
return "<div>This is my new home page.</div>"
By re-defining the ``index()`` method, you change the behavior of the original ``Home`` class. Now the ``'/'`` route
will match the new ``index()`` method in ``Home2``.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2601
addons/web/i18n/vi.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

8
addons/web/package.json Normal file
View File

@ -0,0 +1,8 @@
{
"devDependencies": {
"grunt": "*",
"grunt-contrib-jshint": "*",
"grunt-contrib-sass": "~0.4.1",
"grunt-contrib-watch": "~0.5.1"
}
}

View File

@ -1,179 +0,0 @@
#!/usr/bin/python
import datetime
import babel
import dateutil.relativedelta
import logging
import time
import traceback
import sys
import openerp
_logger = logging.getLogger(__name__)
#----------------------------------------------------------
# OpenERPSession RPC openerp backend access
#----------------------------------------------------------
class AuthenticationError(Exception):
pass
class SessionExpiredException(Exception):
pass
class Service(object):
def __init__(self, session, service_name):
self.session = session
self.service_name = service_name
def __getattr__(self, method):
def proxy_method(*args):
result = self.session.send(self.service_name, method, *args)
return result
return proxy_method
class Model(object):
def __init__(self, session, model):
self.session = session
self.model = model
self.proxy = self.session.proxy('object')
def __getattr__(self, method):
self.session.assert_valid()
def proxy(*args, **kw):
result = self.proxy.execute_kw(self.session._db, self.session._uid, self.session._password, self.model, method, args, kw)
# reorder read
if method == "read":
if isinstance(result, list) and len(result) > 0 and "id" in result[0]:
index = {}
for r in result:
index[r['id']] = r
result = [index[x] for x in args[0] if x in index]
return result
return proxy
def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None, context=None):
record_ids = self.search(domain or [], offset, limit or False, order or False, context or {})
if not record_ids: return []
records = self.read(record_ids, fields or [], context or {})
return records
class OpenERPSession(object):
"""
An OpenERP RPC session, a given user can own multiple such sessions
in a web session.
.. attribute:: context
The session context, a ``dict``. Can be reloaded by calling
:meth:`openerpweb.openerpweb.OpenERPSession.get_context`
.. attribute:: domains_store
A ``dict`` matching domain keys to evaluable (but non-literal) domains.
Used to store references to non-literal domains which need to be
round-tripped to the client browser.
"""
def __init__(self):
self._creation_time = time.time()
self._db = False
self._uid = False
self._login = False
self._password = False
self._suicide = False
self.context = {}
self.jsonp_requests = {} # FIXME use a LRU
def send(self, service_name, method, *args):
return openerp.netsvc.dispatch_rpc(service_name, method, args)
def proxy(self, service):
return Service(self, service)
def bind(self, db, uid, login, password):
self._db = db
self._uid = uid
self._login = login
self._password = password
def authenticate(self, db, login, password, env=None):
uid = self.proxy('common').authenticate(db, login, password, env)
self.bind(db, uid, login, password)
if uid: self.get_context()
return uid
def assert_valid(self, force=False):
"""
Ensures this session is valid (logged into the openerp server)
"""
if self._uid and not force:
return
# TODO use authenticate instead of login
self._uid = self.proxy("common").login(self._db, self._login, self._password)
if not self._uid:
raise AuthenticationError("Authentication failure")
def ensure_valid(self):
if self._uid:
try:
self.assert_valid(True)
except Exception:
self._uid = None
def execute(self, model, func, *l, **d):
model = self.model(model)
r = getattr(model, func)(*l, **d)
return r
def exec_workflow(self, model, id, signal):
self.assert_valid()
r = self.proxy('object').exec_workflow(self._db, self._uid, self._password, model, signal, id)
return r
def model(self, model):
""" Get an RPC proxy for the object ``model``, bound to this session.
:param model: an OpenERP model name
:type model: str
:rtype: a model object
"""
if self._db == False:
raise SessionExpiredException("Session expired")
return Model(self, model)
def get_context(self):
""" Re-initializes the current user's session context (based on
his preferences) by calling res.users.get_context() with the old
context
:returns: the new context
"""
assert self._uid, "The user needs to be logged-in to initialize his context"
self.context = self.model('res.users').context_get() or {}
self.context['uid'] = self._uid
self._fix_lang(self.context)
return self.context
def _fix_lang(self, context):
""" OpenERP provides languages which may not make sense and/or may not
be understood by the web client's libraries.
Fix those here.
:param dict context: context to fix
"""
lang = context['lang']
# inane OpenERP locale
if lang == 'ar_AR':
lang = 'ar'
# lang to lang_REGION (datejs only handles lang_REGION, no bare langs)
if lang in babel.core.LOCALE_ALIASES:
lang = babel.core.LOCALE_ALIASES[lang]
context['lang'] = lang or 'en_US'
# vim:et:ts=4:sw=4:

View File

@ -296,6 +296,11 @@
// Bind the window resize event when the width or height is auto or %
if (/auto|%/.test("" + options.width + options.height))
$(window).resize(function() {
//Forcefully blurred iframe contentWindow, chrome, IE, safari doesn't trigger blur on window resize and due to which text disappears
var contentWindow = editor.$frame[0].contentWindow;
if(!$.browser.mozilla && contentWindow){
$(contentWindow).trigger('blur');
}
// CHM Note MonkeyPatch: if the DOM is not remove, refresh the cleditor
if(editor.$main.parent().parent().size()) {
refresh(editor);

View File

@ -7,7 +7,7 @@
* date.js // English (United States)
* date-en-US.js // English (United States)
* date-de-DE.js // Deutsch (Deutschland)
* date-es-MX.js // français (France)
* date-es-MX.js // français (France)
*/
alert(
@ -17,5 +17,5 @@ alert(
" date.js // English (United States)\n" +
" date-en-US.js // English (United States)\n" +
" date-de-DE.js // Deutsch (Deutschland)\n" +
" date-es-MX.js // français (France)\n"
" date-es-MX.js // français (France)\n"
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 B

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 B

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 B

After

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

After

Width:  |  Height:  |  Size: 107 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 B

After

Width:  |  Height:  |  Size: 97 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 B

After

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 B

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 B

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 B

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 B

After

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

After

Width:  |  Height:  |  Size: 107 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 B

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 B

After

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

File diff suppressed because it is too large Load Diff

9472
addons/web/static/lib/jquery/jquery.js vendored Normal file

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More