# -*- coding: ISO-8859-1 -*-
""" capellaScript -- (c) Paul Villiger
>>> Plugins.dat Updater

    Mit diesem Script können die Einträge in plugins.dat überprüft und ergänzt werden.
    Folgende Funktionen stehen zur Verfügung:|
    |
    - Fehlerhafte Scripteinträge ausgeben|
    - Neue Scripte anhängen|
    - Scriptpfade erneuern|
    - plugins.dat aus Downloadverzeichnis kopieren|
    - die aktuelle Datei wird mit dem Zeitstempel gesichert
    |
    Achtung: Plugins.dat muss den XML Konventionen entsprechen, Vorsicht beim Editieren, Texteinträge werden gelöscht.|

<<<
History:  17.11.07  - Erste Version
          19.11.07  - Korrektur

Rückmeldungen bitte an villpaul(at)bluewin.ch                     

"""
german =("de", {
        'newScripts'            :   ' neue Scripts hinzugefügt',
        'copyFromDownload'      :   '  plugins.dat aus Download übernehmen?',
        'renewAll'              :   '  Alle Pfade erneuern',
        'appendNewScripts'      :   '  Neue Scripts anhängen',
        'searchPath'            :   'Suchverzeichnis für Scripts:',
        'newScripts'            :   ' neue Scripts hinzugefügt'
        })

try:
    exec('from %s import translations' % ( translationModule() ))
    translations.append(german)
    setLanguages(translations)
except:
    def tr(s):
        return german[1].get(s, "???")
#-------------------------------------------------------------------

from xml.dom.minidom import parseString, NodeList, Node, Element
import string, os, _winreg, shutil, time
import new

def latin1(u):
    return u.decode('Latin-1')
def latin1e(u):
    return u.encode('Latin-1')

def gotoChild(self, name, new=False):
    newEl = None
    if new:
        pass
    else:
        for child in self.childNodes:
            if child.nodeType == child.ELEMENT_NODE and child.tagName == name:
                newEl = child
                break
    if newEl == None:
        newEl = doc.createElement(name)
        self.appendChild(newEl)
    return newEl
Node.gotoChild = new.instancemethod(gotoChild,None,Node)

def removeTextNodes(node):
    cc = node.firstChild
    while cc:
        removeTextNodes(cc)
        c1 = cc.nextSibling
        if cc.nodeType == cc.TEXT_NODE:
            cc.parentNode.removeChild(cc)
        cc = c1

ok = True

capella6 = False
if (6, 0, 0) <= capVersion():
    capella6 = True    

# Verzeichnis Eigene Dateien bestimmen
try:
    r = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders')
    personal, x = _winreg.QueryValueEx(r, 'Personal')
    _winreg.CloseKey(r)
    homePath = os.path.join(personal,'capella')
except:
    ok = False
    homePath = ''

# capella 2004 Verzeichnis bestimmen
try:    
    r = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\capella-software\capella\5.0')
    exePath5, x = _winreg.QueryValueEx(r, 'ExePath')
    _winreg.CloseKey(r)
except:
    exePath5 = ''

# capella 2004 Verzeichnis bestimmen
try:    
    r = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\capella-software\capella\6-prof')
    exePath6, x = _winreg.QueryValueEx(r, 'ExePath')
    _winreg.CloseKey(r)
except:
    exePath6 = ''

# Pfade bestimmen
if capella6:            # capella 2008
    if exePath6:        # ist capella 2008 installiert?
        capPath, exe = os.path.split(exePath6)
        scriptPath = os.path.join(homePath, 'scripts')
        configPath = os.path.join(homePath, 'config','data')
        capella6 = True
    else:
        ok = False      # capella 2008 ist nicht installiert
else:                   # capella 2004
    if exePath5:        # ist capella 2004 installiert?
        capPath, exe = os.path.split(exePath5)
        scriptPath = os.path.join(capPath, 'scripts')
        configPath = os.path.join(capPath, 'data')
    else:
        ok = False      # capella 2004 ist nicht installiert

pluginsDatPath = os.path.join(configPath, 'plugins.dat')



# Define selectMethod
sm = 0
if os.path.isdir(os.path.join(scriptPath, 'ScriptDownload')):
    sm = 1

# #################### D I A L O G ####################
selectMethod = Radio(['Plugins_Author', 'ScriptDownload'], value = sm)
copyPD = CheckBox(tr('copyFromDownload'), value = 0)
renewPath = CheckBox(tr('renewAll'), value = 0)
addNewScripts = CheckBox(tr('appendNewScripts'), value = 0) 
if capella6:
    labelCapVer = Label('CAPELLA 2008')
else:
    labelCapVer = Label('CAPELLA 2004')
    
dlg = Dialog('plugins.dat Updater',
             VBox([labelCapVer,
                   Label(''),
                   Label(tr('searchPath')),
                   selectMethod,
                   Label(''),
                   copyPD,
                   renewPath,
                   addNewScripts,
                   Label('')
                   ], padding = 5 ))


if ok and dlg.run():
    selectMethod = selectMethod.value()
    if selectMethod == 0:
        searchOrder = ['Plugins_', 'ScriptDownload']
    else:
        searchOrder = ['ScriptDownload', 'Plugins_']

    renewPath = renewPath.value()
    addNewScripts = addNewScripts.value()
else:
    ok = False

        
# Scriptverzeichnis nach Scripts durchsuchen
if ok:
    spl = len(scriptPath)
    scriptDict ={}
    scriptList = []
    pluginsList = []
    for root, dirs, names in os.walk(scriptPath):
        for name in names:
            if  root[spl+1:] in ['expert-scripts', 'demos']:
                continue
            tail, ext = os.path.splitext(name)
            if ext == '.py' and tail[-3:] <> '_tr':
                scriptList.append((name,os.path.join(root[spl+1:], name)))
            elif ext == '.dat':
                pluginsList.append((name,os.path.join(root[spl+1:], name)))

    # Get standard scripts
    for name, root in scriptList:
        if root == name:
            if name.lower() not in scriptDict:
                scriptDict[name.lower()] = root

    for dir in searchOrder:
        p = dir
        l = len(p)
        for name, root in scriptList:
            if root[:l] == p:
                if name.lower() not in scriptDict:
                    scriptDict[name.lower()] = root

    # Get any scripts
    for name, root in scriptList:
        if name.lower() not in scriptDict:
            scriptDict[name.lower()] = root

    # plugins.dat aus Download kopieren
    if copyPD.value():
        if capella6:
            dl = 'plugins_2008.dat'
        else:
            dl = 'plugins_2004.dat'
        for name, root in pluginsList:
            if name == dl:
                # plugins.dat sichern
                tail, ext = os.path.splitext(pluginsDatPath)
                shutil.copyfile(pluginsDatPath, tail + time.strftime('_%Y%m%d_%H%M%S') + ext)
                # neue plugins.dat kopieren
                shutil.copyfile(os.path.join(scriptPath, root), pluginsDatPath)
                break

    # plugins.dat einlesen
    f = file(pluginsDatPath,'r')
    content = f.read()
    f.close()
    if '<?xml' not in  content[:100]:
        content = '<?xml version="1.0" encoding="ISO-8859-1"?> ' + content
    
    doc = parseString(content)

if ok:
    # Dateipfade in plugins.dat korrigieren oder erneuern
    errorMessage = ''
    for item in doc.getElementsByTagName('item'):
        fileName = item.getAttribute('file')
        if renewPath or not os.path.isfile(os.path.join(scriptPath, fileName)):
            head, tail = os.path.split(fileName)
            if tail.lower() in scriptDict:
                item.setAttribute('file', scriptDict[tail.lower()])
                if item.hasAttribute('error'):
                    item.removeAttribute('error')
            else:
                item.setAttribute('error', 'script not found')
                errorMessage += 'Not existing: ' + fileName + '\n'
        else:
            if item.hasAttribute('error'):
                item.removeAttribute('error')
newCount = 0
if ok and addNewScripts:
    # Neue Scripts anhängen
    usedScriptsList = []
    for item in doc.getElementsByTagName('item'):
        fileName = item.getAttribute('file')
        head, tail = os.path.split(fileName)
        usedScriptsList.append(tail.lower())

    group2 = None
    group1 = doc.gotoChild('group')
    group2 = group1.gotoChild('group',True)

    newScript = False
    scriptList.sort()
    for name, root in scriptList:
        if name.lower() not in usedScriptsList:
            if not newScript:
                group2.setAttribute('name', 'New Scripts')
                newScript = True
            item = group2.gotoChild('item', True)
            item.setAttribute('file', root)
            item.setAttribute('name', name)
            item.setAttribute('symbol', ' ')
            usedScriptsList.append(name.lower())
            newCount += 1
            

if ok:
    # plugins.dat sichern
    tail, ext = os.path.splitext(pluginsDatPath)
    shutil.copyfile(pluginsDatPath, tail + time.strftime('_%Y%m%d_%H%M%S') + ext)
    
    # plugins.dat Datei abspeichern
    removeTextNodes(doc)
    xmlString = doc.toprettyxml('    ', '\n', 'ISO-8859-1')
    f = file(pluginsDatPath,'w')
    f.write(xmlString)

    f.flush()
    f.close()

    # Fehlermeldungen ausgeben
    if errorMessage <> '':
        messageBox('>>> Missing files <<<', errorMessage)
    elif newCount:
        messageBox('>>> New Scripts <<<', str(newCount) + tr('newScriptsAppended'))
    else:
        messageBox('>>> plugins.dat <<<', '>>> updated <<<')

#
#   >>>>>>>>>>>>>>>> ENDE <<<<<<<<<<<<<<<<<<
#
if True: pass

