1 # -*- coding: utf-8 -*-
10 from openerp import tools
14 _logger = logging.getLogger(__name__)
16 # TODO: set a maximum report number per user to avoid DOS attacks
23 self_id_protect = threading.Semaphore()
25 def dispatch(method, params):
26 (db, uid, passwd ) = params[0:3]
27 threading.current_thread().uid = uid
29 if method not in ['report', 'report_get', 'render_report']:
30 raise KeyError("Method not supported %s" % method)
31 security.check(db,uid,passwd)
32 openerp.modules.registry.RegistryManager.check_registry_signaling(db)
33 fn = globals()['exp_' + method]
34 res = fn(db, uid, *params)
35 openerp.modules.registry.RegistryManager.signal_caches_change(db)
38 def exp_render_report(db, uid, object, ids, datas=None, context=None):
44 self_id_protect.acquire()
48 self_id_protect.release()
50 self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
52 cr = openerp.registry(db).db.cursor()
54 result, format = openerp.report.render_report(cr, uid, ids, object, datas, context)
57 self_reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
58 self_reports[id]['result'] = result
59 self_reports[id]['format'] = format
60 self_reports[id]['state'] = True
61 except Exception, exception:
63 _logger.exception('Exception: %s\n', exception)
64 if hasattr(exception, 'name') and hasattr(exception, 'value'):
65 self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value))
68 self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
69 self_reports[id]['state'] = True
73 return _check_report(id)
75 def exp_report(db, uid, object, ids, datas=None, context=None):
81 self_id_protect.acquire()
85 self_id_protect.release()
87 self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
89 def go(id, uid, ids, datas, context):
90 cr = openerp.registry(db).db.cursor()
92 result, format = openerp.report.render_report(cr, uid, ids, object, datas, context)
95 self_reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
96 self_reports[id]['result'] = result
97 self_reports[id]['format'] = format
98 self_reports[id]['state'] = True
99 except Exception, exception:
100 _logger.exception('Exception: %s\n', exception)
101 if hasattr(exception, 'name') and hasattr(exception, 'value'):
102 self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value))
105 self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
106 self_reports[id]['state'] = True
111 threading.Thread(target=go, args=(id, uid, ids, datas, context)).start()
114 def _check_report(report_id):
115 result = self_reports[report_id]
116 exc = result['exception']
118 raise openerp.osv.orm.except_orm(exc.message, exc.traceback)
119 res = {'state': result['state']}
121 if tools.config['reportgz']:
123 res2 = zlib.compress(result['result'])
126 #CHECKME: why is this needed???
127 if isinstance(result['result'], unicode):
128 res2 = result['result'].encode('latin1', 'replace')
130 res2 = result['result']
132 res['result'] = base64.encodestring(res2)
133 res['format'] = result['format']
134 del self_reports[report_id]
137 def exp_report_get(db, uid, report_id):
138 if report_id in self_reports:
139 if self_reports[report_id]['uid'] == uid:
140 return _check_report(report_id)
142 raise Exception, 'AccessDenied'
144 raise Exception, 'ReportNotFound'
146 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: