[MERGE] xmo great-addons-cleanup-of-2011-xmo

Fixed loading of addons, including basic loading of CSS files whern loading addons
Also fixed content type of AjaxIM poll method.

bzr revid: al@openerp.com-20110414135837-ov0y0olvol4omxzh
This commit is contained in:
Antony Lesuisse 2011-04-14 15:58:37 +02:00
commit a0d4acefb1
17 changed files with 219 additions and 209 deletions

View File

@ -58,13 +58,17 @@ class Xml2Json:
class Session(openerpweb.Controller):
_cp_path = "/base/session"
def manifest_glob(self, modlist, key):
def manifest_glob(self, addons, key):
files = []
for i in modlist:
globlist = openerpweb.addons_manifest.get(i, {}).get(key, [])
for j in globlist:
for k in glob.glob(os.path.join(openerpweb.path_addons, i, j)):
files.append(k[len(openerpweb.path_addons):])
for addon in addons:
globlist = openerpweb.addons_manifest.get(addon, {}).get(key, [])
files.extend([
resource_path[len(openerpweb.path_addons):]
for pattern in globlist
for resource_path in glob.glob(os.path.join(
openerpweb.path_addons, addon, pattern))
])
return files
def concat_files(self, file_list):
@ -96,14 +100,16 @@ class Session(openerpweb.Controller):
@openerpweb.jsonrequest
def modules(self, req):
return {"modules": ["base", "base_hello", "base_calendar", "base_gantt"]}
return {"modules": [name
for name, manifest in openerpweb.addons_manifest.iteritems()
if manifest.get('active', True)]}
@openerpweb.jsonrequest
def csslist(self, req, mods='base,base_hello'):
def csslist(self, req, mods='base'):
return {'files': self.manifest_glob(mods.split(','), 'css')}
@openerpweb.jsonrequest
def jslist(self, req, mods='base,base_hello'):
def jslist(self, req, mods='base'):
return {'files': self.manifest_glob(mods.split(','), 'js')}
def css(self, req, mods='base,base_hello'):

View File

@ -23,33 +23,11 @@
<script type="text/javascript" src="/base/static/src/js/list.js"></script>
<script type="text/javascript" src="/base/static/src/js/search.js"></script>
<script type="text/javascript" src="/base/static/src/js/views.js"></script>
<script type="text/javascript" src="/base_diagram/static/src/js/diagram.js"></script>
<script type="text/javascript" src="/base_diagram/static/lib/js/raphael-min.js"></script>
<script type="text/javascript" src="/base_diagram/static/lib/js/dracula_graffle.js"></script>
<script type="text/javascript" src="/base_diagram/static/lib/js/dracula_graph.js"></script>
<script type="text/javascript" src="/base_gantt/static/lib/dhtmlxGantt/codebase/dhtmlxcommon.js"></script>
<script type="text/javascript" src="/base_gantt/static/lib/dhtmlxGantt/codebase/dhtmlxgantt.js"></script>
<script type="text/javascript" src="/base_gantt/static/src/gantt.js"></script>
<script type="text/javascript" src="/base_calendar/static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.js"></script>
<script type="text/javascript" src="/base_calendar/static/src/js/calendar.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.jsonp-1.1.0.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.jstore-all-min.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.md5.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/im.js"></script>
<link rel="stylesheet" type="text/css" media="screen" href="/base/static/lib/jquery.ui/css/smoothness/jquery-ui-1.8.9.custom.css" />
<link rel="stylesheet" type="text/css" media="screen" href="/base/static/lib/jquery.ui.notify/css/ui.notify.css" />
<link rel="stylesheet" type="text/css" href="/base/static/lib/jquery.superfish/css/superfish.css" media="screen">
<link rel="stylesheet" type="text/css" media="screen" href="/base_gantt/static/lib/dhtmlxGantt/codebase/dhtmlxgantt.css" />
<link rel="stylesheet" type="text/css" media="screen" href="/base_calendar/static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.css">
<link rel="stylesheet" href="/base/static/src/css/base.css" type="text/css"/>
<script type="text/javascript">
@ -58,18 +36,6 @@
oe.base.webclient("oe");
});
</script>
<script>
var AjaxIM, AjaxIMLoadedFunction;
$(function() {
AjaxIM.init({
pollServer: '/web_chat/pollserver',
theme: '/web_chat/static/lib/AjaxIM/themes/default',
flashStorage: '/web_chat/static/lib/AjaxIM/js/jStore.Flash.html'
});
AjaxIM.client.login();
});
</script>
</head>
<body id="oe" class="openerp">
</body>

View File

@ -126,9 +126,6 @@ openerp.base = function(instance) {
openerp.base.search(instance);
openerp.base.list(instance);
openerp.base.form(instance);
openerp.base.calendar(instance);
openerp.base.gantt(instance);
openerp.base.diagram(instance);
};
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:

View File

@ -450,10 +450,21 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b
var self = this;
this.rpc('/base/session/modules', {}, function(result) {
self.module_list = result['modules'];
self.rpc('/base/session/jslist', {"mods": self.module_list.join(',')}, self.debug ? self.do_load_modules_debug : self.do_load_modules_prod);
var modules = self.module_list.join(',');
self.rpc('/base/session/csslist', {mods: modules}, self.do_load_css);
self.rpc('/base/session/jslist', {"mods": modules}, self.debug ? self.do_load_modules_debug : self.do_load_modules_prod);
openerp._modules_loaded = true;
});
},
do_load_css: function (result) {
_.each(result.files, function (file) {
$('head').append($('<link>', {
'href': file,
'rel': 'stylesheet',
'type': 'text/css'
}));
});
},
do_load_modules_debug: function(result) {
$LAB.setOptions({AlwaysPreserveOrder: true})
.script(result.files)
@ -466,16 +477,15 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b
// use $.getScript(your_3rd_party-script.js); ? i want to keep lineno !
},
on_modules_loaded: function() {
var self = this;
for(var j=0; j<self.module_list.length; j++) {
var mod = self.module_list[j];
if(self.module_loaded[mod])
for(var j=0; j<this.module_list.length; j++) {
var mod = this.module_list[j];
if(this.module_loaded[mod])
continue;
openerp[mod] = {};
// init module mod
if(openerp._openerp[mod] != undefined) {
openerp._openerp[mod](openerp);
self.module_loaded[mod] = true;
this.module_loaded[mod] = true;
}
}
}
@ -491,7 +501,7 @@ openerp.base.Controller = openerp.base.BasicController.extend( /** @lends opener
controller_manifest: {
register: null,
template: "",
element_post_prefix: false,
element_post_prefix: false
},
/**
* Controller registry,
@ -702,7 +712,7 @@ openerp.base.CrashManager = openerp.base.Controller.extend({
openerp.base.Loading = openerp.base.Controller.extend({
controller_manifest: {
register: ["Loading"],
register: ["Loading"]
},
init: function(session, element_id) {
this._super(session, element_id);

View File

@ -231,10 +231,6 @@
<button type="button" name="delete"></button>
</td>
</tr>
<t t-name="DiagramView">
<h2 class="oe_view_title"><t t-esc="fields_view.arch.attrs.string"/></h2>
<div id="dia-canvas" style="overflow: auto;"></div>
</t>
<t t-name="FormView">
<h2 class="oe_view_title"><t t-esc="view.fields_view.arch.attrs.string"/></h2>
<div class="oe_form_header" t-att-id="view.element_id + '_header'">
@ -574,48 +570,4 @@
</p>
</div>
</t>
<t t-name="CalendarView">
<h3 class="title"><t t-esc="view.fields_view.arch.attrs.string"/></h3>
<table class="calendar-view" width="100%" height="100%" cellspacing="0" cellpadding="0">
<tr>
<td>
<div style="height: 1000px;width: 100%;">
<div id="calendar-sidebar">
</div>
</div>
</td>
<td style="width:85%;" align="left">
<div id="openerp_scheduler" class="dhx_cal_container" style="height: 1000px;width: 100%;">
<div class="dhx_cal_navline">
<div class="dhx_cal_prev_button"></div>
<div class="dhx_cal_next_button"></div>
<div class="dhx_cal_today_button"></div>
<div class="dhx_cal_date"></div>
<div class="dhx_minical_icon" id="dhx_minical_icon"></div>
<div class="dhx_cal_tab" name="day_tab" style="right:204px;"></div>
<div class="dhx_cal_tab" name="week_tab" style="right:140px;"></div>
<div class="dhx_cal_tab" name="month_tab" style="right:76px;"></div>
</div>
<div class="dhx_cal_header">
</div>
<div class="dhx_cal_data">
</div>
</div>
</td>
</tr>
</table>
</t>
<t t-name="GanttView">
<h3 class="title"><t t-esc="view.fields_view.arch.attrs.string"/></h3>
<table class="gantt-view" width="100%" height="100%" cellspacing="0" cellpadding="0">
<tr>
<td style="width:85%">
<div style="width:100%;height:300px;position:relative" id="GanttDiv"></div>
</td>
<td valign = "top">
<div id="gantt-sidebar"></div>
</td>
</tr>
</table>
</t>
</templates>

View File

@ -1,57 +1,11 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
"name" : "Basic Calendar Functionality",
"version" : "1.0",
"depends" : ["base"],
'description': """
This is a full-featured calendar system.
========================================
It supports:
- Calendar of events
- Alerts (create requests)
- Recurring events
- Invitations to people""",
"author" : "OpenERP SA",
'category': 'Tools',
'website': 'http://www.openerp.com',
"init_xml" : [
'base_calendar_data.xml'
"name": "Base calendar",
"version": "2.0",
"depends": ['base'],
"js": [
'static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.js',
'static/src/js/calendar.js'
],
"demo_xml" : [],
"update_xml" : [
'security/calendar_security.xml',
'security/ir.model.access.csv',
'wizard/calendar_event_edit_all_view.xml',
'wizard/base_calendar_invite_attendee_view.xml',
'wizard/base_calendar_set_exrule_view.xml',
'base_calendar_view.xml'
],
"test" : ['test/base_calendar_test.yml'],
"installable" : True,
"active" : False,
"certificate" : "00694071962960352821",
'images': ['images/base_calendar1.jpeg','images/base_calendar2.jpeg','images/base_calendar3.jpeg','images/base_calendar4.jpeg',],
"css": ['static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.css'],
'active': True
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -2,10 +2,10 @@
* OpenERP base_calendar
*---------------------------------------------------------*/
openerp.base.calendar = function(openerp) {
openerp.base.views.add('calendar', 'openerp.base.CalendarView');
openerp.base.CalendarView = openerp.base.Controller.extend({
openerp.base_calendar = function(openerp) {
QWeb.add_template('/base_calendar/static/src/xml/base_calendar.xml');
openerp.base.views.add('calendar', 'openerp.base_calendar.CalendarView');
openerp.base_calendar.CalendarView = openerp.base.Controller.extend({
// Dhtmlx scheduler ?
init: function(view_manager, session, element_id, dataset, view_id){
this._super(session, element_id);
@ -201,7 +201,7 @@ openerp.base.CalendarView = openerp.base.Controller.extend({
do_hide: function () {
this.$element.hide();
},
}
});
//openerp.base.Action = openerp.base.Action.extend({

View File

@ -0,0 +1,33 @@
<template>
<t t-name="CalendarView">
<h3 class="title"><t t-esc="view.fields_view.arch.attrs.string"/></h3>
<table class="calendar-view" width="100%" height="100%" cellspacing="0" cellpadding="0">
<tr>
<td>
<div style="height: 1000px;width: 100%;">
<div id="calendar-sidebar">
</div>
</div>
</td>
<td style="width:85%;" align="left">
<div id="openerp_scheduler" class="dhx_cal_container" style="height: 1000px;width: 100%;">
<div class="dhx_cal_navline">
<div class="dhx_cal_prev_button"/>
<div class="dhx_cal_next_button"/>
<div class="dhx_cal_today_button"/>
<div class="dhx_cal_date"/>
<div class="dhx_minical_icon" id="dhx_minical_icon"/>
<div class="dhx_cal_tab" name="day_tab" style="right:204px;"/>
<div class="dhx_cal_tab" name="week_tab" style="right:140px;"/>
<div class="dhx_cal_tab" name="month_tab" style="right:76px;"/>
</div>
<div class="dhx_cal_header">
</div>
<div class="dhx_cal_data">
</div>
</div>
</td>
</tr>
</table>
</t>
</template>

View File

@ -2,5 +2,5 @@
"name" : "OpenERP Web base Diagram",
"version" : "2.0",
"depends" : [],
'active': True,
'active': False,
}

View File

@ -1,7 +1,12 @@
{
"name": "Base Gantt",
"version": "2.0",
"depends": [],
"js": ["static/*/js/*.js"],
"css": [],
"depends": ['base'],
"js": [
'static/lib/dhtmlxGantt/codebase/dhtmlxcommon.js',
'static/lib/dhtmlxGantt/codebase/dhtmlxgantt.js',
'static/src/js/gantt.js'
],
"css": ['static/lib/dhtmlxGantt/codebase/dhtmlxgantt.css'],
'active': True
}

View File

@ -2,9 +2,10 @@
* OpenERP base_gantt
*---------------------------------------------------------*/
openerp.base.gantt = function (openerp) {
openerp.base.views.add('gantt', 'openerp.base.GanttView');
openerp.base.GanttView = openerp.base.Controller.extend({
openerp.base_gantt = function (openerp) {
QWeb.add_template('/base_gantt/static/src/xml/base_gantt.xml');
openerp.base.views.add('gantt', 'openerp.base_gantt.GanttView');
openerp.base_gantt.GanttView = openerp.base.Controller.extend({
init: function(view_manager, session, element_id, dataset, view_id) {
this._super(session, element_id);
@ -216,7 +217,7 @@ openerp.base.GanttView = openerp.base.Controller.extend({
},
function(result) {
})
},
}
});

View File

@ -0,0 +1,15 @@
<template>
<t t-name="GanttView">
<h3 class="title"><t t-esc="view.fields_view.arch.attrs.string"/></h3>
<table class="gantt-view" width="100%" height="100%" cellspacing="0" cellpadding="0">
<tr>
<td style="width:85%">
<div style="width:100%;height:300px;position:relative" id="GanttDiv"/>
</td>
<td valign = "top">
<div id="gantt-sidebar"/>
</td>
</tr>
</table>
</t>
</template>

View File

@ -1,8 +1,14 @@
{
"name": "Web Chat",
"version": "2.0",
"depends": [],
"js": [],
"depends": ['base'],
"js": [
'static/lib/AjaxIM/js/jquery.jsonp-1.1.0.js',
'static/lib/AjaxIM/js/jquery.jstore-all-min.js',
'static/lib/AjaxIM/js/jquery.md5.js',
'static/lib/AjaxIM/js/im.js',
'static/src/js/web_chat.js'
],
"css": [],
'active': True,
'active': False,
}

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import sys, time
import cherrypy
import simplejson
import random
@ -102,11 +103,6 @@ class PollServer(openerpweb.Controller):
@openerpweb.httprequest
def poll(self, req, **kw):
mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
# Method: Long Poll
"""
--> GET http://im.ajaxim.com/poll?callback=jsonp1302138663582&_1302138663582=
<-- 200 OK
@ -129,8 +125,14 @@ class PollServer(openerpweb.Controller):
echo '<script type="text/javascript">parent.AjaxIM.incoming('. json_encode($this->_pollParseMessages($messages)) . ');</script>'
"""
mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
# Method: Long Poll
msg = '[]'
cherrypy.response.headers['content-type'] = 'application/javascript';
for i in range(5):
received_msg = mq.read('Guest1', i)
@ -145,12 +147,6 @@ class PollServer(openerpweb.Controller):
@openerpweb.httprequest
def send(self, req, **kw):
to = kw.get('to')
message = kw.get('message')
mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
"""
--> GET http://im.ajaxim.com/send?callback=jsonp1302139980022&to=Guest130205108745.47&message=test&_1302139980022=
callback: jsonp1302139980022
@ -168,6 +164,12 @@ class PollServer(openerpweb.Controller):
"""
to = kw.get('to')
message = kw.get('message')
mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
if not req.applicationsession['current_user']:
return dict(r='error', e='no session found')
@ -182,8 +184,6 @@ class PollServer(openerpweb.Controller):
@openerpweb.httprequest
def status(self, req, **kw):
mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
"""
--> GET status call
const Offline = 0;
@ -198,6 +198,8 @@ class PollServer(openerpweb.Controller):
return array('r' => 'error', 'e' => 'no session found');
return array('r' => 'error', 'e' => 'status error');
"""
mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
print "======== chat status ========",kw
# mq.write()
return {"action": ""}

View File

@ -0,0 +1,10 @@
openerp.web_chat = function (openerp) {
openerp.web_chat = {};
openerp.web_chat.im = new AjaxIM({
storageMethod: 'local',
pollServer: '/web_chat/pollserver',
theme: '/web_chat/static/lib/AjaxIM/themes/default',
flashStorage: '/web_chat/static/lib/AjaxIM/js/jStore.Flash.html'
});
openerp.web_chat.im.login();
};

View File

@ -1,24 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery-1.3.2.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.jsonp-1.1.0.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.jstore-all-min.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.md5.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/im.js"></script>
</head>
<body>
<script>
var AjaxIM, AjaxIMLoadedFunction;
$(function() {
AjaxIM.init({
pollServer: '/web_chat/pollserver',
theme: '/web_chat/static/lib/AjaxIM/themes/default',
flashStorage: '/web_chat/static/lib/AjaxIM/js/jStore.Flash.html'
});
AjaxIM.client.login();
});
</script>
</body>
</html>

View File

@ -1,6 +1,10 @@
Developing OpenERP Web Addons
=============================
An OpenERP Web addon is simply a Python package with an openerp
descriptor (a ``__openerp__.py`` file) which follows a few structural
and namespacing rules.
Structure
---------
@ -50,6 +54,79 @@ Structure
``test/``
The directories in which all tests for the addon are located.
Some of these are guidelines (and not enforced by code), but it's
suggested that these be followed. Code which does not fit into these
categories can go wherever deemed suitable.
Namespacing
-----------
Python
++++++
Because addons are also Python packages, they're inherently namespaced
and nothing special needs to be done on that front.
JavaScript
++++++++++
The JavaScript side of an addon has to live in the namespace
``openerp.$addon_name``. For instance, everything created by the addon
``base`` lives in ``openerp.base``.
The root namespace of the addon is a function which takes a single
parameter ``openerp``, which is an OpenERP client instance. Objects
(as well as functions, registry instances, etc...) should be added on
the correct namespace on that object.
The root function will be called by the OpenERP Web client when
initializing the addon.
.. code-block:: javascript
// root namespace of the openerp.example addon
/** @namespace */
openerp.example = function (openerp) {
// basic initialization code (e.g. templates loading)
openerp.example.SomeClass = Class.extend(
/** @lends openerp.example.SomeClass# */{
/**
* Description for SomeClass's constructor here
*
* @constructs
*/
init: function () {
// SomeClass initialization code
}
// rest of SomeClass
});
// access an object in an other addon namespace to replace it
openerp.base.SearchView = openerp.base.SearchView.extend({
init: function () {
this._super.apply(this, arguments);
console.log('Search view initialized');
}
});
}
Utility behaviors
-----------------
JavaScript
++++++++++
* All javascript objects inheriting from
:js:class:`openerp.base.BasicConroller` will have all methods
starting with ``on_`` or ``do_`` bound to their ``this``. This means
they don't have to be manually bound (via ``_.bind`` or ``$.proxy``)
in order to be useable as bound event handlers (event handlers
keeping their object as ``this`` rather than taking whatever
``this`` object they were called with).
Beware that this is only valid for methods starting with ``do_`` and
``on_``, any other method will have to be bound manually.
.. _addons-testing:
Testing