Files
This is the latest iteration of the script.
EDIT: Added a fix for selecting database
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use script "Dialog Toolkit Plus" version "1.1.3"
use script "RegexAndStuffLib" version "1.0.7"
property globalSuccessTags : {"auto-processed-invoice-content"}
-- Update UI fields
property fileNameField : {}
property companyField : {}
property locationPathField : {}
property databaseField : {}
property tagsField : {}
property presetsPopup : {}
property yearlyLocationCheckbox : {}
property originalFileNameLabel : {}
property currentYear : year of (current date)
property dialogPresets : {¬
{presetTitle:"Global: No preset", yearlyLocation:true, basePath:"", databaseName:"", addTags:{}, companyName:""}, ¬
{presetTitle:"Global: No rule", yearlyLocation:false, basePath:"/_Review/.NORULE", databaseName:"Inbox", addTags:{}, companyName:""}, ¬
{presetTitle:"Global: Handbücher", yearlyLocation:false, basePath:"/Handbuecher", databaseName:"knowledge", addTags:{"handbuch"}, companyName:""}, ¬
{presetTitle:"Global: Rente", yearlyLocation:true, basePath:"/Rente", databaseName:"business", addTags:{"rente"}, companyName:""}, ¬
{presetTitle:"Global: Projekte", yearlyLocation:false, basePath:"/_Projekte/" & currentYear & "/CHANGEME", databaseName:"personal", addTags:{"projekt"}, companyName:""}, ¬
{presetTitle:"Global: Sonstiges-Behoerden", yearlyLocation:true, basePath:"/Vertraege-und-Rechnungen/_Sonstiges-Behoerden", databaseName:"business", addTags:{"verwaltung", "behoerden"}, companyName:""}, ¬
{presetTitle:"Global: Sostiges-Gesundheit", yearlyLocation:true, basePath:"/Vertraege-und-Rechnungen/_Sonstiges-Gesundheit", databaseName:"business", addTags:{"health", "gesundheit"}, companyName:""}, ¬
{presetTitle:"Global: Sonstiges-Kaufbelege", yearlyLocation:true, basePath:"/Vertraege-und-Rechnungen/_Sonstiges-Kaufbelege", databaseName:"business", addTags:{"rechnungen", "invoice"}, companyName:""}, ¬
{presetTitle:"Global: Tipps", yearlyLocation:false, basePath:"/Tipps/Assets", databaseName:"knowledge", addTags:{"tipp"}, companyName:""}, ¬
{presetTitle:"Global: Urlaub", yearlyLocation:true, basePath:"/_Urlaub", databaseName:"personal", addTags:{"urlaub", "holidays"}, companyName:""}, ¬
{presetTitle:"Global: Vorlagen", yearlyLocation:false, basePath:"/_Neu", databaseName:"templates", addTags:{"template"}, companyName:""} ¬
}
-----------
-- code to run within Script Debugger
-- tell application "MstyStudio" to activate
-- tell application id "DNtp" to activate
tell application id "DNtp" to my performSmartRule(selected records)
-- test scriptOutput
-- tell application id "DNtp" to my scriptOutput(selected record 1, "")
-----------
-- test performSmartRule
property globalIsDev : true
-- copy template for smart rules
on performSmartRule(theRecords)
local libraryHandler
set libraryHandler to script "library-handling"
tell application id "DNtp"
set currentDb to current database
end tell
libraryHandler's canRun(currentDb, theRecords)
local scriptName
set scriptName to "document-invoices-handle"
local theScriptHandler
set theScriptHandler to libraryHandler's loadScript(scriptName, globalIsDev)
theScriptHandler's globalLog("INFO", "Run script", "script=" & quoted form of scriptName)
theScriptHandler's ForAll(theRecords, globalIsDev)
theScriptHandler's globalLog("INFO", "Script finished", "script=" & quoted form of scriptName)
end performSmartRule
-- Run job for all given records
on ForAll(theRecords, localIsDev)
local titleProgressBar
set titleProgressBar to "Handle documents"
tell application id "DNtp"
show progress indicator titleProgressBar steps (count of theRecords) with cancel button
end tell
-- https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_error_xmpls.html
set len to length of theRecords
set i to 1
my globalLog("INFO", quoted form of "Job started", "count_of_records=" & len)
try
local theRecord
repeat with theRecord in theRecords
tell application id "DNtp"
if cancelled progress then
my recordLog(theRecord, "INFO", quoted form of "Cancel current run of script", missing value)
exit repeat
end if
end tell
tell application id "DNtp"
set theFilename to the filename of theRecord
step progress indicator theFilename
end tell
my recordLog(theRecord, "INFO", quoted form of "Work on record", "index=" & i & "/" & len)
local modifiedRecord
set modifiedRecord to my ForOne(theRecord, localIsDev)
if modifiedRecord is not missing value then
tell application id "DNtp"
set tags of modifiedRecord to (get tags of modifiedRecord) & globalSuccessTags
end tell
end if
set i to i + 1
end repeat
on error errMsg number errNum partial result partialError
tell application id "DNtp"
hide progress indicator
end tell
-- if errNum = -10000 then
-- my globalLog("WARN", quoted form of "Job execution aborted", "error=-10000 count_of_records=" & len)
-- return
-- end if
if errNum = 1000 then
my globalLog("WARN", quoted form of "Job execution aborted by user", "error=1000 count_of_records=" & len)
return
end if
set AppleScript's text item delimiters to {return}
-- An unknown error occurred. Resignal, so the caller
-- can handle it, or AppleScript can display the number
display alert errMsg & ("Error number: ") & errNum & return & (partialError as text)
error errMsg & ("Error number: ") & errNum & return & (partialError as text)
end try
tell application id "DNtp"
hide progress indicator
end tell
my globalLog("INFO", quoted form of "Job completed", "count_of_records=" & len)
end ForAll
-- Run job for single record
on ForOne(theRecord, localIsDev)
local thisYear
tell application id "DNtp"
set thisYear to year of (get creation date of theRecord) as string
end tell
-- repeat for "redo" of a single record
-- * load rules
-- * set metadata from rules
-- * show dialog
local dialogResponse
set dialogResponse to missing value
-- create window to show record and check it with given metadata
local theWindow
tell application id "DNtp"
set theWindow to open window for record theRecord
end tell
repeat
set dialogResponse to my showDialogInLoop(theRecord, dialogResponse, thisYear, localIsDev)
if exitLoop of dialogResponse is true then
exit repeat
end if
end repeat
local theButtonPressed
set theButtonPressed to buttonPressed of dialogResponse
-- handle buttons
if theButtonPressed = "Ignore" or theButtonPressed = "Gave up" then
my recordLog(theRecord, "DEBUG", quoted form of "Button pressed by user", "button=" & theButtonPressed & return & "action=" & quoted form of "Ignore file due to user interaction or time out")
-- if windows has been already closed prevents error
try
tell application id "DNtp"
close theWindow
end tell
end try
return missing value
end if
if theButtonPressed = "Abort" then
my recordLog(theRecord, "DEBUG", quoted form of "Button pressed by user", "button=" & theButtonPressed & return & "action=" & quoted form of "Stop script interaction")
-- no: close theWindow to make review and handling easier
error "Abort handling of documents" number 1000
end if
if theButtonPressed = "Delete" then
my recordLog(theRecord, "DEBUG", quoted form of "Button pressed by user", "button=" & theButtonPressed & return & "action=" & quoted form of "Move file to trash")
-- if windows has been already closed prevents error
try
tell application id "DNtp"
close theWindow
end tell
end try
tell application id "DNtp"
set deleteAlertResult to display alert "Delete record?" buttons {"Yes", "No"} default button "No" giving up after 0
end tell
if button returned of deleteAlertResult = "Yes" then
tell application id "DNtp"
move record theRecord to trash group of (database of theRecord)
end tell
end if
return missing value
end if
my recordLog(theRecord, "DEBUG", quoted form of "Button pressed by user", "button=" & theButtonPressed & return & "action=" & quoted form of "Set attributes and location of record based on rules")
-- get information about record from dialog
local parsedDialogResponse
set parsedDialogResponse to my parseDialogResponse(dialogResponse)
-- get metadata from response
local updatedTags, existingTags, theDatabaseName, theCompany, locationPath, theButtonPressed
set updatedTags to (updatedTags of parsedDialogResponse)
set existingTags to (existingTags of parsedDialogResponse)
set theDatabaseName to (databaseName of parsedDialogResponse)
set theCompany to (companyName of parsedDialogResponse)
set locationPath to (locationPath of parsedDialogResponse)
set newFilename to (newFilename of parsedDialogResponse)
-- if windows has been already closed prevents error
try
tell application id "DNtp"
close theWindow
end tell
end try
-- set name of record
local newName
local oldName
tell application id "DNtp"
set oldName to name of theRecord
set newName to newFilename of dialogResponse
set name of theRecord to newName
end tell
-- create location
local oldLocation
tell application id "DNtp"
set oldLocation to location of theRecord
end tell
local newLocation
tell application id "DNtp"
set newLocation to create location locationPath in database theDatabaseName
end tell
-- get database from location
local theDatabase
tell application id "DNtp"
set theDatabase to (database of newLocation)
end tell
-- update tags
if updatedTags is missing value then
set updatedTags to {}
end if
if existingTags is missing value then
set existingTags to {}
end if
tell application id "DNtp"
set tags of theRecord to updatedTags & existingTags
end tell
-- set company name (custom attribute) from metadata
if (companyName of parsedDialogResponse) is not missing value then
tell application id "DNtp"
add custom meta data companyName of parsedDialogResponse for "company" to theRecord
end tell
end if
-- move record to new location
local movedRecord
tell application id "DNtp"
set movedRecord to move record theRecord to newLocation
end tell
tell application id "DNtp"
set newLocationName to location with name of newLocation
end tell
my recordLog(movedRecord, "INFO", quoted form of "Moved and renamed document", "old_location=" & quoted form of oldLocation & return & "new_location=" & quoted form of (newLocationName) & return & "old_name=" & oldName & return & "new_name=" & newName, missing value)
return movedRecord
end ForOne
on showDialogInLoop(theRecord, dialogResponse, thisYear, localIsDev)
local libraryHandler
set libraryHandler to script "library-handling"
-- (re)load rules
local theScriptHandler
set theScriptHandler to libraryHandler's loadScriptSilent("document-invoices-rules", localIsDev)
tell application id "DNtp"
local theFilename
set theFilename to filename of theRecord
end tell
-- use rules to get metadata about file
-- default is missing value if no rule matches
local recordMetadata
set recordMetadata to theScriptHandler's getMetadataForRecord(theRecord, thisYear)
-- set recordMetadata to my getMetadataForRecord(theRecord, thisYear)
if recordMetadata is missing value then
my recordLog(theRecord, "WARN", quoted form of "No matching rule. Ignore file and go on", missing value)
error "File: " & theFilename & " has no matching rule. I ignore this file and move on if multiple files are selected"
end if
if (basePath of recordMetadata) is missing value or (databaseName of recordMetadata) is missing value then
display alert "DNtp" message "basePath or database is missing for the file " & theFilename & ". This is not allowed. Going on with the next file."
error "basePath or database is missing for the file " & theFilename & ". This is not allowed. Going on with the next file."
end if
-- show dialog and ask user for "help"
set dialogResponse to my showDialog(theRecord, recordMetadata, dialogResponse, thisYear)
local theButtonPressed
set theButtonPressed to buttonPressed of dialogResponse
if (theButtonPressed is not "Redo" and theButtonPressed is not "AI Rename") then
set exitLoop of dialogResponse to true
return dialogResponse
end if
-- nothing to to with theButtonPressed = "Redo"
-- ask model for new name file if AI rename script is asked
if theButtonPressed = "AI Rename" then
my recordLog(theRecord, "DEBUG", quoted form of "Button pressed by user", "button=" & theButtonPressed & return & "action=" & quoted form of "Asking AI for new filename")
set exitLoop of dialogResponse to false
local libraryHandler
set libraryHandler to script "library-handling"
local theScriptHandler
set theScriptHandler to libraryHandler's loadScriptSilent("document-rename", localIsDev)
local thePrompt
set thePrompt to globalPrompt of theScriptHandler
local aiRequestTimeout
set aiRequestTimeout to globalAiRequestTimeout of theScriptHandler
local aiEngine
tell application id "DNtp"
set aiEngine to Ollama
end tell
local newAiGeneratedName
set aiGeneratedName to theScriptHandler's GetNewNameLoop(theRecord, localIsDev, aiEngine, "phi4", thePrompt, aiRequestTimeout)
set newFilename of dialogResponse to aiGeneratedName
end if
my recordLog(theRecord, "DEBUG", quoted form of "Button pressed by user", "button=" & theButtonPressed & return & "action=" & quoted form of "Re-evaluate rules")
return dialogResponse
end showDialogInLoop
on parseDialogResponse(dialogResponse)
local companyName, updatedTags, existingTags, databaseName, locationPath, addedYear, taxYear, locationPath, yearlyLocation
set addedYear to (addedYear of dialogResponse)
set taxYear to (taxYear of dialogResponse)
set newFilename to (newFilename of dialogResponse)
set companyName to (companyName of dialogResponse)
set databaseName to (databaseName of dialogResponse)
set updatedTags to (updatedTags of dialogResponse)
set existingTags to (existingTags of dialogResponse)
set locationPath to (locationPath of dialogResponse)
set yearlyLocation to (yearlyLocation of dialogResponse)
-- if user set year where this document is relevant for tax
if taxYear is not "" then
set taxYear to taxYear as number
set updatedTags to updatedTags & {"taxes-" & taxYear}
end if
-- make sure we append the year the record was added to the database
if yearlyLocation is true then
set locationPath to (locationPath & "/" & addedYear)
end if
-- "missing value" is correct!
if newFilename is "missing value" or newFilename is "" or newFilename is missing value then
error "Missing filename"
end if
-- "missing value" is correct!
if locationPath is "missing value" or locationPath is "" or locationPath is missing value then
error "Undefined individual location for file: Either select a preset with default locations or an individual one"
end if
-- return gathered metadata
return {newFilename:newFilename, companyName:companyName, updatedTags:updatedTags, existingTags:existingTags, databaseName:databaseName, locationPath:locationPath}
end parseDialogResponse
on showDialog(theRecord, recordMetadata, previousDialogResponse, thisYear)
-- gather data
local originalFilename
local newFilename
local existingTags
tell application id "DNtp"
set originalFilename to (filename of theRecord)
set existingTags to (tags of theRecord)
end tell
if previousDialogResponse is missing value then
tell application id "DNtp"
set newFilename to (name without extension of theRecord)
end tell
else if newFilename of previousDialogResponse is not missing value then
set newFilename to (newFilename of previousDialogResponse)
else if newFilename of recordMetadata is not missing value then
set newFilename to (newFilename of recordMetadata)
else
tell application id "DNtp"
set newFilename to (name without extension of theRecord)
end tell
end if
local yearlyLocation
set yearlyLocation to (yearlyLocation of recordMetadata)
local theDatabaseName
set theDatabaseName to (databaseName of recordMetadata)
local theCompanyName
set theCompanyName to (companyName of recordMetadata)
local updatedTags
set updatedTags to (addTags of recordMetadata)
local theLocationPath
set theLocationPath to (basePath of recordMetadata)
local taxYear
set taxYear to (taxYear of recordMetadata)
-- missing value cannot be handled by dialogue
-- optional
if yearlyLocation is missing value then
set yearlyLocation to false
end if
if theCompanyName is missing value then
set theCompanyName to ""
end if
if updatedTags is missing value then
set updatedTags to {}
end if
if taxYear is missing value then
set taxYear to ""
end if
set accViewWidth to 600
-- set buttons
set {theButtons, minWidth} to create buttons {"Delete", "AI Rename", "Redo", "Abort", "Ignore", "Move"} default button "Ignore" without equal widths
if minWidth > accViewWidth then set accViewWidth to minWidth -- make sure buttons fit
-- to make it look better, we can get the length of the longest label we will use, and use that to align the controls
set theLabelStrings to {"Location year", "Tax year", "Company name", "Location", "Database", "New tags", "Existing tags", "Chosen preset", "New filename"}
set maxLabelWidth to max width for labels theLabelStrings
set controlLeft to maxLabelWidth + 8
-- set names for the presets used in dropdown
-- needs to be in the
local presetNames
set presetNames to {}
repeat with preset in dialogPresets
set end of presetNames to (presetTitle of preset)
end repeat
-- empty added year to workaround namespace issue
local addedYear
set addedYear to ""
if yearlyLocation is true then
set addedYear to thisYear
end if
-- space between items
local spacer
set spacer to 20
local joinedUpdatedTags
-- place tags into single input field by joining them into single string
set joinedUpdatedTags to (join strings updatedTags using delimiter ",")
local joinedExistingTags
set joinedExistingTags to (join strings existingTags using delimiter ",")
-- make current record the no preset record
set oldPreset to item 1 of dialogPresets
set newPreset to {presetTitle:"Global: No preset", yearlyLocation:yearlyLocation, basePath:theLocationPath, databaseName:theDatabaseName, addTags:updatedTags, companyName:theCompanyName}
set dialogPresets to {newPreset} & (items 2 thru -1 of dialogPresets)
-- get list of known databases from DT
set sortedListOfDatabases to my getDatabaseList()
-- start from the bottom
set {taxesYearField, taxesYearLabel, theTop, fieldLeft} to create side labeled field taxYear placeholder text "Tax relevant" left inset (accViewWidth / 2) + spacer bottom 8 total width (accViewWidth / 2) - spacer label text (item 2 of theLabelStrings) field left controlLeft
local addedDocYearField
set {addedDocYearField, addedDocYearLabel, theTop, fieldLeft} to create side labeled field addedYear placeholder text "Added date" left inset 0 bottom 8 total width (accViewWidth / 2) - spacer label text (item 1 of theLabelStrings) field left controlLeft
set {yearlyLocationCheckbox, theTop, newWidth} to create checkbox "Create yearly location" left inset controlLeft bottom (theTop + 16) max width accViewWidth initial state yearlyLocation
set {locationPathField, locationPathLabel, theTop, fieldLeft} to create side labeled field theLocationPath placeholder text "The path to location in DB" left inset 0 bottom (theTop + 16) total width accViewWidth label text (item 4 of theLabelStrings) field left controlLeft
set {databaseField, databaseLabel, theTop, fieldLeft} to create labeled popup sortedListOfDatabases left inset 0 bottom (theTop + 14) popup width 435 max width accViewWidth label text (item 5 of theLabelStrings) popup left controlLeft initial choice theDatabaseName
set {companyField, companyLabel, theTop, fieldLeft} to create side labeled field theCompanyName placeholder text "the name of the company" left inset 0 bottom (theTop + 16) total width accViewWidth label text (item 3 of theLabelStrings) field left controlLeft
set {existingTagsField, existingTagsLabel, theTop} to create top labeled field joinedExistingTags placeholder text "List of tags" bottom (theTop + 3) field width accViewWidth - controlLeft label text (item 7 of theLabelStrings) left inset controlLeft extra height 30
set {tagsField, tagsLabel, theTop} to create top labeled field joinedUpdatedTags placeholder text "List of tags" bottom (theTop + 3) field width accViewWidth - controlLeft label text (item 6 of theLabelStrings) left inset controlLeft extra height 30
set {originalFileNameField, theTop} to create label "Original filename with ext: " & originalFilename bottom theTop + 16 max width (accViewWidth - 100) left inset controlLeft
set {fileNameField, fileNameLabel, theTop} to create top labeled field newFilename placeholder text "The new filename" bottom (theTop + 3) field width accViewWidth - controlLeft label text (item 9 of theLabelStrings) left inset controlLeft extra height 60
set {presetsPopup, presetsLabel, theTop} to create labeled popup presetNames left inset 0 bottom (theTop + 14) popup width 435 max width accViewWidth label text (item 8 of theLabelStrings) popup left controlLeft initial choice "Global: No preset"
-- make it possible that the dropdown updates other fields
-- https://www.macscripter.net/t/change-elements-dynamically-using-shanes-dialog-toolkit/70409/11
presetsPopup's setTarget:me
presetsPopup's setAction:"updateOtherFields:"
-- make list of cotronls and pass to display command
set allControls to {yearlyLocationCheckbox, addedDocYearField, addedDocYearLabel, taxesYearField, taxesYearLabel, companyField, companyLabel, locationPathField, locationPathLabel, databaseField, databaseLabel, existingTagsField, existingTagsLabel, tagsField, tagsLabel, originalFileNameField, fileNameField, fileNameLabel, presetsPopup, presetsLabel}
-- controlResults will in the same order as allControls
local buttonPressed, controlsResults
set {buttonPressed, controlsResults} to display enhanced window "Set metadata for file" acc view width accViewWidth acc view height theTop acc view controls allControls buttons theButtons initial position {} giving up after 0 with align
-- debugging
-- my updateOtherFields()
-- gather data from result
local newFilename, companyName, updatedTags, existingTags, databaseName, locationPath, taxYear, locationPath, chosenPreset, yearlyLocation
set yearlyLocation to (item 1 of controlsResults)
set addedYear to (item 2 of controlsResults)
set taxYear to (item 4 of controlsResults)
set companyName to (item 6 of controlsResults)
set locationPath to (item 8 of controlsResults)
set databaseName to (item 10 of controlsResults)
set existingTags to split string (item 12 of controlsResults) using delimiters ","
set updatedTags to split string (item 14 of controlsResults) using delimiters ","
set newFilename to (item 17 of controlsResults)
set chosenPreset to (item 19 of controlsResults)
my recordLog(theRecord, "DEBUG", quoted form of "Result of dialog with user", "new_filename=" & newFilename & return & "yearly_location=" & yearlyLocation & return & "chosen_prese=" & chosenPreset & return & "button_pressed=" & buttonPressed & return & "added_year=" & addedYear & return & "tax_year=" & taxYear & return & "company_name=" & companyName & return & "database_name=" & databaseName & return & "existing_tags=" & (join strings existingTags using delimiter ",") & return & "updated_tags=" & (join strings updatedTags using delimiter ",") & return & "location_path=" & locationPath)
return {exitLoop:missing value, newFilename:newFilename, yearlyLocation:yearlyLocation, presetNames:presetNames, chosenPreset:chosenPreset, buttonPressed:buttonPressed, addedYear:addedYear, taxYear:taxYear, companyName:companyName, databaseName:databaseName, updatedTags:updatedTags, existingTags:existingTags, locationPath:locationPath}
end showDialog
-- update fields by using information from the dropdown
-- requires framework "Foundation" and properties for fields to be updated
-- on updateOtherFields()
on updateOtherFields:sender
try
-- set index of selected dropdown item
local selectedPresetIndex
set selectedPresetIndex to (my presetsPopup's indexOfSelectedItem() as integer) + 1
set selectedPreset to item selectedPresetIndex of dialogPresets
-- get values for selected dropdown
local selectedCompanyName, selectedLocation, selectedTags, joinedTags, selectedDatabase, selectedYearlyLocation
set selectedCompanyName to (companyName of selectedPreset as text)
set selectedLocation to (basePath of selectedPreset as text)
local selectedTags
set selectedTags to (addTags of selectedPreset)
set joinedTags to (join strings selectedTags using delimiter ",")
set selectedDatabase to (databaseName of selectedPreset as text)
set selectedYearlyLocation to (yearlyLocation of selectedPreset as boolean)
-- set values
-- https://www.macscripter.net/t/change-elements-dynamically-using-shanes-dialog-toolkit/70409/11
my (companyField's setStringValue:selectedCompanyName)
my (locationPathField's setStringValue:selectedLocation)
my (tagsField's setStringValue:joinedTags)
my (yearlyLocationCheckbox's setState:selectedYearlyLocation)
local dbList
set dbList to getDatabaseList()
local dbIndex
repeat with n from 1 to count of dbList
if selectedDatabase is (item n of dbList) then
set dbIndex to n - 1
exit repeat
end if
end repeat
my (databaseField's selectItemAtIndex:dbIndex)
on error errMsg number errNum partial result partialError
set AppleScript's text item delimiters to {return}
-- An unknown error occurred. Resignal, so the caller
-- can handle it, or AppleScript can display the number.
display alert errMsg & ("Error number: ") & errNum & return & (partialError as text)
error errMsg & ("Error number: ") & errNum & return & (partialError as text)
end try
end updateOtherFields:
on recordLog(theRecord, level, msg, msgInfo)
if msgInfo is missing value then
set logMsg to "msg=" & msg
else
set logMsg to "msg=" & msg & " " & msgInfo
end if
if level is not "DEBUG" then
tell application id "DNtp"
log message record theRecord info "level=INFO " & logMsg
end tell
return
end if
if globalIsDev is true then
tell application id "DNtp"
log message record theRecord info "level=DEBUG " & logMsg
end tell
end if
end recordLog
on globalLog(level, msg, msgInfo)
if msgInfo is missing value then
set logMsg to "msg=" & msg
else
set logMsg to "msg=" & msg & " " & msgInfo
end if
if level is not "DEBUG" then
tell application id "DNtp"
log message "level=INFO " & logMsg
end tell
return
end if
if globalIsDev is true then
tell application id "DNtp"
log message "level=DEBUG " & logMsg
end tell
end if
end globalLog
on getDatabaseList()
local listOfDatabases
tell application id "DNtp"
set listOfDatabases to name of every database
end tell
-- sort list of databases
-- https://stackoverflow.com/questions/78218289/applescript-how-do-i-sort-a-list-of-sentences-paragraphs-with-an-assigned-numbe
set array to current application's NSArray's arrayWithArray:listOfDatabases
set sortedListOfDatabases to (array's sortedArrayUsingSelector:"localizedStandardCompare:") as list
return sortedListOfDatabases
end getDatabaseList