merging
This commit is contained in:
commit
57d3f138ae
9 files changed
+169
-89
No files matched your search
+1
-1
@@ -77,7 +77,7 @@ INHERITS (ir_actions);
|
||||
CREATE TABLE ir_act_report (
|
||||
model varchar(64) NOT NULL,
|
||||
report_name varchar(64) NOT NULL,
|
||||
report_odt varchar(64),
|
||||
report varchar(64),
|
||||
auto boolean default true,
|
||||
primary key(id)
|
||||
)
|
||||
|
||||
+7
-15
@@ -68,8 +68,8 @@ class ActionKeyword(OSV):
|
||||
.read(cursor, user, action_keyword.action.id,
|
||||
context=context))
|
||||
if action_keyword.action.type == 'ir.actions.report':
|
||||
del res[-1]['report_odt_content_data']
|
||||
del res[-1]['report_odt_content']
|
||||
del res[-1]['report_content_data']
|
||||
del res[-1]['report_content']
|
||||
return res
|
||||
|
||||
ActionKeyword()
|
||||
@@ -102,21 +102,17 @@ class ActionsReport(OSV):
|
||||
'type': fields.char('Report Type', size=32, required=True),
|
||||
'model': fields.char('Model', size=64, required=True),
|
||||
'report_name': fields.char('Internal Name', size=64, required=True),
|
||||
'report_odt': fields.Char('ODT path', size=128),
|
||||
'report_odt_content_data': fields.binary('ODT content'),
|
||||
'report_odt_content': fields.function(_report_content,
|
||||
'report': fields.Char('Path', size=128),
|
||||
'report_content_data': fields.binary('Content'),
|
||||
'report_content': fields.function(_report_content,
|
||||
fnct_inv=_report_content_inv, method=True,
|
||||
type='binary', string='ODT content',),
|
||||
type='binary', string='Content',),
|
||||
'auto': fields.boolean('Automatic', required=True),
|
||||
'multi': fields.boolean('On multiple doc.',
|
||||
help="If set to true, the action will not be displayed " \
|
||||
"on the right toolbar of a form views.")
|
||||
}
|
||||
_defaults = {
|
||||
'type': lambda *a: 'ir.actions.report',
|
||||
'multi': lambda *a: False,
|
||||
'auto': lambda *a: True,
|
||||
'report_odt_content': lambda *a: False,
|
||||
'report_content': lambda *a: False,
|
||||
}
|
||||
|
||||
ActionsReport()
|
||||
@@ -215,13 +211,9 @@ class ActionsWizard(OSV):
|
||||
translate=True),
|
||||
'type': fields.char('Action type', size=32, required=True),
|
||||
'wiz_name': fields.char('Wizard name', size=64, required=True),
|
||||
'multi': fields.boolean('Action on multiple doc.',
|
||||
help="If set to true, the wizard will not be displayed \n" \
|
||||
"on the right toolbar of a form views.")
|
||||
}
|
||||
_defaults = {
|
||||
'type': lambda *a: 'ir.actions.wizard',
|
||||
'multi': lambda *a: False,
|
||||
}
|
||||
|
||||
ActionsWizard()
|
||||
|
||||
@@ -66,8 +66,9 @@
|
||||
<form string="Report">
|
||||
<field name="name" select="1"/>
|
||||
<field name="type" select="1"/>
|
||||
<field name="report_name" select="1"/>
|
||||
<field name="report_odt"/>
|
||||
<field name="model" select="1"/>
|
||||
<field name="report_name" select="2"/>
|
||||
<field name="report"/>
|
||||
<field name="auto"/>
|
||||
</form>
|
||||
]]>
|
||||
@@ -81,6 +82,7 @@
|
||||
<tree string="Report xml">
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
<field name="model"/>
|
||||
<field name="report_name"/>
|
||||
</tree>
|
||||
]]>
|
||||
|
||||
@@ -170,6 +170,8 @@ def load_module_graph(cursor, graph):
|
||||
modules = pool.instanciate(module)
|
||||
pool_wizard = pooler.get_pool_wizard(cursor.dbname)
|
||||
wizards = pool_wizard.instanciate(module, pool)
|
||||
pool_report = pooler.get_pool_report(cursor.dbname)
|
||||
reports = pool_report.instanciate(module, pool)
|
||||
cursor.execute('SELECT state, demo FROM ir_module_module WHERE name = %s',
|
||||
(module,))
|
||||
(package_state, package_demo) = (cursor.rowcount and cursor.fetchone()) \
|
||||
|
||||
+13
-1
@@ -4,9 +4,10 @@ from netsvc import Logger, LOG_INFO
|
||||
_DB = {}
|
||||
_POOL = {}
|
||||
_POOL_WIZARD = {}
|
||||
_POOL_REPORT = {}
|
||||
|
||||
def get_db_and_pool(db_name, force_demo=False, update_module=False,
|
||||
wizard=False):
|
||||
wizard=False, report=False):
|
||||
if db_name in _DB:
|
||||
database = _DB[db_name]
|
||||
else:
|
||||
@@ -18,6 +19,7 @@ def get_db_and_pool(db_name, force_demo=False, update_module=False,
|
||||
if db_name in _POOL:
|
||||
pool = _POOL[db_name]
|
||||
pool_wizard = _POOL_WIZARD[db_name]
|
||||
pool_report = _POOL_REPORT[db_name]
|
||||
else:
|
||||
Logger().notify_channel('pooler', LOG_INFO,
|
||||
'Instanciate pooler for %s' % (db_name))
|
||||
@@ -29,6 +31,10 @@ def get_db_and_pool(db_name, force_demo=False, update_module=False,
|
||||
pool_wizard = WizardService()
|
||||
_POOL_WIZARD[db_name] = pool_wizard
|
||||
|
||||
from report import ReportService
|
||||
pool_report = ReportService()
|
||||
_POOL_REPORT[db_name] = pool_report
|
||||
|
||||
from module import load_modules
|
||||
load_modules(database, force_demo, update_module)
|
||||
|
||||
@@ -38,6 +44,8 @@ def get_db_and_pool(db_name, force_demo=False, update_module=False,
|
||||
pool.get('ir.cron').pool_jobs(database.dbname)
|
||||
if wizard:
|
||||
return database, pool_wizard
|
||||
if report:
|
||||
return database, pool_report
|
||||
return database, pool
|
||||
|
||||
def restart_pool(db_name, force_demo=False, update_module=False):
|
||||
@@ -71,3 +79,7 @@ def get_pool(db_name, force_demo=False, update_module=False):
|
||||
def get_pool_wizard(db_name, force_demo=False, update_module=False):
|
||||
pool = get_db_and_pool(db_name, force_demo, update_module, wizard=True)[1]
|
||||
return pool
|
||||
|
||||
def get_pool_report(db_name, force_demo=False, update_module=False):
|
||||
pool = get_db_and_pool(db_name, force_demo, update_module, report=True)[1]
|
||||
return pool
|
||||
@@ -0,0 +1 @@
|
||||
from report import *
|
||||
@@ -0,0 +1,137 @@
|
||||
"Report"
|
||||
from trytond.netsvc import Service, service_exist, Logger, LOG_ERROR
|
||||
from trytond import pooler
|
||||
import copy
|
||||
from xml import dom
|
||||
from trytond.osv import ExceptORM, ExceptOSV, OSV
|
||||
import sys
|
||||
import base64
|
||||
|
||||
MODULE_LIST = []
|
||||
MODULE_CLASS_LIST = {}
|
||||
CLASS_POOL = {}
|
||||
|
||||
|
||||
class ReportService(Service):
|
||||
|
||||
def __init__(self):
|
||||
self.object_name_pool = {}
|
||||
self.module_obj_list = {}
|
||||
Service.__init__(self, 'report_proxy')
|
||||
Service.join_group(self, 'web-services')
|
||||
Service.export_method(self, self.execute)
|
||||
|
||||
def execute_cr(self, cursor, user, report_name, ids, datas, context=None):
|
||||
try:
|
||||
report = pooler.get_pool_report(cursor.dbname).get(report_name)
|
||||
if not report:
|
||||
self.abort_response('Report Error', 'warning',
|
||||
'Report %s doesn\'t exist' % str(report_name))
|
||||
res = report.execute(cursor, user, ids, datas, context)
|
||||
return res
|
||||
except ExceptORM, inst:
|
||||
self.abort_response(inst.name, 'warning', inst.value)
|
||||
except ExceptOSV, inst:
|
||||
self.abort_response(inst.name, inst.exc_type, inst.value)
|
||||
except:
|
||||
import traceback
|
||||
tb_s = reduce(lambda x, y: x+y, traceback.format_exception(
|
||||
sys.exc_type, sys.exc_value, sys.exc_traceback))
|
||||
Logger().notify_channel("web-services", LOG_ERROR,
|
||||
'Exception in call: ' + tb_s)
|
||||
raise
|
||||
|
||||
def execute(self, dbname, user, report_name, ids, datas, context=None):
|
||||
cursor = pooler.get_db(dbname).cursor()
|
||||
pool = pooler.get_pool_report(dbname)
|
||||
try:
|
||||
try:
|
||||
res = pool.execute_cr(cursor, user, report_name, ids, datas, context)
|
||||
cursor.commit()
|
||||
except Exception:
|
||||
cursor.rollback()
|
||||
raise
|
||||
finally:
|
||||
cursor.close()
|
||||
return res
|
||||
|
||||
def add(self, name, object_name_inst):
|
||||
"""
|
||||
adds a new obj instance to the obj pool.
|
||||
if it already existed, the instance is replaced
|
||||
"""
|
||||
if self.object_name_pool.has_key(name):
|
||||
del self.object_name_pool[name]
|
||||
self.object_name_pool[name] = object_name_inst
|
||||
|
||||
module = str(object_name_inst.__class__)[6:]
|
||||
module = module[:len(module)-1]
|
||||
module = module.split('.')[0][2:]
|
||||
self.module_obj_list.setdefault(module, []).append(object_name_inst)
|
||||
|
||||
def get(self, name):
|
||||
return self.object_name_pool.get(name, None)
|
||||
|
||||
def instanciate(self, module, pool_obj):
|
||||
res = []
|
||||
class_list = MODULE_CLASS_LIST.get(module, [])
|
||||
for klass in class_list:
|
||||
res.append(klass.create_instance(self, module, pool_obj))
|
||||
return res
|
||||
|
||||
class Report(object):
|
||||
_name = ""
|
||||
|
||||
def __new__(cls):
|
||||
for module in cls.__module__.split('.'):
|
||||
if module != 'trytond' and module != 'addons':
|
||||
break
|
||||
if not hasattr(cls, '_module'):
|
||||
cls._module = module
|
||||
MODULE_CLASS_LIST.setdefault(cls._module, []).append(cls)
|
||||
CLASS_POOL[cls._name] = cls
|
||||
if module not in MODULE_LIST:
|
||||
MODULE_LIST.append(cls._module)
|
||||
return None
|
||||
|
||||
def create_instance(cls, pool, module, pool_obj):
|
||||
"""
|
||||
try to apply inheritancy at the instanciation level and
|
||||
put objs in the pool var
|
||||
"""
|
||||
if pool.get(cls._name):
|
||||
parent_class = pool.get(cls._name).__class__
|
||||
nattr = {}
|
||||
for i in (
|
||||
'_context',
|
||||
):
|
||||
new = copy.copy(getattr(pool.get(cls._name), i))
|
||||
if hasattr(new, 'update'):
|
||||
new.update(cls.__dict__.get(i, {}))
|
||||
else:
|
||||
new.extend(cls.__dict__.get(i, []))
|
||||
nattr[i] = new
|
||||
cls = type(cls._name, (cls, parent_class), nattr)
|
||||
|
||||
|
||||
obj = object.__new__(cls)
|
||||
obj.__init__(pool, pool_obj)
|
||||
return obj
|
||||
|
||||
create_instance = classmethod(create_instance)
|
||||
|
||||
def __init__(self, pool, pool_obj):
|
||||
pool.add(self._name, self)
|
||||
self.pool = pool_obj
|
||||
super(Report, self).__init__()
|
||||
|
||||
def execute(self, cursor, user, ids, datas, context=None):
|
||||
action_report_obj = self.pool.get('ir.actions.report')
|
||||
action_report_ids = action_report_obj.search(cursor, user, [
|
||||
('report_name', '=', self._name)
|
||||
], context=context)
|
||||
action_report = action_report_obj.browse(cursor, user,
|
||||
action_report_ids[0], context=context)
|
||||
#TODO add parser
|
||||
type, data = 'odt', action_report.report_content
|
||||
return (type, base64.encodestring(data))
|
||||
Whitespace-only changes.
@@ -1,10 +1,5 @@
|
||||
from trytond.netsvc import Service, LocalService
|
||||
from trytond import security
|
||||
import threading
|
||||
import thread
|
||||
from trytond import pooler
|
||||
from trytond.config import CONFIG
|
||||
import base64
|
||||
|
||||
|
||||
class Report(Service):
|
||||
@@ -12,71 +7,10 @@ class Report(Service):
|
||||
def __init__(self, name='report'):
|
||||
Service.__init__(self, name)
|
||||
Service.join_group(self, 'web-services')
|
||||
Service.export_method(self, self.report)
|
||||
Service.export_method(self, self.report_get)
|
||||
self._reports = {}
|
||||
self.max_id = 0
|
||||
self.id_protect = threading.Semaphore()
|
||||
Service.export_method(self, self.execute)
|
||||
|
||||
def report(self, database, user, passwd, object_name, ids, datas=None,
|
||||
def execute(self, database, user, passwd, report_name, ids, datas=None,
|
||||
context=None):
|
||||
if datas is None:
|
||||
datas = {}
|
||||
if context is None:
|
||||
context = {}
|
||||
security.check(database, user, passwd)
|
||||
|
||||
self.id_protect.acquire()
|
||||
self.max_id += 1
|
||||
report_id = self.max_id
|
||||
self.id_protect.release()
|
||||
|
||||
self._reports[report_id] = {
|
||||
'user': user,
|
||||
'result': False,
|
||||
'state': False,
|
||||
}
|
||||
|
||||
def _go(report_id, user, ids, datas, context):
|
||||
cursor = pooler.get_db(database).cursor()
|
||||
obj = LocalService('report.' + object_name)
|
||||
(result, format) = obj.create(cursor, user, ids, datas, context)
|
||||
cursor.close()
|
||||
self._reports[report_id]['result'] = result
|
||||
self._reports[report_id]['format'] = format
|
||||
self._reports[report_id]['state'] = True
|
||||
return True
|
||||
|
||||
thread.start_new_thread(_go, (report_id, user, ids, datas, context))
|
||||
return report_id
|
||||
|
||||
def _check_report(self, report_id):
|
||||
result = self._reports[report_id]
|
||||
res = {'state': result['state']}
|
||||
if res['state']:
|
||||
if CONFIG['reportgz']:
|
||||
import zlib
|
||||
res2 = zlib.compress(result['result'])
|
||||
res['code'] = 'zlib'
|
||||
else:
|
||||
#CHECKME: why is this needed???
|
||||
if isinstance(result['result'], unicode):
|
||||
res2 = result['result'].encode('latin1', 'replace')
|
||||
else:
|
||||
res2 = result['result']
|
||||
if res2:
|
||||
res['result'] = base64.encodestring(res2)
|
||||
res['format'] = result['format']
|
||||
del self._reports[report_id]
|
||||
return res
|
||||
|
||||
def report_get(self, database, user, passwd, report_id):
|
||||
security.check(database, user, passwd)
|
||||
|
||||
if report_id in self._reports:
|
||||
if self._reports[report_id]['uid'] == user:
|
||||
return self._check_report(report_id)
|
||||
else:
|
||||
raise Exception, 'AccessDenied'
|
||||
else:
|
||||
raise Exception, 'ReportNotFound'
|
||||
report = LocalService('report_proxy')
|
||||
return report.execute(database, user, report_name, ids, datas, context)
|
||||
Reference in new issue
Block a user