You are not logged in.
A few days ago, I posted the script included below in the Mac OS X forum. The script works as expected as long as the value of theFileName variable fits the specified dot pattern; when it doesn't an NSAppleEventDescriptor is returned. I spent some time with Google and the documentation but this is beyond my current level of understanding. How do I get the script to return an error in a usable format when the script is unable to work correctly. Thanks for the help.
The script is:
Applescript:
use framework "Foundation"
use scripting additions
set theFileName to "tv.show.title.S01e02.misc.garbage.characters.mkv" --> works OK
set theFileName to "aa.bb" --> returns NSAppleEventDescriptor
set newFileName to getFileName(theFileName)
on getFileName(theString)
set theString to current application's NSString's stringWithString:theString
set arrayOne to (theString's componentsSeparatedByString:".")
set arrayTwo to arrayOne's valueForKey:"capitalizedString"
return (current application's NSString's stringWithFormat_("%@ %@ %@ %@.%@", item 1 of arrayTwo, item 2 of arrayTwo, item 3 of arrayTwo, item 4 of arrayTwo, item -1 of arrayOne) as text)
end getFileName
The returned NSAppleEventDescriptor is:
Aa Bb <NSAppleEventDescriptor: 'obj '{ 'form':'indx', 'want':'cobj', 'seld':3, 'from':'obj '{ 'form':'ID ', 'want':'ocid', 'seld':'optr'($A002C50300600000$), 'from':null() } }> <NSAppleEventDescriptor: 'obj '{ 'form':'indx', 'want':'cobj', 'seld':4, 'from':'obj '{ 'form':'ID ', 'want':'ocid', 'seld':'optr'($A002C50300600000$), 'from':null() } }>.bb
2018 Mac mini - macOS Monterey - Script Debugger 8
Offline
Just a guess here, but it could be because your accessing a number of elements in the array that don't exist.
In this line here, your trying to access five elements in the array.
Applescript:
return (current application's NSString's stringWithFormat_("%@ %@ %@ %@.%@", item 1 of arrayTwo, item 2 of arrayTwo, item 3 of arrayTwo, item 4 of arrayTwo, item -1 of arrayOne) as text)
But this line here will only give you two elements, when converted into an array separated by "." character.
Applescript:
set theFileName to "aa.bb" --> returns NSAppleEventDescriptor
Maybe check the number of elements first, before trying to access them.
Regards Mark
Last edited by Mark FX (2021-12-10 10:34:42 am)
Offline
Mark is right, the array must contain at least 5 items to work correctly.
This version counts the number of items. The last object is the file extension and if there are more than 5 items only the first 5 items are considered
Applescript:
on getFileName(theString)
set theString to current application's NSString's stringWithString:theString
set arrayOne to (theString's componentsSeparatedByString:".")
set arrayTwo to arrayOne's valueForKey:"capitalizedString"
set fileExtension to arrayOne's lastObject() as text
set arrayLength to arrayTwo's |count|() as integer
if arrayLength > 4 then
set maxLength to 4
else
set maxLength to arrayLength - 1
end if
set indexSet to current application's NSIndexSet's indexSetWithIndexesInRange:{0, maxLength}
set subArray to arrayTwo's objectsAtIndexes:indexSet
return ((subArray's componentsJoinedByString:" ") as text) & "." & fileExtension
end getFileName
regards
Stefan
Offline
As MarkFx told you...
If you use objectAtIndex: it will return a error for the line "aa.bb" and say...
error "*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 1]" number -10000
Here is the code that produce that error, I guess in this example its better to use objectAtIndex
instead of item 1 of something when your return error is very misleading.
Applescript:
use framework "Foundation"
use scripting additions
set theFileName to "tv.show.title.S01e02.misc.garbage.characters.mkv" --> works OK
set theFileName to "aa.bb" --> returns NSAppleEventDescriptor
set newFileName to getFileName(theFileName)
on getFileName(theString)
set theString to current application's NSString's stringWithString:theString
set arrayOne to (theString's componentsSeparatedByString:".")
set arrayTwo to arrayOne's valueForKey:"capitalizedString"
return (current application's NSString's stringWithFormat_("%@ %@ %@ %@.%@", arrayTwo's objectAtIndex:0, arrayTwo's objectAtIndex:1, arrayTwo's objectAtIndex:2, arrayTwo's objectAtIndex:3, arrayOne's lastObject()) as text)
end getFileName
Last edited by Fredrik71 (2021-12-10 11:15:42 am)
if you are the expert, who will you call if its not your imagination.
Offline
Thanks Mark, Stefan, and Fredrik71 for the great ideas. I had my mind fixed on getting an error result from NSAppleEventDescriptor and completely missed simple and effective ways of doing what I wanted.
2018 Mac mini - macOS Monterey - Script Debugger 8
Offline
Also want to note the your arrayTwo is a NSArray and not a list.
So I’m not sure how requesting “item x of” works with a NSArray?
Also NSArray works with zero based start indexing where as a list is one.
You definitely want to use objectAtIndex:
Offline
So I’m not sure how requesting “item x of” works with a NSArray?
Thanks technomorph for responding to my post. I have modified my original script to delete "item x of" and to use objectAtIndex instead.
Just as an aside, it's probably not technically correct but "item x of" does seem to work:
Applescript:
use framework "Foundation"
set theArray to current application's NSArray's arrayWithArray:{"a", "b"}
item 1 of theArray --> (NSString) "a"
The following is from Shane's book and--while the situations are not directly analogous--the thought occurred to me that perhaps "item x of" works with an array for a similar reason that the AppleScript count command works with an array.
You might wonder how count of someArray works; you may expect to have had to use the Cocoa construction someArray's |count|() instead. Presumably AppleScript does some conversion from array to list under the hood. However it is done, in tests it is actually a little faster than the Cocoa method, not to mention more convenient.
I ran a quick timing test with Script Debugger, and "item x of" is marginally faster than objectAtIndex in my script. The concern remains, however, that the use of "item x of" may cause the script to break at some future point.
I also may have happened upon a possible answer as to why the script returns an NSAppleEventDescriptor. The following is from Shane's book:
This [bridging a list to an array] gives you an array, but something else has happened: if the list’s elements were strings, they have been converted to NSStrings at the same time. In fact, any items in the list that scripting bridge can convert will be converted. (Any that cannot will be stored as Cocoa objects called NSAppleEventDescriptors, which is essentially a way of wrapping an AppleScript object in a Cocoa object, so it can be unwrapped on return.)
My *guess* is that the array is converted "under the hood" to a list, but items 3 and 4 of the newly-created list cannot be converted to an NSString. So these items are instead stored as NSAppleEventDescriptors.
Last edited by peavine (2021-12-13 09:02:44 am)
2018 Mac mini - macOS Monterey - Script Debugger 8
Offline
I was testing StefanK solution to the OP.
I find the 2 last example from the log in my modified code of StefanK original code to brake.
So here its
Applescript:
use framework "Foundation"
use scripting additions
set ex1 to "tv.show.title.S01e02.misc.garbage.characters.mkv"
set ex2 to "tv-show.title.S01e02.misc.garbage.characters.mkv"
set ex3 to "tv show title S01e02 misc garbage characters.mkv"
set ex4 to "tv-show title S01e02 misc garbage characters.mkv"
set ex5 to "tv.show.title.S01e02.mkv"
set ex6 to "tv-show.title.S01e02.mkv"
set ex7 to "tv show title S01e02.mkv"
set ex8 to "tv-show title S01e02.mkv"
log (its capitalizedString:ex1 bySeparater:"." itsLength:4 joinedString:" ")
log (its capitalizedString:ex2 bySeparater:"." itsLength:3 joinedString:"_")
log (its capitalizedString:ex3 bySeparater:" " itsLength:4 joinedString:"-")
log (its capitalizedString:ex4 bySeparater:" " itsLength:3 joinedString:" ")
log (its capitalizedString:ex5 bySeparater:"." itsLength:4 joinedString:" ")
log (its capitalizedString:ex6 bySeparater:"." itsLength:3 joinedString:"_")
-- The 2 last example do not work...
log (its capitalizedString:ex7 bySeparater:" " itsLength:3 joinedString:"-")
log (its capitalizedString:ex8 bySeparater:" " itsLength:4 joinedString:".")
on capitalizedString:theString bySeparater:separater itsLength:maxLength joinedString:joinedString
set theString to current application's NSString's stringWithString:theString
set arrayOne to (theString's componentsSeparatedByString:separater)
set arrayTwo to arrayOne's valueForKey:"capitalizedString"
set fileExtension to arrayOne's lastObject() as text
-- Only work with file extension that is not > 3 character
if (count of text items of fileExtension) > 3 then
set fileExtension to text -3 thru -1 of fileExtension
end if
log fileExtension
set arrayLength to arrayTwo's |count|() as integer
if arrayLength > maxLength then
set maxLength to maxLength
else
set maxLength to arrayLength - 1
end if
set indexSet to current application's NSIndexSet's indexSetWithIndexesInRange:{0, maxLength}
set subArray to arrayTwo's objectsAtIndexes:indexSet
return ((subArray's componentsJoinedByString:joinedString) as text) & "." & fileExtension
end capitalizedString:bySeparater:itsLength:joinedString:
if you are the expert, who will you call if its not your imagination.
Offline
This is where regular expressions are hand
You can build a RegEx that can have options IE
A space or . Before a S0
Etc
Offline