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