Last active
February 23, 2025 02:12
-
-
Save LikeCarter/cc6cfad1c0870bda9851cd02df81be4c to your computer and use it in GitHub Desktop.
DevonThink AI Rename
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- Rename Files Using OpenAI API with Verbose Logging and Progress Indicator | |
| -- Based on (c) 1201 Apple, Inc. & (c) 1204-2019 DEVONtechnologies, LLC. | |
| tell application id "DNtp" | |
| try | |
| set this_selection to the selection | |
| if this_selection is {} then error "Please select some contents." | |
| set itemCount to count of this_selection | |
| set currentIndex to 0 | |
| repeat with this_item in this_selection | |
| delay 0.25 | |
| try | |
| set currentIndex to currentIndex + 1 | |
| set docText to plain text of this_item | |
| if docText is not "" then | |
| log "Extracting first 120 words." | |
| set first120Words to my getFirst120Words(docText) | |
| log "First 120 words extracted: " & first120Words | |
| set newTitle to my generateTitle(first120Words) | |
| if newTitle is "" then | |
| log "Skipping..." | |
| else | |
| log "Renaming item to: " & newTitle | |
| set name of this_item to newTitle | |
| end if | |
| else | |
| log "No text content available. Skipping item." | |
| end if | |
| on error inner_error_message number inner_error_number | |
| display dialog "Error processing item: " & inner_error_message | |
| end try | |
| end repeat | |
| on error error_message number error_number | |
| display dialog "Script encountered an error: " & error_message | |
| if the error_number is not -128 then display alert "DEVONthink" message error_message as warning | |
| end try | |
| end tell | |
| on removeQuotes(inputText) | |
| if inputText starts with "\"" and inputText ends with "\"" then | |
| set inputText to text 2 through -2 of inputText -- Remove first and last character (the quotes) | |
| end if | |
| return inputText | |
| end removeQuotes | |
| on replaceText(inputText, searchText, replaceText) | |
| set AppleScript's text item delimiters to searchText | |
| set tempList to text items of inputText | |
| set AppleScript's text item delimiters to replaceText | |
| set outputText to tempList as text | |
| set AppleScript's text item delimiters to "" -- reset delimiters | |
| return outputText | |
| end replaceText | |
| on removeTabsAndNewlines(inputText) | |
| set inputText to replaceText(inputText, (ASCII character 9), "") -- Tab | |
| set inputText to replaceText(inputText, (ASCII character 10), "") -- Linefeed (new line) | |
| set inputText to replaceText(inputText, (ASCII character 13), "") -- Return (carriage return) | |
| return inputText | |
| end removeTabsAndNewlines | |
| on joinWords(wordList) | |
| set AppleScript's text item delimiters to " " -- set delimiter as space | |
| set joinedText to wordList as text | |
| set AppleScript's text item delimiters to "" -- reset delimiters | |
| set joinedText to my removeTabsAndNewlines(joinedText) | |
| return joinedText | |
| end joinWords | |
| on getFirst120Words(theText) | |
| log "Extracting first 120 words from text." | |
| set wordList to words of theText | |
| set wordCount to count of wordList | |
| if wordCount > 120 then | |
| set first120Words to (items 1 thru 120 of wordList) as list | |
| set first120WordsText to my joinWords(first120Words) | |
| else | |
| set first120WordsText to theText | |
| end if | |
| log "First 120 words extracted successfully." | |
| return first120WordsText | |
| end getFirst120Words | |
| on stripSurroundingQuotes(inputText) | |
| if inputText starts with "\"" and inputText ends with "\"" then | |
| set inputText to text 2 through -2 of inputText | |
| end if | |
| return inputText | |
| end stripSurroundingQuotes | |
| on generateTitle(theText) | |
| set apiKey to "sk-proj-" | |
| set model to "gpt-4o" | |
| log "Sending text to OpenAI for title generation." | |
| set promptText to "Generate a concise and descriptive title based on the following text: " & removeTabsAndNewlines(theText) | |
| set jsonData to "{\"model\": \"" & model & "\", \"messages\": [{\"role\": \"system\", \"content\": \"You are a helpful assistant that provides American-style English document titles. Pick the shortest title that contains key information and relevant dates and people, if applicable, in this format [Document Description] - [People (First & Last Names Only) (Comma-Separated)] - [YYYY/MM/DD].\"}, {\"role\": \"user\", \"content\": \"" & promptText & "\"}]}" | |
| log "Sending request to OpenAI API." | |
| set request to "https://api.openai.com/v1/chat/completions" | |
| set cmd to "curl -s -X POST " & quoted form of request & " -H 'Content-Type: application/json' -H 'Authorization: Bearer " & apiKey & "' --data " & quoted form of jsonData | |
| set response to do shell script cmd | |
| log "Received response from OpenAI: " & response | |
| set jsonResponse to (do shell script "echo " & quoted form of response & " | jq -r '.choices[0].message.content'") | |
| if jsonResponse is "null" then | |
| return "" | |
| end if | |
| set jsonResponse to jsonResponse as text | |
| set jsonResponse to my stripSurroundingQuotes(jsonResponse) | |
| log "Extracted title from response: " & jsonResponse | |
| return jsonResponse | |
| end generateTitle |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment