2011-03-02 18:56:06 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2011-03-10 15:53:45 +00:00
|
|
|
import glob, os
|
|
|
|
from xml.etree import ElementTree
|
2011-03-24 20:11:25 +00:00
|
|
|
from cStringIO import StringIO
|
2011-03-02 18:56:06 +00:00
|
|
|
|
2011-03-10 15:53:45 +00:00
|
|
|
import simplejson
|
2011-03-02 18:56:06 +00:00
|
|
|
|
|
|
|
import openerpweb
|
2011-03-28 12:27:24 +00:00
|
|
|
import openerpweb.ast
|
|
|
|
import openerpweb.nonliterals
|
2011-03-02 18:56:06 +00:00
|
|
|
|
2011-03-28 09:18:09 +00:00
|
|
|
__all__ = ['Session', 'Menu', 'DataSet', 'DataRecord',
|
|
|
|
'View', 'FormView', 'ListView', 'SearchView',
|
|
|
|
'Action']
|
2011-03-03 14:55:52 +00:00
|
|
|
|
|
|
|
class Xml2Json:
|
|
|
|
# xml2json-direct
|
|
|
|
# Simple and straightforward XML-to-JSON converter in Python
|
|
|
|
# New BSD Licensed
|
|
|
|
#
|
|
|
|
# URL: http://code.google.com/p/xml2json-direct/
|
|
|
|
@staticmethod
|
|
|
|
def convert_to_json(s):
|
2011-03-28 14:19:20 +00:00
|
|
|
return simplejson.dumps(
|
|
|
|
Xml2Json.convert_to_structure(s), sort_keys=True, indent=4)
|
2011-03-03 14:55:52 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def convert_to_structure(s):
|
|
|
|
root = ElementTree.fromstring(s)
|
|
|
|
return Xml2Json.convert_element(root)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def convert_element(el, skip_whitespaces=True):
|
|
|
|
res = {}
|
2011-03-21 08:13:31 +00:00
|
|
|
if el.tag[0] == "{":
|
|
|
|
ns, name = el.tag.rsplit("}", 1)
|
2011-03-03 14:55:52 +00:00
|
|
|
res["tag"] = name
|
|
|
|
res["namespace"] = ns[1:]
|
|
|
|
else:
|
|
|
|
res["tag"] = el.tag
|
|
|
|
res["attrs"] = {}
|
2011-03-21 08:13:31 +00:00
|
|
|
for k, v in el.items():
|
2011-03-03 14:55:52 +00:00
|
|
|
res["attrs"][k] = v
|
|
|
|
kids = []
|
|
|
|
if el.text and (not skip_whitespaces or el.text.strip() != ''):
|
|
|
|
kids.append(el.text)
|
|
|
|
for kid in el:
|
|
|
|
kids.append(Xml2Json.convert_element(kid))
|
|
|
|
if kid.tail and (not skip_whitespaces or kid.tail.strip() != ''):
|
2011-03-08 14:55:30 +00:00
|
|
|
kids.append(kid.tail)
|
2011-03-16 17:20:42 +00:00
|
|
|
res["children"] = kids
|
2011-03-03 14:55:52 +00:00
|
|
|
return res
|
|
|
|
|
2011-03-02 18:56:06 +00:00
|
|
|
#----------------------------------------------------------
|
|
|
|
# OpenERP Web base Controllers
|
|
|
|
#----------------------------------------------------------
|
|
|
|
|
2011-03-10 11:51:23 +00:00
|
|
|
class Session(openerpweb.Controller):
|
|
|
|
_cp_path = "/base/session"
|
|
|
|
|
2011-03-08 11:19:54 +00:00
|
|
|
def manifest_glob(self, modlist, key):
|
|
|
|
files = []
|
2011-03-11 13:26:22 +00:00
|
|
|
for i in modlist:
|
|
|
|
globlist = openerpweb.addons_manifest.get(i, {}).get(key, [])
|
2011-03-08 11:19:54 +00:00
|
|
|
for j in globlist:
|
2011-03-11 13:26:22 +00:00
|
|
|
for k in glob.glob(os.path.join(openerpweb.path_addons, i, j)):
|
|
|
|
files.append(k[len(openerpweb.path_addons):])
|
2011-03-08 11:19:54 +00:00
|
|
|
return files
|
|
|
|
|
|
|
|
def concat_files(self, file_list):
|
2011-03-02 18:56:06 +00:00
|
|
|
""" Concatenate file content
|
|
|
|
return (concat,timestamp)
|
|
|
|
concat: concatenation of file content
|
|
|
|
timestamp: max(os.path.getmtime of file_list)
|
|
|
|
"""
|
2011-03-07 09:26:32 +00:00
|
|
|
root = openerpweb.path_root
|
2011-03-02 18:56:06 +00:00
|
|
|
files_content = []
|
|
|
|
files_timestamp = 0
|
|
|
|
for i in file_list:
|
2011-03-21 08:13:31 +00:00
|
|
|
fname = os.path.join(root, i)
|
2011-03-02 18:56:06 +00:00
|
|
|
ftime = os.path.getmtime(fname)
|
|
|
|
if ftime > files_timestamp:
|
|
|
|
files_timestamp = ftime
|
|
|
|
files_content = open(fname).read()
|
|
|
|
files_concat = "".join(files_content)
|
|
|
|
return files_concat
|
|
|
|
|
2011-03-11 13:26:22 +00:00
|
|
|
@openerpweb.jsonrequest
|
|
|
|
def login(self, req, db, login, password):
|
2011-03-17 15:01:53 +00:00
|
|
|
req.session.login(db, login, password)
|
2011-03-17 17:14:03 +00:00
|
|
|
return {
|
2011-03-21 08:13:31 +00:00
|
|
|
"session_id": req.session_id,
|
2011-03-11 13:26:22 +00:00
|
|
|
"uid": req.session._uid,
|
|
|
|
}
|
|
|
|
|
|
|
|
@openerpweb.jsonrequest
|
|
|
|
def modules(self, req):
|
2011-03-17 14:53:21 +00:00
|
|
|
return {"modules": ["base", "base_hello", "base_calendar"]}
|
2011-03-11 13:26:22 +00:00
|
|
|
|
2011-03-10 11:51:23 +00:00
|
|
|
@openerpweb.jsonrequest
|
|
|
|
def csslist(self, req, mods='base,base_hello'):
|
|
|
|
return {'files': self.manifest_glob(mods.split(','), 'css')}
|
2011-03-08 11:19:54 +00:00
|
|
|
|
|
|
|
@openerpweb.jsonrequest
|
2011-03-10 11:51:23 +00:00
|
|
|
def jslist(self, req, mods='base,base_hello'):
|
|
|
|
return {'files': self.manifest_glob(mods.split(','), 'js')}
|
2011-03-08 11:19:54 +00:00
|
|
|
|
2011-03-10 11:51:23 +00:00
|
|
|
def css(self, req, mods='base,base_hello'):
|
2011-03-08 11:19:54 +00:00
|
|
|
files = self.manifest_glob(mods.split(','), 'css')
|
2011-03-08 14:57:54 +00:00
|
|
|
concat = self.concat_files(files)[0]
|
2011-03-02 18:56:06 +00:00
|
|
|
# TODO request set the Date of last modif and Etag
|
|
|
|
return concat
|
2011-03-21 08:13:31 +00:00
|
|
|
css.exposed = True
|
2011-03-02 18:56:06 +00:00
|
|
|
|
2011-03-10 11:51:23 +00:00
|
|
|
def js(self, req, mods='base,base_hello'):
|
2011-03-08 11:19:54 +00:00
|
|
|
files = self.manifest_glob(mods.split(','), 'js')
|
2011-03-08 14:57:54 +00:00
|
|
|
concat = self.concat_files(files)[0]
|
2011-03-02 18:56:06 +00:00
|
|
|
# TODO request set the Date of last modif and Etag
|
|
|
|
return concat
|
2011-03-21 08:13:31 +00:00
|
|
|
js.exposed = True
|
|
|
|
|
2011-03-25 12:32:52 +00:00
|
|
|
@openerpweb.jsonrequest
|
2011-03-28 16:39:17 +00:00
|
|
|
def eval_domain_and_context(self, req, contexts, domains,
|
|
|
|
group_by_seq=None):
|
|
|
|
""" Evaluates sequences of domains and contexts, composing them into
|
|
|
|
a single context, domain or group_by sequence.
|
|
|
|
|
|
|
|
:param list contexts: list of contexts to merge together. Contexts are
|
|
|
|
evaluated in sequence, all previous contexts
|
|
|
|
are part of their own evaluation context
|
|
|
|
(starting at the session context).
|
|
|
|
:param list domains: list of domains to merge together. Domains are
|
|
|
|
evaluated in sequence and appended to one another
|
|
|
|
(implicit AND), their evaluation domain is the
|
|
|
|
result of merging all contexts.
|
|
|
|
:param list group_by_seq: list of domains (which may be in a different
|
|
|
|
order than the ``contexts`` parameter),
|
|
|
|
evaluated in sequence, their ``'group_by'``
|
|
|
|
key is extracted if they have one.
|
|
|
|
:returns:
|
|
|
|
a 3-dict of:
|
|
|
|
|
|
|
|
context (``dict``)
|
|
|
|
the global context created by merging all of
|
|
|
|
``contexts``
|
|
|
|
|
|
|
|
domain (``list``)
|
|
|
|
the concatenation of all domains
|
|
|
|
|
|
|
|
group_by (``list``)
|
|
|
|
a list of fields to group by, potentially empty (in which case
|
|
|
|
no group by should be performed)
|
|
|
|
"""
|
2011-03-25 12:32:52 +00:00
|
|
|
context = req.session.eval_contexts(contexts)
|
|
|
|
domain = req.session.eval_domains(domains, context)
|
2011-03-28 16:39:17 +00:00
|
|
|
|
|
|
|
group_by_sequence = []
|
|
|
|
for candidate in (group_by_seq or []):
|
|
|
|
ctx = req.session.eval_context(candidate, context)
|
|
|
|
group_by = ctx.get('group_by')
|
|
|
|
if not group_by:
|
|
|
|
continue
|
|
|
|
elif isinstance(group_by, basestring):
|
|
|
|
group_by_sequence.append(group_by)
|
|
|
|
else:
|
|
|
|
group_by_sequence.extend(group_by)
|
|
|
|
|
2011-03-25 12:32:52 +00:00
|
|
|
return {
|
|
|
|
'context': context,
|
2011-03-28 16:39:17 +00:00
|
|
|
'domain': domain,
|
|
|
|
'group_by': group_by_sequence
|
2011-03-25 12:32:52 +00:00
|
|
|
}
|
2011-03-02 18:56:06 +00:00
|
|
|
|
|
|
|
class Menu(openerpweb.Controller):
|
|
|
|
_cp_path = "/base/menu"
|
|
|
|
|
|
|
|
@openerpweb.jsonrequest
|
2011-03-21 08:13:31 +00:00
|
|
|
def load(self, req):
|
2011-03-21 10:47:35 +00:00
|
|
|
return {'data': self.do_load(req)}
|
|
|
|
|
|
|
|
def do_load(self, req):
|
|
|
|
""" Loads all menu items (all applications and their sub-menus).
|
|
|
|
|
|
|
|
:param req: A request object, with an OpenERP session attribute
|
|
|
|
:type req: < session -> OpenERPSession >
|
|
|
|
:return: the menu root
|
|
|
|
:rtype: dict('children': menu_nodes)
|
|
|
|
"""
|
2011-03-21 08:43:24 +00:00
|
|
|
Menus = req.session.model('ir.ui.menu')
|
2011-03-02 18:56:06 +00:00
|
|
|
# menus are loaded fully unlike a regular tree view, cause there are
|
|
|
|
# less than 512 items
|
2011-03-21 08:43:24 +00:00
|
|
|
menu_ids = Menus.search([])
|
|
|
|
menu_items = Menus.read(menu_ids, ['name', 'sequence', 'parent_id'])
|
2011-03-21 08:13:31 +00:00
|
|
|
menu_root = {'id': False, 'name': 'root', 'parent_id': [-1, '']}
|
2011-03-02 18:56:06 +00:00
|
|
|
menu_items.append(menu_root)
|
2011-03-21 08:43:24 +00:00
|
|
|
|
2011-03-02 18:56:06 +00:00
|
|
|
# make a tree using parent_id
|
2011-03-21 08:43:24 +00:00
|
|
|
menu_items_map = dict((menu_item["id"], menu_item) for menu_item in menu_items)
|
|
|
|
for menu_item in menu_items:
|
2011-03-21 15:40:34 +00:00
|
|
|
if menu_item['parent_id']:
|
|
|
|
parent = menu_item['parent_id'][0]
|
|
|
|
else:
|
|
|
|
parent = False
|
2011-03-21 08:43:24 +00:00
|
|
|
if parent in menu_items_map:
|
2011-03-21 10:47:35 +00:00
|
|
|
menu_items_map[parent].setdefault(
|
|
|
|
'children', []).append(menu_item)
|
2011-03-21 08:43:24 +00:00
|
|
|
|
2011-03-02 18:56:06 +00:00
|
|
|
# sort by sequence a tree using parent_id
|
2011-03-21 08:43:24 +00:00
|
|
|
for menu_item in menu_items:
|
2011-03-21 10:47:35 +00:00
|
|
|
menu_item.setdefault('children', []).sort(
|
2011-03-21 08:43:24 +00:00
|
|
|
key=lambda x:x["sequence"])
|
2011-03-14 09:38:25 +00:00
|
|
|
|
2011-03-21 10:47:35 +00:00
|
|
|
return menu_root
|
2011-03-02 18:56:06 +00:00
|
|
|
|
|
|
|
@openerpweb.jsonrequest
|
2011-03-21 08:13:31 +00:00
|
|
|
def action(self, req, menu_id):
|
2011-03-25 09:41:19 +00:00
|
|
|
Values = req.session.model('ir.values')
|
|
|
|
actions = Values.get('action', 'tree_but_open', [('ir.ui.menu', menu_id)], False, {})
|
|
|
|
|
|
|
|
for _, _, action in actions:
|
2011-03-28 14:19:20 +00:00
|
|
|
# values come from the server, we can just eval them
|
2011-03-28 15:14:10 +00:00
|
|
|
if isinstance(action['context'], basestring):
|
|
|
|
action['context'] = eval(
|
|
|
|
action['context'],
|
|
|
|
req.session.evaluation_context()) or {}
|
2011-03-28 14:19:20 +00:00
|
|
|
|
|
|
|
if isinstance(action['domain'], basestring):
|
|
|
|
action['domain'] = eval(
|
|
|
|
action['domain'],
|
|
|
|
req.session.evaluation_context(
|
|
|
|
action['context'])) or []
|
2011-03-25 09:41:19 +00:00
|
|
|
|
|
|
|
return {"action": actions}
|
2011-03-02 18:56:06 +00:00
|
|
|
|
2011-03-21 08:13:31 +00:00
|
|
|
|
2011-03-02 18:56:06 +00:00
|
|
|
class DataSet(openerpweb.Controller):
|
|
|
|
_cp_path = "/base/dataset"
|
|
|
|
|
|
|
|
@openerpweb.jsonrequest
|
2011-03-21 08:13:31 +00:00
|
|
|
def fields(self, req, model):
|
2011-03-22 19:10:43 +00:00
|
|
|
return {'fields': req.session.model(model).fields_get()}
|
2011-03-02 18:56:06 +00:00
|
|
|
|
|
|
|
@openerpweb.jsonrequest
|
2011-03-23 08:34:41 +00:00
|
|
|
def find(self, request, model, fields=False, offset=0, limit=False,
|
|
|
|
domain=None, context=None, sort=None):
|
2011-03-23 09:08:01 +00:00
|
|
|
return self.do_find(request, model, fields, offset, limit,
|
|
|
|
domain, context, sort)
|
|
|
|
def do_find(self, request, model, fields=False, offset=0, limit=False,
|
|
|
|
domain=None, context=None, sort=None):
|
2011-03-23 12:08:06 +00:00
|
|
|
""" Performs a search() followed by a read() (if needed) using the
|
2011-03-23 12:21:26 +00:00
|
|
|
provided search criteria
|
|
|
|
|
|
|
|
:param request: a JSON-RPC request object
|
|
|
|
:type request: openerpweb.JsonRequest
|
2011-03-28 09:18:09 +00:00
|
|
|
:param str model: the name of the model to search on
|
2011-03-23 12:21:26 +00:00
|
|
|
:param fields: a list of the fields to return in the result records
|
|
|
|
:type fields: [str]
|
2011-03-28 09:18:09 +00:00
|
|
|
:param int offset: from which index should the results start being returned
|
|
|
|
:param int limit: the maximum number of records to return
|
|
|
|
:param list domain: the search domain for the query
|
|
|
|
:param dict context: the context in which the search should be executed
|
|
|
|
:param list sort: sorting directives
|
2011-03-23 12:21:26 +00:00
|
|
|
:returns: a list of result records
|
2011-03-23 12:22:17 +00:00
|
|
|
:rtype: list
|
2011-03-23 12:08:06 +00:00
|
|
|
"""
|
2011-03-23 08:34:41 +00:00
|
|
|
Model = request.session.model(model)
|
|
|
|
ids = Model.search(domain or [], offset or 0, limit or False,
|
|
|
|
sort or False, context or False)
|
|
|
|
if fields and fields == ['id']:
|
|
|
|
# shortcut read if we only want the ids
|
|
|
|
return map(lambda id: {'id': id}, ids)
|
|
|
|
return Model.read(ids, fields or False)
|
2011-03-02 18:56:06 +00:00
|
|
|
|
2011-03-23 12:08:06 +00:00
|
|
|
@openerpweb.jsonrequest
|
|
|
|
def get(self, request, model, ids):
|
|
|
|
self.do_get(request, model, ids)
|
|
|
|
|
|
|
|
def do_get(self, request, model, ids):
|
|
|
|
""" Fetches and returns the records of the model ``model`` whose ids
|
|
|
|
are in ``ids``.
|
|
|
|
|
|
|
|
The results are in the same order as the inputs, but elements may be
|
|
|
|
missing (if there is no record left for the id)
|
|
|
|
|
|
|
|
:param request: the JSON-RPC2 request object
|
|
|
|
:type request: openerpweb.JsonRequest
|
|
|
|
:param model: the model to read from
|
|
|
|
:type model: str
|
|
|
|
:param ids: a list of identifiers
|
|
|
|
:type ids: list
|
2011-03-23 12:21:26 +00:00
|
|
|
:returns: a list of records, in the same order as the list of ids
|
|
|
|
:rtype: list
|
2011-03-23 12:08:06 +00:00
|
|
|
"""
|
|
|
|
Model = request.session.model(model)
|
|
|
|
records = Model.read(ids)
|
|
|
|
|
|
|
|
record_map = dict((record['id'], record) for record in records)
|
|
|
|
|
|
|
|
return [record_map[id] for id in ids if record_map.get(id)]
|
2011-03-21 08:13:31 +00:00
|
|
|
|
2011-03-17 14:06:38 +00:00
|
|
|
class DataRecord(openerpweb.Controller):
|
|
|
|
_cp_path = "/base/datarecord"
|
2011-03-21 08:13:31 +00:00
|
|
|
|
2011-03-17 14:06:38 +00:00
|
|
|
@openerpweb.jsonrequest
|
2011-03-21 08:13:31 +00:00
|
|
|
def load(self, req, model, id, fields):
|
2011-03-17 14:06:38 +00:00
|
|
|
m = req.session.model(model)
|
|
|
|
value = {}
|
|
|
|
r = m.read([id])
|
|
|
|
if r:
|
|
|
|
value = r[0]
|
|
|
|
return {'value': value}
|
|
|
|
|
2011-03-24 20:11:25 +00:00
|
|
|
class View(openerpweb.Controller):
|
|
|
|
def fields_view_get(self, session, model, view_id, view_type, transform=True):
|
|
|
|
Model = session.model(model)
|
|
|
|
r = Model.fields_view_get(view_id, view_type)
|
|
|
|
if transform:
|
|
|
|
context = {} # TODO: dict(ctx_sesssion, **ctx_action)
|
2011-03-28 12:27:24 +00:00
|
|
|
xml = self.transform_view(r['arch'], session, context)
|
2011-03-24 20:11:25 +00:00
|
|
|
else:
|
|
|
|
xml = ElementTree.fromstring(r['arch'])
|
|
|
|
r['arch'] = Xml2Json.convert_element(xml)
|
|
|
|
return r
|
2011-03-28 08:31:12 +00:00
|
|
|
|
|
|
|
def normalize_attrs(self, elem, context):
|
|
|
|
""" Normalize @attrs, @invisible, @required, @readonly and @states, so
|
|
|
|
the client only has to deal with @attrs.
|
|
|
|
|
|
|
|
See `the discoveries pad <http://pad.openerp.com/discoveries>`_ for
|
|
|
|
the rationale.
|
|
|
|
|
|
|
|
:param elem: the current view node (Python object)
|
|
|
|
:type elem: xml.etree.ElementTree.Element
|
|
|
|
:param dict context: evaluation context
|
|
|
|
"""
|
|
|
|
# If @attrs is normalized in json by server, the eval should be replaced by simplejson.loads
|
|
|
|
attrs = eval(elem.attrib.get('attrs', '{}'))
|
|
|
|
if 'states' in elem.attrib:
|
|
|
|
if 'invisible' not in attrs:
|
|
|
|
attrs['invisible'] = []
|
|
|
|
# This should be done by the server
|
|
|
|
attrs['invisible'].append(('state', 'in', elem.attrib['states'].split(',')))
|
|
|
|
del(elem.attrib['states'])
|
|
|
|
if attrs:
|
|
|
|
elem.attrib['attrs'] = simplejson.dumps(attrs)
|
|
|
|
for a in ['invisible', 'readonly', 'required']:
|
|
|
|
if a in elem.attrib:
|
|
|
|
# In the XML we trust
|
|
|
|
avalue = bool(eval(elem.attrib.get(a, 'False'),
|
|
|
|
{'context': context or {}}))
|
|
|
|
if not avalue:
|
|
|
|
del elem.attrib[a]
|
|
|
|
else:
|
|
|
|
elem.attrib[a] = '1'
|
|
|
|
if a == 'invisible' and 'attrs' in elem.attrib:
|
|
|
|
del elem.attrib['attrs']
|
|
|
|
|
2011-03-28 12:27:24 +00:00
|
|
|
def transform_view(self, view_string, session, context=None):
|
2011-03-28 08:31:12 +00:00
|
|
|
# transform nodes on the fly via iterparse, instead of
|
|
|
|
# doing it statically on the parsing result
|
|
|
|
parser = ElementTree.iterparse(StringIO(view_string), events=("start",))
|
2011-03-24 20:11:25 +00:00
|
|
|
root = None
|
|
|
|
for event, elem in parser:
|
|
|
|
if event == "start":
|
|
|
|
if root is None:
|
|
|
|
root = elem
|
2011-03-28 08:31:12 +00:00
|
|
|
self.normalize_attrs(elem, context)
|
2011-03-28 12:27:24 +00:00
|
|
|
self.parse_domains_and_contexts(elem, session)
|
2011-03-24 20:11:25 +00:00
|
|
|
return root
|
|
|
|
|
2011-03-28 12:27:24 +00:00
|
|
|
def parse_domains_and_contexts(self, elem, session):
|
|
|
|
""" Converts domains and contexts from the view into Python objects,
|
|
|
|
either literals if they can be parsed by literal_eval or a special
|
|
|
|
placeholder object if the domain or context refers to free variables.
|
|
|
|
|
|
|
|
:param elem: the current node being parsed
|
|
|
|
:type param: xml.etree.ElementTree.Element
|
|
|
|
:param session: OpenERP session object, used to store and retrieve
|
|
|
|
non-literal objects
|
|
|
|
:type session: openerpweb.openerpweb.OpenERPSession
|
|
|
|
"""
|
|
|
|
domain = elem.get('domain')
|
|
|
|
if domain:
|
|
|
|
try:
|
|
|
|
elem.set(
|
|
|
|
'domain',
|
|
|
|
openerpweb.ast.literal_eval(
|
|
|
|
domain))
|
|
|
|
except ValueError:
|
|
|
|
# not a literal
|
|
|
|
elem.set('domain',
|
|
|
|
openerpweb.nonliterals.Domain(session, domain))
|
2011-03-28 15:14:10 +00:00
|
|
|
context_string = elem.get('context')
|
|
|
|
if context_string:
|
|
|
|
try:
|
|
|
|
elem.set('context',
|
|
|
|
openerpweb.ast.literal_eval(context_string))
|
|
|
|
except ValueError:
|
|
|
|
elem.set('context',
|
|
|
|
openerpweb.nonliterals.Context(
|
|
|
|
session, context_string))
|
2011-03-28 12:27:24 +00:00
|
|
|
|
2011-03-24 20:11:25 +00:00
|
|
|
class FormView(View):
|
2011-03-02 18:56:06 +00:00
|
|
|
_cp_path = "/base/formview"
|
2011-03-21 08:13:31 +00:00
|
|
|
|
2011-03-02 18:56:06 +00:00
|
|
|
@openerpweb.jsonrequest
|
2011-03-21 08:13:31 +00:00
|
|
|
def load(self, req, model, view_id):
|
2011-03-24 20:11:25 +00:00
|
|
|
fields_view = self.fields_view_get(req.session, model, view_id, 'form')
|
|
|
|
return {'fields_view': fields_view}
|
2011-03-21 08:13:31 +00:00
|
|
|
|
2011-03-02 18:56:06 +00:00
|
|
|
|
2011-03-24 20:11:25 +00:00
|
|
|
class ListView(View):
|
2011-03-02 18:56:06 +00:00
|
|
|
_cp_path = "/base/listview"
|
2011-03-21 08:13:31 +00:00
|
|
|
|
2011-03-02 18:56:06 +00:00
|
|
|
@openerpweb.jsonrequest
|
2011-03-21 08:13:31 +00:00
|
|
|
def load(self, req, model, view_id):
|
2011-03-24 20:11:25 +00:00
|
|
|
fields_view = self.fields_view_get(req.session, model, view_id, 'tree')
|
|
|
|
return {'fields_view': fields_view}
|
2011-03-21 08:13:31 +00:00
|
|
|
|
2011-03-02 18:56:06 +00:00
|
|
|
|
2011-03-24 20:11:25 +00:00
|
|
|
class SearchView(View):
|
2011-03-02 18:56:06 +00:00
|
|
|
_cp_path = "/base/searchview"
|
2011-03-21 08:13:31 +00:00
|
|
|
|
2011-03-02 18:56:06 +00:00
|
|
|
@openerpweb.jsonrequest
|
2011-03-21 08:13:31 +00:00
|
|
|
def load(self, req, model, view_id):
|
2011-03-24 20:11:25 +00:00
|
|
|
fields_view = self.fields_view_get(req.session, model, view_id, 'search')
|
|
|
|
return {'fields_view': fields_view}
|
2011-03-21 08:13:31 +00:00
|
|
|
|
2011-03-02 18:56:06 +00:00
|
|
|
|
|
|
|
class Action(openerpweb.Controller):
|
|
|
|
_cp_path = "/base/action"
|
|
|
|
|
|
|
|
@openerpweb.jsonrequest
|
2011-03-21 08:13:31 +00:00
|
|
|
def load(self, req, action_id):
|
2011-03-14 09:38:25 +00:00
|
|
|
return {}
|