Solved the initial issue… (May as well leave this in) What id really like to do is run a script that submits a value followed by a list whose multiple selections returned calculates a list of viable values (script already written) to be matched with the readings from the f0 tags printed to theFiles (as shown in the script below). I’d like to create a dialog/table that brings up a range of categories (labelled by tags) that each have their own row with 12 check boxes, each checkbox would correlate to one of the 12 possible f0 readings of a range. I would like to run a script that duplicated all file matches containing the specified tags (selected bu the checkbox) ordered by the category tag and copied to the category folders Any knowledge appreciated …
tell application "Finder"
set fileName to fileName as text
set currentFile to (get POSIX path of file fileName)
tell currentFile
my tagCmd(it as text)
end tell
end tell
on tagCmd(fileName)
do shell script "/usr/local/bin/tag -a " & "'" & f0 & "'" & space & fileName
I’m not sure that I understand your objective exactly but this script will check the selected files and if they do not have a file label, will tag them with the tags in f0. I find that the removing of the label index is flaky but YMMV. Substitute your own tags in f0.
Basically, it builds an alias list from the selected files and then cycles through them. If they have no label index then their path and the desired tags are fed to the tagCmd handler, where the path is converted to a posix path for the shell to run the tag command against.
set f0 to quoted form of "replacement, Blue, Reading Material"
tell application "Finder"
set fList to selection as alias list
repeat with eaFile in fList
if label index of contents of eaFile is 0 then
my tagCmd(eaFile, f0)
else
set label index of eaFile to 0
end if
end repeat
end tell
on tagCmd(eaFile, f0)
set pp to quoted form of POSIX path of eaFile
do shell script "/usr/local/bin/tag --add " & f0 & space & pp
end tagCmd
This snippet will use mdfind to find matching files on the desktop.
set f0 to quoted form of "replacement, Blue, Reading Material"
set dpath to POSIX path of (path to desktop as text)
do shell script "mdfind -onlyin " & dpath & " kMDItemUserTags == " & f0
Finally, this will put a copy of those matching files into a duplicates folder.
set f0 to quoted form of "replacement, Blue, Reading Material"
set dpath to POSIX path of (path to desktop as text)
set desto to POSIX path of (path to desktop as text) & "duplicates"
try
do shell script "mdfind -onlyin " & dpath & " kMDItemUserTags == " & f0 & " -0 | xargs -0 -J % ditto % " & desto
end try
Thanks for your reply Mockman
Ahh kMDItemUserTags yes, thanks! The f0 property is calculated by analysing a file then using a mostPopularItemInList routine from some data of a csv column, the most popular item in the list is stored then set as a tag. My file database contains over 5000 files. Do you think tagging and using mdfind would be faster than using SQLite DB’s or JSON’s for matching the attributes against file paths?
I can’t speak to your latter options but (assuming your drive is indexed) mdfind is fast and its index is updated quickly upon any file changes. If its functionality is appropriate then it would be viable (and straightforward to work with).
Not sure what I’m missing but… When using finder (get selection) I could use the “if label index is 0” and “else set label index to” but I can’t use that with set fileName to fileName as text set currentFile to (get POSIX path of file fileName) is that because its expecting a list?
Is it possible to do some kind of parallel processing (like multithreading) with this script to the entire contents of several folders concurrently?
`use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
property f0 : {}
property fileName : {}
tell application "Finder"
-- deletes previous sample files
set volume alert volume 0
delete (every item of folder "HD:Users:hm:folder:sample:" whose name extension is "wav")
delete (every item of folder "HD:Users:hm:folder:sample:" whose name extension is "csv")
delete (every item of folder "HD:Users:hm:folder:sample:" whose name contains "example")
delay 0.5
set fileName to (choose file with prompt "Please Select a WAV file for Processing")
set audioWav to fileName
-- duplicate to Audition Folder
set audio_wav to duplicate audioWav to "HD:Users:hm:folder:sample:"
set f to (the first file of ¬
container (alias "HD:Users:hm:folder:sample:") of ¬
application "Finder" whose name ends with "wav")
set ti to text items of (get name of f)
if number of ti is 1 then
set name of f to "example.wav"
else
set name of f to "example" & "." & "wav"
end if
end tell
tell application "Finder"
-- analyse file with pythons crepe and tensorflow
do shell script "/Users/hm/Library/Python/3.9/bin/crepe filename ~/folder/sample/example.wav -v -c 'full' -s '10'"
set recCsv to "/Users/hm/folder/sample/example.f0.csv"
-- read the CSV file. removing any rows in 3rd column with readings under 0.1
set my_data to read recCsv
set my_data to do shell script "awk -F ',' '$3>=0.1' " & (recCsv)'s POSIX path's quoted form
-- set my_data to do shell script "awk -F ',' '$1<=25.111' " & (recCsv)'s POSIX path's quoted form
-- set my_data to do shell script "awk '{ $2 = $2 * 2 }' " & (recCsv)'s POSIX path's quoted form
set csvData to paragraphs 2 thru -2 of my_data as list
-- reading all values in column 2 whose value from column 3 > 0.1
set freqData to {}
set oldDelims to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","
repeat with a_reading in csvData
-- averaging the value of "y" to its closest tonal value. Is there a way to make this section less convoluted?
set y to (text item 2 of a_reading)
-- set y to y as integer
if y ≥ 15.9 and y ≤ 16.8 then
set y to "C0"
else if y ≥ 16.81 and y ≤ 17.8 then
set y to "C#0"
else if y ≥ 17.81 and y ≤ 18.8 then
set y to "D0"
else if y ≥ 18.81 and y ≤ 19.9 then
set y to "D#0"
else if y ≥ 19.91 and y ≤ 21.21 then
set y to "E0"
else if y ≥ 21.22 and y ≤ 22.47 then
set y to "F0"
else if y ≥ 22.48 and y ≤ 23.8 then
set y to "F#0"
else if y ≥ 23.81 and y ≤ 25.22 then
set y to "G0"
else if y ≥ 25.23 and y ≤ 26.71 then
set y to "G#0"
else if y ≥ 26.72 and y ≤ 28.3 then
set y to "A0"
else if y ≥ 28.31 and y ≤ 29.99 then
set y to "A#0"
else if y ≥ 30.0 and y ≤ 31.78 then
set y to "B0"
else if y ≥ 31.79 and y ≤ 33.66 then
set y to "C1"
else if y ≥ 33.67 and y ≤ 35.66 then
set y to "C#1"
else if y ≥ 35.67 and y ≤ 37.78 then
set y to "D1"
else if y ≥ 37.79 and y ≤ 40.4 then
set y to "D#1"
else if y ≥ 40.41 and y ≤ 42.4 then
set y to "E1"
else if y ≥ 42.41 and y ≤ 44.93 then
set y to "F1"
else if y ≥ 44.94 and y ≤ 47.6 then
set y to "F#1"
else if y ≥ 47.61 and y ≤ 50.43 then
set y to "G1"
else if y ≥ 50.44 and y ≤ 53.43 then
set y to "G#1"
else if y ≥ 53.44 and y ≤ 56.6 then
set y to "A1"
else if y ≥ 56.61 and y ≤ 59.12 then
set y to "A#1"
else if y ≥ 59.13 and y ≤ 62.65 then
set y to "B1"
else if y ≥ 62.66 and y ≤ 66.36 then
set y to "C2"
else if y ≥ 66.37 and y ≤ 70.31 then
set y to "C#2"
else if y ≥ 70.32 and y ≤ 74.49 then
set y to "D2"
else if y ≥ 74.5 and y ≤ 78.91 then
set y to "D#2"
else if y ≥ 78.92 and y ≤ 83.61 then
set y to "E2"
else if y ≥ 83.62 and y ≤ 88.58 then
set y to "F2"
else if y ≥ 88.59 and y ≤ 93.85 then
set y to "F#2"
else if y ≥ 93.86 and y ≤ 99.43 then
set y to "G2"
else if y ≥ 99.44 and y ≤ 105.34 then
set y to "G#2"
else if y ≥ 105.35 and y ≤ 111.6 then
set y to "A2"
else if y ≥ 111.61 and y ≤ 118.24 then
set y to "A#2"
else if y ≥ 118.25 and y ≤ 125.27 then
set y to "B2"
else if y ≥ 125.28 and y ≤ 132.71 then
set y to "C3"
else if y ≥ 132.72 and y ≤ 140.61 then
set y to "C#3"
else if y ≥ 140.62 and y ≤ 145.97 then
set y to "D3"
else if y ≥ 145.98 and y ≤ 157.82 then
set y to "D#3"
else if y ≥ 157.83 and y ≤ 167.21 then
set y to "E3"
else if y ≥ 167.22 and y ≤ 177.15 then
set y to "F3"
else if y ≥ 177.16 and y ≤ 187.69 then
set y to "F#3"
else if y ≥ 187.7 and y ≤ 198.85 then
set y to "G3"
else if y ≥ 198.86 and y ≤ 210.67 then
set y to "G#3"
else if y ≥ 210.68 and y ≤ 223.2 then
set y to "A3"
else if y ≥ 223.21 and y ≤ 236.47 then
set y to "A#3"
else if y ≥ 236.48 and y ≤ 250.53 then
set y to "B3"
else if y ≥ 250.54 and y ≤ 265.44 then
set y to "C4"
else if y ≥ 265.45 and y ≤ 281.21 then
set y to "C#4"
else if y ≥ 281.22 and y ≤ 297.93 then
set y to "D4"
else if y ≥ 297.94 and y ≤ 315.66 then
set y to "D#4"
else if y ≥ 315.67 and y ≤ 334.43 then
set y to "E4"
else if y ≥ 334.44 and y ≤ 354.31 then
set y to "F4"
else if y ≥ 354.32 and y ≤ 375.37 then
set y to "F#4"
else if y ≥ 375.38 and y ≤ 397.7 then
set y to "G4"
else if y ≥ 397.71 and y ≤ 421.34 then
set y to "G#4"
else if y ≥ 421.35 and y ≤ 446.4 then
set y to "A4"
else if y ≥ 446.41 and y ≤ 472.94 then
set y to "A#4"
else if y ≥ 472.95 and y ≤ 501.06 then
set y to "B4"
else if y ≥ 501.07 and y ≤ 530.86 then
set y to "C5"
else if y ≥ 530.87 and y ≤ 562.43 then
set y to "C#5"
else if y ≥ 562.44 and y ≤ 595.87 then
set y to "D5"
else if y ≥ 595.88 and y ≤ 631.3 then
set y to "D#5"
else if y ≥ 631.31 and y ≤ 668.85 then
set y to "E5"
else if y ≥ 668.86 and y ≤ 708.62 then
set y to "F5"
else if y ≥ 708.63 and y ≤ 750.75 then
set y to "F#5"
else if y ≥ 750.76 and y ≤ 795.39 then
set y to "G5"
else if y ≥ 795.4 and y ≤ 842.69 then
set y to "G#5"
else if y ≥ 842.7 and y ≤ 892.8 then
set y to "A5"
else if y ≥ 892.81 and y ≤ 945.88 then
set y to "A#5"
else if y ≥ 945.89 and y ≤ 1002.14 then
set y to "B5"
else if y ≥ 1002.15 and y ≤ 1061.72 then
set y to "C6"
else if y ≥ 1061.73 and y ≤ 1124.86 then
set y to "C#6"
else if y ≥ 1124.87 and y ≤ 1191.75 then
set y to "D6"
else if y ≥ 1191.76 and y ≤ 1262.61 then
set y to "D#6"
else if y ≥ 1262.62 and y ≤ 1337.69 then
set y to "E6"
else if y ≥ 1337.7 and y ≤ 1417.23 then
set y to "F6"
else if y ≥ 1417.25 and y ≤ 1501.51 then
set y to "F#6"
else if y ≥ 1501.52 and y ≤ 1590.79 then
set y to "G6"
else if y ≥ 1590.8 and y ≤ 1685.38 then
set y to "G#6"
else if y ≥ 1685.39 and y ≤ 1785.6 then
set y to "A6"
else if y ≥ 1785.61 and y ≤ 1891.78 then
set y to "A#6"
else if y ≥ 1891.79 and y ≤ 2004.26 then
set y to "B6"
else if y ≥ 2004.27 and y ≤ 2123.44 then
set y to "C7"
else if y ≥ 2123.45 and y ≤ 2249.71 then
set y to "C#7"
else if y ≥ 2249.72 and y ≤ 2383.49 then
set y to "D7"
else if y ≥ 2383.5 and y ≤ 2525.22 then
set y to "D#7"
else if y ≥ 2525.23 and y ≤ 2675.38 then
set y to "E7"
else if y ≥ 2675.39 and y ≤ 2834.47 then
set y to "F7"
else if y ≥ 2834.48 and y ≤ 3003.14 then
set y to "F#7"
else if y ≥ 3003.15 and y ≤ 3181.57 then
set y to "G7"
else if y ≥ 3181.58 and y ≤ 3370.77 then
set y to "G#7"
else if y ≥ 3370.78 and y ≤ 3571.2 then
set y to "A7"
else if y ≥ 3571.21 and y ≤ 3783.55 then
set y to "A#7"
else if y ≥ 3783.56 and y ≤ 4008.54 then
set y to "B7"
else if y ≥ 4008.55 and y ≤ 4246.9 then
set y to "C8"
else if y ≥ 4246.91 and y ≤ 4499.43 then
set y to "C#8"
else if y ≥ 4499.44 and y ≤ 4766.98 then
set y to "D8"
else if y ≥ 4766.99 and y ≤ 5050.44 then
set y to "D#8"
else if y ≥ 5050.45 and y ≤ 5350.75 then
set y to "E8"
else if y ≥ 5350.76 and y ≤ 5668.92 then
set y to "F8"
else if y ≥ 5668.93 and y ≤ 6006.02 then
set y to "F#8"
else if y ≥ 6006.03 and y ≤ 6363.16 then
set y to "G8"
else if y ≥ 6363.17 and y ≤ 6741.53 then
set y to "G#8"
else if y ≥ 6741.54 and y ≤ 7142.4 then
set y to "A8"
else if y ≥ 7142.41 and y ≤ 7567.11 then
set y to "A#8"
else if y ≥ 7567.12 and y ≤ 8017.07 then
set y to "B8"
end if
set y to y as text
-- rounds each reading to its tempered tonal counterpart
set end of freqData to y
end repeat
set L to freqData
end tell
-- finds the mostPopularItemInList
set theList to {}
repeat 50 times
set theList to theList & items of L
end repeat
mostPopularItemInList(theList)
to mostPopularItemInList(x)
script accellerator
property theList : x
property originalItems : {}
property originalItemsCount : {}
on indexof(theItem, theList)
set text item delimiters to return
set theList to return & theList & return
set text item delimiters to {""}
try
-1 + (count (paragraphs of (text 1 thru (offset of (return & theItem & return) in theList) of theList)))
on error
0
end try
end indexof
to greaterInteger()
set largerItem to 0
set largerItemIndex to 0
repeat with i from 1 to count originalItemsCount
if originalItemsCount's item i > largerItem then
set largerItem to originalItemsCount's item i
set largerItemIndex to i
end if
end repeat
originalItems's item largerItemIndex
end greaterInteger
end script
repeat with i from 1 to count accellerator's theList
considering case
if accellerator's theList's item i is not in accellerator's originalItems then
set accellerator's originalItems's end to accellerator's theList's item i
set accellerator's originalItemsCount's end to 1
else
set ind to accellerator's indexof(accellerator's theList's item i, accellerator's originalItems)
set accellerator's originalItemsCount's item ind to ((accellerator's originalItemsCount's item ind) + 1)
end if
end considering
end repeat
set f0 to paragraphs 2 thru -2 of return & accellerator's greaterInteger() as text
end mostPopularItemInList
– sets mostPopularItemInList to Finder tag
tell application “Finder”
set fileName to fileName as text
set currentFile to (get POSIX path of file fileName) as list
tell currentFile
my tagCmd(it as text)
end tell
end tell
on tagCmd(f)
do shell script "/usr/local/bin/tag -a " & "'" & f0 & "'" & space & quoted form of POSIX path of fileName -- "(get selection)" -- posix path convert path with colon to use in shell
end tagCmd`
Offhand, I would guess that it’s because the selection is a file object and thus, has those properties (including label index) whereas the others are text strings.
As to multi-processing… my understanding is that applescript is resolutely anti-parallel processing. The shell can do some things in parallel but I don’t know if you can spawn multiple processes from applescript that take full advantage of parallelism.