1 # -*- coding: utf-8 -*-
9 _logger = logging.getLogger(__name__)
11 # TODO: set a maximum report number per user to avoid DOS attacks
18 self_id_protect = threading.Semaphore()
20 def dispatch(method, params):
21 (db, uid, passwd ) = params[0:3]
22 threading.current_thread().uid = uid
24 if method not in ['report', 'report_get', 'render_report']:
25 raise KeyError("Method not supported %s" % method)
26 security.check(db,uid,passwd)
27 openerp.modules.registry.RegistryManager.check_registry_signaling(db)
28 fn = globals()['exp_' + method]
29 res = fn(db, uid, *params)
30 openerp.modules.registry.RegistryManager.signal_caches_change(db)
33 def exp_render_report(db, uid, object, ids, datas=None, context=None):
39 self_id_protect.acquire()
43 self_id_protect.release()
45 self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
47 cr = openerp.pooler.get_db(db).cursor()
49 obj = openerp.netsvc.LocalService('report.'+object)
50 (result, format) = obj.create(cr, uid, ids, datas, context)
53 self_reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
54 self_reports[id]['result'] = result
55 self_reports[id]['format'] = format
56 self_reports[id]['state'] = True
57 except Exception, exception:
59 _logger.exception('Exception: %s\n', exception)
60 if hasattr(exception, 'name') and hasattr(exception, 'value'):
61 self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value))
64 self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
65 self_reports[id]['state'] = True
69 return _check_report(id)
71 def exp_report(db, uid, object, ids, datas=None, context=None):
77 self_id_protect.acquire()
81 self_id_protect.release()
83 self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
85 def go(id, uid, ids, datas, context):
86 cr = openerp.pooler.get_db(db).cursor()
88 obj = openerp.netsvc.LocalService('report.'+object)
89 (result, format) = obj.create(cr, uid, ids, datas, context)
92 self_reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
93 self_reports[id]['result'] = result
94 self_reports[id]['format'] = format
95 self_reports[id]['state'] = True
96 except Exception, exception:
97 _logger.exception('Exception: %s\n', exception)
98 if hasattr(exception, 'name') and hasattr(exception, 'value'):
99 self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value))
102 self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
103 self_reports[id]['state'] = True
108 thread.start_new_thread(go, (id, uid, ids, datas, context))
111 def _check_report(report_id):
112 result = self_reports[report_id]
113 exc = result['exception']
115 raise openerp.osv.orm.except_orm(exc.message, exc.traceback)
116 res = {'state': result['state']}
118 if tools.config['reportgz']:
120 res2 = zlib.compress(result['result'])
123 #CHECKME: why is this needed???
124 if isinstance(result['result'], unicode):
125 res2 = result['result'].encode('latin1', 'replace')
127 res2 = result['result']
129 res['result'] = base64.encodestring(res2)
130 res['format'] = result['format']
131 del self_reports[report_id]
134 def exp_report_get(db, uid, report_id):
135 if report_id in self_reports:
136 if self_reports[report_id]['uid'] == uid:
137 return _check_report(report_id)
139 raise Exception, 'AccessDenied'
141 raise Exception, 'ReportNotFound'
143 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: