Skip to content

Instantly share code, notes, and snippets.

@iainhouston
Last active February 3, 2020 12:56
Show Gist options
  • Save iainhouston/0fcf1db99544bef5ce77853c9c47af08 to your computer and use it in GitHub Desktop.
Save iainhouston/0fcf1db99544bef5ce77853c9c47af08 to your computer and use it in GitHub Desktop.
A Folder Action to encode a script to be Opened in Editor
property done_foldername : "URL Encoded Scripts"
on adding folder items to this_folder after receiving these_items
-- If the result folder doesn't exist, then create it
tell application "Finder"
if not (exists folder done_foldername of this_folder) then
make new folder at this_folder with properties {name:done_foldername}
set current view of container window of this_folder to list view
end if
set the target_folder to folder done_foldername of this_folder
log "info for this_folder: " & (this_folder)
end tell
-- Process each file newly-added to this_folder
try
repeat with i from 1 to number of items in these_items
set this_item to item i of these_items
set the item_info to the info for this_item
if (alias of the item_info is false and the type identifier of the item_info is "com.apple.applescript.text") or (the name extension of the item_info is "applescript") then
log "OK to go"
tell application "Finder"
-- LOOK FOR EXISTING MATCHING ITEMS IN THE DESTINATION FOLDER
-- IF THERE ARE MATCHES, THEN RENAME THE CONFLICTING FILES INCREMENTALLY
my resolve_conflicts(this_item, target_folder)
-- MOVE THE ITEM TO THE DESTINATION FOLDER
set the target_file to (move this_item to the target_folder with replacing) as alias
set target_folderName to the POSIX path of (target_folder as string) as string
set the scriptInputName to target_folderName & the text of (name of (info for target_file))
set the scriptInputExtension to "." & (the text of (name extension of (info for target_file)))
set the scriptOutputName to my trimText(scriptInputName, scriptInputExtension, "end") & ".urlencoded"
set the scriptInputName to the quoted form of scriptInputName
set the scriptOutputName to the quoted form of scriptOutputName
end tell
-- PROCESS THE ITEM
process_item(scriptInputName, scriptOutputName)
end if
end repeat
on error error_message number error_number
if the error_number is not -128 then
tell application "Finder"
activate
display dialog error_message buttons {"Cancel"} default button 1 giving up after 120
end tell
end if
end try
end adding folder items to
on resolve_conflicts(this_item, target_folder)
tell application "Finder"
set the quotedName to quoted form of POSIX path of this_item
log "quotedName: " & quotedName
set the file_name to the name of this_item
if (exists document file file_name of target_folder) then
set file_extension to the name extension of this_item
if the file_extension is "" then
set the trimmed_name to the file_name
else
set the trimmed_name to text 1 thru -((length of file_extension) + 2) of the file_name
end if
set the name_increment to 1
repeat
set the new_name to (the trimmed_name & "." & (name_increment as string) & "." & file_extension) as string
if not (exists document file new_name of the target_folder) then
-- rename to conflicting file
set the name of document file file_name of the target_folder to the new_name
exit repeat
else
set the name_increment to the name_increment + 1
end if
end repeat
end if
end tell
end resolve_conflicts
-- this sub-routine processes files
on process_item(scriptInputName, scriptOutputName)
-- NOTE that the variable this_item is a file reference in alias format
-- FILE PROCESSING STATEMENTS GOES HERE
try
with timeout of 3 seconds
set shellCommand to ¬
"echo '<a href = \"applescript://com.apple.scripteditor?action=new&script=' > " & scriptOutputName & " && iconv -f iso-8859-1 -t UTF-8 " & scriptInputName & " | python3 -c \"import urllib.parse, sys; print(urllib.parse.quote(sys.stdin.read()))\" >> " & scriptOutputName & " && echo '\">Open in Script Editor</a>' >> " & scriptOutputName
do shell script shellCommand
end timeout
on error error_message
tell application "Finder"
activate
display dialog error_message buttons {"Cancel"} default button 1 giving up after 120
end tell
end try
end process_item
on trimText(theText, theCharactersToTrim, theTrimDirection)
set theTrimLength to length of theCharactersToTrim
if theTrimDirection is in {"beginning", "both"} then
repeat while theText begins with theCharactersToTrim
try
set theText to characters (theTrimLength + 1) thru -1 of theText as string
on error
-- text contains nothing but trim characters
return ""
end try
end repeat
end if
if theTrimDirection is in {"end", "both"} then
repeat while theText ends with theCharactersToTrim
try
set theText to characters 1 thru -(theTrimLength + 1) of theText as string
on error
-- text contains nothing but trim characters
return ""
end try
end repeat
end if
return theText
end trimText
@iainhouston
Copy link
Author

You Export your AppleScript using the "Text" file option from the Script Editor to the folder with this script (URLEncodeAppleScript.applescript) attached as a Folder Action.
It is worth noting that AppleScript Editor exports a decompiled version of your compiled script which may contain line continuation characters that the Python urllib.parse finds unpalatable. Thus, instead of merely catenating the .AppleScript into the output file, we do iconv -f iso-8859-1 -t UTF-8 " & scriptInputName & " to create a UTF-8 file that Python is happy with.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment