[FIX] openerp/service/report: missing import
[odoo/odoo.git] / openerp / service / report.py
1 # -*- coding: utf-8 -*-
2
3 import logging
4 import threading
5
6 import openerp.netsvc
7 import openerp.pooler
8
9 import security
10
11 _logger = logging.getLogger(__name__)
12
13 # TODO: set a maximum report number per user to avoid DOS attacks
14 #
15 # Report state:
16 #     False -> True
17
18 self_reports = {}
19 self_id = 0
20 self_id_protect = threading.Semaphore()
21
22 def dispatch(method, params):
23     (db, uid, passwd ) = params[0:3]
24     threading.current_thread().uid = uid
25     params = params[3:]
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)
33     return res
34
35 def exp_render_report(db, uid, object, ids, datas=None, context=None):
36     if not datas:
37         datas={}
38     if not context:
39         context={}
40
41     self_id_protect.acquire()
42     global self_id
43     self_id += 1
44     id = self_id
45     self_id_protect.release()
46
47     self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
48
49     cr = openerp.pooler.get_db(db).cursor()
50     try:
51         obj = openerp.netsvc.LocalService('report.'+object)
52         (result, format) = obj.create(cr, uid, ids, datas, context)
53         if not result:
54             tb = sys.exc_info()
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:
60
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))
64         else:
65             tb = sys.exc_info()
66             self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
67         self_reports[id]['state'] = True
68     cr.commit()
69     cr.close()
70
71     return _check_report(id)
72
73 def exp_report(db, uid, object, ids, datas=None, context=None):
74     if not datas:
75         datas={}
76     if not context:
77         context={}
78
79     self_id_protect.acquire()
80     global self_id
81     self_id += 1
82     id = self_id
83     self_id_protect.release()
84
85     self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
86
87     def go(id, uid, ids, datas, context):
88         cr = openerp.pooler.get_db(db).cursor()
89         try:
90             obj = openerp.netsvc.LocalService('report.'+object)
91             (result, format) = obj.create(cr, uid, ids, datas, context)
92             if not result:
93                 tb = sys.exc_info()
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))
102             else:
103                 tb = sys.exc_info()
104                 self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
105             self_reports[id]['state'] = True
106         cr.commit()
107         cr.close()
108         return True
109
110     thread.start_new_thread(go, (id, uid, ids, datas, context))
111     return id
112
113 def _check_report(report_id):
114     result = self_reports[report_id]
115     exc = result['exception']
116     if exc:
117         raise openerp.osv.orm.except_orm(exc.message, exc.traceback)
118     res = {'state': result['state']}
119     if res['state']:
120         if tools.config['reportgz']:
121             import zlib
122             res2 = zlib.compress(result['result'])
123             res['code'] = 'zlib'
124         else:
125             #CHECKME: why is this needed???
126             if isinstance(result['result'], unicode):
127                 res2 = result['result'].encode('latin1', 'replace')
128             else:
129                 res2 = result['result']
130         if res2:
131             res['result'] = base64.encodestring(res2)
132         res['format'] = result['format']
133         del self_reports[report_id]
134     return res
135
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)
140         else:
141             raise Exception, 'AccessDenied'
142     else:
143         raise Exception, 'ReportNotFound'
144
145 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: