can i add several attachments from subfolders to Mail? - applescript

trying to send several mails with specific attachments for each address. every address has its own subfolder for attachments. the "grab attachments part" does not work and I am not sure if the handler is set up right: should I pass the subfolder to mail inside the handler or keep it as I have it. This is my first long script so please don't be too harsh ;-)
I'm thinking that i get closer to the working solution, I still don't get it to function. here is my script so far:
` with timeout of 600 seconds
-- Liste: Alle Empfänger
tell application "Contacts"
set emailList to {}
set testPersons to every person of group "Test"
repeat with thisTestPerson in testPersons
set end of emailList to (value of email of thisTestPerson) as string
end repeat
end tell
-- Liste fuer die Übergabe alphabetisch sortieren
set the_list to emailList
set otid to AppleScript's text item delimiters
set AppleScript's text item delimiters to {ASCII character 10} -- always a linefeed
set list_string to (the_list as string)
set new_string to do shell script "echo " & quoted form of list_string & " | sort -f"
set new_list to (paragraphs of new_string)
set AppleScript's text item delimiters to otid
-- Liste: Alle Subfolder
tell application "Finder"
set mainfolder to choose folder "select a folder"
set folderList to {}
set myFolders to every folder of mainfolder
repeat with attachFolder from 1 to (count of myFolders)
set end of folderList to attachFolder as string
end repeat
end tell
-- Sicherheits-Check
set count1 to count of myFolders
set count2 to count of new_list
if count1 is not equal to count2 then
display dialog "Houston, we have a problem:" & return & "Die beiden Listen sind nicht gleich lang..." buttons {"ok"} with icon 2
return
end if
end timeout
--handler processfolder(myFiles)
on processfolder(myFiles)
tell application "Mail"
activate
set theAddress to (item i of emailList)
set theMex to (make new outgoing message at end of outgoing messages with properties {visible:true, subject:"Subjectheader", content:"email body"})
tell content of theMex
make new attachment with properties {file name:FileList} at after last paragraph
end tell
tell theMex
make new to recipient at end of to recipients with properties {address:theAddress}
end tell
send theMex
end tell
end processfolder
-- grab attachments and send mail
tell application "Finder"
repeat with myFolder from 1 to (count of folderList)
set FileList to {}
set myFiles to entire contents of myFolder
repeat with thisFile in myFiles
set end of FileList to thisFile as string
end repeat
my processfolder(myFiles)
end repeat
end tell
display dialog (count1 as string) & " Nachrichten verschickt."
end`
i believe the handler should work alright. Matching the subfolder list with the address list still seems to be a problem, I am not sure if my repeat loop "grab attachment und send mail" does the trick. It is a tricky use of repeat loops and I am still struggling with it. any quick thoughts about what I am still doing wrong?
thanks for being helpful! i really appreciate this!
marco

You must pass the variables as parameters in the handler :
1- (item i of emailList) : i and emailList is not defined in the handler.
2- {file name:FileList} : FileList is not defined in the handler, file name must be a path of type alias or string, not a list of path.
set myFiles to entire contents of myFolder : the myfolder variable is an integer, entire contents will contains the folders and files, if the folder doesn't contains subfolders, entire contents is useless, use files of xFolder.
The rest is okay, but contains unnecessary lines.
Here is the script:
with timeout of 600 seconds
-- Liste: Alle Empfänger
tell application "Contacts"
set emailList to value of email 1 of every person of group "Test"
end tell
-- Liste fuer die Übergabe alphabetisch sortieren
set otid to AppleScript's text item delimiters
set AppleScript's text item delimiters to {linefeed}
do shell script "echo " & (quoted form of (emailList as string)) & " | sort -f"
set emailList to (paragraphs of the result)
set AppleScript's text item delimiters to otid
-- Liste: Alle Subfolder
activate
set mainfolder to choose folder "select a folder"
tell application "Finder" to set folderList to folders of mainfolder
-- Sicherheits-Check
set count1 to count folderList
if count1 is not equal to (count emailList) then
display dialog "Houston, we have a problem:" & return & "Die beiden Listen sind nicht gleich lang..." buttons {"ok"} cancel button "ok" with icon 2
end if
end timeout
-- grab attachments and send mail
repeat with i from 1 to count1
try
tell application "Finder" to set myFiles to (files of entire contents of (item i of folderList)) as alias list
my processfolder(myFiles, item i of emailList)
end try -- no error on empty folder
end repeat
display dialog (count1 as string) & " Nachrichten verschickt."
on processfolder(tFiles, theAddress)
tell application "Mail"
activate
tell (make new outgoing message at end of outgoing messages with properties {visible:true, subject:"Subjectheader", content:("email body" & linefeed & " ")})
make new to recipient at end of to recipients with properties {address:theAddress}
tell content to repeat with tFile in tFiles
make new attachment with properties {file name:tFile} at after last paragraph
make new character with data linefeed at after last paragraph
end repeat
send
end tell
end tell
end processfolder

it is done! Thanks to you and one or two other pros I now have a beautiful bulk mailing script routine using automator, a bash line and (mainly) applescript. I use it for job applications but you can use it for any case where you want individualised bulk emailing with Mail, MS Word and any given list of contacts in Excel (or Address Book for that matter). For the sake of being complete I will add all necessary steps. with any given list of x names, email addresses, personal addresses you can generate x subfolders, containing x personalized letters and not-personalized documents (thanks, Jack! adding the docs works perfectly). once you start the last script and select the folder you can watch mail sending them all out, addressing the person by name and attaching the right personalized letter! It corrects for foreign name spelling that is rendered differently in the email address. It works best for email addresses using the last name before the "#" and can now ignore the first name if it is set in front of the last name (i.e. firstname.lastname#company.com). Thank you all very much for the assistance! this was great team effort.
I shall post it as soon as I am home, should I post it up here and in the other related question or is there a sharing forum?

Related

Get text of selected field code in Microsoft Word using AppleScript

I'm making a Automator to jump from citation in Word to the reference software(Zotero). But I can't find a AppleScript to extract text of selected field code (the first step).
The field code in Word is
ADDIN ZOTERO_ITEM CSL_CITATION {"citationID":"AFUiwuqi","properties":{"formattedCitation":"[1]","plainCitation":"[1]","noteIndex":0},"citationItems":[{"id":9752,"uris":["http://zotero.org/users/6410528/items/YYTRWPHH"],"itemData":{"id":9752,"type":"article-journal","container-title":"Nature","DOI":"10.1038/s41586-019-1737-7","ISSN":"0028-0836, 1476-4687","issue":"7782","page":"324-329","title":"Controlled flight of a microrobot powered by soft artificial muscles","volume":"575","author":[{"family":"Chen","given":"Yufeng"},{"family":"Zhao","given":"Huichan"},{"family":"Mao","given":"Jie"},{"family":"Chirarattananon","given":"Pakpong"},{"family":"Helbling","given":"E. Farrell"},{"family":"Hyun","given":"Nak-seung Patrick"},{"family":"Clarke","given":"David R."},{"family":"Wood","given":"Robert J."}],"issued":{"date-parts":[["2019",11,14]]}}}],"schema":"https://github.com/citation-style-language/schema/raw/master/csl-citation.json"}
Here is the script process:
Extract text from selected field code in Word (This is the question)
Get the uris text(http://zotero.org/users/6410528/items/YYTRWPHH)
Get the item-codes (YYTRWPHH).
Open url (zotero://select/library/items?itemKey=YYTRWPHH)
Now I use VBA to extract field code text, see below. But in this way, the file will be changed. So I want to do this via AppleScript.
Sub GetFiledsCodes()
Dim myRange As Range, myCodes As String
Set myRange = Selection.Range
With myRange
If .Fields.Count = 0 Then
MsgBox "No Code!", vbInformation
Exit Sub
Else
.Fields.Update
.TextRetrievalMode.IncludeFieldCodes = True
.TextRetrievalMode.IncludeHiddenText = True
myCodes = .Text
myCodes = VBA.Replace(myCodes, Chr(19), "{")
myCodes = VBA.Replace(myCodes, Chr(21), "}")
.SetRange .End, .End
.InsertAfter myCodes
.Font.Name = "Times New Roman"
.Font.Size = 12
.Cut
End If
End With
End Sub
PS:
Here is my process in Automator(it can work but using VBA):
Run AppleScript
on run {input, parameters}
tell application "Microsoft Word" to activate
tell application "Microsoft Word"
run VB macro macro name "GetFiledsCodes"
delay 0.5
end tell
return input
end run
Get contents from clipboard
Extract URLs from Text
Filter Paragraphs begin with http://zotero.org/users/
Copy to Clipboard
Run AppleScript
set myStr to do shell script "pbpaste"
tell application "Zotero" to activate
set AppleScript's text item delimiters to "
"
set myList to every text item of myStr
set zoterocode to ""
set codes to ""
repeat with j from 1 to the length of myList
set itemValue to item j of myList
set zoterocode to (do shell script "sed -E 's#http://zotero.org/users/[0-9]+/items/##g' <<< " & itemValue)
if j = 1 then
set codes to zoterocode
else
set codes to codes & "," & zoterocode
end if
end repeat
tell application "System Events"
key code 18 using {command down, control down, option down}
delay 0.5
set collectionKey to do shell script "pbpaste"
if collectionKey = myStr then
set theurl to "zotero://select/library/items?itemKey=" & codes
else
set theurl to collectionKey & "/items?itemKey=" & codes
end if
open location theurl
end tell
That helps a lot. Okay, so this isn't a turnkey solution for your question but I don't think you really need that as you'd probably end up having to tell me more about how this app works than is really necessary. So this script focuses on your initial question about getting the field codes/result ranges from a merge document.
I put together a simple mail merge consisting of labels and a data file with 8 records, each of which have 5 fields: {"«LastName»", "«JobTitle»", "«Company»", "«City»", "«Web»"}. The latter is the key field.
Basically, the script runs through the data merge document and cycles first through its fields, then the web field, and finally the web addresses.
Based on your script, I can't really determine what you are doing with each address so it finishes by collecting just the final part of each address in a list. The obscure parts for me are the pbpastes, the codes and the whole System Events block. This area would need tweaking.
Incidentally, it's quite likely that you can avoid some of the shell scripts but I can't say how yet. Obviously the script has some redundancies and could be further refined but I think it demonstrates how to extract the information you need. Take a look at it and let me know what issues there are that need addressing.
tell application "Microsoft Word"
set d1 to document "cardo_labels.docx"
set fContents to {} -- list of mergefield
set fResRange to {} -- list of result range, i.e. field merge data
repeat with x from 1 to (count of fields of d1)
set fcs to content of field code of field x of d1 --> " MERGEFIELD LastName "
set frr to content of result range of field x of d1 --> "Smith"
if fcs is not " NEXT " then -- ignore «Next Record»
set end of fContents to fcs
set end of fResRange to frr
end if
end repeat
--> single record example
fContents --> {" MERGEFIELD LastName ", " MERGEFIELD JobTitle ", " MERGEFIELD Company ", " MERGEFIELD City ", " MERGEFIELD Web "}
fResRange --> {"Smith", "President", "Acme Screw & Gear", "Metz", "http://zotero.org/users/1234/items/smith-metz"}
-- NB when not displaying 'merged data', fResRange will appear thusly: {"«LastName»", "«JobTitle»", "«Company»", "«City»", "«Web»"}
set webList to {}
repeat with y from 1 to (count of fResRange)
if item y of fResRange begins with "http://zotero.org/users/" then
set end of webList to (item y of fResRange)
end if
end repeat
--> {"http://zotero.org/users/1234/items/smith-metz"}
--> {"http://zotero.org/users/1234/items/smith-metz", "http://zotero.org/users/4222/items/branson-metz", "http://zotero.org/users/3236/items/house-metz", "http://zotero.org/users/3342/items/kurtz-london", "http://zotero.org/users/12345/items/jones-london"}
set urlPiece to {}
set AppleScript's text item delimiters to "/"
repeat with z in webList
set end of urlPiece to last text item of z
end repeat
-- contents of z
--> "http://zotero.org/users/1234/items/smith-metz"
set AppleScript's text item delimiters to ""
urlPiece
--> {"smith-metz"}
--> {"smith-metz", "jones-saopaolo", "branson-metz", "house-metz", "kurtz-london", "jones-london"}
end tell
Thanks to ideas from #Mockman.
Combining with the selection, here is the way to extract text from selected field code via AppleScript:
tell application "Microsoft Word"
tell selection
set fcs to content of field code of field of text object
end tell
end tell
fcs

Populate iTunes playlist from csv file

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];
}

applescript to create multiple sequentially numbered folders with a specific prefix

I would like to create an applescript that will create multiple folders with the same root name but the numbers change? or at least a repeating folder creation script until the person has enough folders. So something that makes folders like this: JOYR-15-0035-00, JOYR-15-0036-00, JOYR-15-0037-00 and so on. Is that at all possible? I am just learning this. I am normally a graphic designer but I feel like I can get a lot from applescript.
Currently I just have this basic script:
tell application "Finder"
set KDID to text returned of (display dialog "Enter the KDID ID:" default answer "JOYR-")
set loc to choose folder "Choose Parent Folder Location"
set newfoldername to {name:KDID}
set newfo to make new folder at loc with properties {name:KDID}
reveal newfo
end tell
Try this, it assumes that the KDID is just the number 15 in the example, the syntax is always JOYR-<KDID>-<consecutive number>-00 and the leading JOYR as well as the trailing double zero don't change.
The script asks for the parent folder, the KDID and the number of sequential folders. Then it checks the parent folder for the greatest existing number (the 0035 part) and creates folders starting with the greatest number plus 1 or – if no existing folders are found – with 1. The number has always four digits.
property letterPrefix : "JOYR"
property KDID : "15"
property parentFolder : missing value
set parentFolder to choose folder "Choose Parent Folder Location"
tell application "Finder"
activate
set KDID to text returned of (display dialog "Enter the KDID ID:" default answer "15")
repeat
set howManyFolders to text returned of (display dialog "Enter the Number of Folders to create:" default answer "1")
try
set howManyFolders to howManyFolders as integer
if howManyFolders < 1 then error
exit repeat
on error
display dialog "Please enter an integer value greater than 0" default answer "1"
end try
end repeat
set currentNumber to my getGreatestFolderNumber()
repeat howManyFolders times
set folderName to letterPrefix & "-" & KDID & "-" & my pad(currentNumber) & "-00"
make new folder at parentFolder with properties {name:folderName}
set currentNumber to currentNumber + 1
end repeat
open parentFolder
end tell
on getGreatestFolderNumber()
tell application "Finder"
set {ASTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "-"}
try
set folderNames to name of folders of parentFolder whose name starts with (letterPrefix & "-" & KDID & "-")
set maxNumber to 0
repeat with aName in folderNames
set curNumber to (text item 3 of aName) as integer
if curNumber > maxNumber then set maxNumber to curNumber
end repeat
set AppleScript's text item delimiters to ASTID
return maxNumber + 1
on error
set AppleScript's text item delimiters to ASTID
return 1
end try
end tell
end getGreatestFolderNumber
on pad(v)
return text -4 thru -1 of ("000" & v)
end pad

Get the recipient of a draft (AppleScript, Mail.app)

I want to get the recipients ("to" fields, etc) of a draft on my draft's folder of Mail.app, by using AppleScript. Can't seem to find the correct syntax to that.
Thanks.
Here's code to do it, in Scripting Bridge (Cocoa):
for (MailRecipient *recp in message.recipients) {
MailToRecipient *theRecipient = [[[mail classForScriptingClass:#"to recipient"] alloc] initWithProperties:[NSDictionary dictionaryWithObjectsAndKeys:recp.address, #"address", nil]];
}
Actually it is possible with pure AppleScript unlike the Cocoa solution proposed earlier. Here's a snippet of the code used to get the input values of the "TO" recipients field.
tell application "Mail"
set draftMessages to every message in drafts mailbox
set draftMessagesID to {}
# go through each draft message
repeat with draftMessage in draftMessages
set draftMessageID to id of draftMessage as string
copy draftMessageID to the end of draftMessagesID
end repeat
# go through the list of draft message ids and process the most recent item
if (count of the draftMessagesID) is greater than 1 then
set sortedDraftMessagesID to the reverse of my sortAlphabetically(the draftMessagesID)
# get only the first item, as this is the most recent
set lastDraftMessageID to first item of sortedDraftMessagesID as integer
# get the most recent draft message
set draftMessage to first message of drafts mailbox whose id is lastDraftMessageID
set toAddresees to {}
repeat with toRecipient in (get to recipients of draftMessage)
set toName to name of toRecipient
set toAddress to address of toRecipient
set toFinal to my composeNameAndAddress(toName, toAddress)
copy toFinal to end of toAddresees
end repeat
# now you have the input values of the TO field
log toAddresees
end if
end tell
#handler to compose name and address when one is missing
on composeNameAndAddress(name, address)
if name is missing value then
return address
else
return name & space & "<" & address & ">"
end if
end composeNameAndAddress
#handler to sort a list alphabetically
on sortAlphabetically(theList)
set the indexList to {}
set the sortedList to {}
repeat (the number of items in theList) times
set the lowItem to ""
repeat with i from 1 to (number of items in theList)
if i is not in the indexList then
set thisItem to item i of theList as string
if the lowItem is "" then
set the lowItem to thisItem
set the lowItemIndex to i
else if thisItem comes before the lowItem then
set the lowItem to thisItem
set the lowItemIndex to i
end if
end if
end repeat
set the end of sortedList to the lowItem
set the end of the indexList to the lowItemIndex
end repeat
return the sortedList
end sortAlphabetically
You mentioned that you needed a specific draft, for this script I've assumed that you can (for instance) obtain the latest draft by taking the draft message with the highest ID. This is what the above script does using the reverse command with a generic simple sort handler.
The drafts mailbox is contained by the message viewer. Since the messages have not been sent yet, you cannot get its "to recipients". However, you can get the message source that contains the list of recipients. The trick is to then extract the recipients from this text.
tell application "Mail"
set the_messages to every message in drafts mailbox
repeat with this_message in the_messages
set message_content to the source of this_message
log message_content
end repeat
end tell

Applescript: Get filenames in folder without extension

I can get the names of all files in a folder by doing this:
tell application "Finder"
set myFiles to name of every file of somePath
end tell
How can I change the strings in myFiles so that they do not include the file extension?
I could for example get {"foo.mov", "bar.mov"}, but would like to have {"foo", "bar"}.
Current solution
Based on the accepted answer I came up with the code below. Let me know if it can be made cleaner or more efficient somehow.
-- Gets a list of filenames from the
on filenames from _folder
-- Get filenames and extensions
tell application "Finder"
set _filenames to name of every file of _folder
set _extensions to name extension of every file of _folder
end tell
-- Collect names (filename - dot and extension)
set _names to {}
repeat with n from 1 to count of _filenames
set _filename to item n of _filenames
set _extension to item n of _extensions
if _extension is not "" then
set _length to (count of _filename) - (count of _extension) - 1
set end of _names to text 1 thru _length of _filename
else
set end of _names to _filename
end if
end repeat
-- Done
return _names
end filenames
-- Example usage
return filenames from (path to desktop)
From http://www.macosxautomation.com/applescript/sbrt/index.html :
on remove_extension(this_name)
if this_name contains "." then
set this_name to ¬
(the reverse of every character of this_name) as string
set x to the offset of "." in this_name
set this_name to (text (x + 1) thru -1 of this_name)
set this_name to (the reverse of every character of this_name) as string
end if
return this_name
end remove_extension
Single line way of doing it, no Finder, no System Events. So more efficient and faster. Side effect (could be good, or bad): a file name ending with "." will have this character stripped out. Using "reverse of every character" makes it works if the name as more than one period.
set aName to text 1 thru ((aName's length) - (offset of "." in ¬
(the reverse of every character of aName) as text)) of aName
The solution as a handler to process a list of names:
on RemoveNameExt(aList)
set CleanedList to {}
repeat with aName in aList
set the end of CleanedList to text 1 thru ((aName's length) - (offset of ¬
"." in (the reverse of every character of aName) as text)) of aName
end repeat
return CleanedList
end RemoveNameExt
Here's an applescriptish method to get Finder's idea of what the stripped filename is but please note it will only work if you have NOT enabled the option in Finder's preferences to "Show all filename extensions":
set extension hidden of thisFile to true
set thisName to displayed name of thisFile
-- display dialog "hey"
set extension hidden of thisFile to false
Here's a full script that does what you wanted. I was reluctant to post it originally because I figured there was some simple one-liner which someone would offer as a solution. Hopefully this solution is not a Rube Goldberg way of doing things.
The Finder dictionary does have a name extension property so you can do something like:
tell application "Finder"
set myFiles to name extension of file 1 of (path to desktop)
end tell
So the above will get you just the extension of the first file on the user's desktop. It seems like there would be a simple function for getting the (base name - extension) but I didn't find one.
Here's the script for getting just the filenames without extension for every file in an entire directory:
set filesFound to {}
set filesFound2 to {}
set nextItem to 1
tell application "Finder"
set myFiles to name of every file of (path to desktop) --change path to whatever path you want
end tell
--loop used for populating list filesFound with all filenames found (name + extension)
repeat with i in myFiles
set end of filesFound to (item nextItem of myFiles)
set nextItem to (nextItem + 1)
end repeat
set nextItem to 1 --reset counter to 1
--loop used for pulling each filename from list filesFound and then strip the extension
--from filename and populate a new list called filesFound2
repeat with i in filesFound
set myFile2 to item nextItem of filesFound
set myFile3 to text 1 thru ((offset of "." in myFile2) - 1) of myFile2
set end of filesFound2 to myFile3
set nextItem to (nextItem + 1)
end repeat
return filesFound2
Though the above script does work if anyone knows a simpler way of doing what the OP wanted please post it cause I still get the sense that there should be a simpler way of doing it. Maybe there's a scripting addition which facilitates this as well. Anyone know?
Based on Lauri Ranta's nice solution, which works for extensions that Finder doesn't know about:
set delims to AppleScript's text item delimiters
set AppleScript's text item delimiters to "."
set myNames to {}
tell application "Finder"
set myFiles to name of every file of (path to Desktop)
repeat with myfile in myFiles
set myname to name of file myfile
if myname contains "." then set myname to (text items 1 thru -2 of myname) as text
set end of myNames to myname
end repeat
end tell
set AppleScript's text item delimiters to delims
return myNames
I don't know how to remove the extensions when you use the "every file"
syntax but if you don't mind looping (loop not shown in example) through each file then this will work:
tell application "Finder"
set myFile to name of file 1 of somePath
set myFile2 to text 1 thru ((offset of "." in myFile) - 1) of myFile
end tell
Within a tell "Finder" block this collects file names stripped of the extension in myNames:
repeat with f in myFiles
set myNames's end to ¬
(f's name as text)'s text 1 thru -(((f's name extension as text)'s length) + 2)
end repeat
For a single file I found the answer here, copied below.
set theFileName to "test.jpg"
set thePrefix to text 1 thru ((offset of "." in theFileName) - 1) of theFileName
This is a little more than you need, but it will handle more than one "." in a file name.
Assuming that a file alias is passed in to the method.
on Process(myFileAlias)
set myFile to myFileAlias as string
set AppleScript's text item delimiters to ":"
set myItemCount to the number of text items in myFile
set myFileName to the last text item of myFile
set myFilePath to text items 1 through (myItemCount - 1) of myFile
set AppleScript's text item delimiters to "."
set myItemCount to the number of text items in myFileName
set myExtension to the last text item of myFile
// This line is the key.
set myShortFilename to text items 1 through (myItemCount - 1) of myFileName as string
log (myFileName)
log (myShortFilename)
end

Resources