2013-01-30 15:56:24 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2013-02-14 15:35:11 +00:00
|
|
|
import base64
|
2013-01-30 15:56:24 +00:00
|
|
|
import logging
|
2013-02-14 15:35:11 +00:00
|
|
|
import sys
|
2013-01-30 15:56:24 +00:00
|
|
|
import threading
|
|
|
|
|
2013-03-27 11:10:14 +00:00
|
|
|
import openerp
|
2013-02-22 12:48:01 +00:00
|
|
|
import openerp.report
|
2013-02-14 15:35:11 +00:00
|
|
|
from openerp import tools
|
2013-01-30 15:56:24 +00:00
|
|
|
|
2013-02-14 15:08:25 +00:00
|
|
|
import security
|
|
|
|
|
2013-01-30 15:56:24 +00:00
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
# TODO: set a maximum report number per user to avoid DOS attacks
|
|
|
|
#
|
|
|
|
# Report state:
|
|
|
|
# False -> True
|
|
|
|
|
|
|
|
self_reports = {}
|
|
|
|
self_id = 0
|
|
|
|
self_id_protect = threading.Semaphore()
|
|
|
|
|
|
|
|
def dispatch(method, params):
|
|
|
|
(db, uid, passwd ) = params[0:3]
|
|
|
|
threading.current_thread().uid = uid
|
|
|
|
params = params[3:]
|
|
|
|
if method not in ['report', 'report_get', 'render_report']:
|
|
|
|
raise KeyError("Method not supported %s" % method)
|
|
|
|
security.check(db,uid,passwd)
|
|
|
|
openerp.modules.registry.RegistryManager.check_registry_signaling(db)
|
|
|
|
fn = globals()['exp_' + method]
|
|
|
|
res = fn(db, uid, *params)
|
|
|
|
openerp.modules.registry.RegistryManager.signal_caches_change(db)
|
|
|
|
return res
|
|
|
|
|
|
|
|
def exp_render_report(db, uid, object, ids, datas=None, context=None):
|
|
|
|
if not datas:
|
|
|
|
datas={}
|
|
|
|
if not context:
|
|
|
|
context={}
|
|
|
|
|
|
|
|
self_id_protect.acquire()
|
|
|
|
global self_id
|
|
|
|
self_id += 1
|
|
|
|
id = self_id
|
|
|
|
self_id_protect.release()
|
|
|
|
|
|
|
|
self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
|
|
|
|
|
2013-03-27 11:10:14 +00:00
|
|
|
cr = openerp.registry(db).db.cursor()
|
2013-01-30 15:56:24 +00:00
|
|
|
try:
|
2013-02-22 12:48:01 +00:00
|
|
|
result, format = openerp.report.render_report(cr, uid, ids, object, datas, context)
|
2013-01-30 15:56:24 +00:00
|
|
|
if not result:
|
|
|
|
tb = sys.exc_info()
|
|
|
|
self_reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
|
|
|
|
self_reports[id]['result'] = result
|
|
|
|
self_reports[id]['format'] = format
|
|
|
|
self_reports[id]['state'] = True
|
|
|
|
except Exception, exception:
|
|
|
|
|
|
|
|
_logger.exception('Exception: %s\n', exception)
|
|
|
|
if hasattr(exception, 'name') and hasattr(exception, 'value'):
|
|
|
|
self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value))
|
|
|
|
else:
|
|
|
|
tb = sys.exc_info()
|
|
|
|
self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
|
|
|
|
self_reports[id]['state'] = True
|
|
|
|
cr.commit()
|
|
|
|
cr.close()
|
|
|
|
|
|
|
|
return _check_report(id)
|
|
|
|
|
|
|
|
def exp_report(db, uid, object, ids, datas=None, context=None):
|
|
|
|
if not datas:
|
|
|
|
datas={}
|
|
|
|
if not context:
|
|
|
|
context={}
|
|
|
|
|
|
|
|
self_id_protect.acquire()
|
|
|
|
global self_id
|
|
|
|
self_id += 1
|
|
|
|
id = self_id
|
|
|
|
self_id_protect.release()
|
|
|
|
|
|
|
|
self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
|
|
|
|
|
|
|
|
def go(id, uid, ids, datas, context):
|
2013-03-27 11:10:14 +00:00
|
|
|
cr = openerp.registry(db).db.cursor()
|
2013-01-30 15:56:24 +00:00
|
|
|
try:
|
2013-02-22 12:48:01 +00:00
|
|
|
result, format = openerp.report.render_report(cr, uid, ids, object, datas, context)
|
2013-01-30 15:56:24 +00:00
|
|
|
if not result:
|
|
|
|
tb = sys.exc_info()
|
|
|
|
self_reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
|
|
|
|
self_reports[id]['result'] = result
|
|
|
|
self_reports[id]['format'] = format
|
|
|
|
self_reports[id]['state'] = True
|
|
|
|
except Exception, exception:
|
|
|
|
_logger.exception('Exception: %s\n', exception)
|
|
|
|
if hasattr(exception, 'name') and hasattr(exception, 'value'):
|
|
|
|
self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value))
|
|
|
|
else:
|
|
|
|
tb = sys.exc_info()
|
|
|
|
self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
|
|
|
|
self_reports[id]['state'] = True
|
|
|
|
cr.commit()
|
|
|
|
cr.close()
|
|
|
|
return True
|
|
|
|
|
2013-02-14 15:35:11 +00:00
|
|
|
threading.Thread(target=go, args=(id, uid, ids, datas, context)).start()
|
2013-01-30 15:56:24 +00:00
|
|
|
return id
|
|
|
|
|
|
|
|
def _check_report(report_id):
|
|
|
|
result = self_reports[report_id]
|
|
|
|
exc = result['exception']
|
|
|
|
if exc:
|
|
|
|
raise openerp.osv.orm.except_orm(exc.message, exc.traceback)
|
|
|
|
res = {'state': result['state']}
|
|
|
|
if res['state']:
|
|
|
|
if tools.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 exp_report_get(db, uid, report_id):
|
|
|
|
if report_id in self_reports:
|
|
|
|
if self_reports[report_id]['uid'] == uid:
|
|
|
|
return _check_report(report_id)
|
|
|
|
else:
|
|
|
|
raise Exception, 'AccessDenied'
|
|
|
|
else:
|
|
|
|
raise Exception, 'ReportNotFound'
|
|
|
|
|
|
|
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|