Setup Erweiterungen aus anderen Projekten übernommen:

create_from_dump, anonym, invalidate_email, uninstall, cancel_upgrade, finance_config
Zusätzlich:
   setup_part (Setup mit Angabe der Setup Methode), usage erweitert
develop
Ulrich Krenn 2016-02-22 16:26:43 +01:00
parent a9d0bb2b59
commit 2fb31d259b
6 changed files with 499 additions and 48 deletions

83
dev/scripts/transform_po.py Executable file
View File

@ -0,0 +1,83 @@
#!/usr/bin/python
# -*- encoding: utf-8 -*-
import fnmatch
import polib
import re
import os
import string
start_directory = '../..'
language_filename = 'de.po'
print "Start"
search_replace_regex = [(u'Ist ein Unternehmen\?', u'Hauptkontakt?'),
(u'Ist ein Unternehmen', u'Hauptkontakt'),
(u'Aufträge', u'Kundenbestellungen'),
(u'der Auftrag', u'die Kundenbestellung'),
(u'des Auftrags', u'der Kundenbestellung'),
(u'dem Auftrag', u'der Kundenbestellung'),
(u'den Auftrag', u'die Kundenbestellung'),
(u'ein Auftrag', u'eine Kundenbestellung'),
(u'einen Auftrag', u'eine Kundenbestellung'),
(u'diesen Auftrag', u'diese Kundenbestellung'),
(u'Der Auftrag', u'Die Kundenbestellung'),
(u'Des Auftrags', u'Der Kundenbestellung'),
(u'Dem Auftrag', u'Der Kundenbestellung'),
(u'Den Auftrag', u'Die Kundenbestellung'),
(u'Ein Auftrag', u'Eine Kundenbestellung'),
(u'Einen Auftrag', u'Eine Kundenbestellung'),
(u'Diesen Auftrag', u'Diese Kundenbestellung'),
(u'Auftragsnummer', u'Kundenbestellung Nr.'),
(u'Auftrag', u'Kundenbestellung'),
(u'der Verkaufsauftrag', u'die Kundenbestellung'),
(u'des Verkaufsauftrag', u'der Kundenbestellung'),
(u'dem Verkaufsauftrag', u'der Kundenbestellung'),
(u'den Verkaufsauftrag', u'die Kundenbestellung'),
(u'ein Verkaufsauftrag', u'eine Kundenbestellung'),
(u'einen Verkaufsauftrag', u'eine Kundenbestellung'),
(u'diesen Verkaufsauftrag', u'diese Kundenbestellung'),
(u'Der Verkaufsauftrag', u'Die Kundenbestellung'),
(u'Des Verkaufsauftrag', u'Der Kundenbestellung'),
(u'Dem Verkaufsauftrag', u'Der Kundenbestellung'),
(u'Den Verkaufsauftrag', u'Die Kundenbestellung'),
(u'Ein Verkaufsauftrag', u'Eine Kundenbestellung'),
(u'Einen Verkaufsauftrag', u'Eine Kundenbestellung'),
(u'Diesen Verkaufsauftrag', u'Diese Kundenbestellung'),
(u'Verkaufsauftrag', u'Kundenbestellung'),
(u'Verkaufsauftrag', u'Kundenbestellung'),
(u'Amount Paid', u'Betrag bezahlt'),
]
search_module = ['sale', 'base']
valid_entries = []
for root, dirs, files in os.walk(start_directory):
for filename in fnmatch.filter(files, language_filename):
print "File: " + filename
src = os.path.join(root, filename)
po = polib.pofile(src)
for e in po:
if not e.obsolete:
valid_entries.append(e)
po2 = polib.POFile()
for se in search_replace_regex:
for entry in valid_entries:
module = re.search(u'(module:)(.*)', entry.comment)
if module:
module = module.group(2).strip()
if module in search_module:
if re.search(se[0], entry.msgstr):
entry.msgstr = string.replace(entry.msgstr, se[0], se[1])
po2.append(entry)
print entry.msgid, "<->", entry.msgstr
elif re.search(se[0], entry.msgid):
entry.msgstr = se[1]
po2.append(entry)
print entry.msgid, "<->", entry.msgstr
po2.save('../../setup/auto_translated2.po')

70
dev/scripts/transform_po2.py Executable file
View File

@ -0,0 +1,70 @@
#!/usr/bin/python
# -*- encoding: utf-8 -*-
import fnmatch
import polib
import re
import os
import string
start_directory = '../..'
language_filename = '*.pot'
search_replace_regex = [(u'^Partner$', u'Kunde'),
(u'^Partners$', u'Kunden'),
(u'^Partner:$', u'Kunde:'),
(u'^Partners:$', u'Kunden:'),
(u'^Whole Company$', u'Ganzes Unternehmen'),
(u'^General announces for all employees.$', u'Allgemeine Nachrichten für alle Mitarbeiter'),
#(u'^Exception Rules$', u'Ausnahmeregeln'),
(u'^Payment Method$', u'Zahlungsart'),
#(u'^Automatic Workflow$', u'Automatischer Workflow'),
#(u'^Exception Name$', u'Name der Ausnahme'),
(u'^Description$', u'Beschreibung'),
(u'^Apply on$', u'Anwenden auf'),
(u'^Payment Term$', u'Zahlungsziel'),
(u'^Company$', u'Firma'),
#(u'^Journal for payment$', u'Journal für Zahlungseingänge'),
(u'^Default Values$', u'Standardwerte'),
(u'^Main Exception$', u'Fehlermeldung'),
# (u'^$', u''),
]
search_module = False # ['sale', 'stock']
valid_entries = []
for root, dirs, files in os.walk(start_directory):
for filename in fnmatch.filter(files, language_filename):
print filename
src = os.path.join(root, filename)
try:
po = polib.pofile(src)
except IOError as e:
print "ERROR", e
continue
for e in po:
if not e.obsolete:
valid_entries.append(e)
po2 = polib.POFile()
cnt = 0
for se in search_replace_regex:
for entry in valid_entries:
module = re.search(u'(module:)(.*)', entry.comment)
if module:
module = module.group(2).strip()
if search_module is False or module in search_module:
if re.search(se[0], entry.msgstr):
entry.msgstr = string.replace(entry.msgstr, se[0], se[1])
po2.append(entry)
cnt += 1
print entry.msgid, "<->", entry.msgstr, cnt
elif re.search(se[0], entry.msgid):
entry.msgstr = se[1]
po2.append(entry)
cnt += 1
print entry.msgid, "<->", entry.msgstr, cnt
po2.save('../../setup/auto_translated2.po')

53
dev/scripts/transform_po3.py Executable file
View File

@ -0,0 +1,53 @@
#!/usr/bin/python
# -*- encoding: utf-8 -*-
import fnmatch
import polib
import re
import os
import string
start_directory = '../..'
language_filename = '*.pot'
search_replace_regex = [
]
search_module = False # ['sale', 'stock']
valid_entries = []
for root, dirs, files in os.walk(start_directory):
for filename in fnmatch.filter(files, language_filename):
print filename
src = os.path.join(root, filename)
try:
po = polib.pofile(src)
except IOError as e:
print "ERROR", e
continue
for e in po:
if not e.obsolete:
valid_entries.append(e)
po2 = polib.POFile()
cnt = 0
for se in search_replace_regex:
for entry in valid_entries:
module = re.search(u'(module:)(.*)', entry.comment)
if module:
module = module.group(2).strip()
if search_module is False or module in search_module:
if re.search(se[0], entry.msgstr):
entry.msgstr = string.replace(entry.msgstr, se[0], se[1])
po2.append(entry)
cnt += 1
print entry.msgid, "<->", entry.msgstr, cnt
elif re.search(se[0], entry.msgid):
entry.msgstr = se[1]
po2.append(entry)
cnt += 1
print entry.msgid, "<->", entry.msgstr, cnt
po2.save('../../setup/auto_translated3.po')

View File

@ -7,9 +7,25 @@ from environments import ENVIRONMENTS, Environment
from functions import CamadeusFunctions
def main():
def _usage():
print 'cam.py <environment> [create|setup|rollout|update] [<module_name>]'
print 'cam.py list-envs'
print '\nVerwendung: cam.py <environment> <command> [<module_name>/<setup_function>]\n'
print 'Commands:\n'
print ' create Neue Datenbank erstellen'
print ' create_from_dump Neue Datenbank von Dump erstellen'
print ' setup Modulinstallation. Konfigurationen.'
print ' setup_part setup_function Aufruf eines einzelnen Setup Schrittes.'
print ' "setup_part info" listet die verfügbaren Setup Schritte auf.'
print ' rollout Setzt Dokumentnummern, importiert Benutzer, setzt cam_dmi auf noupdate, ...'
print ' update module_name Modul updaten'
print ' install modul_name Modul installieren'
print ' uninstall modul_name Modul deinstallieren'
print ' cancel_upgrade modul_name Abbruch Modulinstallation'
print ' update_modules Update aller Module in der config Modulliste.'
print ' update_all Update aller verfügbaren Module'
print ' list-envs Environments auflisten'
print ' anonym Daten anonymisieren (Namen, Adresse, E-Mail, ...)'
print ' invalidate_email E-Mail Adressen invalidieren (@ > #)\n'
sys.exit(3)
argv = sys.argv[1:]
@ -38,7 +54,7 @@ def main():
return
else:
if len(argv) != 2:
if len(argv) == 3 and argv[1] in ['update', 'install']:
if len(argv) == 3 and argv[1] in ['update', 'install', 'uninstall', 'cancel_update' 'setup_part']:
# 'update' requires additional param 'module_name'
pass
else:
@ -70,38 +86,47 @@ def main():
'set_admin_rights',
]
if cmd == 'setup':
if cmd == 'create_from_dump':
methods = [
'login',
'uninstall_chat',
'install_modules',
'set_warehouse',
'base_config',
'sale_config',
'hr_config',
'stock_config',
'mrp_config',
'stock_set_cost_method',
'set_incoterms',
'purchase_config',
'set_date_format',
'set_company',
'set_taxes',
'set_uom',
'set_steuerzuordnung',
'setup_journals',
'set_currencies',
'set_decimal_price',
'set_default_values',
'set_translations',
'set_default_removal_strategy',
'default_set_order_policy',
'delete_mail_server',
'update_values',
'set_sys_params',
'setup_reports',
'create_db_from_dump',
]
setup_methods = [
'login',
'uninstall_chat',
'install_modules',
'set_warehouse',
'base_config',
'sale_config',
#'finance_config',
'hr_config',
'stock_config',
'mrp_config',
'stock_set_cost_method',
'set_incoterms',
'purchase_config',
'set_date_format',
'set_company',
'set_taxes',
'set_uom',
'set_steuerzuordnung',
'setup_journals',
'set_currencies',
'set_decimal_price',
'set_default_values',
'set_translations',
'set_default_removal_strategy',
'default_set_order_policy',
'delete_mail_server',
'update_values',
'update_special_values',
'set_sys_params',
'setup_reports',
]
if cmd == 'setup':
methods = setup_methods
if cmd == 'rollout':
methods = [
'login',
@ -125,6 +150,20 @@ def main():
'install_module',
]
if cmd == 'uninstall':
instance.config.module_name = argv[2]
methods = [
'login',
'uninstall_module',
]
if cmd == 'cancel_upgrade':
instance.config.module_name = argv[2]
methods = [
'login',
'cancel_upgrade_module',
]
if cmd == 'update_modules':
methods = [
'login',
@ -137,6 +176,28 @@ def main():
'update_all',
]
if cmd == 'setup_part':
if ((argv[2] == 'info') or (not (argv[2] in setup_methods))):
print '\nVerfügbare setup Methoden: ' + str(setup_methods) + '\n'
return
methods = [
'login',
argv[2],
]
if cmd == 'anonym':
methods = [
'login',
'make_anonymous',
]
if cmd == 'invalidate_email':
methods = [
'login',
'invalidate_email',
]
if not methods:
print 'Unbekanntes Kommando'
_usage()

View File

@ -1,6 +1,9 @@
# -*- coding: utf-8 -*-
class Config():
def __init__(self):
self.dump_file = "upgraded_file_name.dump"
self.module_name = None
self.lang = 'de_DE' # de_DE, en_US
self.chart_of_accounts = 'l10n_at'
@ -98,6 +101,12 @@ class Config():
'group_costing_method': True, # Benutzen Sie 'Einkaufs-' oder 'Durchschnittspreis' zur Bestandsbewertung
}
self.finance_config = {
#'group_multi_currency':True
}
#Einstellungen Personal
self.hr_config = {
'module_hr_expense': True, # Spesen der Mitarbeiter verwalten
@ -224,8 +233,11 @@ class Config():
self.users_file = 'res.users.csv'
self.translation_files = [
'ir.translation.csv'
self.translation_files = [ # Reihenfolge!
#'auto_translated2.po',
'ir.translation.csv',
#'auto_translated.po',
#'auto_translated3.po',
]
self.default_values = [ # ir.values

View File

@ -33,6 +33,22 @@ class CamadeusFunctions():
print 'Error occured: %s' % msg
return False
def create_db_from_dump(self):
""" Neue Datenbank von Dump erstellen"""
fh = open(self.config.dump_file, 'rb')
files = {
'db_file': ('db_file', fh.read(), 'application/octet-stream'),
}
url = '%s:%s/web/database/restore?restore_pwd=%s&new_db=%s&mode=restore'
url %= (self.env.host, self.env.port, self.env.admin_pw, self.env.dbname)
res = requests.post(url, files=files, verify=False)
# print 'Status:', res.status_code
# print 'Response:', res.content
return True
def login(self):
"""Login"""
@ -191,16 +207,16 @@ class CamadeusFunctions():
"""Modul 'Sale' installieren"""
modules_to_install = self._execute('ir.module.module', 'search', [('name', '=', 'sale'), ('state', '!=', 'installed')])
res = self._execute('ir.module.module', 'button_install', modules_to_install)
res = self._execute('base.module.upgrade', 'upgrade_module', modules_to_install)
self._execute('ir.module.module', 'button_install', modules_to_install)
self._execute('base.module.upgrade', 'upgrade_module', modules_to_install)
return True
def install_modules(self):
"""Module installieren"""
modules_to_install = self._execute('ir.module.module', 'search', [('name', 'in', self.config.modules), ('state', '!=', 'installed')])
res = self._execute('ir.module.module', 'button_install', modules_to_install)
res = self._execute('base.module.upgrade', 'upgrade_module', modules_to_install)
self._execute('ir.module.module', 'button_install', modules_to_install)
self._execute('base.module.upgrade', 'upgrade_module', modules_to_install)
return True
def _set_picking_sequence_prefix(self, code, value):
@ -310,7 +326,7 @@ class CamadeusFunctions():
vals = self._execute('account.installer', 'default_get', [])
vals['charts'] = self.config.chart_of_accounts
wizard_id = self._execute('account.installer', 'create', vals)
res = self._execute('account.installer', 'action_next', [wizard_id])
self._execute('account.installer', 'action_next', [wizard_id])
return True
def setup_accounting2(self):
@ -333,7 +349,7 @@ class CamadeusFunctions():
vals['company_id'] = 1 # Default
vals['currency_id'] = currency_id
wizard_id = self._execute('wizard.multi.charts.accounts', 'create', vals)
res = self._execute('wizard.multi.charts.accounts', 'action_next', [wizard_id])
self._execute('wizard.multi.charts.accounts', 'action_next', [wizard_id])
return True
def set_currencies(self):
@ -360,8 +376,8 @@ class CamadeusFunctions():
modules = ['im_chat', 'im_odoo_support', 'bus']
modules_to_install = self._execute('ir.module.module', 'search', [('name', 'in', modules)])
res = self._execute('ir.module.module', 'button_uninstall', modules_to_install)
res = self._execute('base.module.upgrade', 'upgrade_module', modules_to_install)
self._execute('ir.module.module', 'button_uninstall', modules_to_install)
self._execute('base.module.upgrade', 'upgrade_module', modules_to_install)
return True
def set_uom(self):
@ -421,8 +437,8 @@ class CamadeusFunctions():
if not len(mod_ids) == 1:
raise Exception('Module "%s" not found or not installed.' % module_name)
res = self._execute('ir.module.module', 'button_upgrade', mod_ids)
res = self._execute('base.module.upgrade', 'upgrade_module', [])
self._execute('ir.module.module', 'button_upgrade', mod_ids)
self._execute('base.module.upgrade', 'upgrade_module', [])
return True
def install_module(self):
@ -433,8 +449,8 @@ class CamadeusFunctions():
if not len(mod_ids) == 1:
raise Exception('Module "%s" not found or is not in state "uninstalled".' % module_name)
res = self._execute('ir.module.module', 'button_install', mod_ids)
res = self._execute('base.module.upgrade', 'upgrade_module', [])
self._execute('ir.module.module', 'button_install', mod_ids)
self._execute('base.module.upgrade', 'upgrade_module', [])
return True
def update_modules(self):
@ -444,6 +460,27 @@ class CamadeusFunctions():
vals = self._execute('base.module.update', 'update_module', [wizard_id])
return True
def uninstall_module(self):
"""Deinstalliere Modul"""
module_name = self.config.module_name
mod_ids = self._execute('ir.module.module', 'search', [('name','=',module_name),('state','=','installed')])
if not len(mod_ids) == 1:
raise Exception("Module '%s' not found or is not installed." % module_name)
self._execute('ir.module.module', 'button_uninstall', mod_ids)
self._execute('base.module.upgrade', 'upgrade_module', [])
return True
def cancel_upgrade_module(self):
"""Modul Upgrade abbrechen"""
module_name = self.config.module_name
mod_ids = self._execute('ir.module.module', 'search', [('name','=',module_name),('state','=','to upgrade')])
if not len(mod_ids) == 1:
raise Exception("Module '%s' not found or is not installed." % module_name)
self._execute('ir.module.module', 'button_upgrade_cancel', mod_ids)
return True
def setup_journals(self):
"""Update journals"""
@ -465,9 +502,9 @@ class CamadeusFunctions():
mod_ids = self._execute('ir.module.module', 'search', [('name', '=', module_name), ('state', '=', 'installed')])
if not len(mod_ids) == 1:
raise Exception('Module "%s" not found or ist not installed.' % module_name)
res = self._execute('ir.module.module', 'button_upgrade', mod_ids)
self._execute('ir.module.module', 'button_upgrade', mod_ids)
res = self._execute('base.module.upgrade', 'upgrade_module', [])
self._execute('base.module.upgrade', 'upgrade_module', [])
return True
def set_warehouse(self):
@ -635,6 +672,32 @@ class CamadeusFunctions():
self._execute('ir.values', 'create', vals)
return True
def update_special_values(self):
"""Spezialwerte setzen"""
#Z.B.:
## Lösche alle Anreden außer Herr und Frau
#data_deletes = [
# 'base.res_partner_title_doctor',
# 'base.res_partner_title_miss',
# 'base.res_partner_title_prof',
# 'base.res_partner_title_sir',
# 'base.res_partner_title_pvt_ltd',
# 'base.res_partner_title_ltd',
# 'sale.email_template_edi_sale',
# 'account.email_template_edi_invoice',
#]
#for xml_id in data_deletes:
# try:
# dummy,model,res_id = self._execute('ir.model.data', 'xmlid_lookup', xml_id)
# self._execute(model, 'unlink', [res_id])
# except:
# pass
return True
def update_values(self):
"""Existierende Daten aktualisieren"""
@ -669,3 +732,112 @@ class CamadeusFunctions():
else:
return False
return True
def invalidate_email(self):
"""E-Mail adressen @ durch # erstezen um unbeabsichtigen E-Mail Versand zu vermeiden"""
#E-Mail adressen von res_partner: @ -> #
p_ids = self._execute('res.partner', 'search', [('email','ilike','%@%')])
partner = self._execute('res.partner', 'read', p_ids, ['email'])
for p in partner:
id = p['id']
email = p['email']
new_email = email.replace('@','#')
self._execute('res.partner', 'write', [id], {'email': new_email})
def finance_config(self):
"""Basiskonfiguration für Finanzen Laden"""
if hasattr(self.config, 'finance_config'):
vals = self._execute('account.config.settings', 'default_get', [])
vals.update(self.config.finance_config)
wizard_id = self._execute('account.config.settings', 'create', vals)
return self._execute('account.config.settings', 'execute', [wizard_id])
return True
def make_anonymous(self):
"""Anonymisieren der Daten"""
res = True
res &= self.make_anonymous_one('make_anonymous_partner')
res &= self.make_anonymous_one('make_anonymous_project')
res &= self.make_anonymous_one('make_anonymous_employee')
res &= self.make_anonymous_one('make_anonymous_leads')
res &= self.make_anonymous_one('make_anonymous_mailserver')
res &= self.make_anonymous_one('make_anonymous_cron')
return res
def make_anonymous_one(self, func_name):
"""Anonymisieren der Daten ein Schritt"""
try:
getattr(self, func_name)()
print '.............. ' + func_name + ": OK"
except:
print '.............. ' + func_name + ": ERROR!!!"
return False
return True
def make_anonymous_partner(self):
ids = self._execute('res.partner', 'search', [])
for id in ids:
vals = {
'name': "Partner %s" % id,
'street': '----',
'email': 'test@example.com',
}
self._execute('res.partner', 'write', [id], vals)
def make_anonymous_project(self):
if(self._execute('ir.module.module', 'search', [('name', '=', 'project'), ('state', '=', 'installed')])):
ids = self._execute('project.project', 'search', [])
for id in ids:
vals = {
'name': "Projekt %s" % id,
}
self._execute('project.project', 'write', [id], vals)
#Tasks
ids = self._execute('project.task', 'search', [])
for id in ids:
vals = {
'name': "Aufgabe %s" % id,
}
self._execute('project.task', 'write', [id], vals)
def make_anonymous_employee(self):
if (self._execute('ir.module.module', 'search', [('name', '=', 'hr'), ('state', '=', 'installed')])):
ids = self._execute('hr.employee', 'search', [])
for id in ids:
vals = {
'name': "Mitarbeiter %s" % id,
'work_email': 'test@example.com',
}
self._execute('hr.employee','write', [id], vals)
def make_anonymous_leads(self):
if (self._execute('ir.module.module', 'search', [('name', '=', 'crm'), ('state', '=', 'installed')])):
ids = self._execute('crm.lead', 'search', [])
for id in ids:
vals = {
'name': "Lead %s" % id,
'email_from': 'test@example.com',
'description': '',
}
ids = self._execute('crm.lead','write', [id], vals)
def make_anonymous_mailserver(self):
server_ids = self._execute('ir.mail_server', 'search', [])
self._execute('ir.mail_server', 'write', server_ids, {'active': False})
server_ids = self._execute('fetchmail.server', 'search', [])
self._execute('fetchmail.server', 'unlink', server_ids)
def make_anonymous_cron(self):
cron_ids = self._execute('ir.cron', 'search', [])
if cron_ids:
self._execute('ir.cron', 'write', cron_ids, {'active': False})