Merge branch 'master' of /home/panos/tmp/tinyerp/openobject-server/ into mdv-gpl3

Conflicts:
	bin/addons/base/ir/ir_actions.py
	bin/report/interface.py
	bin/tools/config.py

bzr revid: p_christ@hol.gr-20081228102522-po9ix8j0l6f5akxp
This commit is contained in:
P. Christeas 2008-12-28 12:25:22 +02:00
commit cb42fd7a59
18 changed files with 240 additions and 256 deletions

View File

@ -119,6 +119,7 @@ class report_xml(osv.osv):
('raw', 'raw'),
('sxw', 'sxw'),
('txt', 'txt'),
('odt', 'odt'),
], string='Type', required=True),
'groups_id': fields.many2many('res.groups', 'res_groups_report_rel', 'uid', 'gid', 'Groups'),
'attachment': fields.char('Save As Attachment Prefix', size=32, help='This is the prefix of the file name the print will be saved as attachement. Keep empty to not save the printed reports')

View File

@ -346,7 +346,7 @@ class module(osv.osv):
mod_sort = {}
for m in modules:
name, version, extension = m[0], m[1], m[-1]
if version == 'x': # 'x' version was a mistake
if not version or version == 'x': # 'x' version was a mistake
version = '0'
if name in mod_sort:
if parse_version(version) <= parse_version(mod_sort[name][0]):
@ -367,7 +367,7 @@ class module(osv.osv):
else:
id = ids[0]
installed_version = self.read(cr, uid, id, ['latest_version'])['latest_version']
if installed_version == 'x': # 'x' version was a mistake
if not installed_version or installed_version == 'x': # 'x' version was a mistake
installed_version = '0'
if parse_version(version) > parse_version(installed_version):
self.write(cr, uid, id, { 'url': url })

View File

@ -3,18 +3,16 @@
<template pageSize="(595.0,842.0)" title="Test" author="Martin Simon" allowSplitting="20">
<pageTemplate id="first">
<frame id="first" x1="42.0" y1="42.0" width="511" height="758"/>
<header>
<pageGraphics>
<setFont name="Helvetica-Bold" size="9"/>
<drawString x="1.0cm" y="28.1cm">[[ company.name ]]</drawString>
<drawRightString x="20cm" y="28.1cm"> Reference Guide </drawRightString>
<lineMode width="0.7"/>
<stroke color="black"/>
<lines>1cm 28cm 20cm 28cm</lines>
</pageGraphics>
</header>
<header>
<pageGraphics>
<setFont name="Helvetica-Bold" size="9"/>
<drawString x="1.0cm" y="28.1cm">[[ company.name ]]</drawString>
<drawRightString x="20cm" y="28.1cm"> Reference Guide </drawRightString>
<lineMode width="0.7"/>
<stroke color="black"/>
<lines>1cm 28cm 20cm 28cm</lines>
</pageGraphics>
</header>
</pageTemplate>
</template>
<stylesheet>
@ -66,6 +64,10 @@
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="4,0" stop="4,0"/>
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="4,-1" stop="4,-1"/>
</blockTableStyle>
<blockTableStyle id="depen_tbl">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
</blockTableStyle>
<blockTableStyle id="Tableau3">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
@ -104,44 +106,45 @@
<paraStyle name="terp_default_Right_8" fontName="Helvetica" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="terp_default_Centre_8" fontName="Helvetica" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="terp_header_Right" fontName="Helvetica-Bold" fontSize="15.0" leading="19" alignment="LEFT" spaceBefore="12.0" spaceAfter="6.0"/>
<paraStyle name="terp_header_Centre" fontName="Helvetica-Bold" fontSize="15.0" leading="19" alignment="CENTER" spaceBefore="12.0" spaceAfter="6.0"/>
<paraStyle name="terp_header_Centre" fontName="Helvetica-Bold" fontSize="11.0" leading="14" alignment="CENTER" spaceBefore="12.0" spaceAfter="6.0"/>
<paraStyle name="terp_default_address" fontName="Helvetica" fontSize="10.0" leading="13" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="terp_default_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="terp_default_11" fontName="Helvetica-Bold" fontSize="11.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="terp_default_Bold_9" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="terp_default_Centre_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="terp_default_Right_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="terp_default_1" fontName="Helvetica" fontSize="2.0" leading="3" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="terp_default_8_underline" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
</stylesheet>
<images/>
<story>
<para style="Standard">
<para style="terp_default_9">
<font color="white"> </font>
</para>
<para style="Standard">
<font color="white"> </font>
</para>
<blockTable colWidths="19.0,220.0,12.0" repeatRows="1" style="Table1">
<blockTable colWidths="139.0,220.0,152.0" repeatRows="1" style="Table1">
<tr>
<td>
<para style="terp_header_Centre">
<font color="white"> </font>
</para>
</td>
<td>
<para style="terp_default_11">Introspection report on objects</para>
<td>
<para style="terp_header_Centre">Introspection report on objects</para>
</td>
<td>
<para style="terp_header_Centre">
<font color="white"> </font>
</para>
</td>
</tr>
<tr>
<td>
</td>
</tr>
</blockTable>
<para style="Standard">
<font color="white"> </font>
</para>
<para style="Standard">
<font color="white"> </font>
</para>
<section>
<para style="Text body">[[ repeatIn(objects, 'module') ]]</para>
<para style="Text body">[[ repeatIn(objects,'module') ]]</para>
<blockTable colWidths="102.0,102.0,102.0,102.0,102.0" style="module_tbl_heading">
<tr>
<td>
@ -180,10 +183,41 @@
</td>
</tr>
</blockTable>
<para style="terp_default_9">
<para style="terp_default_Bold_8">
<font color="white"> </font>
</para>
<para style="terp_default_9">[[ module.description ]]</para>
<para style="terp_default_8_underline">Reports :</para>
<para style="terp_default_8">[[ format(module.reports_by_module) ]]</para>
<para style="terp_default_8">
<font color="white"> </font>
</para>
<para style="terp_default_8_underline">Menu :</para>
<para style="terp_default_8">[[ format(module.menus_by_module) ]]</para>
<para style="terp_default_8">
<font color="white"> </font>
</para>
<para style="terp_default_8_underline">View :</para>
<para style="terp_default_8">[[ format(module.views_by_module) ]]</para>
<para style="terp_default_8">
<font color="white"> </font>
</para>
<blockTable colWidths="510.0" style="depen_tbl">
<tr>
<td>
<para style="terp_default_8_underline">Dependencies :</para>
</td>
</tr>
<tr>
<td>
<para style="terp_default_8">[[ repeatIn(module.dependencies_id,'dependencies_id') ]]</para>
<para style="terp_default_8">[[ dependencies_id.name ]] - [[ dependencies_id.state ]]</para>
</td>
</tr>
</blockTable>
<para style="terp_default_8">
<font color="white"> </font>
</para>
<para style="terp_default_8">[[ module.description ]]</para>
<section>
<para style="terp_default_9">
<font color="white"> </font>

View File

@ -115,7 +115,6 @@ class Service(object):
self._response = s(self._response_process_id)
def abortResponse(self, error, description, origin, details):
import tools
if not tools.config['debug_mode']:
raise Exception("%s -- %s\n\n%s"%(origin, description, details))
else:
@ -152,12 +151,11 @@ LOG_CRITICAL = 'critical'
logging.DEBUG_RPC = logging.DEBUG - 1
def init_logger():
from tools import config
import os
logger = logging.getLogger()
if config['syslog']:
if tools.config['syslog']:
# SysLog Handler
if os.name == 'nt':
sysloghandler = logging.handlers.NTEventLogHandler("%s %s" %
@ -171,9 +169,9 @@ def init_logger():
# create a format for log messages and dates
formatter = logging.Formatter('[%(asctime)s] %(levelname)s:%(name)s:%(message)s', '%a %b %d %Y %H:%M:%S')
if config['logfile']:
if tools.config['logfile']:
# LogFile Handler
logf = config['logfile']
logf = tools.config['logfile']
try:
dirname = os.path.dirname(logf)
if dirname and not os.path.isdir(dirname):
@ -192,7 +190,7 @@ def init_logger():
# add the handler to the root logger
logger.addHandler(handler)
logger.setLevel(config['log_level'] or '0')
logger.setLevel(tools.config['log_level'] or '0')
if (not isinstance(handler, logging.FileHandler)) and os.name != 'nt':
# change color of level names
@ -240,13 +238,14 @@ class Logger(object):
level_method = getattr(log, level)
result = str(msg).strip().split('\n')
result = tools.ustr(msg).strip().split('\n')
if len(result)>1:
for idx, s in enumerate(result):
level_method('[%02d]: %s' % (idx+1, s,), extra=extra)
elif result:
level_method(result[0], extra=extra)
import tools
init_logger()
class Agent(object):
@ -303,7 +302,6 @@ class GenericXMLRPCRequestHandler:
self.log('exception', e)
tb_s = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
s = str(e)
import tools
if tools.config['debug_mode']:
import pdb
tb = sys.exc_info()[2]
@ -314,7 +312,6 @@ class SSLSocket(object):
def __init__(self, socket):
if not hasattr(socket, 'sock_shutdown'):
from OpenSSL import SSL
import tools
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.use_privatekey_file(tools.config['secure_pkey_file'])
ctx.use_certificate_file(tools.config['secure_cert_file'])
@ -475,7 +472,6 @@ class TinySocketClientThread(threading.Thread):
except Exception, e:
print repr(e)
tb_s = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
import tools
if tools.config['debug_mode']:
import pdb
tb = sys.exc_info()[2]

View File

@ -61,14 +61,6 @@ if pwd.getpwuid(os.getuid())[0] == 'root' :
import netsvc
logger = netsvc.Logger()
def atexit_callback():
logger.notifyChannel('shutdown', netsvc.LOG_INFO, "Shutdown Server!")
#logger.notifyChannel('pan! pan!', netsvc.LOG_INFO, "Killed Server ;-)")
import atexit
atexit.register(atexit_callback)
#-----------------------------------------------------------------------
# import the tools module so that the commandline parameters are parsed
#-----------------------------------------------------------------------
@ -95,18 +87,6 @@ logger.notifyChannel("objects", netsvc.LOG_INFO, 'initialising distributed objec
#---------------------------------------------------------------
import pooler
#----------------------------------------------------------
# launch modules install/upgrade/removes if needed
#----------------------------------------------------------
if tools.config['upgrade']:
logger.notifyChannel('init', netsvc.LOG_INFO, 'Upgrading new modules...')
import tools.upgrade
(toinit, toupdate) = tools.upgrade.upgrade()
for m in toinit:
tools.config['init'][m] = 1
for m in toupdate:
tools.config['update'][m] = 1
#----------------------------------------------------------
# import basic modules
#----------------------------------------------------------
@ -139,7 +119,9 @@ if tools.config["translate_out"]:
msg = "language %s" % (tools.config["language"],)
else:
msg = "new language"
logger.notifyChannel("init", netsvc.LOG_INFO, 'writing translation file for %s to %s' % (msg, tools.config["translate_out"]))
logger.notifyChannel("init", netsvc.LOG_INFO,
'writing translation file for %s to %s' % (msg,
tools.config["translate_out"]))
fileformat = os.path.splitext(tools.config["translate_out"])[-1][1:].lower()
buf = file(tools.config["translate_out"], "w")
@ -150,7 +132,9 @@ if tools.config["translate_out"]:
sys.exit(0)
if tools.config["translate_in"]:
tools.trans_load(tools.config["db_name"], tools.config["translate_in"], tools.config["language"])
tools.trans_load(tools.config["db_name"],
tools.config["translate_in"],
tools.config["language"])
sys.exit(0)
#----------------------------------------------------------------------------------
@ -165,11 +149,7 @@ if tools.config["stop_after_init"]:
#----------------------------------------------------------
if tools.config['xmlrpc']:
try:
port = int(tools.config["port"])
except Exception:
logger.notifyChannel("init", netsvc.LOG_CRITICAL, "invalid port: %r" % (tools.config["port"],))
sys.exit(1)
port = int(tools.config['port'])
interface = tools.config["interface"]
secure = tools.config["secure"]
@ -177,7 +157,9 @@ if tools.config['xmlrpc']:
xml_gw = netsvc.xmlrpc.RpcGateway('web-services')
httpd.attach("/xmlrpc", xml_gw)
logger.notifyChannel("web-services", netsvc.LOG_INFO, "starting XML-RPC%s services, port %s" % ((tools.config['secure'] and ' Secure' or ''), port))
logger.notifyChannel("web-services", netsvc.LOG_INFO,
"starting XML-RPC%s services, port %s" %
((tools.config['secure'] and ' Secure' or ''), port))
#
#if tools.config["soap"]:
@ -187,39 +169,44 @@ if tools.config['xmlrpc']:
#
if tools.config['netrpc']:
try:
netport = int(tools.config["netport"])
except Exception:
logger.notifyChannel("init", netsvc.LOG_ERROR, "invalid port '%s'!" % (tools.config["netport"],))
sys.exit(1)
netport = int(tools.config['netport'])
netinterface = tools.config["netinterface"]
tinySocket = netsvc.TinySocketServerThread(netinterface, netport, False)
logger.notifyChannel("web-services", netsvc.LOG_INFO, "starting NET-RPC service, port "+str(netport))
logger.notifyChannel("web-services", netsvc.LOG_INFO,
"starting NET-RPC service, port %d" % (netport,))
SIGNALS = dict(
[(getattr(signal, sign), sign) for sign in ('SIGINT', 'SIGTERM', 'SIGUSR1', 'SIGQUIT')]
)
def handler(signum, frame):
from tools import config
def handler(signum, _):
"""
:param signum: the signal number
:param _:
"""
if tools.config['netrpc']:
tinySocket.stop()
if tools.config['xmlrpc']:
httpd.stop()
netsvc.Agent.quit()
if config['pidfile']:
os.unlink(config['pidfile'])
if tools.config['pidfile']:
os.unlink(tools.config['pidfile'])
logger.notifyChannel('shutdown', netsvc.LOG_INFO,
"Shutdown Server! - %s" % ( SIGNALS[signum], ))
sys.exit(0)
from tools import config
if config['pidfile']:
fd = open(config['pidfile'], 'w')
for signum in SIGNALS:
signal.signal(signum, handler)
if tools.config['pidfile']:
fd = open(tools.config['pidfile'], 'w')
pidtext = "%d" % (os.getpid())
fd.write(pidtext)
fd.close()
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGTERM, handler)
logger.notifyChannel("web-services", netsvc.LOG_INFO,
'the server is running, waiting for connections...')
logger.notifyChannel("web-services", netsvc.LOG_INFO, 'the server is running, waiting for connections...')
if tools.config['netrpc']:
tinySocket.start()
if tools.config['xmlrpc']:

View File

@ -1364,12 +1364,11 @@ class orm_memory(orm_template):
return result
class orm(orm_template):
_sql_constraints = []
_log_access = True
_table = None
_protected = ['read','write','create','default_get','perm_read','unlink','fields_get','fields_view_get','search','name_get','distinct_field_get','name_search','copy','import_data','search_count']
def _parent_store_compute(self, cr):
logger = netsvc.Logger()
logger.notifyChannel('init', netsvc.LOG_INFO, 'Computing parent left and right for table %s...' % (self._table, ))
@ -2244,7 +2243,10 @@ class orm(orm_template):
if self.pool._init:
self.pool._init_parent[self._name]=True
else:
cr.execute('select parent_left,parent_right from '+self._table+' where id=%s', (vals[self._parent_name],))
if vals[self._parent_name]:
cr.execute('select parent_left,parent_right from '+self._table+' where id=%s', (vals[self._parent_name],))
else:
cr.execute('SELECT parent_left,parent_right FROM '+self._table+' WHERE id IS NULL')
res = cr.fetchone()
if res:
pleft,pright = res

View File

@ -50,9 +50,10 @@ def get_db_and_pool(db_name, force_demo=False, status=None, update_module=False)
return db, pool
def restart_pool(db_name, force_demo=False, update_module=False):
del pool_dic[db_name]
return get_db_and_pool(db_name, force_demo, update_module=update_module)
def restart_pool(db_name, force_demo=False, status=None, update_module=False):
if db_name in pool_dic:
del pool_dic[db_name]
return get_db_and_pool(db_name, force_demo, status, update_module=update_module)
def get_db_only(db_name):

View File

@ -81,11 +81,13 @@ class report_rml(report_int):
'html': self.create_html,
'raw': self.create_raw,
'sxw': self.create_sxw,
'txt': self.create_txt,
'txt': self.create_txt,
'odt': self.create_odt,
}
def create(self, cr, uid, ids, datas, context):
xml = self.create_xml(cr, uid, ids, datas, context)
xml = tools.ustr(xml).encode('utf8')
if datas.get('report_type', 'pdf') == 'raw':
return xml
rml = self.create_rml(cr, xml, uid, context)
@ -212,6 +214,10 @@ class report_rml(report_int):
def create_sxw(self, path, logo=None, title=None):
return path
def create_odt(self, data, logo=None, title=None):
return data
from report_sxw import report_sxw

View File

@ -157,7 +157,7 @@ class report_printscreen_list(report_int):
line[f]= line[f][1]
if fields[f]['type'] in ('one2many','many2many') and line[f]:
line[f] = '( '+str(len(line[f])) + ' )'
line[f] = '( '+tools.ustr(len(line[f])) + ' )'
if fields[f]['type'] == 'float':
precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2
line[f]='%.2f'%(line[f])
@ -166,7 +166,7 @@ class report_printscreen_list(report_int):
col.setAttribute('para','yes')
col.setAttribute('tree','no')
if line[f] != None:
txt = new_doc.createTextNode(str(line[f] or ''))
txt = new_doc.createTextNode(tools.ustr(line[f] or ''))
if temp[count] == 1:
tsum[count] = float(tsum[count]) + float(line[f]);

View File

@ -292,8 +292,9 @@ class rml_parse(object):
pp=self._node
self._node = pp
lst=''
if type(text)==type(''):
if isinstance(text,(str,unicode)):
lst = text.split('\n')
# lst = str(text).split('\n') # This is also acceptable, isn't it?
if lst and (not len(lst)):
return None
nodes = []
@ -618,7 +619,7 @@ class report_sxw(report_rml):
rml = tools.file_open(self.tmpl, subdir=None).read()
report_type= data.get('report_type', report_type)
if report_type == 'sxw' and report_xml:
if report_type in ['sxw','odt'] and report_xml:
context['parents'] = sxw_parents
sxw_io = StringIO.StringIO(report_xml.report_sxw_content)
sxw_z = zipfile.ZipFile(sxw_io, mode='r')
@ -668,7 +669,10 @@ class report_sxw(report_rml):
if self.header:
#Add corporate header/footer
rml = tools.file_open('custom/corporate_sxw_header.xml').read()
if report_type=='odt':
rml = tools.file_open('custom/corporate_odt_header.xml').read()
if report_type=='sxw':
rml = tools.file_open('custom/corporate_sxw_header.xml').read()
rml_parser = self.parser(cr, uid, self.name2, context)
rml_parser.parents = sxw_parents
rml_parser.tag = sxw_tag
@ -707,7 +711,6 @@ class report_sxw(report_rml):
}, context=context
)
cr.commit()
return (pdf, report_type)

View File

@ -82,8 +82,8 @@ class db(netsvc.Service):
cr.commit()
cr.close()
cr = None
pool = pooler.get_pool(db_name, demo, serv.actions[id],
update_module=True)
pool = pooler.restart_pool(db_name, demo, serv.actions[id],
update_module=True)[1]
cr = sql_db.db_connect(db_name).cursor()

View File

@ -197,42 +197,44 @@ class PoolManager(object):
_dsn = None
maxconn = int(tools.config['db_maxconn']) or 64
def dsn(db_name):
if PoolManager._dsn is None:
PoolManager._dsn = ''
@classmethod
def dsn(cls, db_name):
if cls._dsn is None:
cls._dsn = ''
for p in ('host', 'port', 'user', 'password'):
cfg = tools.config['db_' + p]
if cfg:
PoolManager._dsn += '%s=%s ' % (p, cfg)
return '%s dbname=%s' % (PoolManager._dsn, db_name)
dsn = staticmethod(dsn)
cls._dsn += '%s=%s ' % (p, cfg)
return '%s dbname=%s' % (cls._dsn, db_name)
def get(db_name):
if db_name not in PoolManager._pools:
@classmethod
def get(cls, db_name):
if db_name not in cls._pools:
logger = netsvc.Logger()
try:
logger.notifyChannel('dbpool', netsvc.LOG_INFO, 'Connecting to %s' % (db_name,))
PoolManager._pools[db_name] = ConnectionPool(ThreadedConnectionPool(1, PoolManager.maxconn, PoolManager.dsn(db_name)), db_name)
cls._pools[db_name] = ConnectionPool(ThreadedConnectionPool(1, cls.maxconn, cls.dsn(db_name)), db_name)
except Exception, e:
logger.notifyChannel('dbpool', netsvc.LOG_ERROR, 'Unable to connect to %s: %s' %
(db_name, str(e)))
raise
return PoolManager._pools[db_name]
get = staticmethod(get)
return cls._pools[db_name]
def close(db_name):
if db_name in PoolManager._pools:
@classmethod
def close(cls, db_name):
if db_name in cls._pools:
logger = netsvc.Logger()
logger.notifyChannel('dbpool', netsvc.LOG_INFO, 'Closing all connections to %s' % (db_name,))
PoolManager._pools[db_name].closeall()
del PoolManager._pools[db_name]
close = staticmethod(close)
cls._pools[db_name].closeall()
del cls._pools[db_name]
def db_connect(db_name, serialize=0):
return PoolManager.get(db_name)
def close_db(db_name):
return PoolManager.close(db_name)
PoolManager.close(db_name)
tools.cache.clean_cache_for_db(db_name)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,7 +1,7 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#
@ -120,7 +120,7 @@ def _100_to_text_nl(number):
else:
units = units_nl[number % 10]
if units[-1] == 'e':
joinword = 'ën'
joinword = 'ën'
else:
joinword = 'en'
return units+joinword+tens_nl[number / 10]

View File

@ -42,9 +42,9 @@ class configmanager(object):
self.options = {
'email_from':False,
'interface': '', # this will bind the server to all interfaces
'port': '8069',
'port': 8069,
'netinterface': '',
'netport': '8070',
'netport': 8070,
'db_host': False,
'db_port': False,
'db_name': False,
@ -76,6 +76,7 @@ class configmanager(object):
'syslog' : False,
'log_level': logging.INFO,
'assert_exit_level': logging.WARNING, # level above which a failed assert will be raise
'cache_timeout': 100000,
}
hasSSL = check_ssl()
@ -87,26 +88,34 @@ class configmanager(object):
parser = optparse.OptionParser(version=version)
parser.add_option("-c", "--config", dest="config", help="specify alternate config file")
parser.add_option("-s", "--save", action="store_true", dest="save", default=False, help="save configuration to ~/.openerp_serverrc")
parser.add_option("-s", "--save", action="store_true", dest="save", default=False,
help="save configuration to ~/.openerp_serverrc")
parser.add_option("--pidfile", dest="pidfile", help="file where the server pid will be stored")
parser.add_option("-n", "--interface", dest="interface", help="specify the TCP IP address")
parser.add_option("-p", "--port", dest="port", help="specify the TCP port")
parser.add_option("-p", "--port", dest="port", help="specify the TCP port", type="int")
parser.add_option("--net_interface", dest="netinterface", help="specify the TCP IP address for netrpc")
parser.add_option("--net_port", dest="netport", help="specify the TCP port for netrpc")
parser.add_option("--net_port", dest="netport", help="specify the TCP port for netrpc", type="int")
parser.add_option("--no-netrpc", dest="netrpc", action="store_false", default=True, help="disable netrpc")
parser.add_option("--no-xmlrpc", dest="xmlrpc", action="store_false", default=True, help="disable xmlrpc")
parser.add_option("-i", "--init", dest="init", help="init a module (use \"all\" for all modules)")
parser.add_option("--without-demo", dest="without_demo", help="load demo data for a module (use \"all\" for all modules)", default=False)
parser.add_option("-u", "--update", dest="update", help="update a module (use \"all\" for all modules)")
parser.add_option("--without-demo", dest="without_demo",
help="load demo data for a module (use \"all\" for all modules)", default=False)
parser.add_option("-u", "--update", dest="update",
help="update a module (use \"all\" for all modules)")
parser.add_option("--cache-timeout", dest="cache_timeout",
help="set the timeout for the cache system", default=100000, type="int")
# stops the server from launching after initialization
parser.add_option("--stop-after-init", action="store_true", dest="stop_after_init", default=False, help="stop the server after it initializes")
parser.add_option("--stop-after-init", action="store_true", dest="stop_after_init", default=False,
help="stop the server after it initializes")
parser.add_option('--debug', dest='debug_mode', action='store_true', default=False, help='enable debug mode')
parser.add_option("--assert-exit-level", dest='assert_exit_level', type="choice", choices=loglevels.keys(), help="specify the level at which a failed assertion will stop the server. Accepted values: " + str(loglevels.keys()))
parser.add_option("--assert-exit-level", dest='assert_exit_level', type="choice", choices=loglevels.keys(),
help="specify the level at which a failed assertion will stop the server. Accepted values: %s" % (loglevels.keys(),))
if hasSSL:
group = optparse.OptionGroup(parser, "SSL Configuration")
group.add_option("-S", "--secure", dest="secure", action="store_true", help="launch server over https instead of http", default=False)
group.add_option("-S", "--secure", dest="secure", action="store_true",
help="launch server over https instead of http", default=False)
group.add_option("--cert-file", dest="secure_cert_file",
default="server.cert",
help="specify the certificate file for the SSL connection")
@ -128,7 +137,7 @@ class configmanager(object):
group = optparse.OptionGroup(parser, "SMTP Configuration")
group.add_option('--email-from', dest='email_from', default='', help='specify the SMTP email address for sending email')
group.add_option('--smtp', dest='smtp_server', default='', help='specify the SMTP server for sending email')
group.add_option('--smtp-port', dest='smtp_port', default='25', help='specify the SMTP port')
group.add_option('--smtp-port', dest='smtp_port', default='25', help='specify the SMTP port', type="int")
if hasSSL:
group.add_option('--smtp-ssl', dest='smtp_ssl', default='', help='specify the SMTP server support SSL or not')
group.add_option('--smtp-user', dest='smtp_user', default='', help='specify the SMTP username for sending email')
@ -136,18 +145,17 @@ class configmanager(object):
group.add_option('--price_accuracy', dest='price_accuracy', default='2', help='specify the price accuracy')
parser.add_option_group(group)
group = optparse.OptionGroup(parser, "Modules related options")
group.add_option("-g", "--upgrade", action="store_true", dest="upgrade", default=False, help="Upgrade/install/uninstall modules")
group = optparse.OptionGroup(parser, "Database related options")
group.add_option("-d", "--database", dest="db_name", help="specify the database name")
group.add_option("-r", "--db_user", dest="db_user", help="specify the database user name")
group.add_option("-w", "--db_password", dest="db_password", help="specify the database password")
group.add_option("--pg_path", dest="pg_path", help="specify the pg executable path")
group.add_option("--db_host", dest="db_host", help="specify the database host")
group.add_option("--db_port", dest="db_port", help="specify the database port")
group.add_option("--db_maxconn", dest="db_maxconn", default='64', help="specify the the maximum number of physical connections to posgresql")
group.add_option("-P", "--import-partial", dest="import_partial", help="Use this for big data importation, if it crashes you will be able to continue at the current state. Provide a filename to store intermediate importation states.", default=False)
group.add_option("--db_port", dest="db_port", help="specify the database port", type="int")
group.add_option("--db_maxconn", dest="db_maxconn", default='64',
help="specify the the maximum number of physical connections to posgresql")
group.add_option("-P", "--import-partial", dest="import_partial",
help="Use this for big data importation, if it crashes you will be able to continue at the current state. Provide a filename to store intermediate importation states.", default=False)
parser.add_option_group(group)
group = optparse.OptionGroup(parser, "Internationalisation options",
@ -156,11 +164,17 @@ class configmanager(object):
"Option '-l' is mandatory in case of importation"
)
group.add_option('-l', "--language", dest="language", help="specify the language of the translation file. Use it with --i18n-export or --i18n-import")
group.add_option("--i18n-export", dest="translate_out", help="export all sentences to be translated to a CSV file, a PO file or a TGZ archive and exit")
group.add_option("--i18n-import", dest="translate_in", help="import a CSV or a PO file with translations and exit. The '-l' option is required.")
group.add_option("--modules", dest="translate_modules", help="specify modules to export. Use in combination with --i18n-export")
group.add_option("--addons-path", dest="addons_path", help="specify an alternative addons path.", action="callback", callback=self._check_addons_path, nargs=1, type="string")
group.add_option('-l', "--language", dest="language",
help="specify the language of the translation file. Use it with --i18n-export or --i18n-import")
group.add_option("--i18n-export", dest="translate_out",
help="export all sentences to be translated to a CSV file, a PO file or a TGZ archive and exit")
group.add_option("--i18n-import", dest="translate_in",
help="import a CSV or a PO file with translations and exit. The '-l' option is required.")
group.add_option("--modules", dest="translate_modules",
help="specify modules to export. Use in combination with --i18n-export")
group.add_option("--addons-path", dest="addons_path",
help="specify an alternative addons path.",
action="callback", callback=self._check_addons_path, nargs=1, type="string")
parser.add_option_group(group)
(opt, args) = parser.parse_args()
@ -189,7 +203,7 @@ class configmanager(object):
self.options['pidfile'] = False
keys = ['interface', 'port', 'db_name', 'db_user', 'db_password', 'db_host',
'db_port', 'logfile', 'pidfile', 'smtp_port',
'db_port', 'logfile', 'pidfile', 'smtp_port', 'cache_timeout',
'email_from', 'smtp_server', 'smtp_user', 'smtp_password', 'price_accuracy',
'netinterface', 'netport', 'db_maxconn', 'import_partial', 'addons_path',
'netrpc', 'xmlrpc', 'syslog', 'without_demo']
@ -202,7 +216,7 @@ class configmanager(object):
if getattr(opt, arg):
self.options[arg] = getattr(opt, arg)
keys = ['language', 'translate_out', 'translate_in', 'upgrade', 'debug_mode',
keys = ['language', 'translate_out', 'translate_in', 'debug_mode',
'stop_after_init']
for arg in keys:
@ -219,18 +233,9 @@ class configmanager(object):
if not self.options['addons_path'] or self.options['addons_path']=='None':
self.options['addons_path'] = os.path.join(self.options['root_path'], 'addons')
init = {}
if opt.init:
for i in opt.init.split(','):
init[i] = 1
self.options['init'] = init
self.options['init'] = opt.init and dict.fromkeys(opt.init.split(','), 1) or {}
self.options["demo"] = not opt.without_demo and self.options['init'] or {}
update = {}
if opt.update:
for i in opt.update.split(','):
update[i] = 1
self.options['update'] = update
self.options['update'] = opt.update and dict.fromkeys(opt.update.split(','), 1) or {}
self.options['translate_modules'] = opt.translate_modules and map(lambda m: m.strip(), opt.translate_modules.split(',')) or ['all']
self.options['translate_modules'].sort()

View File

@ -536,14 +536,34 @@ class cache(object):
Use it as a decorator of the function you plan to cache
Timeout: 0 = no timeout, otherwise in seconds
"""
def __init__(self, timeout=10000, skiparg=2, multi=None):
__caches = []
def __init__(self, timeout=None, skiparg=2, multi=None):
assert skiparg >= 2 # at least self and cr
self.timeout = timeout
if timeout is None:
self.timeout = config['cache_timeout']
else:
self.timeout = timeout
self.skiparg = skiparg
self.multi = multi
self.lasttime = time.time()
self.cache = {}
cache.__caches.append(self)
@classmethod
def clean_cache_for_db(cls, dbname):
def get_dbname_from_key(key):
for e in key:
if e[0] == 'dbname':
return e[1]
return None
for cache in cls.__caches:
keys_to_del = [key for key in cache.cache if get_dbname_from_key(key) == dbname]
for key in keys_to_del:
del cache.cache[key]
def __call__(self, fn):
arg_names = inspect.getargspec(fn)[0][self.skiparg:]
@ -552,7 +572,7 @@ class cache(object):
if time.time()-self.timeout > self.lasttime:
self.lasttime = time.time()
t = time.time()-self.timeout
for key in self.cache:
for key in self.cache.keys():
if self.cache[key][1]<t:
del self.cache[key]
@ -629,10 +649,6 @@ def ustr(value):
@return: unicode string
"""
if (value is None) or (value is False):
return value
if not value:
return u''
if isinstance(value, unicode):
return value
@ -644,6 +660,29 @@ def ustr(value):
return unicode(value, 'utf-8')
# to be compatible with python 2.4
import __builtin__
if not hasattr(__builtin__, 'all'):
def all(iterable):
for element in iterable:
if not element:
return False
return True
__builtin__.all = all
del all
if not hasattr(__builtin__, 'any'):
def any(iterable):
for element in iterable:
if element:
return True
return False
__builtin__.any = any
del any
def get_languages():
languages={

View File

@ -71,7 +71,7 @@ def parse_version(s):
contain them.
"""
parts = []
for part in _parse_version_parts(s.lower()):
for part in _parse_version_parts((s or '0.1').lower()):
if part.startswith('*'):
if part<'*final': # remove '-' before a prerelease tag
while parts and parts[-1]=='*final-': parts.pop()

View File

@ -1,92 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import tarfile
import re
import urllib2
import os
import shutil
import tools
# remove an existing version of modules if it exist
def remove(name):
adp = tools.config['addons_path']
addons = os.listdir(adp)
if name in addons:
try:
shutil.rmtree(os.path.join(adp, name))
except:
print "Unable to remove module %s !" % name
def install(name, url):
tar = tarfile.open(mode="r|gz", fileobj=urllib2.urlopen(url))
for tarinfo in tar:
tar.extract(tarinfo, tools.config['addons_path'])
def upgrade():
import pooler
cr = pooler.db.cursor()
toinit = []
toupdate = []
# print 'Check for correct rights (create and unlink on addons)...'
# todo: touch addons/test.txt
# todo: rm addons/test.txt
print 'Check for modules to remove...'
cr.execute('select id,name,url from ir_module_module where state=%s', ('to remove',))
for module_id,name,url in cr.fetchall():
print '\tremoving module %s' % name
remove(name)
cr.execute('update ir_module_module set state=%s where id=%s', ('uninstalled', module_id))
cr.commit()
print 'Check for modules to upgrade...'
cr.execute('select id,name,url from ir_module_module where state=%s', ('to upgrade',))
for module_id,name,url in cr.fetchall():
print '\tupgrading module %s' % name
remove(name)
install(name, url)
cr.execute('update ir_module_module set state=%s where id=%s', ('installed', module_id))
cr.commit()
toupdate.append(name)
print 'Check for modules to install...'
cr.execute('select id,name,url from ir_module_module where state=%s', ('to install',))
for module_id,name,url in cr.fetchall():
print '\tinstalling module %s' % name
install(name, url)
cr.execute('update ir_module_module set state=%s where id=%s', ('installed', module_id))
cr.commit()
toinit.append(name)
print 'Initializing all datas...'
cr.commit()
cr.close()
return (toinit, toupdate)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: