vorweg, ich bin kein großer Apple-Script Künstler
Somit bevorzuge ich es Auswertungen eines PDF-Dokuments mit einem kleinen Perl-Script auszuführen. Dazu habe ich ein Apple-Script zusammen gebastelt, welches mir den Plain-Text eines PDF’s in eine temp. Datei schreiben soll. Anschließend soll das Perlscript seinen Job durchführen und die Ergebnisse an das Apple-Script zurückgeben.
Hier mein Apple-Script
on performSmartRule(theRecords)
tell application id "DNtp"
repeat with theRecord in theRecords
set this_type to ((type of theRecord) as string)
display alert this_type
if (this_type contains "PDF") then
display alert "PDF"
set thetext to plain text of theRecord
set oldDelims to AppleScript's text item delimiters -- save their current state
-- Text in temp. Datei schreiben
set target_file to (path to temporary items folder as text) & "dummy.dat"
set the target_file to the target_file as text
set the open_target_file to open for access file target_file with write permission
set eof of the open_target_file to 0
write thetext to the open_target_file starting at eof
close access the open_target_file
-- temp. Datei mit perl-Script durchsuchen
set return_value to do shell script "/Users/boni/perl-Scripts/get_first_date_in_txt.pl \"" & target_file & "\" "
-- wenn String nicht gefunden wird Fehler ausgeben
if (return_value contains "error") then
display alert "Das Rechnungsdatum wurde im Document nicht gefunden"
else
display dialog (return_value as string)
-- Datum setzen
set fuTmp to the current date
set AppleScript's text item delimiters to {"."}
set the year of fuTmp to (text item 3 of return_value)
set the month of fuTmp to text item 2 of return_value
set the day of fuTmp to text item 1 of return_value
set theDate to fuTmp
set date of theRecord to theDate
end if
set AppleScript's text item delimiters to oldDelims
end if
end repeat
end tell
end performSmartRule
Aufgerufen werden soll das Script über eine intelligente Regel. Beim Ausführen der Regel erhalte ich nach set the open_target_file to open for access file target_file with write permission
on performSmartRule (Falsche Zugriffsrechte auf die Datei.)
Kann mir jemand einen Tip geben, wie ich eine temporäre Datei anlegen kann?
Fehlt da vielleicht ein Slash zwischen Verzeichnis und Dateiname? Den Test auf PDF würde ich ohnehin nicht im Script, sondern in der Regel ansiedeln.
Ich würde das Script jedenfalls (in Javascript schreiben und) im Script editor laufen lassen, wegen der etwas leichteren Fehlersuche dort.
Btw: in Javascript kann man zumindest mit regulären Ausdrücken gut arbeiten, sodass du uU kein separates Perl-Script brauchst.
Beispiel (nicht getestet):
function performsmartrule(recs) {
let app = Application("DEVONthink 3");
app.includeStandardAdditions = true;
recs.forEach(r => {
let txt = r.plainText();
let res = findFirstDate(txt);
if (!res) {
app.displayAlert(`Kein Rechnungsdatum im Dokument "${r.name()}" gefunden`)
} else {
// res[0] = "dd.mm.yy<yy>"
let dateStr = res[0].split(".").reverse().join("-");
// dateStr = "yy<yy>-mm-dd"
// BEWARE: JavaScript Date constructor expects a 4 digit year!
r.date = new Date(dateStr);
}
})
}
function findFirstDate(txt) {
let dateRe = /\d+\.\d+.\d{2,4}/;
return txt.match(dateRe);
// return value is null for no match, otherwise an array with the match as its only element
}
(() => {
let app = Application("DEVONthink 3");
performsmartrule(app.selectedRecords());
})()
Der reguläre Ausdruck in findFirstDate ist natürlich nur ein triviales Beispiel, da muss man nachbessern.
Hi,
danke für die Infos.
Ich stehe etwas auf dem Schlauch. Wie kann ich Dein Script testen, ich habs in den Scripteditor geladen, aber wie stelle ich nun den Bezug zu einem Dokument in DTP3 her?
Oder kann das Script nur als SmartRule ausgeführt werden?
so habe ich es auch gemacht, aber leider ohne Erfolg.
Nun aber:
function performsmartrule(recs) {
//let app = Application("DEVONthink 3");
recs.forEach(r => {
let txt = r.plainText();
let res = findFirstDate(txt);
if (!res) {
app.displayAlert(`Kein Rechnungsdatum im Dokument "${r.name()}" gefunden`)
} else {
// res[0] = "dd.mm.yy<yy>"
let dateStr = res[0].split(".").reverse().join("-");
// dateStr = "yy<yy>-mm-dd"
// BEWARE: JavaScript Date constructor expects a 4 digit year!
r.date = new Date(dateStr);
}
})
}
function findFirstDate(txt) {
let dateRe = /\d+\.\d+.\d{2,4}/;
return txt.match(dateRe);
// return value is null for no match, otherwise an array with the match as its only element
}
var app = Application("DEVONthink 3");
app.includeStandardAdditions = true
performsmartrule(app.selection());
Nachdem ich das Script um die 3 letzten Zeilen ergänzt habe, läuft es nun aus dem Scripteditor heraus direkt auf Anhieb.
Wenn ich die Funktion findFirstDate richtig verstehe liefert mit txt.match(dateRe); den ersten Treffer der RegEx aus dem text txt
Prima, genau das wollte ich. Leider funktioniert es nicht, wenn ich es als SmartRule einbinde.
Im Log erscheint
20:57:57: ~/Library/Application Scripts/com.devon-technologies.think3/Smart Rules/test-db2.scpt
on performSmartRule (Error: Error: Kein Fehler.)
Sorry, in meinem Script fehlte ganz am Ende ein Klammerpaar. Das habe ich jetzt ergänzt. Damit werden die letzten paar Zeilen zu einer self-executing function, sodass das Script ohne Änderung im Editor bei markierten DT-Datensätzen und als externes Script in Smart Rules funktionieren sollte. “sollte”, weil DT JavaScript nicht ganz so gut unterstützt wie AppleScript. Es kommt da immer mal wieder zu Merkwürdigkeiten.
Genau. Allerdings eben nur für Daten der Form “1.1.2021”, wobei Monat und Tag mindestens einstellig sein müssen und das Jahr zwei- oder vierstellig sein darf. Das könnte man durchaus noch verbessern, aber da Du Perl kannst … Die Allianz schreibt z.B. gerne “2. November 2020”, das erwischt man damit nicht. Außerdem muss man das Jahr unbedingt noch vierstellig machen, damit in der Hauptfunktion der Aufruf von new Date(...) funktioniert.
Das ist bekannt. Passiert immer, wenn man JavaScript extern in Smart Rules verwendet. Ich vermute, dass das DTs KI-Maschine in den Philosophie-Modus schickt und sie sich mit dem Sein und dem Nichts beschäftigt…
Nun ja, aus dem Script-Editor läuft es jetzt genau wie es soll, binde ich es in eine Smart-Rule ein, verabschiedet sich DT mit dem wunderschönen Farbball. Ich kann DT dann nur noch abschießen.
Ich vermute DT landet mit der Smart-Rule in einer kleinen Endlos-Schleife.
Wenn Du noch eine Idee hättest, wäre das prima, ansonsten werde ich mich mal etwas mehr dem Apple-Script zuwenden, wobei ich mich damit bisher nicht wirklich anfreunden konnte.
Tja, DT und Javascript pflegen nicht unbedingt eine Liebesbeziehung.
Eine Umgehung könnte sein, eine Smartgroup mit den gewünschten Bedingungen einzurichten, dann darin aller Datensätze markieren und das Script ausführen. Es lässt sich, denke ich, in der jetzigen Form auch als normales Script installieren und nutzen.
AppleScript… Dazu kann ich nicht wirklich was sagen. Ich vermute, das in der ursprünglich hier geposteten Version einfach nur der Slash zwischen Verzeichnis und Datei (bei dem tempfile) fehlte.