This seems to be a feature of JavaScript actually:
This would explain why it’s executed only once right after compiling and executing the script for the first time.
This seems to be a feature of JavaScript actually:
This would explain why it’s executed only once right after compiling and executing the script for the first time.
Of course. The whole OO thing is borken. The date functions are clumsy. Scoping is irritating. Some APIs, notably the DOM, were lacking simple functionality for a long time.
But then JavaScript is to Applescript what Pascal was to Basic.
In the end, you can solve any problem in any language. It’s just a matter of time
You’re right of course. So my beloved toy has a nasty side effect I hadn’t thought of and I’ll have to look for another way to achieve the same goal: have but one code run identically in Script Editor and in DT. And preferably only once in both, too.
The original problem remains though: the same code works ok in Script Editor and doesn’t in DT.
That’s why I prefer AppleScript in most cases. It’s easy to find useful documentation and good examples on the web but for JXA… well, good luck!
I could of course point you to a brilliant site on JXA … but yes, you’re right. Although I find AS badly documented (the language itself and by Apple), there’s a lot of stuff to be found on the Web. Not so for JXA, unfortunately. And it requires a lot of experimentation in some cases.
Anyway, I came up with this now to permit using the same JS script in DT and in Script Edtior:
function performsmartrule(records) {
const app = Application("DEVONthink 3");
records.forEach (r => {
/* CODE goes here */
})
}
(() => {
if (currentAppID() === "DNtp") return;
const app = Application("DEVONthink 3");
performsmartrule(app.selectedRecords());
})()
function currentAppID() {
const p = Application.currentApplication().properties();
return Application(p.name).id();
}
If run from inside DT, i.e. a smart rule, the anonymous function returns immidiately without calling performsmartrule
. The latter will then be called directly by the smart rule in the next step – so only once. The function currentAppID
is used to determine the id of the currently running app.
@Blanc I got it so far:
tell application id "DNtp"
set theRecords to selected records
if theRecords = {} then error "Please select a record"
repeat with currentRecord in theRecords
set metaData to custom meta data of currentRecord
set recordDate to mddate of metaData
set recordDateDay to get day of recordDate as text
set recordDateMonth to get month of recordDate as integer
if recordDateMonth < 10 then
set recordDateMonth to "0" & recordDateMonth as string
else
set recordDateMonth to recordDateMonth as string
end if
set recordDateYear to get year of recordDate as text
set recordDateString to recordDateYear & "." & recordDateMonth & "." & recordDateDay
set recordCompany to mdcompany of metaData
set recordPurpose to mdpurpose of metaData
set newName to recordDateString
if recordCompany is not equal to "" then set newName to newName & " - " & recordCompany
if recordPurpose is not equal to "" then set newName to newName & " - " & recordPurpose
set name of currentRecord to newName
end repeat
end tell
I got that AppleScript running in the script editor. But now I have the problem of, that a property must not exist. How can I check that? Searched for it, but doesn’t find a solution.
That’s slightly too abstract for me; can you explain in more detail (which property, what needs to happen?), so I can think about it?
I often use a try
routine - if a property exists, no error is thrown on trying to read or manipulate the property; but if it doesn’t exist, then an error is thrown which you can trap with on error
within the try
routine. But as I said, more information on which property would help determine whether you can determine the presents directly or whether you need to go an indirect route as above.
As of now I have 3 fields.
Date → example: 20.10.2021
Company → example: Apple
Purpose → example: Invoice
By the script I want to rename the file to:
2021.10.20 - Apple - Invoice.pdf
But company and purpose can also be empty. So if for example the purpose is not filled the name could also be: 2021.10.20 - Apple.pdf
If the purpose is empty in devonthink it’s not represented as an empty property, the property is missing at all and by this I get the following error:
error "Can’t get mdpurpose of {mdincomingoutgoing:\"Incoming\", mddate:date \"Friday, 1. January 2021 at 01:00:00\", mdbelongsto:\"Denis\", mdcompany:\"fitseveneleven\", mdcustomernumber:\"asdasd\"}." number -1728 from mdpurpose of {mdincomingoutgoing:"Incoming", mddate:date "Friday, 1. January 2021 at 01:00:00", mdbelongsto:"Denis", mdcompany:"fitseveneleven", mdcustomernumber:"asdasd"}
try
set recordPurpose to mdpurpose of metaData
on error
set recordPurpose to ""
end try
It works, thank you .
on performSmartRule(theRecords)
tell application id "DNtp"
repeat with currentRecord in theRecords
set metaData to custom meta data of currentRecord
set recordDate to mddate of metaData
set recordDateDay to get day of recordDate as text
set recordDateMonth to get month of recordDate as integer
if recordDateMonth < 10 then
set recordDateMonth to "0" & recordDateMonth as string
else
set recordDateMonth to recordDateMonth as string
end if
set recordDateYear to get year of recordDate as text
set recordDateString to recordDateYear & "." & recordDateMonth & "." & recordDateDay
set newName to recordDateString
try
set newName to newName & " - " & (mdcompany of metaData)
end try
try
set newName to newName & " - " & (mdpurpose of metaData)
end try
set name of currentRecord to newName
end repeat
end tell
end performSmartRule
This is how I have it now in devonthink in a smart rule.
Thanks to all of you for the fast responses. Will definitely buy now devonthink.
Hope also that devonthink will get available for shortcuts on macOS.