I am a pretty good applescripter, and would like some help with this. I am making a recycle bin application, similar to that of the Windows XP Recycle Bin. It is of course a droplet. When I drop items onto the application, the application starts a subroutine designed to check whether the size limit of the Recycle Bin (Trash) was exceeded. However, when I try to get the info for the items in the Trash, the error message that comes up is: "Finder got an error. File item 1 wasn't found." I really need help :(
The subroutine is below:
on check()
tell application "Finder"
set the total_size to 0
set the trash_items to get every item in trash
if the trash_items is not {} then
repeat with i from 1 to the count of items in trash
set this_info to get info for item i of trash --ERROR ON THIS LINE
set the total_size to the total_size + (size of this_info)
end repeat
try
set the second_value to the free_space / (RBPFMS / 100)
if the total_size is greater than the second_value then
display alert "Size Limit Exceeded" message "The Recycle Bin cannot receive any more items because it can only use " & RBPFMS as string & " of your hard drive." buttons {"OK"} default button 1
return false
else
return true
end if
on error
set RBP to ((path to startup disk) as string) & "Recycle Bin Properties"
display dialog "Error: You have modified the properties file for the Recycle Bin. Do not modify the properties file. It is there to store information that is used to determine the properties for the Recycle Bin." with title "Property File Modified" with icon 0 buttons {"OK"} default button 1
set the name of RBP to "DELETE ME"
error number -128
end try
end if
end tell
end check
The error is caused by the expression info for item i of trash. The subexpression item i of trash returns a (Finder) item object. The info for command however requires an alias or file reference to the file (see AppleScript language guide).
There are two ways to fix the expression. Explicitly cast the item to an alias, i.e.:
repeat with i from 1 to the (count of items) in trash
set this_info to get info for (item i of trash as alias)
set the total_size to the total_size + (size of this_info)
end repeat
Or instead of using the info for command, simply use the Finder item's size property:
repeat with i from 1 to the (count of items) in trash
set the total_size to the total_size + (size of item i)
end repeat
Be sure to have both RBPFMS and free_space declared as global variables in the check function:
on check()
global RBPFMS
global free_space
...
end
Another bug: put parentheses around RBPFMS as string in the display alert statement:
display alert "Size Limit Exceeded" message "The Recycle Bin cannot receive any more items because it can only use " & (RBPFMS as string) & " of your hard drive." buttons {"OK"} default button 1
when I try to call the subroutine, it errors "Can't continue check."
The call needs a "my" in front of "check()".
Telling the Finder to call its "check" subroutine won't work. The Finder will tell you that it doesn't know how to "check". The words it will use are "Finder can't continue check." But you can tell the Finder to call your locally-defined "check" subroutine. You simply prefix my to "check" when you call the subroutine. You need to do this every time you call your own subroutine from inside a tell block.
Related
I've been struggling to try and figure out an Automator workflow or Applescript that can accomplish this task.
I want to:
Target a folder with hundreds of subfolders with numeric names (i.e. 00000001, 00000002, 00000003, etc.)
Filter to return only folders that DO NOT already contain files within them (either by size or by number of files, etc.)
Sort by name, Ascending
Select top result (lowest number folder name that doesn't already contain files) and set the folder path as a variable so it can be the next folder the workflow adds files to
Any ideas on how to accomplish this? Thanks!
Most of your requirements will be addressed automatically since you're dealing with file objects rather than text strings, e.g. sorting will occur naturally.
The script begins by designating the parent folder as an alias and then gets its items whose filenames begin with '00000' as a list. If the number of folders increases, eventually you may need to reduce that to four zeros. Needless to say, there shouldn't be non-folder items here with such a filename.
It then cycles through this list, getting the count of disk items within each folder. Based on that number, the name is added to either the empty or non-empty list, and optionally, the folder has its label colour changed to make it visibly obvious.
Finally, it grabs the first item from the list as the next folder up. Obviously, the next time you run it, that item will instead be added to the non-empty list.
tell application "System Events"
set pdk to (path to desktop) & "repo" as text as alias
set fList to disk items of pdk whose name begins with "00000"
set emptyList to {} -- empty folder list
set nonList to {} -- non-empty folder list
repeat with x in fList
set cx to contents of x
set acx to (get path of cx) as alias -- use to change label
if (count of (disk items of cx)) is greater than 0 then -- non-empty
set end of nonList to name of x
tell application "Finder" to set label index of acx to 3
else -- empty
set end of emptyList to name of x
tell application "Finder" to set label index of acx to 0
end if
end repeat
set nextUp to pdk & item 1 of emptyList as text
end tell
So I'm a novice with AppleScript but learning a lot. I'm trying to create an AppleScript to let me know when Apple Compressor is finished encoding and notify me if it was successful or not. I have the part down about telling when compressor is done and the notification but having difficulty getting the file name and status (complete/fail/cancelled) from Compressor's history log.
Originally tried with UI scripting, but Compressor's window hierarchy list changes with every new encode. So now onto pulling it from the history log, which is in the user folder "Library/Application Support/" folder like this:
And then, the file itself contains the status (whether it was successful or failed) near the bottom of the file like this:
So getting confused about how to A) find the last file and its name, and B) get the value of the last "ElementStatusState" in the document.
This is where I started but get errors when trying to resolve the path to the folder:
tell application "Finder"
set latestFile to (last item of (sort (get files in folder "~/Library/Application Support/Compressor/History/V4" of application "System Events") by name)) as text
set fileName to latestFile's name
end tell
This code throws an error about not being able to make it into the expected file type but also, I can see that It's grabbing a file that's not the last one modified.
In the end I want 2 variables that are 1) theFileName = ie name of encoded movie(s), and 2) theStatus = ie number 4,5, or 6)
Any ideas out there?
You'll want to do something like the script below. This script finds the most recently modified file, then drills down through the plist file to find the various status numbers, and the names of the records they are logged in. I'm assuming that every file Compressor generates has the same structure; if not, you may find you have to alter the script. But this should give you an idea how to do that.
Names and status values are stored in the nameList and valueList variables, in order of depth.
set filePath to POSIX file "~/Library/Application Support/Compressor/History/V4"
-- sort the file list by modification date, then get the last item.
tell application "Finder"
set mostRecentFile to last item of (sort files of folder filePath by modification date) as alias
end tell
set mostRecentFilePath to POSIX path of mostRecentFile
set nameList to {}
set valueList to {}
tell application "System Events"
set plistFile to property list file mostRecentFilePath
tell plistFile
tell (first property list item whose kind is record)
copy value of property list item "ElementInfoName" to end of nameList
copy value of property list item "ElementStatusState" to end of valueList
tell (first property list item whose kind is list)
tell (first property list item whose kind is record)
copy value of property list item "ElementInfoName" to end of nameList
copy value of property list item "ElementStatusState" to end of valueList
tell (first property list item whose kind is list)
tell (first property list item whose kind is record)
copy value of property list item "ElementInfoName" to end of nameList
copy value of property list item "ElementStatusState" to end of valueList
end tell
end tell
end tell
end tell
end tell
end tell
end tell
Okay i want to check to see if the "user" has entered a number above 10, but i do not know where to put it or how to do it.
set volume 10
say "Hello and Welcome to Tyler's Spam Bot"
set amount to text returned of (display dialog "How many times?" default answer "More than 10")
repeat amount times
tell application "Finder" to make new Finder window
if amount comes before 10 then
return true
else
return false
end if
end repeat
Check if the value can be converted to an integer using a try/on error block. If it can, continue, and ask if the number is greater than 10; if so, perform your action.
set received_integer to "False"
repeat while received_integer is not "True"
set amount to text returned of (display dialog "How many times?" default answer "More than 10")
try
set amt_as_int to amount as integer
if amt_as_int ≥ 10 then
set received_integer to "True"
repeat amt_as_int times
tell application "Finder" to make new Finder window
end repeat
end if
end try
end repeat
I was wondering how to return just the file extension from a string. I've tried the 'set variable to name extension of...' detailed in this question, but that only seems to work for recognized extensions. The idea is to sort files with the extension '.meta' into their own collection.
What I have now looks like
tell application "Finder'
set everyName to name of every item in entire contents of this_folder
end tell
set metaFiles to {}
repeat with n from 1 to count of everyName
set currentName to item n of everyName
set currentExt to last word of currentName --this assignment fails
if currentExt is "meta" then
set end of metaFiles to currentExt
end if
end repeat
I'm brand new to applescript so I appreciate any and all help/direction. Thanks!
Edit: Hacky Solution
I solved this by using the split function described here to break up the filename after every period. I grabbed the last string, made sure it wasn't the same as the first string in case there were no period characters, and then stored the corresponding filename.
The name includes the file extension, whether the Finder recognizes it or not. So just sort on the name like this...
tell application "Finder"
set metaFiles to (every item in entire contents of this_folder whose name ends with "meta") as alias list
end tell
If you aren't getting a name extension, make sure there actually is one and that you aren't looking at the end of the name. If you are going to be moving files around, you will also need to get the path, and not just the name. I don't think that making a list of your extensions is what you are going for, either - several different characters are used for word boundaries, but a period isn't one of them.
Why not just ask Finder for your file items?
tell application "Finder"
set metaFiles to (every item in entire contents of this_folder whose name extension is "meta") as alias list
end tell
I am building a Applescript droplet to automate some stuff. I have the following line:
tell application "Finder" to duplicate dropped
Dropped being a reference to the file that was dropped on the droplet. The documentation says that this returns a reference to the duplicated object.
I want to set myVariable to the reference that is returned but I can't find in any of the documentation how to actually do that!
if it's a droplet, be aware that the parameter is a list of aliases (you can drag more than one file!), and that if you duplicate a single finder item you will get a finder item, whereas if you duplicate more than one finder item, you will get a list of finder items. i.e. the return value of duplicate depends on the parameters sent to it.
AND... finder items are not very useful outside the finder. You'd be better off with aliases or POSIX paths.
So you probably need something like
on open (dropped)
tell application "Finder"
set duplicate_Finder_items to duplicate dropped
end tell
-- convert the Finder reference for each duplicate item to an AppleScript alias
set duplicate_item_aliases to {}
if class of duplicate_Finder_items is list then
repeat with i from 1 to number of items of duplicate_Finder_items
set the end of duplicate_item_aliases to (item i of duplicate_Finder_items) as alias
end repeat
else -- result was a single Finder item, not a list
set duplicate_item_aliases to {duplicate_Finder_items as alias}
end if
repeat with f in duplicate_item_aliases
set inf to (info for (f as alias))
set n to name of inf
display dialog "You duplicated a file. The duplicate is now known as " & n
end repeat
end open
The duplicate command allows for a location to be specified:
set theResult to duplicate reference ¬
to insertion location ¬
replacing boolean ¬
routing suppressed boolean
Parameter, Required, Type, Description
direct parameter, required, reference, the object(s) to duplicate
replacing, optional, boolean, Specifies whether or not to replace items in the destination that have the same name as items being duplicated
routing suppressed, optional, boolean, Specifies whether or not to autoroute items (default is false). Only applies when copying to the system folder.
to, optional, insertion location, the new location for the object(s)