[REF] services: moved the report service to openerp.service.report.
bzr revid: vmt@openerp.com-20130130155624-u3vfqwd3komo3wfs
This commit is contained in:
parent
796bb74426
commit
4aacad4abf
|
@ -46,7 +46,7 @@ class Logger(object):
|
||||||
_logger.warning(
|
_logger.warning(
|
||||||
"notifyChannel API shouldn't be used anymore, please use "
|
"notifyChannel API shouldn't be used anymore, please use "
|
||||||
"the standard `logging` module instead.")
|
"the standard `logging` module instead.")
|
||||||
from service.web_services import common
|
from service import common
|
||||||
|
|
||||||
log = logging.getLogger(__name__ + '.deprecated.' + ustr(name))
|
log = logging.getLogger(__name__ + '.deprecated.' + ustr(name))
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ class Logger(object):
|
||||||
try:
|
try:
|
||||||
msg = ustr(msg).strip()
|
msg = ustr(msg).strip()
|
||||||
if level in (LOG_ERROR, LOG_CRITICAL): # and tools.config.get_misc('debug','env_info',False):
|
if level in (LOG_ERROR, LOG_CRITICAL): # and tools.config.get_misc('debug','env_info',False):
|
||||||
msg = common().exp_get_server_environment() + "\n" + msg
|
msg = common.exp_get_server_environment() + "\n" + msg
|
||||||
|
|
||||||
result = msg.split('\n')
|
result = msg.split('\n')
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
|
|
|
@ -119,6 +119,8 @@ class ExportService(object):
|
||||||
return openerp.service.db
|
return openerp.service.db
|
||||||
if name == 'common':
|
if name == 'common':
|
||||||
return openerp.service.common
|
return openerp.service.common
|
||||||
|
if name == 'report':
|
||||||
|
return openerp.service.report
|
||||||
return cls._services[name]
|
return cls._services[name]
|
||||||
|
|
||||||
# Dispatch a RPC call w.r.t. the method name. The dispatching
|
# Dispatch a RPC call w.r.t. the method name. The dispatching
|
||||||
|
|
|
@ -29,8 +29,6 @@ import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import cron
|
import cron
|
||||||
import web_services
|
|
||||||
import web_services
|
|
||||||
import wsgi_server
|
import wsgi_server
|
||||||
|
|
||||||
import openerp.modules
|
import openerp.modules
|
||||||
|
@ -42,6 +40,7 @@ import openerp.tools
|
||||||
import common
|
import common
|
||||||
import db
|
import db
|
||||||
import model
|
import model
|
||||||
|
import report
|
||||||
|
|
||||||
#.apidoc title: RPC Services
|
#.apidoc title: RPC Services
|
||||||
|
|
||||||
|
@ -78,9 +77,6 @@ def start_internal():
|
||||||
openerp.netsvc.init_logger()
|
openerp.netsvc.init_logger()
|
||||||
openerp.modules.loading.open_openerp_namespace()
|
openerp.modules.loading.open_openerp_namespace()
|
||||||
|
|
||||||
# Export (for RPC) services.
|
|
||||||
web_services.start_service()
|
|
||||||
|
|
||||||
load_server_wide_modules()
|
load_server_wide_modules()
|
||||||
start_internal_done = True
|
start_internal_done = True
|
||||||
|
|
||||||
|
|
|
@ -204,7 +204,6 @@ def _set_pg_password_in_environment():
|
||||||
|
|
||||||
|
|
||||||
def exp_dump(db_name):
|
def exp_dump(db_name):
|
||||||
logger = logging.getLogger('openerp.service.web_services.db.dump')
|
|
||||||
with _set_pg_password_in_environment():
|
with _set_pg_password_in_environment():
|
||||||
cmd = ['pg_dump', '--format=c', '--no-owner']
|
cmd = ['pg_dump', '--format=c', '--no-owner']
|
||||||
if openerp.tools.config['db_user']:
|
if openerp.tools.config['db_user']:
|
||||||
|
@ -221,20 +220,19 @@ def exp_dump(db_name):
|
||||||
res = stdout.close()
|
res = stdout.close()
|
||||||
|
|
||||||
if not data or res:
|
if not data or res:
|
||||||
logger.error(
|
_logger.error(
|
||||||
'DUMP DB: %s failed! Please verify the configuration of the database password on the server. '
|
'DUMP DB: %s failed! Please verify the configuration of the database password on the server. '
|
||||||
'It should be provided as a -w <PASSWD> command-line option, or as `db_password` in the '
|
'It should be provided as a -w <PASSWD> command-line option, or as `db_password` in the '
|
||||||
'server configuration file.\n %s', db_name, data)
|
'server configuration file.\n %s', db_name, data)
|
||||||
raise Exception, "Couldn't dump database"
|
raise Exception, "Couldn't dump database"
|
||||||
logger.info('DUMP DB successful: %s', db_name)
|
_logger.info('DUMP DB successful: %s', db_name)
|
||||||
|
|
||||||
return base64.encodestring(data)
|
return base64.encodestring(data)
|
||||||
|
|
||||||
def exp_restore(db_name, data):
|
def exp_restore(db_name, data):
|
||||||
logger = logging.getLogger('openerp.service.web_services.db.restore')
|
|
||||||
with _set_pg_password_in_environment():
|
with _set_pg_password_in_environment():
|
||||||
if exp_db_exist(db_name):
|
if exp_db_exist(db_name):
|
||||||
logger.warning('RESTORE DB: %s already exists', db_name)
|
_logger.warning('RESTORE DB: %s already exists', db_name)
|
||||||
raise Exception, "Database already exists"
|
raise Exception, "Database already exists"
|
||||||
|
|
||||||
_create_empty_database(db_name)
|
_create_empty_database(db_name)
|
||||||
|
@ -263,7 +261,7 @@ def exp_restore(db_name, data):
|
||||||
res = stdout.close()
|
res = stdout.close()
|
||||||
if res:
|
if res:
|
||||||
raise Exception, "Couldn't restore database"
|
raise Exception, "Couldn't restore database"
|
||||||
logger.info('RESTORE DB: %s', db_name)
|
_logger.info('RESTORE DB: %s', db_name)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import threading
|
||||||
|
|
||||||
|
import openerp.netsvc
|
||||||
|
import openerp.pooler
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# TODO: set a maximum report number per user to avoid DOS attacks
|
||||||
|
#
|
||||||
|
# Report state:
|
||||||
|
# False -> True
|
||||||
|
|
||||||
|
self_reports = {}
|
||||||
|
self_id = 0
|
||||||
|
self_id_protect = threading.Semaphore()
|
||||||
|
|
||||||
|
def dispatch(method, params):
|
||||||
|
(db, uid, passwd ) = params[0:3]
|
||||||
|
threading.current_thread().uid = uid
|
||||||
|
params = params[3:]
|
||||||
|
if method not in ['report', 'report_get', 'render_report']:
|
||||||
|
raise KeyError("Method not supported %s" % method)
|
||||||
|
security.check(db,uid,passwd)
|
||||||
|
openerp.modules.registry.RegistryManager.check_registry_signaling(db)
|
||||||
|
fn = globals()['exp_' + method]
|
||||||
|
res = fn(db, uid, *params)
|
||||||
|
openerp.modules.registry.RegistryManager.signal_caches_change(db)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def exp_render_report(db, uid, object, ids, datas=None, context=None):
|
||||||
|
if not datas:
|
||||||
|
datas={}
|
||||||
|
if not context:
|
||||||
|
context={}
|
||||||
|
|
||||||
|
self_id_protect.acquire()
|
||||||
|
global self_id
|
||||||
|
self_id += 1
|
||||||
|
id = self_id
|
||||||
|
self_id_protect.release()
|
||||||
|
|
||||||
|
self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
|
||||||
|
|
||||||
|
cr = openerp.pooler.get_db(db).cursor()
|
||||||
|
try:
|
||||||
|
obj = openerp.netsvc.LocalService('report.'+object)
|
||||||
|
(result, format) = obj.create(cr, uid, ids, datas, context)
|
||||||
|
if not result:
|
||||||
|
tb = sys.exc_info()
|
||||||
|
self_reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
|
||||||
|
self_reports[id]['result'] = result
|
||||||
|
self_reports[id]['format'] = format
|
||||||
|
self_reports[id]['state'] = True
|
||||||
|
except Exception, exception:
|
||||||
|
|
||||||
|
_logger.exception('Exception: %s\n', exception)
|
||||||
|
if hasattr(exception, 'name') and hasattr(exception, 'value'):
|
||||||
|
self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value))
|
||||||
|
else:
|
||||||
|
tb = sys.exc_info()
|
||||||
|
self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
|
||||||
|
self_reports[id]['state'] = True
|
||||||
|
cr.commit()
|
||||||
|
cr.close()
|
||||||
|
|
||||||
|
return _check_report(id)
|
||||||
|
|
||||||
|
def exp_report(db, uid, object, ids, datas=None, context=None):
|
||||||
|
if not datas:
|
||||||
|
datas={}
|
||||||
|
if not context:
|
||||||
|
context={}
|
||||||
|
|
||||||
|
self_id_protect.acquire()
|
||||||
|
global self_id
|
||||||
|
self_id += 1
|
||||||
|
id = self_id
|
||||||
|
self_id_protect.release()
|
||||||
|
|
||||||
|
self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
|
||||||
|
|
||||||
|
def go(id, uid, ids, datas, context):
|
||||||
|
cr = openerp.pooler.get_db(db).cursor()
|
||||||
|
try:
|
||||||
|
obj = openerp.netsvc.LocalService('report.'+object)
|
||||||
|
(result, format) = obj.create(cr, uid, ids, datas, context)
|
||||||
|
if not result:
|
||||||
|
tb = sys.exc_info()
|
||||||
|
self_reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
|
||||||
|
self_reports[id]['result'] = result
|
||||||
|
self_reports[id]['format'] = format
|
||||||
|
self_reports[id]['state'] = True
|
||||||
|
except Exception, exception:
|
||||||
|
_logger.exception('Exception: %s\n', exception)
|
||||||
|
if hasattr(exception, 'name') and hasattr(exception, 'value'):
|
||||||
|
self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value))
|
||||||
|
else:
|
||||||
|
tb = sys.exc_info()
|
||||||
|
self_reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
|
||||||
|
self_reports[id]['state'] = True
|
||||||
|
cr.commit()
|
||||||
|
cr.close()
|
||||||
|
return True
|
||||||
|
|
||||||
|
thread.start_new_thread(go, (id, uid, ids, datas, context))
|
||||||
|
return id
|
||||||
|
|
||||||
|
def _check_report(report_id):
|
||||||
|
result = self_reports[report_id]
|
||||||
|
exc = result['exception']
|
||||||
|
if exc:
|
||||||
|
raise openerp.osv.orm.except_orm(exc.message, exc.traceback)
|
||||||
|
res = {'state': result['state']}
|
||||||
|
if res['state']:
|
||||||
|
if tools.config['reportgz']:
|
||||||
|
import zlib
|
||||||
|
res2 = zlib.compress(result['result'])
|
||||||
|
res['code'] = 'zlib'
|
||||||
|
else:
|
||||||
|
#CHECKME: why is this needed???
|
||||||
|
if isinstance(result['result'], unicode):
|
||||||
|
res2 = result['result'].encode('latin1', 'replace')
|
||||||
|
else:
|
||||||
|
res2 = result['result']
|
||||||
|
if res2:
|
||||||
|
res['result'] = base64.encodestring(res2)
|
||||||
|
res['format'] = result['format']
|
||||||
|
del self_reports[report_id]
|
||||||
|
return res
|
||||||
|
|
||||||
|
def exp_report_get(db, uid, report_id):
|
||||||
|
if report_id in self_reports:
|
||||||
|
if self_reports[report_id]['uid'] == uid:
|
||||||
|
return _check_report(report_id)
|
||||||
|
else:
|
||||||
|
raise Exception, 'AccessDenied'
|
||||||
|
else:
|
||||||
|
raise Exception, 'ReportNotFound'
|
||||||
|
|
||||||
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -1,200 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# OpenERP, Open Source Management Solution
|
|
||||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU Affero General Public License as
|
|
||||||
# published by the Free Software Foundation, either version 3 of the
|
|
||||||
# License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU Affero General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
##############################################################################
|
|
||||||
from __future__ import with_statement
|
|
||||||
import contextlib
|
|
||||||
import base64
|
|
||||||
import locale
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import platform
|
|
||||||
import security
|
|
||||||
import sys
|
|
||||||
import thread
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
import traceback
|
|
||||||
from cStringIO import StringIO
|
|
||||||
|
|
||||||
from openerp.tools.translate import _
|
|
||||||
import openerp.netsvc as netsvc
|
|
||||||
import openerp.pooler as pooler
|
|
||||||
import openerp.service.model
|
|
||||||
import openerp.sql_db as sql_db
|
|
||||||
import openerp.tools as tools
|
|
||||||
import openerp.modules
|
|
||||||
import openerp.exceptions
|
|
||||||
import openerp.osv.orm # TODO use openerp.exceptions
|
|
||||||
from openerp.service import http_server
|
|
||||||
from openerp import SUPERUSER_ID
|
|
||||||
|
|
||||||
#.apidoc title: Exported Service methods
|
|
||||||
#.apidoc module-mods: member-order: bysource
|
|
||||||
|
|
||||||
""" This python module defines the RPC methods available to remote clients.
|
|
||||||
|
|
||||||
Each 'Export Service' is a group of 'methods', which in turn are RPC
|
|
||||||
procedures to be called. Each method has its own arguments footprint.
|
|
||||||
"""
|
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# TODO: set a maximum report number per user to avoid DOS attacks
|
|
||||||
#
|
|
||||||
# Report state:
|
|
||||||
# False -> True
|
|
||||||
#
|
|
||||||
|
|
||||||
class report_spool(netsvc.ExportService):
|
|
||||||
def __init__(self, name='report'):
|
|
||||||
netsvc.ExportService.__init__(self, name)
|
|
||||||
self._reports = {}
|
|
||||||
self.id = 0
|
|
||||||
self.id_protect = threading.Semaphore()
|
|
||||||
|
|
||||||
def dispatch(self, method, params):
|
|
||||||
(db, uid, passwd ) = params[0:3]
|
|
||||||
threading.current_thread().uid = uid
|
|
||||||
params = params[3:]
|
|
||||||
if method not in ['report', 'report_get', 'render_report']:
|
|
||||||
raise KeyError("Method not supported %s" % method)
|
|
||||||
security.check(db,uid,passwd)
|
|
||||||
openerp.modules.registry.RegistryManager.check_registry_signaling(db)
|
|
||||||
fn = getattr(self, 'exp_' + method)
|
|
||||||
res = fn(db, uid, *params)
|
|
||||||
openerp.modules.registry.RegistryManager.signal_caches_change(db)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def exp_render_report(self, db, uid, object, ids, datas=None, context=None):
|
|
||||||
if not datas:
|
|
||||||
datas={}
|
|
||||||
if not context:
|
|
||||||
context={}
|
|
||||||
|
|
||||||
self.id_protect.acquire()
|
|
||||||
self.id += 1
|
|
||||||
id = self.id
|
|
||||||
self.id_protect.release()
|
|
||||||
|
|
||||||
self._reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
|
|
||||||
|
|
||||||
cr = pooler.get_db(db).cursor()
|
|
||||||
try:
|
|
||||||
obj = netsvc.LocalService('report.'+object)
|
|
||||||
(result, format) = obj.create(cr, uid, ids, datas, context)
|
|
||||||
if not result:
|
|
||||||
tb = sys.exc_info()
|
|
||||||
self._reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
|
|
||||||
self._reports[id]['result'] = result
|
|
||||||
self._reports[id]['format'] = format
|
|
||||||
self._reports[id]['state'] = True
|
|
||||||
except Exception, exception:
|
|
||||||
|
|
||||||
_logger.exception('Exception: %s\n', exception)
|
|
||||||
if hasattr(exception, 'name') and hasattr(exception, 'value'):
|
|
||||||
self._reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value))
|
|
||||||
else:
|
|
||||||
tb = sys.exc_info()
|
|
||||||
self._reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
|
|
||||||
self._reports[id]['state'] = True
|
|
||||||
cr.commit()
|
|
||||||
cr.close()
|
|
||||||
|
|
||||||
return self._check_report(id)
|
|
||||||
|
|
||||||
def exp_report(self, db, uid, object, ids, datas=None, context=None):
|
|
||||||
if not datas:
|
|
||||||
datas={}
|
|
||||||
if not context:
|
|
||||||
context={}
|
|
||||||
|
|
||||||
self.id_protect.acquire()
|
|
||||||
self.id += 1
|
|
||||||
id = self.id
|
|
||||||
self.id_protect.release()
|
|
||||||
|
|
||||||
self._reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
|
|
||||||
|
|
||||||
def go(id, uid, ids, datas, context):
|
|
||||||
cr = pooler.get_db(db).cursor()
|
|
||||||
try:
|
|
||||||
obj = netsvc.LocalService('report.'+object)
|
|
||||||
(result, format) = obj.create(cr, uid, ids, datas, context)
|
|
||||||
if not result:
|
|
||||||
tb = sys.exc_info()
|
|
||||||
self._reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
|
|
||||||
self._reports[id]['result'] = result
|
|
||||||
self._reports[id]['format'] = format
|
|
||||||
self._reports[id]['state'] = True
|
|
||||||
except Exception, exception:
|
|
||||||
_logger.exception('Exception: %s\n', exception)
|
|
||||||
if hasattr(exception, 'name') and hasattr(exception, 'value'):
|
|
||||||
self._reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value))
|
|
||||||
else:
|
|
||||||
tb = sys.exc_info()
|
|
||||||
self._reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb)
|
|
||||||
self._reports[id]['state'] = True
|
|
||||||
cr.commit()
|
|
||||||
cr.close()
|
|
||||||
return True
|
|
||||||
|
|
||||||
thread.start_new_thread(go, (id, uid, ids, datas, context))
|
|
||||||
return id
|
|
||||||
|
|
||||||
def _check_report(self, report_id):
|
|
||||||
result = self._reports[report_id]
|
|
||||||
exc = result['exception']
|
|
||||||
if exc:
|
|
||||||
raise openerp.osv.orm.except_orm(exc.message, exc.traceback)
|
|
||||||
res = {'state': result['state']}
|
|
||||||
if res['state']:
|
|
||||||
if tools.config['reportgz']:
|
|
||||||
import zlib
|
|
||||||
res2 = zlib.compress(result['result'])
|
|
||||||
res['code'] = 'zlib'
|
|
||||||
else:
|
|
||||||
#CHECKME: why is this needed???
|
|
||||||
if isinstance(result['result'], unicode):
|
|
||||||
res2 = result['result'].encode('latin1', 'replace')
|
|
||||||
else:
|
|
||||||
res2 = result['result']
|
|
||||||
if res2:
|
|
||||||
res['result'] = base64.encodestring(res2)
|
|
||||||
res['format'] = result['format']
|
|
||||||
del self._reports[report_id]
|
|
||||||
return res
|
|
||||||
|
|
||||||
def exp_report_get(self, db, uid, report_id):
|
|
||||||
if report_id in self._reports:
|
|
||||||
if self._reports[report_id]['uid'] == uid:
|
|
||||||
return self._check_report(report_id)
|
|
||||||
else:
|
|
||||||
raise Exception, 'AccessDenied'
|
|
||||||
else:
|
|
||||||
raise Exception, 'ReportNotFound'
|
|
||||||
|
|
||||||
|
|
||||||
def start_service():
|
|
||||||
report_spool()
|
|
||||||
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
Loading…
Reference in New Issue