Public Access
348 lines
11 KiB
AppleScript
348 lines
11 KiB
AppleScript
(*
|
|
START.scpt - Version 1.4
|
|
Rolle dieses Scripts
|
|
--------------------
|
|
Dieses Script ist der sichtbare Einstiegspunkt für Anwender:innen.
|
|
Es selbst verschickt keine Belege und führt auch keine Einrichtung durch,
|
|
sondern übernimmt nur zwei Aufgaben:
|
|
1. Prüfen, ob relativ zur aktuellen DEVONthink-Auswahl eine Konfigurationsdatei
|
|
für den Belegversand existiert.
|
|
2. Falls in dieser Konfiguration SHOW_README=true gesetzt ist,
|
|
einen kurzen Willkommen-/Hinweisdialog anzeigen.
|
|
3. Danach das Setup-Script _belegversand_setup.scpt starten.
|
|
Das Setup-Script entscheidet anschließend selbst:
|
|
- ob bereits eine gültige Einrichtung vorliegt und direkt das Hauptscript
|
|
gestartet werden kann,
|
|
- oder ob zunächst die Konfiguration eingerichtet werden muss.
|
|
Wichtig:
|
|
--------
|
|
START.scpt ist bewusst klein gehalten.
|
|
Die eigentliche Fachlogik liegt in:
|
|
- _belegversand_setup.scpt
|
|
- _belegversand.scpt
|
|
*)
|
|
-- Name des Setup-Scripts, das im Unterordner "Helpers/scripts" liegt.
|
|
-- Dieses Script wird von START.scpt immer am Ende aufgerufen.
|
|
property setupScriptName : "_belegversand_setup.scpt"
|
|
-- Name der DEVONthink-Gruppe, in der Konfigurationsdateien liegen.
|
|
property configGroupName : "_config"
|
|
-- Name der eigentlichen Konfigurationsdatei in DEVONthink.
|
|
property configRecordName : "belegversand.conf"
|
|
|
|
property appVersion : "1.4"
|
|
property basePath : "/Library/Application Scripts/com.devon-technologies.think/Menu/Belegversand"
|
|
|
|
property windowTitle : "Belegversand, Vers. " & appVersion
|
|
|
|
(*
|
|
runSiblingScript(scriptFileName)
|
|
--------------------------------
|
|
Lädt und startet ein weiteres AppleScript aus dem Unterordner "Helpers/scripts".
|
|
Parameter:
|
|
- scriptFileName : Dateiname des aufzurufenden Scripts, z. B.
|
|
"_belegversand_setup.scpt"
|
|
Ablauf:
|
|
- absolute Basis-Path setzen
|
|
- daran den Unterordner "Helpers/scripts" und den Dateinamen anhängen
|
|
- prüfen, ob die Scriptdatei existiert
|
|
- Script laden
|
|
- Script ausführen
|
|
Fehlerbehandlung:
|
|
- wenn die Datei nicht gefunden wird -> Hinweisdialog
|
|
- wenn das Laden oder Starten fehlschlägt -> Hinweisdialog mit Fehlermeldung
|
|
Wichtig:
|
|
--------
|
|
Der absolute Pfad ist invariant und unabhängig vom Speicherort dieses Scripts.
|
|
*)
|
|
on runSiblingScript(scriptFileName)
|
|
-- Absolute Basis-Path (Home + fest Installation)
|
|
set expandedPath to (do shell script "echo ~") & "/" & basePath
|
|
set targetPath to expandedPath & "/Helpers/scripts/" & scriptFileName
|
|
|
|
try
|
|
set targetAlias to POSIX file targetPath as alias
|
|
on error
|
|
display dialog "Hinweis: Scriptdatei nicht gefunden:" & return & targetPath buttons {"OK"} default button "OK"
|
|
return
|
|
end try
|
|
|
|
try
|
|
set loadedScript to load script targetAlias
|
|
run loadedScript
|
|
on error errMsg number errNum
|
|
display dialog "Hinweis: Konnte Script nicht starten:" & return & scriptFileName & return & return & errMsg buttons {"OK"} default button "OK"
|
|
end try
|
|
end runSiblingScript
|
|
(*
|
|
recordText(theRecord)
|
|
---------------------
|
|
Liest den Textinhalt eines DEVONthink-Records.
|
|
Verwendung in START.scpt:
|
|
-------------------------
|
|
Hier wird dieser Handler genutzt, um den Inhalt der Datei
|
|
"_config/belegversand.conf" als Text einzulesen.
|
|
Ablauf:
|
|
- zunächst plain text versuchen
|
|
- wenn das fehlschlägt, auf content ausweichen
|
|
- wenn beides fehlschlägt, leeren String zurückgeben
|
|
Hinweis:
|
|
--------
|
|
Die Konvertierung erscheint hier als "rich text", weil AppleScript/Script Editor
|
|
solche Stellen beim Kompilieren teilweise selbstständig umschreiben kann.
|
|
Der funktionale Zweck ist hier aber: Textinhalt lesbar zurückgeben.
|
|
*)
|
|
on recordText(theRecord)
|
|
tell application id "DNtp"
|
|
try
|
|
set t to plain text of theRecord
|
|
if t is missing value then set t to ""
|
|
return t as rich text
|
|
on error
|
|
try
|
|
set t to content of theRecord
|
|
if t is missing value then set t to ""
|
|
return t as rich text
|
|
on error
|
|
return ""
|
|
end try
|
|
end try
|
|
end tell
|
|
end recordText
|
|
(*
|
|
findChildByName(parentRecord, childName)
|
|
----------------------------------------
|
|
Sucht innerhalb einer DEVONthink-Gruppe ein direktes Kind mit bestimmtem Namen.
|
|
Parameter:
|
|
- parentRecord : die Gruppe, in der gesucht werden soll
|
|
- childName : Name des gesuchten direkten Kinds
|
|
Rückgabe:
|
|
- den gefundenen DEVONthink-Record
|
|
- oder missing value, wenn nichts passt
|
|
Verwendung in START.scpt:
|
|
-------------------------
|
|
- _config-Gruppe unter der DB-Wurzel suchen
|
|
- belegversand.conf innerhalb von _config suchen
|
|
*)
|
|
on findChildByName(parentRecord, childName)
|
|
tell application id "DNtp"
|
|
try
|
|
set kids to children of parentRecord
|
|
repeat with i from 1 to count of kids
|
|
set c to item i of kids
|
|
if (name of c as rich text) is childName then return c
|
|
end repeat
|
|
end try
|
|
end tell
|
|
return missing value
|
|
end findChildByName
|
|
(*
|
|
getTopParentGroup(theRecord)
|
|
----------------------------
|
|
Ermittelt die oberste Gruppe einer DEVONthink-Hierarchie ausgehend von einem Record.
|
|
Ablauf:
|
|
- starte mit dem aktuell übergebenen Record
|
|
- frage wiederholt nach dessen Eltern
|
|
- solange es noch einen Parent gibt, gehe eine Ebene nach oben
|
|
- sobald kein Parent mehr vorhanden ist, ist die Wurzel erreicht
|
|
Verwendung in START.scpt:
|
|
-------------------------
|
|
START.scpt kennt die gewünschte Datenbank nicht direkt.
|
|
Darum nimmt es irgendein ausgewähltes Objekt in DEVONthink
|
|
und geht davon über die Parent-Kette bis zur obersten Gruppe hoch.
|
|
Dort wird dann _config gesucht.
|
|
Vorteil:
|
|
--------
|
|
Das Script ist dadurch nicht an einen festen Datenbanknamen gebunden,
|
|
sondern arbeitet relativ zur aktuellen Auswahl.
|
|
*)
|
|
on getTopParentGroup(theRecord)
|
|
tell application id "DNtp"
|
|
set currentRecord to theRecord
|
|
|
|
repeat
|
|
try
|
|
set p to parents of currentRecord
|
|
if p is {} then return currentRecord
|
|
set currentRecord to item 1 of p
|
|
on error
|
|
return currentRecord
|
|
end try
|
|
end repeat
|
|
end tell
|
|
end getTopParentGroup
|
|
(*
|
|
configValue(configText, keyName)
|
|
--------------------------------
|
|
Liest aus einem einfachen key=value-Konfigurationstext den Wert zu einem bestimmten Schlüssel.
|
|
Parameter:
|
|
- configText : kompletter Textinhalt der Konfigurationsdatei
|
|
- keyName : gesuchter Schlüssel, z. B. "SHOW_README"
|
|
Rückgabe:
|
|
- Textwert des gefundenen Schlüssels
|
|
- oder missing value, wenn kein passender Eintrag existiert
|
|
Funktionsweise:
|
|
---------------
|
|
- zeilenweise durch die Konfiguration gehen
|
|
- prüfen, ob eine Zeile mit "KEY=" beginnt
|
|
- den Teil rechts vom "=" zurückgeben
|
|
*)
|
|
on configValue(configText, keyName)
|
|
set keyPrefix to keyName & "="
|
|
repeat with oneLine in paragraphs of configText
|
|
set lineText to oneLine as text
|
|
if lineText starts with keyPrefix then
|
|
if (length of lineText) is equal to (length of keyPrefix) then
|
|
return ""
|
|
else
|
|
set val to text ((length of keyPrefix) + 1) thru -1 of lineText
|
|
return val as text
|
|
end if
|
|
end if
|
|
end repeat
|
|
return missing value
|
|
end configValue
|
|
(*
|
|
findConfigInCurrentDB()
|
|
-----------------------
|
|
Sucht die Konfigurationsdatei belegversand.conf relativ zur aktuellen DEVONthink-Auswahl.
|
|
Ablauf:
|
|
1. aktuelle Auswahl holen
|
|
2. falls nichts ausgewählt ist -> missing value
|
|
3. von der Auswahl zur DB-Wurzel hochgehen
|
|
4. dort die Gruppe _config suchen
|
|
5. darin die Datei belegversand.conf suchen
|
|
Rückgabe:
|
|
- den gefundenen Config-Record
|
|
- oder missing value, wenn keine passende Konfiguration existiert
|
|
Wichtig:
|
|
--------
|
|
Es wird absichtlich nicht global in allen Datenbanken gesucht,
|
|
sondern immer nur relativ zur aktuellen Auswahl.
|
|
So bleibt das Verhalten bei mehreren Datenbanken stabil und nachvollziehbar.
|
|
*)
|
|
on findConfigInCurrentDB()
|
|
tell application id "DNtp"
|
|
set sel to selection
|
|
if sel is {} then return missing value
|
|
set selectedRecord to item 1 of sel
|
|
end tell
|
|
|
|
set dbRootRecord to my getTopParentGroup(selectedRecord)
|
|
set configGroupRecord to my findChildByName(dbRootRecord, configGroupName)
|
|
if configGroupRecord is missing value then return missing value
|
|
|
|
set configRecord to my findChildByName(configGroupRecord, configRecordName)
|
|
return configRecord
|
|
end findConfigInCurrentDB
|
|
|
|
(*
|
|
showWelcomeDialogIfNeeded()
|
|
---------------------------
|
|
Zeigt den Willkommensdialog beim Start an, falls konfiguriert (SHOW_README=true).
|
|
Ablauf:
|
|
1. Config-Datei relativ zur aktuellen Auswahl suchen
|
|
2. Wert SHOW_README auslesen
|
|
3. falls SHOW_README=true -> Dialog mit "Nicht mehr anzeigen"-Option anzeigen
|
|
4. falls User "Diesen Dialog nicht mehr anzeigen" wählt:
|
|
-> SHOW_README auf false in der Config zurückschreiben
|
|
|
|
Wichtig:
|
|
--------
|
|
Der Dialog-Text wird aus Helpers/scripts/_text_about.scpt geladen.
|
|
So wird verhindert, dass buildAboutText() doppelt definiert ist.
|
|
*)
|
|
(*
|
|
showWelcomeDialogIfNeeded()
|
|
---------------------------
|
|
Zeigt den Willkommensdialog beim Start an, falls konfiguriert (SHOW_README=true).
|
|
Ablauf:
|
|
1. Config-Datei relativ zur aktuellen Auswahl suchen
|
|
2. Wert SHOW_README auslesen
|
|
3. falls SHOW_README=true -> Dialog mit "Nicht mehr anzeigen"-Option anzeigen
|
|
4. falls User "Diesen Dialog nicht mehr anzeigen" wählt:
|
|
-> SHOW_README auf false in der Config zurückschreiben
|
|
|
|
Wichtig:
|
|
--------
|
|
Der Dialog-Text wird aus Helpers/scripts/_text_about.scpt geladen.
|
|
So wird verhindert, dass buildAboutText() doppelt definiert ist.
|
|
*)
|
|
on showWelcomeDialogIfNeeded()
|
|
set configRecord to my findConfigInCurrentDB()
|
|
if configRecord is missing value then return
|
|
|
|
set cfgText to my recordText(configRecord)
|
|
set showReadmeVal to my configValue(cfgText, "SHOW_README")
|
|
if showReadmeVal is missing value then return
|
|
|
|
set showReadmeLower to do shell script "printf %s " & quoted form of showReadmeVal & " | tr '[:upper:]' '[:lower:]'"
|
|
if showReadmeLower is not "true" then return
|
|
|
|
set basePath to (do shell script "echo ~") & "/Library/Application Scripts/com.devon-technologies.think/Menu/Belegversand"
|
|
set textScript to basePath & "/Helpers/scripts/_text_about.scpt"
|
|
|
|
try
|
|
set loadedScript to load script (POSIX file textScript as alias)
|
|
run loadedScript
|
|
tell loadedScript
|
|
set msgText to buildAboutText()
|
|
end tell
|
|
on error errMsg
|
|
display dialog "Fehler beim Laden des About-Textes:" & return & errMsg buttons {"OK"}
|
|
return
|
|
end try
|
|
|
|
set choice to button returned of (display dialog msgText buttons {"Diesen Dialog nicht mehr anzeigen", "Weiter"} default button "Weiter")
|
|
|
|
if choice is "Diesen Dialog nicht mehr anzeigen" then
|
|
set newCfgText to ""
|
|
repeat with oneLine in paragraphs of cfgText
|
|
set lineText to oneLine as text
|
|
if lineText starts with "SHOW_README=" then
|
|
set newCfgText to newCfgText & "SHOW_README=false" & return
|
|
else
|
|
set newCfgText to newCfgText & lineText & return
|
|
end if
|
|
end repeat
|
|
|
|
tell application id "DNtp"
|
|
try
|
|
set plain text of configRecord to newCfgText
|
|
on error
|
|
set content of configRecord to newCfgText
|
|
end try
|
|
end tell
|
|
end if
|
|
end showWelcomeDialogIfNeeded
|
|
|
|
|
|
(*
|
|
run
|
|
---
|
|
Haupteinstiegspunkt des START-Scripts.
|
|
Ablauf:
|
|
1. optionalen Startdialog anzeigen
|
|
2. Setup-Script starten
|
|
Wichtig:
|
|
--------
|
|
START.scpt delegiert die eigentliche Entscheidung an das Setup-Script.
|
|
Dort wird geprüft:
|
|
- existiert schon eine gültige Konfiguration?
|
|
-> dann Hauptscript starten
|
|
- oder muss erst eingerichtet werden?
|
|
*)
|
|
on run
|
|
with timeout of 3600 seconds
|
|
my showWelcomeDialogIfNeeded()
|
|
my runSiblingScript(setupScriptName)
|
|
end timeout
|
|
end run
|
|
|
|
with timeout of 3600 seconds
|
|
|
|
my showWelcomeDialogIfNeeded()
|
|
my runSiblingScript(setupScriptName)
|
|
|
|
end timeout
|
|
|
|
end run |