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