Changing how files are sorted in Finder - applescript

I have the following simple script:
tell application "Finder"
activate
set sort column of list view options of Finder window 1 to size column
end tell
I get no errors but nothing happens, the files in the window remain sorted by modification date. The result says: size column.

Related

Hide duplicate files in macOS search results?

I don't want to delete duplicate files, but I only want to see one instance of each.
Prioritization among duplicates doesn't matter in this case.
///
The actual scenario:
I want to create a VLC playlist containing every video I have ever downloaded from a particular domain. The files are not well-organized and many exist in more than one location on my computer. Consequently, a Finder search for "Where from" --> [the domain] returns many duplicate files. Which means I can't just drag and drop the search results into VLC without there being many duplicates.
I don't want to deduplicate the files themselves.
How can I make this happen?
It is not possible to hide duplicates in the Finder search because there is no option for filtering duplicates in the Finder search.
But your job is to search, then create a playlist. This can be done by dragging and dropping your selection onto the next droplet, which you can call "VLC Playlist Creator". (Or turn it into a "Make VLC Playlist" service using Automator). It will filter for you the duplicates and open Save Playlist Dialog of VLC.app.
on open theAliases
set {namesList, moviesList} to {{}, {}}
repeat with i from 1 to count theAliases
set anAlias to item i of theAliases
tell application "Finder" to set theName to name of anAlias
if not (namesList contains theName) then
set end of namesList to theName
set end of moviesList to anAlias
end if
end repeat
-- try to restart "VLC" to clear old playlist
if running of application "VLC" then quit application "VLC"
repeat while running of application "VLC"
delay 0.1
end repeat
-- add movies to playlist
tell application "VLC"
open moviesList
stop
activate
end tell
-- save playlist dialog
tell application "System Events" to keystroke "s" using command down
tell application "VLC" to activate
end open

Selecting files in a sorted list via Applescript in Automator

I have a bunch of files within a folder that I'd like to periodically delete the oldest 3 files in it. The problem is I can't rely on "creation date" or "last modified date" on these files (long story). These files all have the same name with appended timestamps -- xxxxx 2019-08-29-_01-37.sparsebundle
I've created Automator steps as shown
here.
Now after the "Sort Finder Items" step, how do I use Applescript to select and delete the bottom 2 or 3 files?
Any help would be much appreciated.
To move to the Trash, or permanently delete, the last three items in the list returned from the Sort Finder Items action, add a Run Apple Script action with the following example AppleScript code:
on run {input, parameters}
try
repeat with i in items -3 thru -1 of input
# To move to Trash, use Finder.
-- tell application "Finder" to delete alias (i as text)
# To permanently delete, use System Events.
-- tell application "System Events" to delete alias (i as text)
end repeat
end try
end run
Remove the -- from in front of the tell application ... statement for which action you wish to take.
If you only want to work with the last two items in the list then change -3 to -2 in: repeat with i in items -3 thru -1 of input
Note that this example AppleScript code worked for me in macOS High Sierra.
Note: The example AppleScript code is just that and does not contain any aditional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors.

Move all files / folder within SmartFinderFolder to destination w/ serial / single consecutive operation with AppleScript MacOS Serria

Objective: Move all files and files in folders to destination folder and maintain the file structure [files and named folders]. Important for music files in albums.
Functional: Move all listed files in SmartFolder [named] to destinationFolder with serial / consecutive move operation and maintain the same file structure and copy of dataFiles listed in SmartFolder.
Key: All files were obtained for transfer. Normal CMD + A, CMD + C, CMD + V hangs up the computer and the transfer does not initiate. The AppleScript to move each dataObject to destinationPath is all.
Facts: How to reference objects [files, folders] and their proper reference format and accepted path syntax; path or POSIX, and use of alias. Basic operations. I ran an AppleScript to move filePath to pathDestination, and was otherwise successful, and would be nice to known the formalization syntax for path reference.
tell application "Finder"
move allFiles to destinationFolder
// recursive/repeat code to loop through all listed files and folder
end tell
Reference: Applescript, show all files with tag
[Moving / selecting listed files from 'smartfolder' containers as active windows and displayLists. It was an alt. solution since AppleScript will not reference the SmartFolder as an object, nor will it dynamically call the listProperty of the SmartFolder object unless called by an unknown or un-reference method or command.
Since your main issue, as far as I can tell, seems to be dealing with SmartFolders in AppleScript, which—as you said—cannot be referenced as folder objects, this little snippet might be of help:
set SmartFolder to "/Users/CK/My Smart Folder.savedSearch"
tell application "System Events" to get value of property list file SmartFolder
set {[Scope], Query} to {SearchScopes, RawQuery} of RawQueryDict of result
set AppleScript's text item delimiters to tab
set Command to {"mdfind -onlyin", ¬
quoted form of Scope as text, ¬
quoted form of Query as text} as text
set SearchResults to paragraphs of (do shell script Command)
--> returns a list of posix files
--> e.g. {"/Users/CK/Downloads/This is file one.txt", ...}
This will return a list of POSIX paths to files that match the search criteria.
I would recommend using System Events rather than Finder to deal with large numbers of files. It can also handle posix paths without the need to manually coerce them into aliases or whatever. So, given a posix path, such as the ones returned in the list using the above code snippet, you simply do this:
set myfile to item 1 of SearchResults
tell application "System Events" to move myfile to "/Users/CK/Desktop"
Without knowing more details of what your smart folder contains (since some searches could easily return a folder plus the contents of that folder, which you'd have to bear in mind when getting your AppleScript to recurse through the search results), I can't give you more than that. But, you said your main problems were being unable to handle SmartFolders and not knowing how to reference files/folders.
This works for me using the latest version of Sierra.
Set the value of property moveToNewFolderto the destination folder of your choice
This script creates a "Choose From List" Dialog, allowing you to choose any smart folder which resides on your system. It will then move all of these files and folders in the chosen smart folder, to your set destination folder.
property savedSearches : (path to home folder as string) & "Library" & ":Saved Searches"
property savedSearchesSubFolders : {}
property namesOfSavedSearchesSubFolders : {}
property selectedSearchFolder : ""
property selectedSearchFolderPath : missing value
property moveTheseItems : missing value
property moveToNewFolder : (path to desktop as text) & "untitled folder" -- change this value to your preferred destination folder
tell application "Finder"
activate
delay 0.1 -- may need to adjust delay time value
open savedSearches
delay 0.1 -- may need to adjust delay time value
reveal savedSearches
delay 0.1 -- may need to adjust delay time value
select savedSearches
delay 0.1 -- may need to adjust delay time value
set current view of Finder window 1 to column view
delay 0.1 -- may need to adjust delay time value
tell its Finder window (POSIX path of savedSearches)
delay 0.1 -- may need to adjust delay time value
set savedSearchesSubFolders to items
set namesOfSavedSearchesSubFolders to name of items
-- Allows to choose any smart folder from a list of all smart folders
set selectedSearchFolder to choose from list namesOfSavedSearchesSubFolders ¬
with title ¬
"Smart Search Folders" with prompt ¬
"Choose Your Folder" OK button name ¬
"OK" cancel button name "CANCEL"
set selectedSearchFolder to selectedSearchFolder as text
set selectedSearchFolderPath to savedSearches & ":" & selectedSearchFolder
set selectedSearchFolderPath to selectedSearchFolderPath as string
end tell
delay 0.2 -- may need to adjust delay time value
select selectedSearchFolderPath
tell Finder window 1
set defaultView to current view
set current view to list view
delay 0.1 -- may need to adjust delay time value
set current view to defaultView
delay 0.5 -- may need to adjust delay time value
tell application "System Events"
key code 0 using command down
end tell
end tell
set moveTheseItems to selection
end tell
tell application "Finder"
set resultObject to move moveTheseItems ¬
to moveToNewFolder ¬
with replacing
end tell

How to apply a verb to every item in an AppleScript reference? (Specifically, Microsoft Excel)

In Microsoft Excel, I'm trying to use AppleScript to hide a bunch of rows that match a simple query: if the value of column F is 0.0. I have it working, but the script has to loop through each match to hide it, which is slower – and less elegant – than I'd like:
tell application "Microsoft Excel"
tell used range of active sheet of active workbook
set row_references to ((every row whose value of cell 6 is 0.0))
repeat with current_row in row_references
set hidden of entire row of current_row to true
end repeat
end tell
end tell
What I would really like, is if I could hide each row just using one Apple Event:
tell application "Microsoft Excel"
tell used range of active sheet of active workbook
set hidden of (entire row of (every row whose value of cell 6 is 0.0)) to true
end tell
end tell
… but this throws an error: "Can’t set hidden of entire row of every row of used range of active sheet of active workbook whose value of cell 6 = 0.0 to true."
If I used the "delete" verb, I can do something close to what I'm after:
tell application "Microsoft Excel"
tell used range of active sheet of active workbook
delete (every row whose value of cell 6 is 0.0)
end tell
end tell
This just deletes every matching row in one fell swoop, no looping required.
(Note that I had to use the "entire row" reference in the first two examples, because the "hidden" property will only work if you specify an entire row or column as a range. The delete command doesn't have this requirement.)
So my question is: is what I'm trying to do even possible? Why does the "delete" verb work with no problems, but it doesn't seem to like "set"?
Thanks.

Applescript: Get absolute path of item in a File > Open window

I'm trying to automate JPEGmini which is not entirely scriptable - the only way to control it is via the "Open" dialog.
Repeatedly calling it once per image is extremely slow.
Instead I'm trying to to perform a search for .jpg or .jpeg files in the "Open" dialog, so that within that result set I can select the batch of files I want to process and open them in a single pass.
(More detail after the code example)
-- later within the search results list I get, I want to select these
set filesToSelect to {"/Users/me/Desktop/photo.jpg", "/Users/me/Documents/image.jpeg"}
-- the actual app is JPEGmini but the same principle applies to Preview
tell application "Preview"
-- start the app
activate
-- let it boot up
delay 3
-- ensure it still has focus
activate
end tell
tell application "System Events"
tell process "Preview"
-- spawn "Open" window
keystroke "o" using {command down}
delay 1
-- spawn "Go to" window
keystroke "g" using {command down, shift down}
delay 1
-- Go to root of hard drive
keystroke "/"
keystroke return
delay 1
-- Perform search
keystroke "f" using {command down}
delay 1
keystroke ".jpg OR .jpeg"
keystroke return
end tell
end tell
Having done the above, how do I access the list of search results, repeat over each item and get it's absolute file path?
I've tried a few variations but am getting nowhere.
Thanks for your time.
You could simplify this by using cross between the shell command line and applescript.
set jpegSearch to paragraphs of (do shell script "mdfind -onlyin / 'kMDItemContentType == \"public.jpeg\" '")
The mdfind command
consults the central metadata store and returns a list
of files that match the given metadata query. The query can be a string
or a query expression.
AFAIK this is what spotlight uses.
mdfind documents will give you an idea of how this command works. But ths script searches only in "/" and looks for content type attribute that is public.jpeg
The return is text. A list of POSIX Paths of the matching files. This text is like a text document each path on a new line but in effect one item as far as Applescript is concerned.
They need to be broken up in a applescript list. So I do this by asking for the paragraphs of the result.
Also if you want to open a new finder window:
try something like:
tell application "Finder"
activate
set myWindow to make new Finder window to startup disk
end tell
To answer why you are getting your error in trying to get the POSIX paths of the target of the files.
If you look at the properties of one of the files returned in your Search Window.
tell application "Finder" to set fileList to properties of first file of front window
You will see the file properties have a property named original item
If you really want to do it the way you are doing it then one way is to get the original item. Coerce the result into alias form then get the posix path.
tell application "Finder" to set aFile to POSIX path of (original item of first file of front window as alias)
In a normal finder window you can use.
tell application "Finder" to set fileList to POSIX path of (first file of front window as alias)
These are just examples to show you whats going on.
The difference in the type of finder window results is because in a Search window what is being displayed is alias files (class:alias file) to the original files, hence the original item property.
Update 2.
To go through your items in your list and check them against another list is simple.
Apple have some tools that will help you with the code.
When in your script.
crtl + Mouse Click the Variable that will hold the jpg result as a list.
This will give you a contextual menu that contains helper code.
Go to the Repeat routines folder in the menu.
Then to its 'Process Every Item'
This will add a repeat routine to your code.
And from there you can use it to check each item against your other list.
set yourOtherList to {"/Library/Desktop Pictures/Abstract/Abstract 2.jpg", "/Library/Desktop Pictures/Abstract/Abstract 1.jpg"}
set jpegSearch to paragraphs of (do shell script "mdfind -onlyin / 'kMDItemContentType == \"public.jpeg\" '")
repeat with i from 1 to number of items in jpegSearch
set this_item to item i of jpegSearch
if this_item is in yourOtherList then
-- do something
log this_item
end if
end repeat
The repeat routine works like this.
It loops over each item in the given list
It will iterate from item 1 to the count of the items in the list.
The i variable holds the loop iteration number. I.e it will be 1 on the first loop and 300 on the 300th loop.
so on the first loop set this_item to item i of jpegSearch is equivalent to writing set this_item to item 1 of jpegSearch
But apple saves you having to write each number of each item with the Repeat with i..
The variable i can be any word or letter you choose that conforms to the normal allowed Variable naming syntax.
Something you can do is build a new list from the matched items. by copying them into a previously declared list. You can then work on that list after the repeat loop has completed.
Here bigList is declared as a empty list {}
The matched items are copied to the bigList. Each new item it receives is added to the end of the list.
set bigList to {}
set yourOtherList to {"/Library/Desktop Pictures/Abstract/Abstract 2.jpg", "/Library/Desktop Pictures/Abstract/Abstract 1.jpg"}
set jpegSearch to paragraphs of (do shell script "mdfind -onlyin / 'kMDItemContentType == \"public.jpeg\" '")
repeat with i from 1 to number of items in jpegSearch
set this_item to item i of jpegSearch
if this_item is in yourOtherList then
copy this_item to end of bigList
end if
end repeat
bigList

Resources