1 # -*- coding: utf-8 -*-
11 _logger = logging.getLogger(__name__)
13 # TODO: set a maximum report number per user to avoid DOS attacks
20 self_id_protect = threading.Semaphore()
22 def dispatch(method, params):
23 (db, uid, passwd ) = params[0:3]
24 threading.current_thread().uid = uid
26 if method not in ['report', 'report_get', 'render_report']:
27 raise KeyError("Method not supported %s" % method)
28 security.check(db,uid,passwd)
29 openerp.modules.registry.RegistryManager.check_registry_signaling(db)
30 fn = globals()['exp_' + method]
31 res = fn(db, uid, *params)
32 openerp.modules.registry.RegistryManager.signal_caches_change(db)
35 def exp_render_report(db, uid, object, ids, datas=None, context=None):
41 self_id_protect.acquire()
45 self_id_protect.release()
47 self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
49 cr = openerp.pooler.get_db(db).cursor()
51 obj = openerp.netsvc.LocalService('report.'+object)
52 (result, format) = obj.create(cr, uid, ids, datas, context)
55 self_reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
56 self_reports[id]['result'] = result
57 self_reports[id]['format'] = format
58 self_reports[id]['state'] = True
59 except Exception, exception:
61 _logger.exception('Exception: %s\n', exception)
62 if hasattr(exception, 'name') and hasattr(exception, 'value'):
63 self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value))
66 self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
67 self_reports[id]['state'] = True
71 return _check_report(id)
73 def exp_report(db, uid, object, ids, datas=None, context=None):
79 self_id_protect.acquire()
83 self_id_protect.release()
85 self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
87 def go(id, uid, ids, datas, context):
88 cr = openerp.pooler.get_db(db).cursor()
90 obj = openerp.netsvc.LocalService('report.'+object)
91 (result, format) = obj.create(cr, uid, ids, datas, context)
94 self_reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
95 self_reports[id]['result'] = result
96 self_reports[id]['format'] = format
97 self_reports[id]['state'] = True
98 except Exception, exception:
99 _logger.exception('Exception: %s\n', exception)
100 if hasattr(exception, 'name') and hasattr(exception, 'value'):
101 self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value))
104 self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
105 self_reports[id]['state'] = True
110 thread.start_new_thread(go, (id, uid, ids, datas, context))
113 def _check_report(report_id):
114 result = self_reports[report_id]
115 exc = result['exception']
117 raise openerp.osv.orm.except_orm(exc.message, exc.traceback)
118 res = {'state': result['state']}
120 if tools.config['reportgz']:
122 res2 = zlib.compress(result['result'])
125 #CHECKME: why is this needed???
126 if isinstance(result['result'], unicode):
127 res2 = result['result'].encode('latin1', 'replace')
129 res2 = result['result']
131 res['result'] = base64.encodestring(res2)
132 res['format'] = result['format']
133 del self_reports[report_id]
136 def exp_report_get(db, uid, report_id):
137 if report_id in self_reports:
138 if self_reports[report_id]['uid'] == uid:
139 return _check_report(report_id)
141 raise Exception, 'AccessDenied'
143 raise Exception, 'ReportNotFound'
145 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: