I'm currently trying to make an AppleScript which should recognize the selected file in Finder and do the relative command in Terminal.
Everything was going fine since I reached the part where it should define the language of the selected file: it just doesn't check the ifs.
I checked if it writes fileExtension correctly (via return) and it does.
Thanks
--> Useful variables
set fileCheck to false
set languageCheck to false
set selectionCheck to false
set fileExtension to ""
set myCommand to ""
--> Get selected file
tell application "Finder"
if selection is {} then
tell application "Terminal"
activate
end tell
else
set finderSelection to selection as alias list
set selectionCheck to true
end if
end tell
--> Get file POSIX path
if selectionCheck is true then
set filePath to quoted form of POSIX path of finderSelection
end if
--> Get file extensions
if filePath contains "." then
set fileCheck to true
set fileExtension to text ((offset of "." in filePath) + 1) thru -1 of filePath
end if
--> Check language
-- No Extension
if fileCheck is false then
display dialog "warning:
the file you selected has no extension" buttons ("Ok") default button 1
-- Text
else if fileExtension is "txt" then
set myCommand to "open"
set languageCheck to true
-- Perl
else if fileExtension = "pl" then
set myCommand to "perl"
set languageCheck to true
-- Ruby
else if fileExtension is "rb" then
set myCommand to "ruby"
set languageCheck to true
-- Python
else if fileExtension is "py" then
set myCommand to "python"
set languageCheck to true
-- AppleScript
else if fileExtension is "scpt" then
set myCommand to "osascript"
set languageCheck to true
else
display dialog "warning:
the extension is not supported" buttons ("Ok") default button 1
end if
--> Terminal time!
if fileCheck is true and languageCheck is true then
do shell script "" & myCommand & " " & filePath
end if
Since you can't figure it out, here's how I would write that script...
--> Useful variables
set myCommand to missing value
set fileExtension to missing value
--> Get selected file
tell application "Finder"
set finderSelection to selection
if finderSelection is {} then
display dialog "Warning: Nothing is selected!" buttons ("Ok") default button 1
return
else
set theFile to item 1 of finderSelection
set filePath to POSIX path of (theFile as text)
set fileExtension to name extension of theFile
end if
end tell
if fileExtension is "txt" then
set myCommand to "open"
-- Perl
else if fileExtension is "pl" then
set myCommand to "perl"
-- Ruby
else if fileExtension is "rb" then
set myCommand to "ruby"
-- Python
else if fileExtension is "py" then
set myCommand to "python"
-- AppleScript
else if fileExtension is "scpt" then
set myCommand to "osascript"
else if fileExtension is not missing value then
display dialog "Warning: the file is not supported" & return & return & filePath buttons ("Ok") default button 1
end if
--> Terminal time!
if myCommand is not missing value then
do shell script myCommand & " " & quoted form of filePath
end if
Your code is wrong. The Finder selection in the variable finderSelection is a list. A list has "items" because a list can hold more than one thing. So if you want to handle multiple selected items in the Finder then you need a repeat loop and to check each item in the list individually. If you only want the first selected item then you want "item 1" of the selection. As such you probably want something like this...
tell application "Finder"
set finderSelection to selection as alias list
end tell
set firstItem to item 1 of finderSelection
set filePath to quoted form of POSIX path of firstItem
set fileExtension to text ((offset of "." in filePath) + 1) thru -1 of filePath
Related
I’m trying to create an Applescript-Objc to mount multiple EFI partitions, but I’m not able to mount the EFI partitions on external drives only those on the internal disk,
what I've done so far is this:
set a to do shell script "diskutil list | grep EFI | grep -o -e disk[0-9]s[0-9]"
set b to do shell script "diskutil info " & a & " | awk '/Identifier/' | grep -o -e disk[[:digit:]]*"
set c to do shell script "diskutil info " & b & "| grep 'Media Name' | awk /'Name:/{print$5,$6}'"
choose from list c with prompt "Multiple EFI partitions found:"
display alert "Do you want to mount the EFI partition?" buttons {"Yes", "No"} default button 1
set response to button returned of the result
if response = "Yes" then
do shell script "diskutil mount " & a with administrator privileges
display alert result
end if
Note: when asked the user I want the disk name to be displayed and not something like: ''disk0s1''
Thanks in advance!
I wrote an EFI mount/unmount utility applet a while ago that uses an NSAlert with a combo box to try to avoid the death by dialog typical with AppleScripts. I extracted the script from that and added disk names to the initial dialog - the alert stuff makes it a bit longer than your snippet, but there should be something in there you can use:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
property alertHeader : " --- CAUTION ---" & return & "This utility works with EFI boot partitions -" & return & "Administrator authorization will be required."
property resources : "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/"
property leadText : " "
property identifiers : missing value -- this will be a list of the EFI partition identifiers, e.g. {disk0s1}
on run -- example can be run as app and from Script Editor
if current application's NSThread's isMainThread() as boolean then
doStuff()
else
my performSelectorOnMainThread:"doStuff" withObject:(missing value) waitUntilDone:true
end if
end run
on doStuff() -- the main stuff
set theDisks to setup() -- set up properties and get disks with EFI partitions, e.g. {/dev/disk0}
set reply to {button:missing value, answer:""} -- preset a previous empty dialog result
repeat -- forever
set theAnswer to answer of reply -- use previous
set reply to (showAlert given settings:{title:"EFI [un]Mounter", message:alertHeader, information:"EFI partitions have been found on the following disks:" & return & return & theDisks & return & "The EFI partition of the specified disk will be [un]mounted." & return & "Enter the disk identifier or select one from the menu:", answer:theAnswer, icon:(resources & "AlertCautionIcon.icns"), buttons:{"Cancel", "Mount", "Unmount", "More Info"}})
if button of reply is "Cancel" then error number -128
set diskID to checkID(answer of reply)
if diskID is not missing value then -- found it
if button of reply is "More Info" then
set reply to moreInfo(answer of reply) -- result of the moreInfo dialog
if button of reply is not "Change" then exit repeat
else
exit repeat
end if
else -- try again
beep
set answer of reply to ""
end if
end repeat
processEFI(button of reply, diskID)
end doStuff
to processEFI(command, diskID) -- mount or unmount the specified disk - admin authorization will be needed
log diskID
try
set command to (do shell script "echo " & command & " | tr [:upper:] [:lower:]")
if command is not in {"mount", "unmount"} then error "The processEFI handler received an invalid command."
set theResult to (do shell script "diskutil " & command & " /dev/" & diskID with administrator privileges)
if command is "mount" then tell application "Finder" -- show it
make new Finder window to ("/Volumes/EFI" as POSIX file)
activate
end tell
display notification theResult
delay 2
on error errmess
log errmess
showAlert given settings:{title:"EFI [un]Mounter", message:return & "There was an error processing the partition.", information:errmess, icon:(resources & "AlertCautionIcon.icns")}
end try
end processEFI
on moreInfo(diskID) -- get more information about the specified disk identifier
set infoText to ""
set diskName to (do shell script "diskutil info " & diskID & " | grep 'Media Name' | awk '{print substr($0,index($0,$5))}'")
if diskName is "" then
set diskName to "the following disk"
else
set diskName to "disk " & quoted form of diskName
end if
repeat with aParagraph in paragraphs of (do shell script "diskutil list " & diskID)
if aParagraph starts with leadText then -- trim information text
if (paragraph -2 of infoText does not start with leadText) then set infoText to infoText & leadText & trimWhitespace(text 1 thru -1 of contents of aParagraph) & return
else if aParagraph does not start with " #:" then -- don't include header text
if length of aParagraph is less than 56 then
set infoText to infoText & aParagraph & return
else -- trim description text
set infoText to infoText & space & space & space & text 1 thru 6 of aParagraph & tab & trimWhitespace(text 7 thru 56 of aParagraph)
set infoText to infoText & return
end if
end if
end repeat
set reply to (showAlert given settings:{title:"EFI [un]Mounter", message:alertHeader, information:"The EFI partition of " & diskName & " will be [un]mounted:" & return & return & infoText, icon:(resources & "AlertCautionIcon.icns"), buttons:{"Cancel", "Mount", "Unmount", "Change"}})
if button of reply is "Cancel" then error number -128
return {button:button of reply, answer:diskID}
end moreInfo
to showAlert given settings:arguments -- show a custom alert
set arguments to arguments & {title:"", message:"Alert", information:"", answer:missing value, icon:"", buttons:{"OK"}} -- a record is used for input parameters, unspecified keys will use default values
tell current application's NSAlert's alloc's init()
if (icon of arguments) as text is "Critical" then -- everything else is NSInformationalAlertStyle
set its alertStyle to current application's NSCriticalAlertStyle
else -- use the contents of an image file - informational icon will be used if no image or file (missing value)
set its icon to current application's NSImage's alloc's initByReferencingFile:((icon of arguments) as text)
end if
set its |window|'s title to (title of arguments) as text
set its messageText to (message of arguments) as text -- the bold text
set its informativeText to (information of arguments) as text -- the normal text
set buttonList to my (setButtons for it from (buttons of arguments))
if (answer of arguments) is not missing value then
set its |window|'s autorecalculatesKeyViewLoop to true
set accessory to my (makeComboAccessory for it)
set accessory's stringValue to answer of arguments
end if
activate me
set response to ((its runModal) as integer) - 999 -- get index - 1000 is rightmost button
end tell
if answer of arguments is not missing value then set answer of arguments to (accessory's stringValue) as text
return {button:item response of buttonList, answer:answer of arguments} -- returns a record: {button:(button title), answer:(text field value, or 'missing value' if not used)}
end showAlert
to setButtons for alert from buttons -- set buttons for the alert - filters for blanks and duplicates; returns a list of the button titles (left-to-right)
set {buttonList, theButton} to {{}, missing value}
repeat with aButton in reverse of (buttons as list) -- match dialog order
set aButton to aButton as text
if aButton is not in buttonList and aButton is not in {missing value, ""} then -- filter
set theButton to (alert's addButtonWithTitle:aButton)
set end of buttonList to aButton
end if
end repeat
if buttonList is {} then -- better have at least one
set theButton to alert's addButtonWithTitle:"OK"
set end of buttonList to "OK"
end if
set alert's |window|()'s initialFirstResponder to theButton -- the last (leftmost) one
return buttonList
end setButtons
to makeComboAccessory for alert -- make and return a comboBox accessory view for the alert
tell (current application's NSComboBox's alloc's initWithFrame:{{0, 0}, {288, 28}})
set its completes to true
set its hasVerticalScroller to true
set its placeholderString to "a disk identifier, for example disk0" -- arbitrary
repeat with anItem in identifiers -- populate the combo box with the disks with EFI partitions
set here to offset of "s" in (reverse of characters of anItem) as text
set anItem to text 1 thru -(here + 1) of anItem -- strip off partition
(its addItemWithObjectValue:anItem)
end repeat
set alert's accessoryView to it
return it
end tell
end makeComboAccessory
to checkID(diskID) -- check the disk identifier against the EFI partitions - returns the EFI partition, or missing value if not found
if diskID is not "" then repeat with anItem in identifiers
set anItem to anItem as text
set here to offset of "s" in (reverse of characters of anItem) as text -- partition index
if text 1 thru -(here + 1) of anItem is first word of diskID then return anItem
end repeat
return missing value
end checkID
to trimWhitespace(someText) -- trim whitespace characters from the beginning and end of a string
set someText to someText as text
if someText is "" then return ""
set whiteSpace to {space, tab, return, linefeed}
repeat until the first character of someText is not in whiteSpace
if (count someText) is 1 then return ""
set someText to text 2 thru -1 of someText
end repeat
repeat until the last character of someText is not in whiteSpace
if (count someText) is 1 then return ""
set someText to text 1 thru -2 of someText
end repeat
return someText
end trimWhitespace
to setup() -- set up properties and stuff
set {theDisks, identifiers} to {"", {}}
try
repeat with aPartition in paragraphs of (do shell script "diskutil list | grep 'EFI EFI' | grep -E -o 'disk[0-9]?[0-9]s[0-9]?[0-9]'") -- just EFI partitions named EFI
set aDisk to first paragraph of (do shell script "diskutil list " & aPartition)
if aDisk does not contain "disk image" then -- don't add disk images
set diskName to (do shell script "diskutil info " & text 1 thru -3 of aPartition & " | grep 'Media Name' | awk '{print substr($0,index($0,$5))}'")
if diskName is in {"", missing value} then
set diskName to ""
else
set diskName to "(" & diskName & ")"
end if
set theDisks to theDisks & tab & text 1 thru 11 of aDisk & space & diskName & return
set end of my identifiers to aPartition
end if
end repeat
if (count identifiers) < 1 then error "No EFI partitions were found."
return theDisks -- returns the disks found with EFI partitions (for the initial dialog)
on error errmess
log errmess
showAlert given settings:{title:"EFI [un]Mounter", message:return & errmess, icon:(resources & "AlertStopIcon.icns")}
error number -128
end try
end setup
Am writing Applescript to take a list of folders, compress them to .zip files, and transfer the spotlight comment and label from the folder to the new file.
Thank you to CRGreen for the suggestion. Here is the final script.
on run {input, parameters}
tell application "Finder"
set theItems to selection
repeat with i from 1 to (count of theItems)
set theItem to (item i of theItems) as alias
set itemPath to quoted form of POSIX path of theItem
set theParent to POSIX path of (container of theItem as alias)
set fileName to theParent & (name of theItem) & ".zip"
set zipFile to quoted form of fileName
do shell script "zip -jr " & zipFile & " " & itemPath
do shell script "setfile -a E " & zipFile
set newItem to POSIX file fileName as alias
set comment of newItem to (get comment of theItem)
set label index of newItem to (get label index of theItem)
set oldFolder to quoted form of (theParent & name of theItem)
do shell script "rm -rf " & oldFolder
end repeat
end tell
return input
end run
The magic of parentheses! (and alias coercion):
set comment of ((POSIX file newItem) as alias) to theComment
set label index of ((POSIX file newItem) as alias) to theLabel
Working on a script that downloads files and places them in a folder for for automated installation. This is the first time I've created an "on" sub-routine and I'm having issues with resolving the path to check if the file exists. The process uses a Terminal window to monitor the download status.
set theContentPath to POSIX path of (choose folder)
set toInstall to (theContentPath & "ToInstall/")
set inStalled to (theContentPath & "Installed/")
set theTemp to (theContentPath & "theTemp/")
do shell script "mkdir -p " & quoted form of toInstall
do shell script "mkdir -p " & quoted form of inStalled
do shell script "mkdir -p " & quoted form of theTemp
set theList to {"http://url1.pkg",
"http://url2.pkg",
"http://url3.pkg",
"http://url4.pkg",
"http://url5.pkg",
"http://url6.pkg"}
repeat with x from 1 to (count theList)
--display dialog item x of theList
set thisOne to item x of theList
getFileIfNeeded(thisOne, toInstall, theTemp)
end repeat
on getFileIfNeeded(theFileToGet, whereToSave, tempFiles)
set AppleScript's text item delimiters to "/"
set theItems to text items of theFileToGet
set theFile to item 5 of theItems
set theFileCheck to whereToSave & theFile
set theURL to quoted form of theFileToGet
tell application "Finder"
if not (exists file theFileCheck) then
tell application "Terminal"
if (count of windows) is 0 then
activate
end if
do script "cd " & quoted form of tempFiles & " ; curl -O " & theURL in front window
do script "mv " & quoted form of tempFiles & "*.pkg " & quoted form of whereToSave in front window
end tell
end if
end tell
end getFileIfNeeded
Tried adding the following set theFileCheck2 to (POSIX file theFileCheck) as string but the results are not what I expected as the file still get's downloaded.
Here's the routine with my attempt to get the path right.
on getFileIfNeeded(theFileToGet, whereToSave, tempFiles)
set AppleScript's text item delimiters to "/"
set theItems to text items of theFileToGet
set theFile to item 5 of theItems
set theFileCheck to whereToSave & theFile
set theURL to quoted form of theFileToGet
tell application "Finder"
set theFileCheck2 to (POSIX file theFileCheck) as string
if not (exists file theFileCheck2) then
tell application "Terminal"
if (count of windows) is 0 then
activate
end if
do script "cd " & quoted form of tempFiles & " ; curl -O " & theURL in front window
do script "mv " & quoted form of tempFiles & "*.pkg " & quoted form of whereToSave in front window
end tell
end if
end tell
end getFileIfNeeded
This should fix it.
It targets "System Events" instead of "Finder", a lot of the functionality previously in the Finders dictionary has been shifted to System Events over the last several years.
Also i simplified the part that extracts theFile, you can use the 'last' keyword in this case instead of a hard coded number.
on getFileIfNeeded(theFileToGet, whereToSave, tempFiles)
set AppleScript's text item delimiters to "/"
set theFile to the last text item of theFileToGet
set theFileCheck to whereToSave & theFile
set theURL to quoted form of theFileToGet
tell application "System Events"
if not (exists file theFileCheck) then
tell application "Terminal"
if (count of windows) is 0 then
activate
end if
do script "cd " & quoted form of tempFiles & " ; curl -O " & theURL in front window
do script "mv " & quoted form of tempFiles & "*.pkg " & quoted form of whereToSave in front window
end tell
end if
end tell
end getFileIfNeeded
I have multiple folders with sub folders that have files in them that need to be labeled with their parent folder+grandparent folder name.
i.e. Folder 1>Folder 2>File.jpg needs to be renamed to Folder_1_Folder_2_File.jpg
I was able to find a script that somewhat does it, and have been trying to reverse engineer it, but am not having any luck. The script below presents two challenges, 1) It includes the entire path from the root directory, and two, it deletes the name of the file, therefore only allowing one file to be renamed before it errors out. I know that the problem is that the script is renaming the entire file, I just don't know how to proceed.
tell application "Finder"
set a to every folder of (choose folder)
repeat with aa in a
set Base_Name to my MakeBase(aa as string)
set all_files to (every file in aa)
repeat with ff in all_files
set ff's name to (Base_Name & "." & (ff's name extension))
end repeat
end repeat
end tell
to MakeBase(txt)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to ":"
set new_Name_Raw to every text item of txt
set AppleScript's text item delimiters to "_"
set final_Name to every text item of new_Name_Raw as text
set AppleScript's text item delimiters to astid
return final_Name
end MakeBase
Thank you!
tell application "Finder"
repeat with theItem in (the selection as list)
set theItem's name to (theItem's container's container's name) & "_" & (theItem's container's name) & "_" & (theItem's name)
end repeat
end tell
If you want to learn how AppleScript can work with an app, look through the app's dictionary of AppleScript commands (AppleScript Editor > File > Open Dictionary...).
Edit 1
Here's a version in which you select the "grandparent folder" containing folders containing the items to rename:
tell application "Finder"
set itemsToRename to {}
set selectedFolders to (the selection as list)
repeat with selectedFolder in selectedFolders
set childFolders to every item of selectedFolder
repeat with childFolder in childFolders
set grandchildItems to every item of childFolder
set itemsToRename to itemsToRename & grandchildItems
end repeat
end repeat
repeat with theItem in itemsToRename
set theItem's name to (theItem's container's container's name) & "_" & (theItem's container's name) & "_" & (theItem's name)
end repeat
end tell
Try:
set myFolder to do shell script "sed 's/\\/$//' <<< " & quoted form of POSIX path of (choose folder)
set myFiles to paragraphs of (do shell script "find " & quoted form of myFolder & " \\! -name \".*\" -type f -maxdepth 2 -mindepth 2")
repeat with aFile in myFiles
tell application "System Events" to set file aFile's name to (do shell script "sed 's/.*\\/\\([^/]*\\)\\/\\([^/]*\\)\\/\\([^/]*$\\)/\\1_\\2_\\3/' <<< " & quoted form of aFile)
end repeat
)
I want to write an apple-script which collect the color profile of an image.. can anyone please help me out how to do this? I've no idea!!
Thanks in advance.
I like using ExifTool by Phil Harvey to extract metadata. Here is a service I wrote to access the metadata quickly.
on run {input, parameters}
-- creates a metadata folder in the Documents folder to store results
set thePath to POSIX path of (path to documents folder) & "metadata" & "/"
do shell script "mkdir -p " & quoted form of POSIX path of thePath
set {inputFiles, outputFiles} to {{}, {}}
repeat with anItem in input
set end of inputFiles to quoted form of POSIX path of (anItem as text)
tell application "Finder" to set {name:fileName, name extension:nameExtension} to anItem
set baseName to text 1 thru ((get offset of "." & nameExtension in fileName) - 1) of fileName
set end of outputFiles to quoted form of (thePath & baseName & ".txt")
end repeat
set {TID, text item delimiters} to {text item delimiters, space}
set {inputFiles, outputFiles} to {(inputFiles as text), (outputFiles as text)}
set text item delimiters to TID
do shell script "exiftool -a " & inputFiles & " -w " & quoted form of (thePath & "%f.txt" as text) & "; open " & outputFiles
end run