# -*- encoding: utf-8 -*-
##############################################################################
#
-# Copyright (c) 2004-2008 Tiny SPRL (http://tiny.be) All Rights Reserved.
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+# $Id$
#
-# $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.
#
-# WARNING: This program as such is intended to be used by professional
-# programmers who take the whole responsability of assessing all potential
-# consequences resulting from its eventual inadequacies and bugs
-# End users who are looking for a ready-to-use solution with commercial
-# garantees and support are strongly adviced to contract a Free Software
-# Service Company
+# 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.
#
-# 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 2
-# of the License, or (at your option) any later version.
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-###############################################################################
-
-import base64, os, string
+##############################################################################
-import netsvc
-import pooler, security, ir, tools
+import base64
import logging
-
-import threading, thread
-
+import os
+import security
+import string
+import thread
+import threading
import time
-import base64
-import addons
-import sql_db
from tools.translate import _
+import addons
+import ir
+import netsvc
+import pooler
+import release
+import sql_db
+import tools
logging.basicConfig()
self.exportMethod(self.list_lang)
self.exportMethod(self.change_admin_password)
self.exportMethod(self.server_version)
+ self.exportMethod(self.migrate_databases)
self.actions = {}
self.id = 0
self.id_protect = threading.Semaphore()
self.actions[id] = {'clean': False}
db = sql_db.db_connect('template1', serialize=1)
- db.truedb.autocommit()
cr = db.cursor()
+ cr.autocommit(True)
+ time.sleep(0.2)
cr.execute('CREATE DATABASE ' + db_name + ' ENCODING \'unicode\'')
cr.close()
class DBInitialize(object):
cr.commit()
cr.close()
cr = None
- pool = pooler.get_pool(db_name, demo,serv.actions[id],
- update_module=True)
- if lang and lang != 'en_US':
- filename = tools.config["root_path"] + "/i18n/" + lang + ".csv"
- tools.trans_load(db_name, filename, lang)
- serv.actions[id]['clean'] = True
+ pool = pooler.restart_pool(db_name, demo, serv.actions[id],
+ update_module=True)[1]
+
cr = sql_db.db_connect(db_name).cursor()
- cr.execute('UPDATE res_users SET password=%s, active=True WHERE login=%s', (
- user_password, 'admin'))
- cr.execute('select login, password, name ' \
- 'from res_users ' \
- 'order by login')
+
+ if lang:
+ modobj = pool.get('ir.module.module')
+ mids = modobj.search(cr, 1, [('state', '=', 'installed')])
+ modobj.update_translations(cr, 1, mids, lang)
+
+ cr.execute('UPDATE res_users SET password=%s, context_lang=%s, active=True WHERE login=%s', (
+ user_password, lang, 'admin'))
+ cr.execute('SELECT login, password, name ' \
+ ' FROM res_users ' \
+ ' ORDER BY login')
serv.actions[id]['users'] = cr.dictfetchall()
+ serv.actions[id]['clean'] = True
+ cr.commit()
cr.close()
except Exception, e:
serv.actions[id]['clean'] = False
traceback.print_exc(file=e_str)
traceback_str = e_str.getvalue()
e_str.close()
- print traceback_str
+ netsvc.Logger().notifyChannel('web-services', netsvc.LOG_ERROR, 'CREATE DATABASE\n%s' % (traceback_str))
serv.actions[id]['traceback'] = traceback_str
if cr:
cr.close()
logger = netsvc.Logger()
- logger.notifyChannel("web-services", netsvc.LOG_INFO,
- 'CREATE DB: %s' % (db_name))
+ logger.notifyChannel("web-services", netsvc.LOG_INFO, 'CREATE DATABASE: %s' % (db_name.lower()))
dbi = DBInitialize()
create_thread = threading.Thread(target=dbi,
args=(self, id, db_name, demo, lang, user_password))
def drop(self, password, db_name):
security.check_super(password)
- pooler.close_db(db_name)
+ sql_db.close_db(db_name)
logger = netsvc.Logger()
db = sql_db.db_connect('template1', serialize=1)
- db.truedb.autocommit()
cr = db.cursor()
+ cr.autocommit(True)
try:
try:
cr.execute('DROP DATABASE ' + db_name)
- except:
- logger.notifyChannel("web-service", netsvc.LOG_ERROR,
- 'DROP DB: %s failed' % (db_name,))
- raise
+ except Exception, e:
+ logger.notifyChannel("web-services", netsvc.LOG_ERROR,
+ 'DROP DB: %s failed:\n%s' % (db_name, e))
+ raise Exception("Couldn't drop database %s: %s" % (db_name, e))
else:
logger.notifyChannel("web-services", netsvc.LOG_INFO,
'DROP DB: %s' % (db_name))
security.check_super(password)
logger = netsvc.Logger()
- if tools.config['db_password']:
- logger.notifyChannel("web-service", netsvc.LOG_ERROR,
- 'DUMP DB: %s doesn\'t work with password' % (db_name,))
- raise Exception, "Couldn't dump database with password"
-
cmd = ['pg_dump', '--format=c']
if tools.config['db_user']:
cmd.append('--username=' + tools.config['db_user'])
data = stdout.read()
res = stdout.close()
if res:
- logger.notifyChannel("web-service", netsvc.LOG_ERROR,
+ logger.notifyChannel("web-services", netsvc.LOG_ERROR,
'DUMP DB: %s failed\n%s' % (db_name, data))
raise Exception, "Couldn't dump database"
logger.notifyChannel("web-services", netsvc.LOG_INFO,
logger = netsvc.Logger()
if self.db_exist(db_name):
- logger.notifyChannel("web-service", netsvc.LOG_WARNING,
+ logger.notifyChannel("web-services", netsvc.LOG_WARNING,
'RESTORE DB: %s already exists' % (db_name,))
raise Exception, "Database already exists"
- if tools.config['db_password']:
- logger.notifyChannel("web-service", netsvc.LOG_ERROR,
- 'RESTORE DB: %s doesn\'t work with password' % (db_name,))
- raise Exception, "Couldn't restore database with password"
-
db = sql_db.db_connect('template1', serialize=1)
- db.truedb.autocommit()
cr = db.cursor()
+ cr.autocommit(True)
cr.execute('CREATE DATABASE ' + db_name + ' ENCODING \'unicode\'')
cr.close()
def db_exist(self, db_name):
try:
db = sql_db.db_connect(db_name)
- db.truedb.close()
return True
except:
return False
import pwd
db_user = pwd.getpwuid(os.getuid())[0]
if not db_user:
- cr.execute("select usename from pg_user where usesysid=(select datdba from pg_database where datname=%s)", (tools.config["db_name"],))
+ cr.execute("select decode(usename, 'escape') from pg_user where usesysid=(select datdba from pg_database where datname=%s)", (tools.config["db_name"],))
res = cr.fetchone()
- db_user = res and res[0]
+ db_user = res and str(res[0])
if db_user:
- cr.execute("select datname from pg_database where datdba=(select usesysid from pg_user where usename=%s) and datname not in ('template0', 'template1', 'postgres')", (db_user,))
+ cr.execute("select decode(datname, 'escape') from pg_database where datdba=(select usesysid from pg_user where usename=%s) and datname not in ('template0', 'template1', 'postgres')", (db_user,))
else:
- cr.execute("select datname from pg_database where datname not in('template0', 'template1','postgres')")
- res = [name for (name,) in cr.fetchall()]
+ cr.execute("select decode(datname, 'escape') from pg_database where datname not in('template0', 'template1','postgres')")
+ res = [str(name) for (name,) in cr.fetchall()]
cr.close()
except:
res = []
- db.truedb.close()
+ res.sort()
return res
def change_admin_password(self, old_password, new_password):
tools.config['admin_passwd'] = new_password
tools.config.save()
return True
-
+
def list_lang(self):
return tools.scan_languages()
- import glob
- file_list = glob.glob(os.path.join(tools.config['root_path'], 'i18n', '*.csv'))
- def lang_tuple(fname):
- lang_dict=tools.get_languages()
- lang = os.path.basename(fname).split(".")[0]
- return (lang, lang_dict.get(lang, lang))
- return [lang_tuple(fname) for fname in file_list]
def server_version(self):
""" Return the version of the server
Used by the client to verify the compatibility with its own version
"""
- return tinyerp_version
+ return release.version
+
+ def migrate_databases(self, password, databases):
+ security.check_super(password)
+ l = netsvc.Logger()
+ for db in databases:
+ try:
+ l.notifyChannel('migration', netsvc.LOG_INFO, 'migrate database %s' % (db,))
+ tools.config['update']['base'] = True
+ pooler.restart_pool(db, force_demo=False, update_module=True)
+ except Exception, e:
+ tools.debug(e)
+ raise
db()
+class MigrationException(Exception): pass
+
class common(netsvc.Service):
def __init__(self,name="common"):
netsvc.Service.__init__(self,name)
self.exportMethod(self.ir_del)
self.exportMethod(self.about)
self.exportMethod(self.login)
+ self.exportMethod(self.logout)
self.exportMethod(self.timezone_get)
+ self.exportMethod(self.get_migration_scripts)
def ir_set(self, db, uid, password, keys, args, name, value, replace=True, isobject=False):
security.check(db, uid, password)
res = security.login(db, login, password)
logger = netsvc.Logger()
msg = res and 'successful login' or 'bad login or password'
- logger.notifyChannel("web-service", netsvc.LOG_INFO, "%s from '%s' using database '%s'" % (msg, login, db))
+ logger.notifyChannel("web-service", netsvc.LOG_INFO, "%s from '%s' using database '%s'" % (msg, login, db.lower()))
return res or False
+ def logout(self, db, login, password):
+ logger = netsvc.Logger()
+ logger.notifyChannel("web-service", netsvc.LOG_INFO,'Logout %s from database %s'%(login,db))
+ return True
+
def about(self, extended=False):
"""Return information about the OpenERP Server.
(c) 2003-TODAY, Fabien Pinckaers - Tiny sprl''')
if extended:
- return info, tinyerp_version
+ return info, release.version
return info
def timezone_get(self, db, login, password):
return time.tzname[0]
+
+
+ def get_migration_scripts(self, password, contract_id, contract_password):
+ security.check_super(password)
+ l = netsvc.Logger()
+ try:
+ from tools.maintenance import remote_contract
+ rc = remote_contract(contract_id, contract_password)
+ if not rc.id:
+ raise MigrationException('This contract does not exist or is not active')
+ if rc.status != 'full':
+ raise MigrationException('Can not get updates for a partial contract')
+
+ l.notifyChannel('migration', netsvc.LOG_INFO, 'starting migration with contract %s' % (rc.name,))
+
+ zips = rc.retrieve_updates(rc.id)
+
+ from shutil import rmtree
+ for module in zips:
+ l.notifyChannel('migration', netsvc.LOG_INFO, 'upgrade module %s' % (module,))
+ mp = addons.get_module_path(module)
+ if mp:
+ if os.path.isdir(mp):
+ rmtree(os.path.realpath(mp))
+ else:
+ os.unlink(mp + '.zip')
+
+ mp = os.path.join(tools.config['addons_path'], module + '.zip')
+
+ zip = open(mp, 'w')
+ zip.write(base64.decodestring(zips[module]))
+ zip.close()
+ except MigrationException, e:
+ self.abortResponse(1, 'Migration Error', 'warning', str(e))
+ except Exception, e:
+ import traceback
+ tb_s = reduce(lambda x, y: x+y, traceback.format_exception( sys.exc_type, sys.exc_value, sys.exc_traceback))
+ l.notifyChannel('migration', netsvc.LOG_ERROR, tb_s)
+ raise
+
common()
class objects_proxy(netsvc.Service):
self.exportMethod(self.execute)
self.exportMethod(self.exec_workflow)
self.exportMethod(self.obj_list)
-
+
def exec_workflow(self, db, uid, passwd, object, method, id):
security.check(db, uid, passwd)
service = netsvc.LocalService("object_proxy")
res = service.exec_workflow(db, uid, object, method, id)
return res
-
+
def execute(self, db, uid, passwd, object, method, *args):
security.check(db, uid, passwd)
service = netsvc.LocalService("object_proxy")
if not context:
context={}
security.check(db, uid, passwd)
-
+
self.id_protect.acquire()
self.id += 1
id = self.id
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:
- cr = pooler.get_db(db).cursor()
obj = netsvc.LocalService('report.'+object)
(result, format) = obj.create(cr, uid, ids, datas, context)
- cr.close()
self._reports[id]['result'] = result
self._reports[id]['format'] = format
self._reports[id]['state'] = True
tb_s = reduce(lambda x, y: x+y, traceback.format_exception(
sys.exc_type, sys.exc_value, sys.exc_traceback))
logger = netsvc.Logger()
- logger.notifyChannel('web-service', netsvc.LOG_ERROR,
+ logger.notifyChannel('web-services', netsvc.LOG_ERROR,
'Exception: %s\n%s' % (str(exception), tb_s))
self._reports[id]['exception'] = exception
self._reports[id]['state'] = True
+ cr.close()
return True
thread.start_new_thread(go, (id, uid, ids, datas, context))