I'm computing some data in AppleScript that I'd like to then insert into a specific FileMaker record. Here's my AppleScript:
on sendDataToFM(FileNameWithExtension, ClipLength)
tell application "FileMaker Pro Advanced"
show every record of database 1
show (every record whose cell "File Name" = FileNameWithExtension)
repeat with i from 1 to (count record)
set MatchingRecord to record i
set data cell "CLIP LENGTH" of MatchingRecord to ClipLength
end repeat
end tell
end sendDataToFM
...
my sendDataToFM('Some Video.mov', '00:01:22.55')
Everything works except the line
set data cell "CLIP LENGTH" of MatchingRecord to ClipLength
The error returned is
(*Can’t get cell "CLIP LENGTH" of {"Some Video.mov", ... }.*)
The script finds the right record, and the FileMaker field name is definitely "CLIP LENGTH". What am I doing wrong?
Try:
on sendDataToFM(FileNameWithExtension, ClipLength)
tell application "FileMaker Pro"
show (every record of current table whose cell "File Name" = FileNameWithExtension)
repeat with i from 1 to (count record)
set cell "CLIP LENGTH" of (record i) to ClipLength
end repeat
end tell
end sendDataToFM
my sendDataToFM("Some Video.mov", "00:01:22.55")
Related
I get the syntax error below with this script. It fails in the line beginning repeat with cell in rows. How can I get the script to compile?
Expected variable name or property but found class name.
-- Declare variables
property albumDescription : ""
-- Display input box to get album description
display dialog "Enter the album description:" default answer ""
set albumDescription to text returned of result
-- Open Excel
tell application "Microsoft Excel"
activate
end tell
-- Set variables for the active sheet and range of cells
tell application "Microsoft Excel"
set sh to active sheet
set rng to range of sh
end tell
-- Loop through each cell in the range, starting from row 2
repeat with cell in rows 2 thru (count of rows of rng) of rng
-- Check if the cell value is not empty
if value of cell is not "" then
-- Update the album description for the row
set value of cell to albumDescription
end if
end repeat
Actually there are three issues:
All terminology which belongs to a specific application (in this case rows, the content of rng and value) must be inside a tell application block.
You cannot use the reserved word cell as a variable name. Well, you can, but you have to wrap the word in pipes (|cell|). However I recommend to use a different name like aCell
range in set rng to... must be used range
-- Declare variables
property albumDescription : ""
-- Display input box to get album description
display dialog "Enter the album description:" default answer ""
set albumDescription to text returned of result
-- Open Excel
activate application "Microsoft Excel"
-- Set variables for the active sheet and range of cells
tell application "Microsoft Excel"
set sh to active sheet
set rng to used range of sh
-- Loop through each cell in the range, starting from row 2
repeat with aCell in rows 2 thru (count of rows of rng) of rng
-- Check if the cell value is not empty
if value of aCell is not "" then
-- Update the album description for the row
set value of aCell to albumDescription
end if
end repeat
end tell
Could anyone offer a way to populate my playlist with songs from a csv file/text file formatted like this:
song title,artist?
I can do it for title alone but can't specify it must have a certain artist.
EDIT: Here is an example of how I'm getting them by titles:
set TheFile to read file "Macintosh HD:Applications:Automator stuff:01b iTunes Scripts:SongList.txt"
tell application "iTunes"
set thePlaylist to playlist "SongList"
try
delete every track of thePlaylist
end try
set MySongs to paragraphs of (TheFile) -- read artist names (separated by newlines) from the file
repeat with AnItem in MySongs -- get all tracks from each artist
set AnItem to (contents of AnItem)
if AnItem is not "" then try -- don't bother with empty names
set MyTracks to (location of file tracks of playlist "Music" whose name is AnItem)
--can also modify the above from "is" to "contains" or "_begins with_"
add MyTracks to thePlaylist
on error errmess -- oopsie (not found, etc)
log errmess -- just log it
end try
end repeat
end tell
OK, figured it out! Couldn't work out how to work around titles with commas in them (which I have a few of), so I ended up using tab separating them instead. So, once I have my tab-separated file, this code did the trick:
set thisTSVFile to (choose file with prompt "Select the CSV file")
readTabSeparatedValuesFile(thisTSVFile)
set theList to readTabSeparatedValuesFile(thisTSVFile)
tell application "iTunes"
set myPlaylist to playlist "Test1"
set sourcePlaylist to playlist "Music"
end tell
repeat with i from 2 to number of items in readTabSeparatedValuesFile(thisTSVFile)
--gets first column
set theName to item 1 of item i of theList
--gets second
set theArtist to item 2 of item i of theList
tell application "iTunes"
duplicate (some track of sourcePlaylist whose name is theName and artist is theArtist) to myPlaylist
end tell
delay 0.1
end repeat
on readTabSeparatedValuesFile(thisTSVFile)
try
set dataBlob to (every paragraph of (read thisTSVFile))
set the tableData to {}
set AppleScript's text item delimiters to tab
repeat with i from 1 to the count of dataBlob
set the end of the tableData to (every text item of (item i of dataBlob))
end repeat
set AppleScript's text item delimiters to ""
return tableData
on error errorMessage number errorNumber
set AppleScript's text item delimiters to ""
error errorMessage number errorNumber
end try
end readTabSeparatedValuesFile
You can use ObjectiveC (or probably Swift too) with XCode to do the heavy lifting (parsing the files) then hit iTunes from there, although it will likely be a lot slower than running in the iTunes process through its script menu.
Here's some ObjectiveC code that gets the current track title; you can adapt the method to suit a more complicated script like populating a playlist.
+(NSString *)getTitle {
return [self runAppleScriptAndReturnResult:#"Tell application \"iTunes\" \nreturn the name of the current track\nend tell"];
}
+(NSString *)runAppleScriptAndReturnResult:(NSString*)script {
NSAppleScript *appleScript=[[NSAppleScript alloc] initWithSource:[NSString stringWithFormat:#"with timeout of 3 seconds\n%#\nend timeout\n", script]];
return [[appleScript executeAndReturnError:nil] stringValue];
}
I am brand new to Applescript. I would like a script that would list the artist and the number of songs in that artist's folder. I would like to do it just for artists whose names starts with A. When I am ready, I would then get the list for artist whose names starts with B, and so on. I did find this post: "What's the fastest way in iOS to retrieve the number of songs for a specific artist?" Maybe that script would work but I don't know how to modify this line "if (artistName != nil)" to get what I want. Also, I don't know where the information is stored so I can retreive it "// store the new count
[artists setObject:[NSNumber numberWithInt:numSongs] forKey:artistName]; Oh, and I am not using iOS I will be using osx. Perhaps I could modify this script that I found. It gets the number of albums by artist.
MPMediaQuery *albumQuery = [MPMediaQuery albumsQuery];
NSArray *albumCollection = [albumQuery collections];
NSCountedSet *artistAlbumCounter = [NSCountedSet set];
[albumCollection enumerateObjectsUsingBlock:^(MPMediaItemCollection *album, NSUInteger idx, BOOL *stop) {
NSString *artistName = [[album representativeItem] valueForProperty:MPMediaItemPropertyArtist];
[artistAlbumCounter addObject:artistName];
}];
NSLog(#"Artist Album Counted Set: %#", artistAlbumCounter);
I appreciate any help that you can offer. Thanks!
It makes no sense to look at iOS code and ObjectiveC at that in order to figure out what you should do with Applescript! In any case, here is what you want.
tell application "iTunes"
# Get playlist currently selected
set myPlayList to view of window 1
set s to (every track in myPlayList whose artist begins with "g")
repeat with t in s
log name of t
end repeat
log (count of s)
end tell
This one uses the selected playlist (or, if that fails for some reason, the whole library) and goes from A to Z. Replace the log parts with your code. To see how it works make sure in Script-Editor it shows the Log and for a better view select the Messages tab. Only file tracks are handled.
tell application "iTunes"
try
set selectedPlayList to view of window 1
on error
beep
set selectedPlayList to (container of browser window 1) -- whole library (I think)
end try
end tell
set totalItems to 0
repeat with i from (id of "A") to (id of "Z")
set thisLetter to (character id i)
log "-----------------------------------------------------------"
tell application "iTunes"
try
set currentItems to (file tracks in selectedPlayList whose artist begins with thisLetter)
set countItems to number of items in currentItems
set totalItems to totalItems + countItems
set s to "s"
if countItems = 1 then set s to ""
log (countItems as text) & " item" & s & " for artists starting with the letter " & quoted form of thisLetter
log "-----------------------------------------------------------"
repeat with i from 1 to countItems
set thisItem to item i of currentItems
tell thisItem -- this is like "tell file track x". Shortens the code because we can use "artist" instead of "artist of thisItem"
log (i as text) & ". " & quoted form of (get artist) & " | " & quoted form of (get name) & " [ " & time & " ] "
end tell
end repeat
on error the error_message number the error_number
beep
display dialog "Error: " & the error_number & ". " & the error_message buttons {"OK"} default button 1
return
end try
end tell
end repeat
log "-----------------------------------------------------------"
log "Items: " & totalItems as text
I'd like to know how you'd go about creating an action where you could highlight a group of files and get the modification date from them, then have it highlight/select/label the file with the most recent date.
UPDATE: I want to do it on Applescript because I've gotten further in that. Here's what I have so far
set dateList to {}
tell application "Finder"
set inputList to get selection
repeat with i from 1 to count (inputList)
set end of dateList to get modification date of item i of inputList
end repeat
end tell
dateList
--Compare section...
set boolList to {}
set j to 1
repeat with i from 1 to count (dateList)
if i is (count (dateList)) then
set j to 0
end if
set end of boolList to item i of dateList > item (i + j) of dateList
end repeat
boolList
Looking at your existing applescript code this should sort any files you've selected by last modified date and return the latest result into a dialog box for you:
set dateList to {}
tell application "Finder"
set inputList to get selection
repeat with i from 1 to count (inputList)
set end of dateList to get modification date of item i of inputList
end repeat
end tell
--Compare section...
set modDate to item 1 of dateList
repeat with i from 1 to count (inputList)
if dateList's item i > modDate then
set modDate to dateList's item i
set theResult to displayed name of item i of inputList
set theResultDate to item i of dateList
end if
end repeat
--Display Result…
display alert "Most recently modified file in selection:" message "" & theResult & "
" & theResultDate
Dick got it, but I just fixed something and made it so it labels the file instead of a popup.
set dateList to {}
tell application "Finder"
set inputList to get selection
repeat with i from 1 to count (inputList)
set end of dateList to get modification date of item i of inputList
end repeat
end tell
--Compare section...
set theResult to item 1 of inputList as alias
set theResultDate to item 1 of dateList
set modDate to item 1 of dateList
repeat with i from 1 to count (inputList)
if dateList's item i > modDate then
set modDate to dateList's item i
set theResult to item i of inputList as alias
set theResultDate to item i of dateList
end if
end repeat
--Display Result…
--display alert "Most recently modified file in selection:" message "" & theResult & "
--" & theResultDate
tell application "Finder" to set label index of (theResult as alias) to 6
This will label it green, if you want a different color fiddle around with the index number 1-8, they're apparently not in order. Finder is also apparently smart enough to not count the selections in other open windows.
Thanks!
And finally, to make it useful as a right-click item, open Automator, make a Service, select at the top to use this on files/folders, drag Run Applescript in there, paste script, save. Now it will be available on right click. One downside is it seems the files need to stay selected until something is labeled. So no clicking while it's working.
You are making it more complicated than it needs to be:
tell application "Finder" to reveal item 1 of (sort (get selection) by modification date)
There is a bug in 10.7 and 10.8 that can make all of the suggested scripts almost unusable depending on the way they are run. If you open a new Finder window and select some files, tell application "Finder" to selection returns files selected in some window behind the frontmost window (or an empty list).
One workaround is to switch focus to another application and back:
activate app "SystemUIServer"
tell application "Finder"
activate
set label index of item 1 of (sort selection by modification date) to 6
end tell
You could also create an Automator service with a Run AppleScript action like this:
on run {input, parameters}
tell application "Finder"
sort (input as alias list) by modification date
set label index of item 1 of result to 6
end tell
end run
I've created the following AppleScript for deleting all the selected tracks:
property okflag : false
-- check if iTunes is running
tell application "Finder"
if (get name of every process) contains "iTunes" then set okflag to true
end tell
if okflag then
tell application "iTunes"
if selection is not {} then
repeat with this_track in selection
try
try
set cla to class of this_track
set floc to (get location of this_track)
delete this_track
on error error_message number error_number
display alert error_message message ("Error number: ") & error_number & "."
end try
if cla is file track then
my delete_the_file(floc)
end if
end try
end repeat
end if
end tell
end if
to delete_the_file(floc)
try
-- tell application "Finder" to delete floc
do shell script "mv " & quoted form of POSIX path of (floc as string) & " " & quoted form of POSIX path of (path to trash as string)
on error
display dialog "Track deleted, but could not be moved to trash" buttons {"Hmm"} default button 1 with icon 1
end try
end delete_the_file
It works fine when I select a single item, but when I select more than one I get: "Can't get location of item 2 of selection" (error number -1728). I believe this is because by deleting a track, the script's index into the selection is corrupted.
I thought I'd try making my own list of tracks to be deleted first:
tell application "iTunes"
if selection is not {} then
set to_delete to {}
repeat with this_track in selection
try
set cla to class of this_track
set floc to (get location of this_track)
if cla is file track then
set pair to {this_track, floc}
set to_delete to to_delete & pair
end if
end try
end repeat
repeat with pair in to_delete
set the_track to item 1 of pair
set floc to item 2 of pair
delete the_track
my delete_the_file(floc)
end repeat
end if
end tell
But then I get 'Can't get item 1 of item 1 of selection of application "iTunes".' I think the problem is "this_track" is not an object of class Track, but an item of a selection. How do I get the actual track object from the selection item?
If you don't see the solution, I'll welcome tips on debugging or any other suggestions.
The variable this_track is a reference to an object specifier. You have to use the contents property to get the enclosed object specifier. The same is true for accessing the variable pair in the second loop. See the class reference section on the class reference in the AppleScript language guide.
Another problem exists in the way the list to_delete is being built. The statement set to_delete to to_delete & pair will not produce a list of pairs but a flat list. See the class reference section on the class list in the AppleScript language guide.
Here's a version of your second script, where these bugs have been removed:
tell application "iTunes"
if selection is not {} then
set to_delete to {}
repeat with this_track in selection
try
set cla to class of this_track
set floc to (get location of this_track)
if cla is file track then
set pair to {contents of this_track, floc}
copy pair to end of to_delete
end if
end try
end repeat
repeat with pair in to_delete
set the_track to item 1 of contents of pair
set floc to item 2 of contents of pair
delete the_track
my delete_the_file(floc)
end repeat
end if
end tell