diff --git a/dev/scripts/transform_po.py b/dev/scripts/transform_po.py new file mode 100755 index 00000000..697c301a --- /dev/null +++ b/dev/scripts/transform_po.py @@ -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') \ No newline at end of file diff --git a/dev/scripts/transform_po2.py b/dev/scripts/transform_po2.py new file mode 100755 index 00000000..cc461f70 --- /dev/null +++ b/dev/scripts/transform_po2.py @@ -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') \ No newline at end of file diff --git a/dev/scripts/transform_po3.py b/dev/scripts/transform_po3.py new file mode 100755 index 00000000..1c5684cc --- /dev/null +++ b/dev/scripts/transform_po3.py @@ -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') diff --git a/setup/lib/cli.py b/setup/lib/cli.py index 498d484b..f549cbb3 100755 --- a/setup/lib/cli.py +++ b/setup/lib/cli.py @@ -7,9 +7,25 @@ from environments import ENVIRONMENTS, Environment from functions import CamadeusFunctions def main(): + def _usage(): - print 'cam.py [create|setup|rollout|update] []' - print 'cam.py list-envs' + print '\nVerwendung: cam.py [/]\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() diff --git a/setup/lib/config_at.py b/setup/lib/config_at.py index 5a46ed06..00a19d39 100644 --- a/setup/lib/config_at.py +++ b/setup/lib/config_at.py @@ -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 diff --git a/setup/lib/functions.py b/setup/lib/functions.py index c3bf78bc..c97bd961 100755 --- a/setup/lib/functions.py +++ b/setup/lib/functions.py @@ -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}) + + + \ No newline at end of file