Saturday, July 4, 2020

#1 2020-04-22 08:26:34 am

RobK
Member
Registered: 2007-02-17
Posts: 36

Why Doesn't This Code Work?

Here is some code that I believe should change the extension from an image type to a JPG. 
(e.g. Change Image.TIFF to Image.JPG)

But instead it returns a file with a double filename extension.  (e.g.  Image.TIFF becomes Image.TIFF.JPG).

Why?  What am I missing?

Applescript:


property openTypes : {"PDF", "com.adobe.pdf", "BMP", "com.microsoft.bmp", "PICT", "com.apple.pict", "PNG", "public.png", "PSD", "com.adobe.photoshop-image", "TIFF", "public.tiff"}

--Get the artwork file
set theFiles to choose file with prompt "Choose art file(s)" of type openTypes without invisibles
set theType to "JPG"

runTest(theFiles, theType)

on runTest(theArt, theType)
   display dialog "theArt is " & theArt
   tell application "Finder"
       set saveExt to extension hidden of theArt
       set extension hidden of theArt to true
       set theFolder to (container of theArt) as text
       set theNewArt to (theFolder as text) & (displayed name of theArt) & "." & theType
       set extension hidden of theArt to saveExt
   end tell
   display dialog "theNewArt is " & theNewArt
end runTest

By the way, here is some workaround code.  But I am curious why the code above does not work as expected:

Applescript:


property openTypes : {"PDF", "com.adobe.pdf", "BMP", "com.microsoft.bmp", "PICT", "com.apple.pict", "PNG", "public.png", "PSD", "com.adobe.photoshop-image", "TIFF", "public.tiff"}

--Get the artwork file
set theFiles to choose file with prompt "Choose art file(s)" of type openTypes without invisibles
set theType to "JPG"

runTest(theFiles, theType)

on runTest(theArt, theType)
   display dialog "theArt is " & theArt
   set noExtName to removeExtension(theArt as text)
   tell application "Finder"
       set theNewArt to (noExtName as text) & "." & theType
   end tell
   display dialog "theNewArt is " & theNewArt
end runTest

on removeExtension(thisName)
   if thisName contains "." then
       set thisName to (the reverse of every character of thisName) as string
       set x to the offset of "." in thisName
       set thisName to (text (x + 1) thru -1 of thisName)
       set thisName to (the reverse of every character of thisName) as string
   end if
   return thisName
end removeExtension

Offline

 

#2 2020-04-22 08:42:01 am

RobK
Member
Registered: 2007-02-17
Posts: 36

Re: Why Doesn't This Code Work?

After some testing, I solved the problem.

The first code (using "extension hidden") does work BUT ONLY if you do NOT have the "Show all filename extensions" option enabled in the preferences for Finder.

My workaround code will work no matter how you set that option in Finder.

I hope this helps others.  I was pulling out my hair for awhile!

Offline

 

#3 2020-04-22 10:40:43 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 4533

Re: Why Doesn't This Code Work?

Let me disagree with your workaround.
Look at this example.

Applescript:

on removeExtension(thisName)
   if thisName contains "." then
       set thisName to (the reverse of every character of thisName) as string
       set x to the offset of "." in thisName
       set thisName to (text (x + 1) thru -1 of thisName)
       set thisName to (the reverse of every character of thisName) as string
   end if
   return thisName
end removeExtension

set thisName to "Macintoh HD:Users:moi:Documents:31.12.43:myFile"
my removeExtension(thisName) --> "Macintoh HD:Users:moi:Documents:31.12"

No need to reinvent the wheel.

For years, stripping the extension is done with such kind of code.

Applescript:


property openTypes : {"PDF", "com.adobe.pdf", "BMP", "com.microsoft.bmp", "PICT", "com.apple.pict", "PNG", "public.png", "PSD", "com.adobe.photoshop-image", "TIFF", "public.tiff"}

--Get the artwork file
set theFiles to choose file with prompt "Choose art file(s)" of type openTypes without invisibles
set theType to "JPG"

runTest(theFiles, theType)

on runTest(theArt, theType)
   display dialog "theArt is " & theArt
   
   tell application "Finder"
       set theExt to name extension of theArt
       set theArt to theArt as string
       if theExt is "" then
           set noExtPath to theArt as string
       else
           set noExtPath to (text items 1 thru -(2 + (count theExt)) of theArt) as string
       end if
       set theNewArt to noExtPath & "." & theType
   end tell
   display dialog "theNewArt is " & theNewArt
end runTest

I know that some helpers dislike to use the Finder (I'm one of them but here, you already used it, with no real need) to drop the name extension.
But they take care to drop it from the file name, not from the file path as your code does.
It's why I took care to use a varName matching what it's supposed to contain.

I'm a bit puzzled by your first instruction.
As far as I know you would get the same behaviour with this shorter one:

Applescript:

property openTypes : {"com.adobe.pdf", "com.microsoft.bmp", "com.apple.pict", "public.png", "com.adobe.photoshop-image", "public.tiff"}

If you wish to experiment you may try to use this instruction:

Applescript:

set showExtensions to do shell script "defaults read com.apple.finder AppleShowAllExtensions"

If it returns 1, your paths are supposed to have an extension, if it returns 0 they are supposed to haven't. I wrote 'are supposed' because my memory which may be facetious tell me that this feature doesn't apply to path of applications.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) Wednesday 22 April 2020  18:25:45

Offline

 

#4 2020-04-22 02:10:04 pm

RobK
Member
Registered: 2007-02-17
Posts: 36

Re: Why Doesn't This Code Work?

Many thanks Yvan!  My updated code fixed one problem but created another one.
(I was trying to fix the original code for ImageConvert in the Unscripted Forum on this website).

I agree that your code for is much better.  It solves the original problem for the ImageConvert  script.  (i.e.  the original code would create converted image files with double extensions (e.g.  Image.PNG.JPG) when a user has enabled "Show all filename extensions" in the preferences for Finder.  The extension hidden attribute of the Finder really does not work when this option is enabled in the preferences for Finder). 

P.S. I turned your code into a subroutine so I can reuse it in other scripts I develop.  Below is a sample script using the subroutine.

Applescript:


property openTypes : {"PDF", "com.adobe.pdf", "BMP", "com.microsoft.bmp", "PICT", "com.apple.pict", "PNG", "public.png", "PSD", "com.adobe.photoshop-image", "TIFF", "public.tiff"}

--Get the artwork file
set theFile to choose file with prompt "Choose art file(s)" of type openTypes without invisibles
set theNewType to "JPG"

runTest(theFile, theNewType)

on runTest(theArt, theType)
   display dialog "theArt is " & theArt
   
   set noExtPath to removeExtension(theArt)
   set theNewArt to noExtPath & "." & theType
   
   display dialog "theNewArt is " & theNewArt
end runTest

on removeExtension(thisName)
   tell application "Finder"
       set theExt to (name extension of thisName)
   end tell
   set thisName to thisName as string
   if theExt is "" then
       set noExtPath to thisName as string
   else
       set noExtPath to (text items 1 thru -(2 + (count theExt)) of thisName) as string
   end if
   return noExtPath as text
end removeExtension

I also created a companion subroutine that replaces the extension.  See the sample script below using this subroutine:

Applescript:


property openTypes : {"com.adobe.pdf", "com.microsoft.bmp", "com.apple.pict", "public.png", "com.adobe.photoshop-image", "public.tiff"}

--Get the artwork file
set theFile to choose file with prompt "Choose art file(s)" of type openTypes without invisibles
set theNewType to "JPG"

runTest(theFile, theNewType)

on runTest(theArt, theType)
   display dialog "theArt is " & theArt
   set theNewArt to replaceExtension(theArt, theType)
   display dialog "theNewArt is " & theNewArt
end runTest

on replaceExtension(thisName, newExt)
   tell application "Finder"
       set theExt to (name extension of thisName)
   end tell
   set thisName to thisName as string
   if theExt is "" then
       set noExtPath to thisName as string
   else
       set noExtPath to (text items 1 thru -(2 + (count theExt)) of thisName) as string
   end if
   return (noExtPath & "." & newExt) as text
end replaceExtension

I also agree with you that one can use the simpler property statement:

property openTypes : {"com.adobe.pdf", "com.microsoft.bmp", "com.apple.pict", "public.png", "com.adobe.photoshop-image", "public.tiff"}

instead of

property openTypes : {"PDF", "com.adobe.pdf", "BMP", "com.microsoft.bmp", "PICT", "com.apple.pict", "PNG", "public.png", "PSD", "com.adobe.photoshop-image", "TIFF", "public.tiff"}

I suspect the other unnecessary types were added for readability sake by the original coder, Kevin Bradley. 

Again many thanks for improving the code!

Offline

 

#5 2020-04-22 02:30:35 pm

RobK
Member
Registered: 2007-02-17
Posts: 36

Re: Why Doesn't This Code Work?

Yvan - FYI - I have updated the original code for ImageConvert using your method. 

Please see
https://macscripter.net/viewtopic.php?id=24736

Offline

 

#6 2020-04-22 03:54:45 pm

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 4533

Re: Why Doesn't This Code Work?

@RobK

thank you.
The code removing the extension is used by many Applescript users for years.
As I dislike the Finder (in fact I hate it) in my new scripts I do the job using ASObjC which is verbose but very efficient and powerful

Applescript:

----------------------------------------------------------------
use AppleScript version "2.5"
use framework "Foundation"
use scripting additions
----------------------------------------------------------------

set aFile to choose file of type {"png", "pdf"}
my buildJpgPath:aFile

on buildJpgPath:aFile
   set POSIXPath to POSIX path of aFile
   set pathNSString to current application's NSString's stringWithString:POSIXPath
   set newPath to pathNSString's stringByDeletingPathExtension()
   set newPath to newPath's stringByAppendingPathExtension:"jpg"
   return newPath as «class furl» as string
end buildJpgPath:

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) Wednesday 22 April 2020  23:53:53

Offline

 

#7 2020-04-22 05:57:11 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6395

Re: Why Doesn't This Code Work?

RobK wrote:


Applescript:


       set thisName to (the reverse of every character of thisName) as string
       set x to the offset of "." in thisName
       set thisName to (text (x + 1) thru -1 of thisName)
       set thisName to (the reverse of every character of thisName) as string



set noExtPath to (text items 1 thru -(2 + (count theExt)) of thisName) as string



These snippets, which involve coercion of a list to a string, are a bit of a disaster waiting to happen, because the results depend on the state of text item delimiters. You should explicitly set them before doing this sort of thing.

Better, and more efficient, is not to coerce at all:

set noExtPath to text 1 thru -(2 + (count theExt)) of thisName

Last edited by Shane Stanley (2020-04-23 05:26:56 am)


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#8 2020-04-23 01:42:28 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 5233

Re: Why Doesn't This Code Work?

Shane Stanley wrote:

set thisName to text 1 thru -1 of (the reverse of every character of thisName)
      set noExtPath to text 1 thru -(2 + (count theExt)) of thisName


Hi Shane. I don't think you meant to include the first line.


NG

Offline

 

#9 2020-04-23 01:50:37 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6395

Re: Why Doesn't This Code Work?

Nigel, does it make more sense now? I was referring to separate scripts...


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#10 2020-04-23 03:14:39 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 5233

Re: Why Doesn't This Code Work?

Hi Shane.

text 1 thru -1 of (the reverse of every character of thisName) produces a list. I got the impression your intention was to demonstrate a direct substring extraction.

Applescript:

set thisName to "fred.jpg"
set thisName to text 1 thru -1 of (the reverse of every character of thisName)
--> {"g", "p", "j", ".", "d", "e", "r", "f"}


NG

Offline

 

#11 2020-04-23 03:32:27 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 4533

Re: Why Doesn't This Code Work?

RobK wrote:

Yvan - FYI - I have updated the original code for ImageConvert using your method. 

Please see
https://macscripter.net/viewtopic.php?id=24736



I looked carefully at the pointed thread and discovered that you misunderstood what I wrote.

Yvan Koenig pointed a problem with my updated code in another forum of this website.   It may not work properly if your image filename to be converted contains periods.  (e.g. Image-12.22.09.bmp).



It's not what I pointed to.

Applescript:

on removeExtension(thisName)
   if thisName contains "." then
       set thisName to (the reverse of every character of thisName) as string
       set x to the offset of "." in thisName
       set thisName to (text (x + 1) thru -1 of thisName)
       set thisName to (the reverse of every character of thisName) as string
   end if
   return thisName
end removeExtension


-- what you posted. It behaves flawlessly
-- bad choice of variable name, it's not a name but a path
set thisName to "Macintoh HD:Users:moi:Documents:31.12.43:Image-12.22.09.bmp"
my removeExtension(thisName) --> "Macintoh HD:Users:moi:Documents:31.12.43:Image-12.22.09"

-- what I pointed to. It returns an awful result
-- bad choice of variable name, it's not a name but a path
set thisName to "Macintoh HD:Users:moi:Documents:31.12.43:myFile"
my removeExtension(thisName) --> "Macintoh HD:Users:moi:Documents:31.12"


-- correct variable name
set thisName to "myFile"
my removeExtension(thisName) --> "myFile"

As you carefully worked upon the reverse of the original path, your code gave a correct result when a name contain several dots.
The problem is that if the name contains no dot and a folder name in the path contains such character, the result will be awful: the  end of the folder name will be dropped with the file name.

I repeat that your choice of the  variable name facilitate this kind of error.
If you were really passing a file name the problem wouldn't strike

Back to the extraction of the name extension.
I dislike to write that but only the Finder make a correct job.

Applescript:

----------------------------------------------------------------
use AppleScript version "2.5"
use framework "Foundation"
use scripting additions
----------------------------------------------------------------

on getExtension:aFile
   set POSIXPath to POSIX path of aFile
   set pathNSString to current application's NSString's stringWithString:POSIXPath
   set theExt to pathNSString's pathExtension()
   return theExt as string
end getExtension:


set aFile to ((path to desktop as string) & "essai.jpeg") as alias

set theExt to name extension of (info for aFile) --> "jpeg"
log result
tell application "Finder" to set theExt to name extension of aFile --> "jpeg"
log result
tell application "System Events" to set theExt to name extension of aFile --> "jpeg"
log result
set theExt to my getExtension:aFile --> "jpeg"
log result

set aFile to ((path to desktop as string) & "essay") as alias

set theExt to name extension of (info for aFile) --> missing value which is correct but requires a 'special' treatment
log result
tell application "Finder" to set theExt to name extension of aFile --> ""
log result
tell application "System Events" to set theExt to name extension of aFile --> ""
log result
set theExt to my getExtension:aFile --> ""
log result


set aFile to ((path to desktop as string) & "essai.YK") as alias

set theExt to name extension of (info for aFile) --> "YK" which is WRONG
log result
tell application "Finder" to set theExt to name extension of aFile --> "" which is correct
log result
tell application "System Events" to set theExt to name extension of aFile --> "YK" which is WRONG
log result
set theExt to my getExtension:aFile --> --> "YK" which is WRONG
log result

As info for is deprecated for years, I'm not really bored by it's behavior.
The behavior of System Events and ASObjC is more problematic.
With them, we must be sure of what we pass to them ends with a valid name extension.

YK is an acronym which I often use but it's not a name extension.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) jeudi 23 avril 2020  11:31:02

Offline

 

#12 2020-04-23 05:26:35 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6395

Re: Why Doesn't This Code Work?

Nigel Garvey wrote:

I got the impression your intention was to demonstrate a direct substring extraction.



Thanks, Nigel -- it was. I'll edit accordingly (and get some sleep).


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#13 2020-04-23 08:44:26 am

RobK
Member
Registered: 2007-02-17
Posts: 36

Re: Why Doesn't This Code Work?

Thanks Yvan.  Now I understand the original problem with my proposed solution code.   It will not work if the filename does not have an extension (i.e. no period) and the path to the filename contains periods (or dots) (e.g one of the folders has a name with dots in it).   

I also agree with you that it is better to just manipulate the filename and not the whole path including the filename.  Working with the filename will help avoid a lot of problems.

In any event, it looks like I could fix my original code by checking whether the filename is missing an extension and deal with that case accordingly.  For example:

Applescript:


on removeExtension(thisName)
   tell application "Finder"
       set theEXT to (name extension of thisName)
   end tell
   if theEXT is "" then
       set noExtName to thisName as string
   else
       set noExtName to (the reverse of every character of (thisName as string)) as string
       set x to the offset of "." in noExtName
       set noExtName to (text (x + 1) thru -1 of noExtName)
       set noExtName to (the reverse of every character of noExtName) as string
   end if
   return noExtName
end removeExtension

It appears to work with your test case (i.e. no filename extension but the path to the filename contains periods).

But your code is simpler and more elegant.  It will probably run a lot faster too.  (It also avoids coercion into strings!)

And thank you for taking the time to write your last example code.  I never realized that there was a difference between a "name extension" and a "filename extension".   I always thought that they were the same.  Your example using "assai.YK" shows that they are different.

I learned something new today!  That is always a good thing.

Merci Beaucoup!

Robert
Quebec, Canada

Last edited by RobK (2020-04-23 09:08:59 am)

Offline

 

#14 2020-04-23 09:26:33 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 4533

Re: Why Doesn't This Code Work?

It seems that I am unable to find the correct words.

Name extension is not a property of a file name, it's a property of a file (aka a file path or a file reference)
Finder may get the name extension of an item which is a file descriptor.
It may be an alias like what is returned by choose file
or a Finder reference like what we get when we start from a selection.

Applescript:

tell application "Finder"
   set aFile1 to item 1 of (get selection)
   --> document file "P3110225.psd" of folder "Baudart YK" of folder "Desktop" of folder "**********" of folder "Users" of startup disk of application "Finder"
   set theExt1 to name extension of aFile1
   --> "psd"
   set aFile2 to (item 1 of (get selection)) as alias
   --> alias "SSD 1000:Users:**********:Desktop:Baudart YK:P3110225.psd"
   set theExt2 to name extension of aFile2
   --> "psd"
   
   set aFile3 to (item 1 of (get selection)) as «class furl»
   --> file "SSD 1000:Users:**********:Desktop:Baudart YK:P3110225.psd"
   try
       set theExt3 to name extension of aFile3
   on error errMsg number errNbr
       log errMsg & ", number#" & errNbr
       --> (*Erreur dans Finder : Il est impossible d’obtenir name extension of file "SSD 1000:Users:**********:Desktop:Baudart YK:P3110225.psd"., number#-1728*)
   end try
   
   set aName1 to name of aFile1
   try
       name extension of aName1
   on error errMsg number errNbr
       log errMsg & ", number#" & errNbr
       --> (*Il est impossible d’obtenir name extension of "P3110225.psd"., number#-1728*)
   end try
end tell

Maybe it's more clear.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) jeudi 23 avril 2020  17:15:14

Offline

 

#15 2020-04-23 10:00:52 am

RobK
Member
Registered: 2007-02-17
Posts: 36

Re: Why Doesn't This Code Work?

Yes, human language can be vague and confusing. 

But I believe I do understand you.   in Applescript, the term "name extension" refers to a property of a file NOT to a property of the name of a file (or filename).

So you can only use "name extension" (typically within a Finder or System Events Tell Block) when one is dealing with files NOT names of files.

I will try  to remember that.   But maybe it is better to avoid using the Finder altogether! :-)

And "name extensions" are not the same as the extension of a file.

Using your example - assai.YK

YK is NOT a valid "name extension".  The name extension for assai.YK is "".

But in my mind YK is an extension to the filename.  It is just not a name extension.

Offline

 

#16 2020-04-23 11:19:47 am

KniazidisR
Member
Registered: 2019-03-03
Posts: 1259

Re: Why Doesn't This Code Work?

Something has property in the programming only when it is object (1 special structure of code with properties, and methods). For example, string "Dog.txt" is not object, so the following will raise error:

Applescript:

properties of "Dog.txt"

the following returns result, but only because command item works here. It is not property:

Applescript:

item 1 of "Dog.txt" -- Result: "D"

NOTE: NSString @"Dog.txt" is object:

Applescript:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
set aDog to current application's NSString's stringWithString:"Dog.txt"
aDog's pathExtension() -- Result: "txt"

Here, used property pathExtension, which returns method pathExtension() of NSString class

Last edited by KniazidisR (2020-04-23 11:52:15 am)


Model: MacBook Pro
OS X: Catalina 10.15.4
Web Browser: Safari 13.1
Ram: 4 GB

Offline

 

#17 2020-04-23 11:32:54 am

RobK
Member
Registered: 2007-02-17
Posts: 36

Re: Why Doesn't This Code Work?

Thanks KniazidisR. 

Yes that makes sense.  Only objects in programming have properties.

So going back to Yvan's example.    The "name" of a file is NOT an object so it does not have any properties.

But files are typically considered objects in programming.  So files do have properties such as names, extensions etc.

Offline

 

#18 2020-04-23 12:18:14 pm

KniazidisR
Member
Registered: 2019-03-03
Posts: 1259

Re: Why Doesn't This Code Work?

Exactly, you understand me.

More specifically, AppleScript simple strings are also objects, only these are the simplest low-level objects. They have only one main method - the method that, when accessing an object, returns only 1, its value:

Applescript:

set anObject to a reference to "Dog.txt" -- Result: "Dog.txt"

But, anyway, it will be more correct to name an object only that which has some other properties and methods besides this main one.

Last edited by KniazidisR (2020-04-23 12:25:00 pm)


Model: MacBook Pro
OS X: Catalina 10.15.4
Web Browser: Safari 13.1
Ram: 4 GB

Offline

 

#19 2020-04-23 02:56:38 pm

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 4533

Re: Why Doesn't This Code Work?

RobK wrote:

But in my mind YK is an extension to the filename.  It is just not a name extension.




How would you describe a filename like my old friend "31.12.43" which is perfectly correct?

On my machine there is not such filename because I NEVER urge the Finder to hide name extensions.

I repeat that, although I hate it, the Finder is the unique tool treating the name extensions correctly.

Info for is obsolete.
System Events and ASObjC assume that the last piece of a file name which is preceded by a dot is an extension. If I name a file : "La.guillotine", guillotine will be treated as a name extension although it's really not what it's designed to achieve ????

Imagine a folder named "La.guillotine" passed erroneously in your original code. It would become La.JPG and I doubt that Preview would be at ease with it.

It's important to understand that although AppleScript try to resemble to a natural language, it's not one. Its vocabulary is made of words borrowed to natural languages but their meaning is not guaranteed to be exactly the common one.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) jeudi 23 avril 2020  22:42:26

Offline

 

#20 2020-04-23 07:26:38 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6395

Re: Why Doesn't This Code Work?

Yvan Koenig wrote:

System Events and ASObjC assume that the last piece of a file name which is preceded by a dot is an extension. If I name a file : "La.guillotine", guillotine will be treated as a name extension although it's really not what it's designed to achieve ????



It's not that simple, though. Suppose I write a new application, say Chop.app, and it saves its files as .guillotine files. guillotine is now a file extension -- just not one defined in an app on your Mac (yet). By that argument, any extension not defined by the system or OS-installed apps is potentially not really an extension.

As you point out, the Finder's scripting dictionary takes the stricter view. But most applications, and much of the system, take the opposite view -- they use the approach Foundation uses because, well, they are built on Foundation. (FWIW, I suspect the Finder's behavior is a hangover from the days of file types and creators, when extensions were entirely optional. In that world, it made sense.)

I think the real point here is that the whole notion of extensions is very fragile, and if you stray from the rule of always using them for documents, you're asking for unpredictable results.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#21 2020-04-24 03:33:34 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 4533

Re: Why Doesn't This Code Work?

Shane Stanley wrote:
Yvan Koenig wrote:

System Events and ASObjC assume that the last piece of a file name which is preceded by a dot is an extension. If I name a file : "La.guillotine", guillotine will be treated as a name extension although it's really not what it's designed to achieve ????



It's not that simple, though. Suppose I write a new application, say Chop.app, and it saves its files as .guillotine files. guillotine is now a file extension -- just not one defined in an app on your Mac (yet). By that argument, any extension not defined by the system or OS-installed apps is potentially not really an extension.

As you point out, the Finder's scripting dictionary takes the stricter view. But most applications, and much of the system, take the opposite view -- they use the approach Foundation uses because, well, they are built on Foundation. (FWIW, I suspect the Finder's behavior is a hangover from the days of file types and creators, when extensions were entirely optional. In that world, it made sense.)

I think the real point here is that the whole notion of extensions is very fragile, and if you stray from the rule of always using them for documents, you're asking for unpredictable results.




Hello Shane.

The Finder has a "logical behavior". If the ending substring "describes the contents of the file", it IS a name extension. In the other case, ITSN’T such object.
What is the interest of the object "name extension" if it is not guaranteed to be a "contents descriptor" ?

My grand daughter urged the Finder to never display the name extension. She also urged it to display windows with icons and to build them on the fly according to file's contents. The result is that she never know which kind of file is in front of her.

My daughter made a more 'logical' choice. She hide name extensions but she display windows in columns mode so she see the fil type in its dedicated column.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 24 avril 2020  11:32:27

Offline

 

#22 2020-04-24 06:02:25 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6395

Re: Why Doesn't This Code Work?

Yvan Koenig wrote:

The Finder has a "logical behavior". If the ending substring "describes the contents of the file", it IS a name extension. In the other case, ITSN’T such object.



But how does the Finder know? You have a file called La.guillotine. How does it know I didn't save the file from my Chop.app and send it to you?


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#23 2020-04-24 07:42:31 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 4533

Re: Why Doesn't This Code Work?

@Shane
I'm sure that you know that but some readers may ignore it.
The Finder maintain a database of every name extension defined by the applications installed on the running machine.
As long of your application is not installed, "guillotine" is not identified as a name extension.
Such infos are given by the info.plist of every application in the array Exported Type UTIs.
For instance, in Preview's plist, the first item of the array is the dictionary Item 0 (public radiance).
This dictionary  contains a dictionary named Equivalent Types which itself contain an array of strings which are some of the name extensions which may be given to files exported by the app.
Here they are "pic", "PIC", "hdr", "HDR"
In your app it would be "guillotine" (with perhaps its Uppercase version "GUILLOTINE")
Complementary detail, if we uninstall the application, its set of extensions remains in the Finder's database (the launchservices one if I remember well).

As System Events and Foundation are too lazy to use the informations available to both of them, they make no difference between a registered/identified extension and a standard string.

Jean-Paul Sartre wrote a play entitled "La P... respectueuse" (when he did we didn't use ellipsis but 3 dots and France was ridiculous enough to refuse to write the word "Putain")

If I saved a text file containing this play in old times, the file would have been named "La P... respectueuse" because in these old times Apple system didn't use name extensions.
I have a lot of such old files and I never spent time to give them an extension.
As far as I know, nobody created an application using "respectueuse" as a name extension so, the Finder would be fair enough to know that the file has no extension.
The other tools, which may perfectly grab the info are too lazy to do that and would state that the file has the name extension "respectueuse" which is perfectly ridiculous and just prove their infamous laziness.

@KniazidisR
I apologize but I can't check what you wrote.
I tried to urge the Finder to stop displaying name extensions.
I entered its Preferences pane and unchecked the dedicated checkbox and for safe, I rebooted
No luck, extensions were always displayed.
I entered the file com.apple.finder.plist and saw that the property AppleShowAllExtensions was set to YES. I edited it as NO, rebooted and extensions were always visibe.

The script below extracts the available settings and you will see that the results match what I wrote.

Applescript:

tell application "System Events" to tell process "Finder"
   set frontmost to true
   keystroke "," using {command down}
   class of UI elements --> {window, menu bar, scroll area}
   name of windows --> {"Préférences du Finder"}
   tell window 1
       class of UI elements --> {checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, static text, pop up button, button, button, button, toolbar, static text}
       tell toolbar 1
           class of UI elements --> {button, button, button, button}
           name of buttons --> {"Général", "Tags", "Barre latérale", "Options avancées"}
           click button -1 --> "Options avancées"
       end tell --> toolbar 1
       class of UI elements --> {checkbox, checkbox, checkbox, checkbox, checkbox, checkbox, static text, pop up button, button, button, button, toolbar, static text}
       title of checkbox 1 --> "Afficher toutes les extensions de fichiers"
       value of checkbox 1 --> 0 -- unchecked
       title of checkbox 4 --> "Avertir avant de vider la corbeille"
       value of checkbox 4 --> 1 -- checked
   end tell
end tell

set showExtensions to do shell script "defaults read com.apple.finder AppleShowAllExtensions"--> "0"

If I ask the Finder for the properties of a file, I get something like:

Applescript:

{class:document file, name:"|ContentsStoreFormat%1$@_loc|.txt", index:263, displayed name:"|ContentsStoreFormat%1$@_loc|.txt", name extension:"txt", extension hidden:false, container:folder "Desktop" of folder "**********" of folder "Users" of startup disk of application "Finder", disk:startup disk of application "Finder", position:{-1, -1}, desktop position:{1134, 768}, bounds:{-33, -33, 31, 31}, kind:"Document format texte", label index:0, locked:false, description:missing value, comment:"", size:674, physical size:4096, creation date:date "samedi 11 avril 2020 à 12:22:33", modification date:date "samedi 11 avril 2020 à 12:22:33", icon:missing value, URL:"file:///Users/**********/Desktop/%7CContentsStoreFormat%251$@_loc%7C.txt", owner:"**********", group:"(inconnu)", owner privileges:read write, group privileges:read only, everyones privileges:read only, file type:missing value, creator type:missing value, stationery:false, product version:"", version:""}

I may live with a system behaving this way but if you tell me what I must do to really stop the extensions display I would be glad to check how it behaves at script level.
Of course, after doing that I would return to my standard settings.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 24 avril 2020  15:11:06

Offline

 

#24 2020-04-24 08:08:46 am

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 530

Re: Why Doesn't This Code Work?

This point has been made above, but I ran a simple test just to confirm my understanding and thought I would report the results.

I created two files with the following names: "Test File.txt" and "Test File.xxx". I then ran the following scripts and received the results shown:

Applescript:

tell application "Finder"
   name extension of file "Macintosh HD:Users:Robert:Test File.txt" --> "txt"
   name extension of file "Macintosh HD:Users:Robert:Test File.xxx" --> ""
end tell

tell application "System Events"
   name extension of file "Macintosh HD:Users:Robert:Test File.txt" --> "txt"
   name extension of file "Macintosh HD:Users:Robert:Test File.xxx" --> "xxx"
end tell

So, at least in this case, Finder was able to distinguish an invalid file extension and System Events was not. I ran these tests twice--first with the file extensions visible in the Finder and then with the file extensions hidden. The results did not change from those shown above.


2018 Mac mini - macOS Catalina

Offline

 

#25 2020-04-24 08:52:56 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 4533

Re: Why Doesn't This Code Work?

I discovered a funny thing.
Most of my files appear with their name extension but some don't.
In a given folder
16 .numbers doc have their extension, 4 haven't
2 .pages documents have their extension, 3 haven't
20 applets/droplets have no extension
every pdf or rtf files have their extension
50 .scpt files have their extension, one hasn't
15 .applescript files have their extension, one hasn't

I can't guess what is the logic at work in such behavior.
As I'm curious I ran a test file.

Applescript:

set aFile to (choose file) as alias

tell application "Finder"
   properties of aFile --> {class:document file, name:"Chèques YK 2019.numbers", index:9, displayed name:"Chèques YK 2019", name extension:"numbers", extension hidden:true, container:folder "ƒ banque" of folder "Important" of folder "Documents" of folder "**********" of folder "Users" of startup disk of application "Finder", disk:startup disk of application "Finder", position:{592, 22}, desktop position:missing value, bounds:{560, -10, 624, 54}, kind:"Feuille de calcul Numbers", label index:0, locked:false, description:missing value, comment:"", size:582932, physical size:618496, creation date:date "lundi 13 mai 2019 à 15:59:54", modification date:date "vendredi 24 avril 2020 à 15:44:00", icon:missing value, URL:"file:///Users/**********/Documents/Important/%C6%92%20banque/Che%CC%80ques%20YK%202019.numbers", owner:"**********", group:"(inconnu)", owner privileges:read write, group privileges:read only, everyones privileges:read only, file type:missing value, creator type:missing value, stationery:false, product version:"", version:""}
end tell

And what I see doesn't match KniazidisR's statements (but am'I really surprised by that?).
The name of the file has its extension "numbers".
The extension "numbers" is perfectly returned.
The extension is described as hidden.
The displayed name is correctly deprived of the extension.


I ran an expanded version of the KniazidisR's script:

Applescript:


property openTypes : {"PDF", "com.adobe.pdf", "BMP", "com.microsoft.bmp", "PICT", "com.apple.pict", "PNG", "public.png", "PSD", "com.adobe.photoshop-image", "TIFF", "public.tiff"}

--Get the artwork file
set theFiles to choose file with prompt "Choose art file(s)" of type openTypes with multiple selections allowed without invisibles
set theType to "JPG"

repeat with aFile in theFiles
   runTest(aFile, theType)
end repeat

on runTest(theArt, theType)
   log "theArt is " & theArt
   tell application "Finder"
       set theFolder to (container of theArt) as text
       set visiName to displayed name of theArt
       set theNewArt to theFolder & (name of theArt) & "." & theType
   end tell
   log "visible name is " & visiName & ", theNewArt is " & theNewArt & linefeed
end runTest

and what I got doesn't match KniazidisR's statements.
Note that the 1st and 3rd items have their extension visible, the 2nd one has its extension hidden although the 3 aliases appear with their extension.

Applescript:

tell application "Script Editor"
   choose file with prompt "Choose art file(s)" of type {"PDF", "com.adobe.pdf", "BMP", "com.microsoft.bmp", "PICT", "com.apple.pict", "PNG", "public.png", "PSD", "com.adobe.photoshop-image", "TIFF", "public.tiff"} with multiple selections allowed without invisibles
       --> {alias "SSD 1000:Users:**********:Documents:Important:ƒ banque:2018-11-23 Taxe habitation Roquesteron.pdf", alias "SSD 1000:Users:**********:Documents:Important:ƒ banque:2018-12-13.pdf", alias "SSD 1000:Users:**********:Documents:Important:ƒ banque:attestation tva 10%.pdf"}
end tell

(*theArt is SSD 1000:Users:**********:Documents:Important:ƒ banque:2018-11-23 Taxe habitation Roquesteron.pdf*)
tell application "Finder"
   get container of alias "SSD 1000:Users:**********:Documents:Important:ƒ banque:2018-11-23 Taxe habitation Roquesteron.pdf"
       --> "SSD 1000:Users:**********:Documents:Important:ƒ banque:"
   get displayed name of alias "SSD 1000:Users:**********:Documents:Important:ƒ banque:2018-11-23 Taxe habitation Roquesteron.pdf"
       --> "2018-11-23 Taxe habitation Roquesteron.pdf"
   get name of alias "SSD 1000:Users:**********:Documents:Important:ƒ banque:2018-11-23 Taxe habitation Roquesteron.pdf"
       --> "2018-11-23 Taxe habitation Roquesteron.pdf"
end tell
(*visible name is 2018-11-23 Taxe habitation Roquesteron.pdf, theNewArt is SSD 1000:Users:**********:Documents:Important:ƒ banque:2018-11-23 Taxe habitation Roquesteron.pdf.JPG
*)
WHICH IS WRONG

(*theArt is SSD 1000:Users:**********:Documents:Important:ƒ banque:2018-12-13.pdf*)
tell application "Finder"
   get container of alias "SSD 1000:Users:**********:Documents:Important:ƒ banque:2018-12-13.pdf"
       --> "SSD 1000:Users:**********:Documents:Important:ƒ banque:"
   get displayed name of alias "SSD 1000:Users:**********:Documents:Important:ƒ banque:2018-12-13.pdf"
       --> "2018-12-13"
   get name of alias "SSD 1000:Users:**********:Documents:Important:ƒ banque:2018-12-13.pdf"
       --> "2018-12-13.pdf"
end tell
(*visible name is 2018-12-13, theNewArt is SSD 1000:Users:**********:Documents:Important:ƒ banque:2018-12-13.pdf.JPG
*)
WHICH IS WRONG

(*theArt is SSD 1000:Users:**********:Documents:Important:ƒ banque:attestation tva 10%.pdf*)
tell application "Finder"
   get container of alias "SSD 1000:Users:**********:Documents:Important:ƒ banque:attestation tva 10%.pdf"
       --> "SSD 1000:Users:**********:Documents:Important:ƒ banque:"
   get displayed name of alias "SSD 1000:Users:**********:Documents:Important:ƒ banque:attestation tva 10%.pdf"
       --> "attestation tva 10%.pdf"
   get name of alias "SSD 1000:Users:**********:Documents:Important:ƒ banque:attestation tva 10%.pdf"
       --> "attestation tva 10%.pdf"
end tell
(*visible name is attestation tva 10%.pdf, theNewArt is SSD 1000:Users:**********:Documents:Important:ƒ banque:attestation tva 10%.pdf.JPG
*)
WHICH IS WRONG

Important feature, the authoring application name its documents and its windows according to the Finder's displayed name.

Applescript:

set aFile to ((path to documents folder as string) & "Important:ƒ banque:Chèques YK 2019.numbers") as «class furl»
tell application "Numbers"
   open aFile
   name of window 1 --> "Chèques YK 2019"
   tell document 1
       its name --> "Chèques YK 2019"
       its file --> file "SSD 1000:Users:**********:Documents:Important:ƒ banque:Chèques YK 2019.numbers"
       its modified --> false
   end tell
end tell

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 24 avril 2020  16:52:26

Last edited by Yvan Koenig (2020-04-24 08:54:59 am)

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)