[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(
|
||||
"notifyChannel API shouldn't be used anymore, please use "
|
||||
"the standard `logging` module instead.")
|
||||
from service.web_services import common
|
||||
from service import common
|
||||
|
||||
log = logging.getLogger(__name__ + '.deprecated.' + ustr(name))
|
||||
|
||||
|
@ -63,7 +63,7 @@ class Logger(object):
|
|||
try:
|
||||
msg = ustr(msg).strip()
|
||||
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')
|
||||
except UnicodeDecodeError:
|
||||
|
|
|
@ -119,6 +119,8 @@ class ExportService(object):
|
|||
return openerp.service.db
|
||||
if name == 'common':
|
||||
return openerp.service.common
|
||||
if name == 'report':
|
||||
return openerp.service.report
|
||||
return cls._services[name]
|
||||
|
||||
# Dispatch a RPC call w.r.t. the method name. The dispatching
|
||||
|
|
|
@ -29,8 +29,6 @@ import threading
|
|||
import time
|
||||
|
||||
import cron
|
||||
import web_services
|
||||
import web_services
|
||||
import wsgi_server
|
||||
|
||||
import openerp.modules
|
||||
|
@ -42,6 +40,7 @@ import openerp.tools
|
|||
import common
|
||||
import db
|
||||
import model
|
||||
import report
|
||||
|
||||
#.apidoc title: RPC Services
|
||||
|
||||
|
@ -78,9 +77,6 @@ def start_internal():
|
|||
openerp.netsvc.init_logger()
|
||||
openerp.modules.loading.open_openerp_namespace()
|
||||
|
||||
# Export (for RPC) services.
|
||||
web_services.start_service()
|
||||
|
||||
load_server_wide_modules()
|
||||
start_internal_done = True
|
||||
|
||||
|
|
|
@ -204,7 +204,6 @@ def _set_pg_password_in_environment():
|
|||
|
||||
|
||||
def exp_dump(db_name):
|
||||
logger = logging.getLogger('openerp.service.web_services.db.dump')
|
||||
with _set_pg_password_in_environment():
|
||||
cmd = ['pg_dump', '--format=c', '--no-owner']
|
||||
if openerp.tools.config['db_user']:
|
||||
|
@ -221,20 +220,19 @@ def exp_dump(db_name):
|
|||
res = stdout.close()
|
||||
|
||||
if not data or res:
|
||||
logger.error(
|
||||
_logger.error(
|
||||
'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 '
|
||||
'server configuration file.\n %s', db_name, data)
|
||||
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)
|
||||
|
||||
def exp_restore(db_name, data):
|
||||
logger = logging.getLogger('openerp.service.web_services.db.restore')
|
||||
with _set_pg_password_in_environment():
|
||||
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"
|
||||
|
||||
_create_empty_database(db_name)
|
||||
|
@ -263,7 +261,7 @@ def exp_restore(db_name, data):
|
|||
res = stdout.close()
|
||||
if res:
|
||||
raise Exception, "Couldn't restore database"
|
||||
logger.info('RESTORE DB: %s', db_name)
|
||||
_logger.info('RESTORE DB: %s', db_name)
|
||||
|
||||
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