[REF] services: moved the report service to openerp.service.report.

bzr revid: vmt@openerp.com-20130130155624-u3vfqwd3komo3wfs
This commit is contained in:
Vo Minh Thu 2013-01-30 16:56:24 +01:00
parent 796bb74426
commit 4aacad4abf
6 changed files with 152 additions and 213 deletions

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

143
openerp/service/report.py Normal file
View File

@ -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:

View File

@ -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: