I have the below code up and running in my project , it is working fine apart from the way the result is displayed in the drop box, i.e: /Volumes/RIP FILES/12345-TEST.ps, what i am trying to have it do is be displayed like this 12345-TEST, but cannot not figure ou how to do that, I think I’m using the
return paragraphs of (do shell script t_command) wrong, but cannot get a result to display in the drop box with out it, can some one please advise me on how to do what i’m after please.
on TEST_(sender) --attached button in ib
MakeMenu(search_files("TEST", -1)) --search for file TEST
end TEST_
on search_files(findstring)
set Fileext to "ps" --postscript file
set t_command to "mdfind -onlyin '/Volumes/RIP FILES/' 'kMDItemDisplayName == " & quote & findstring & "*" & quote & "wc" & " && (kMDItemFSName == " & quote & "*." & Fileext & quote & ")'"
return paragraphs of (do shell script t_command) -- returns items found from mdfind
end search_files
on MakeMenu(_list)
try
aPopupMenu's removeAllItems()
end try
aPopupMenu's addItemsWithTitles_(_list) --add titles found to drop box in ib
end MakeMenu
mdfind returns always the full path to the items.
You need either a repeat loop to trim the strings or maybe it could work with a pipe passing the paths to /usr/bin/basename
I have tried the code below which returns the file name with out the full path, sweet, but it only returns 1 item,
to the drop box, it needs to return multiple items with the base name of TEST, and I’m not really sure how to alter my code to do that.
set foundfFiles to paragraphs of (do shell script t_command & " |/usr/bin/xargs -0 /usr/bin/basename")
I’m not sure exactly what you are trying to do since I don’t have much experience with shell scripts, but it looks like you are trying to find all files that start with “TEST” and have the file extension of ps. Is that so? And, does this method go into the sub folders of your folder, or does it only do a shallow search? If it is a shallow search, I think the following ASOC code will work to get you the array you need (theFolder is a POSIX path to your search folder).
set pathsArray to current application's NSFileManager's defaultManager()'s contentsOfDirectoryAtPath_error_(theFolder, missing value)
set nameArray to current application's NSMutableArray's alloc()'s init()
repeat with fullPath in pathsArray
set ext to fullPath's pathExtension()
set theName to fullPath's stringByDeletingPathExtension()'s lastPathComponent()
if (ext's isEqualToString_("ps") as integer is 1) and (theName's hasPrefix_("TEST") as integer is 1) then
nameArray's addObject_(theName)
end if
end repeat
log nameArray
this is a solution which combines the power of Spotlight searching with Cocoa’s efficiency.
Another advantage is that the search will be performed asynchronously.
Note: I changed the name of your methods to respect Objective-C’s name convention,
that all methods should start with a lowercase letter
property NSPredicate : class "NSPredicate"
property NSMetadataQuery : class "NSMetadataQuery"
property NSNotificationCenter : class "NSNotificationCenter"
property query : NULL -- variable for the NSMetadataQuery instance
on test_(sender) --attached button in ib
makeMenu_("TEST") --search for file TEST
end test_
on makeMenu_(searchString)
NSNotificationCenter's defaultCenter's addObserver_selector_name_object_(me, "queryDidFinish:", "NSMetadataQueryDidFinishGatheringNotification", missing value)
set pathExtension to "ps"
set searchPath to "/Volumes/RIP FILES/"
set searchKey to quote & "*" & searchString & "*." & pathExtension & quote
set predicate to NSPredicate's predicateWithFormat_("kMDItemFSName like[c] " & searchKey)
set query to NSMetadataQuery's alloc()'s init()
query's setSearchScopes_({searchPath})
query's setPredicate_(predicate)
query's startQuery()
end makeMenu_
on queryDidFinish_(theNote)
query's stopQuery()
aPopupMenu's removeAllItems()
set foundItems to theNote's |object|()'s results()
repeat with anItem in foundItems
aPopupMenu's addItemWithTitle_(anItem's valueForAttribute_("kMDItemFSName")'s stringByDeletingPathExtension())
aPopupMenu's lastItem()'s setRepresentedObject_(anItem's valueForAttribute_("kMDItemPath"))
end
NSNotificationCenter's defaultCenter's removeObserver_(me)
end queryDidFinish_
The full path of the found object is assigned to the representedObject property of the popup menu item
You can retrieve it, when you connect the action of the popup menu to this handler
on didSelectPopupMenuItem_(sender)
log sender's selectedItem()'s representedObject()
end didSelectPopupMenuItem_
Thanks for that example, I haven’t seen any for NSMetadataQuery before. I have one question about search scope. If I do a search for files in /Users/rdelmar/Documents/Weather/ I find the files I’m looking for. If I set the search scope to /Users/rdelmar/Documents/ I also find what I’m looking for, but if I go to /Users/rdelmar/ I don’t get anything. This seems to be somewhere between a shallow and deep search. Does it typically just go one level down?
I tried: query’s setSearchScopes_({current application’s NSMetadataQueryUserHomeScope}) and that didn’t work to find any files, but an empty array did.
I have files that have these type of names 12345-A100-SOPQ.ps or 12345-A100-CRSOPQ.ps or 1234-TEST.ps or 1234-HTEST.ps or 12345-A100-341-SOPQ.ps when I click a button that has makeMenu_(“SOPQ”) the search needs to look ONLY for files that have SOPQ at the end and nothing else, or makeMenu_(“341-SOPQ”) only look for files that have 341-SOPQ, the same goes for TEST, only search for files that say TEST not files that have HTEST and so on, I do have a lot of naming conventions that require the same kind of search, only searching for the specific name supplied.
The search is shallow “/Volumes/RIP FILES/” no sub folders
Stefan:
Thanks for replying, your code works great, thank you
If I click on a button makeMenu_(“SOPQ”) the result is files with CSOPQ or PNSOPQ or CPNSOPQ are being added to the drop box, im trying to get only files that have SOPQ added to the drop box, as mentioned above, is this possible with your code?, what would I need to do to achieve that please