Search Outlook contacts by category - applescript

Is there a way to search for Contacts in Outlook 2011 for the Mac by Categories?
tell application "Microsoft Outlook"
-- get the category by name
set theCategory to item 1 of (every category whose name = "Recruiter")
-- correctly displays 'Recruiter [25]'
display dialog (name of theCategory) & " [" & (id of theCategory) & "]"
-- perform the search (incorrectly, it seems)
set theContacts to (every contact whose (every category contains theCategory))
-- should display ~100; actually displays 0
display dialog (count of theContacts)
end tell

I think there may be some bugs/features in the OL dictionary implementation with regard to categories - I think your search statement should work, but I agree it doesn't.
One workaround to this is to do a spotlight search instead. This may even be preferable, because it is probably faster than using the OL dictionary. In short, replace your set theContacts to ... line with the following:
set currentIdentityFolder to quoted form of POSIX path of (current identity folder as string)
set theContactIDs to words of (do shell script "mdfind -onlyin " & currentIdentityFolder & " 'kMDItemContentType == com.microsoft.outlook14.contact && com_microsoft_outlook_categories == " & id of theCategory & "' | xargs -I % mdls -name com_microsoft_outlook_recordID '%' | cut -d'=' -f2 | sort -u | paste -s -")
set theContacts to {}
repeat with thisContactID in theContactIDs
set end of theContacts to contact id thisContactID
end repeat
-- For example display the first name of the first contact
display dialog first name of (item 1 of theContacts) as string
This will do a spotlight search (mdfind command) for the contacts you require:
It will only look in your current identity folder
It will only look for contacts
It will only return contacts which are marked with the id of the "Recruiter" category
The output of the mdfind command is a list of files which match this query. So this output is piped to mdls, which will list all spotlight-searchable fields, including category. A simple list of contact IDs should be returned to applescript.
The list of contact IDs can then be converted to a list of contacts with the simple repeat loop.

Related

Count number of iTunes songs by Artist with a name starting with a letter

I am brand new to Applescript. I would like a script that would list the artist and the number of songs in that artist's folder. I would like to do it just for artists whose names starts with A. When I am ready, I would then get the list for artist whose names starts with B, and so on. I did find this post: "What's the fastest way in iOS to retrieve the number of songs for a specific artist?" Maybe that script would work but I don't know how to modify this line "if (artistName != nil)" to get what I want. Also, I don't know where the information is stored so I can retreive it "// store the new count
[artists setObject:[NSNumber numberWithInt:numSongs] forKey:artistName]; Oh, and I am not using iOS I will be using osx. Perhaps I could modify this script that I found. It gets the number of albums by artist.
MPMediaQuery *albumQuery = [MPMediaQuery albumsQuery];
NSArray *albumCollection = [albumQuery collections];
NSCountedSet *artistAlbumCounter = [NSCountedSet set];
[albumCollection enumerateObjectsUsingBlock:^(MPMediaItemCollection *album, NSUInteger idx, BOOL *stop) {
NSString *artistName = [[album representativeItem] valueForProperty:MPMediaItemPropertyArtist];
[artistAlbumCounter addObject:artistName];
}];
NSLog(#"Artist Album Counted Set: %#", artistAlbumCounter);
I appreciate any help that you can offer. Thanks!
It makes no sense to look at iOS code and ObjectiveC at that in order to figure out what you should do with Applescript! In any case, here is what you want.
tell application "iTunes"
# Get playlist currently selected
set myPlayList to view of window 1
set s to (every track in myPlayList whose artist begins with "g")
repeat with t in s
log name of t
end repeat
log (count of s)
end tell
This one uses the selected playlist (or, if that fails for some reason, the whole library) and goes from A to Z. Replace the log parts with your code. To see how it works make sure in Script-Editor it shows the Log and for a better view select the Messages tab. Only file tracks are handled.
tell application "iTunes"
try
set selectedPlayList to view of window 1
on error
beep
set selectedPlayList to (container of browser window 1) -- whole library (I think)
end try
end tell
set totalItems to 0
repeat with i from (id of "A") to (id of "Z")
set thisLetter to (character id i)
log "-----------------------------------------------------------"
tell application "iTunes"
try
set currentItems to (file tracks in selectedPlayList whose artist begins with thisLetter)
set countItems to number of items in currentItems
set totalItems to totalItems + countItems
set s to "s"
if countItems = 1 then set s to ""
log (countItems as text) & " item" & s & " for artists starting with the letter " & quoted form of thisLetter
log "-----------------------------------------------------------"
repeat with i from 1 to countItems
set thisItem to item i of currentItems
tell thisItem -- this is like "tell file track x". Shortens the code because we can use "artist" instead of "artist of thisItem"
log (i as text) & ". " & quoted form of (get artist) & " | " & quoted form of (get name) & " [ " & time & " ] "
end tell
end repeat
on error the error_message number the error_number
beep
display dialog "Error: " & the error_number & ". " & the error_message buttons {"OK"} default button 1
return
end try
end tell
end repeat
log "-----------------------------------------------------------"
log "Items: " & totalItems as text

AppleScript - How to change category of calendar event based on subject of calendar event

I'm using Outlook 2011 for Mac.
The idea is to label all calendar events with "X123" as subject with a new category: category "Blabla". With this change, I also want to delete the old category, if there is one.
I got a little snippet from Ramon's topic (thanks!), but could someone help me out, since the question is a bit different.
This is what I got till now:
tell application "Microsoft Outlook"
set theCategory to first category whose name is "Blabla"
set theEventList to every calendar event whose (subject is "X123")
display dialog "There are " & (count of theEventList) & " Events."
set theEvent to item 1 of items of theEventList
set currentIdentityFolder to quoted form of POSIX path of (current identity folder as string)
set cmd to "mdfind -onlyin " & currentIdentityFolder & " 'kMDItemContentType == com.microsoft.outlook14.event && com_microsoft_outlook_categories == " & id of theCategory & "' | xargs -I % mdls -name com_microsoft_outlook_recordID '%' | cut -d'=' -f2 | sort -u | paste -s -"
set theEventIDs to words of (do shell script cmd)
set theCategory to {}
repeat with thisEventID in theEventIDs
-- set the new category
set theCategory to category "Blabla"
display dialog "test"
end repeat
end tell
Thanks ShooTerKo. I've got some help from a genius. This piece of AppleScript is the answer of my own question:
tell application "Microsoft Outlook"
set theCategory to category "Blabla" -- theCategory = "Blabla"
set theEventList to every calendar event whose subject contains "X123" -- theEventList contains "X123"
-- Loop through each event
repeat with theEvent in theEventList
set category of theEvent to {} -- Empty all other categories
set category of theEvent to {theCategory} -- Set the new category to theCategory
end repeat
end tell
tell application "Microsoft Outlook"
set theCategory to category "iOGS" -- theCategory = "Blabla"
set theEventList to every calendar event whose organizer contains "#yourdomain.com" -- theEventList contains "X123"
-- Loop through each event
repeat with theEvent in theEventList
set category of theEvent to {} -- Empty all other categories
set category of theEvent to {theCategory} -- Set the new category to theCategory
end repeat
end tell
The above code uses the previous, excellent code as a basis and modifies it to set the category based on the organizer's email domain.

Applescript Returned Text not Splitting

Ive been playing with applescript for about 2 weeks now, but I have hit a problem
Im trying to create an applescript that reads all the names of the folders on our server.
Then displays them in a drop down menu so that I can select the client.
The problem I have is that it is displaying the result as one selection option as a big sentence and is not separating each client, so they can be selected individually.
so far I have:
set theFolder to alias "server:"
tell application "Finder"
set theText to name of theFolder & return
set k to 0
repeat with thisSubfolder in (get folders of theFolder)
set k to k + 1
set theText to theText & name of thisSubfolder & return
end repeat
end tell
set l to {theText}
set l2 to ""
repeat with i in l
set l2 to l2 & quoted form of i & " "
end repeat
do shell script "/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog \\
standard-dropdown --title Title --text Text --items " & l2
set {button, answer} to paragraphs of result
if button is 1 then
return item {answer + 1} of l
end if
Many thanks
D
When you do this:
set l to {theText}
You're just creating a list of one item (your string), which means you end up with this:
{"theFolder
folder1
folder2
folder3
"}
You're then repeating in that "list," trying to add spaces between the items. But, you don't have a list really. You have a one item list, with return-delimited strings.
The best way to get a list of folder names would be to get them from System Events. Notice that in this case, you have to create a list with the name of the first folder as the only item. Otherwise, the & operation will join everything together as a string, instead of creating a list.
tell application "System Events"
set l to (name of theFolder as list) & name of folders of theFolder
end tell
There are also some syntactical issues that will hurt you later:
1 != "1"
CocoaDialog returns a string, with the button number: "1". You are using if button is 1. For equality, it should be if button is "1".
Parentheses are used for grouping, not brackets
If button is "1", you are returning item {answer + 1} of l. I blame Applescript for letting this work when it shouldn't. You're actually creating a list with a number, which then gets coerced by Applescript for the list index. Here are all the steps, assuming answer is 0:
item {answer + 1} of l gets turned into
item {1} of {folder1, folder2, folder3}
Applescript coerces to item 1 of {folder1, folder2, folder3}
Value returned: folder1
Here is a fully updated version of your script:
set theFolder to alias "server:"
tell application "System Events"
set l to {name of theFolder} & name of folders of theFolder
end tell
set args to ""
repeat with i from 1 to (count l)
set args to args & quoted form of item i of l
if i < (count l) then
set args to args & " "
end if
end repeat
do shell script "/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog \\
standard-dropdown --title Title --text Text --items " & args
set {button, answer} to paragraphs of result
if button is "1" then
return item (answer + 1) of l
end if
Change the line:
set l to {theText}
to:
set l to paragraphs of theText
and you should be good to go.

applescript transforming a list into a txt file

I'm trying to write all the song names my iTunes to a txt document. The first issue I had was that I can't seem to correctly loop the operation. Here is my test case with the first 15 songs in my iTunes:
tell application "TextEdit"
make new document
end tell
tell application "iTunes"
set trNameID1 to name of track 1
set trNameID2 to name of track 2
set trNameID3 to name of track 3
set trNameID4 to name of track 4
set trNameID5 to name of track 5
set trNameID6 to name of track 6
set trNameID7 to name of track 7
set trNameID8 to name of track 8
set trNameID9 to name of track 9
set trNameID10 to name of track 10
set trNameID11 to name of track 11
set trNameID12 to name of track 12
set trNameID13 to name of track 13
set trNameID14 to name of track 14
set trNameID15 to name of track 15
tell application "TextEdit"
set text of document 1 to {trNameID1 & "
", trNameID2 & "
", trNameID3 & "
", trNameID4 & "
", trNameID5 & "
", trNameID6 & "
", trNameID7 & "
", trNameID8 & "
", trNameID9 & "
", trNameID10 & "
", trNameID11 & "
", trNameID12 & "
", trNameID13 & "
", trNameID14 & "
", trNameID15} as text
end tell
end tell
When I try to loop it, the txt document only contains the last song name, for instance:
tell application "TextEdit"
make new document
end tell
tell application "iTunes"
set trNum to 1
repeat 15 times
set trNameID to name of track (trNum)
tell application "TextEdit"
set text of document 1 to trNameID & "
"
end tell
end repeat
end tell
This will only output the fifteenth song's name onto the txt document.
I realize that this may be very basic, but I have literally been using applescript for about 48 hours, and I can't seem to figure this out. I would like all of the song names to be in a txt document so I can read and analyze the strings in c++. Does anyone have any ideas?
Also, I'm not sure if there is a way, in AppleScript, to look at the entire iTunes library and see the last song, record that song's id in iTunes, and then make a repeat loop that goes through that id. This way the loop would work for exactly the number of songs that are in the library.
Any ideas would be very much appreciated!
You don't really need a repeat loop at all. You can get track names directly from iTunes. You get it in list format so we just convert that list into a string separating the list items with a return character. Then we write it to TextEdit. So this code optimizes #Michele Percich's code by eliminating the repeat loop and using applescript's text item delimiters to convert the list to a string for use in TextEdit.
tell application "iTunes"
set trackNames to name of every track in (first playlist whose special kind is Music)
end tell
set text item delimiters to return
set trackNames to trackNames as text
set text item delimiters to ""
tell application "TextEdit"
make new document
set text of document 1 to trackNames
end tell
You need to increment the value of trNum variable at the end of your repeat loop:
set trNum to trNum + 1
Or better use a different repeat syntax:
repeat with trNum from 1 to 15
And also to add (and not replace) the track name to the document:
set text of document 1 to text of document 1 & trNameID & return
However, this probably is a better way to do what you want:
tell application "iTunes"
set trackList to ""
set allTracks to every track in (first playlist whose special kind is Music)
repeat with currentTrack in allTracks
set trNameID to name of currentTrack
set trackList to trackList & trNameID & return
end repeat
end tell
tell application "TextEdit"
make new document
set text of document 1 to trackList
end tell
i see you all use the:
tell application "TextEdit"
make new document
set text of document 1 to trackNames
end tell
command
You can use a faster way:
set textlocation to "/users/yourusername/desktop/test.txt"
set Line_1 to "Hello this is line one, if you want more lines just copy > this script and change the variables."
do shell script "echo " & quoted form of Line_1 & " >> " & quoted form of textlocation
You can see in the script the 2 ">>" signs, this will add each textline in a new line in a txt file.
If there is only one ">" the text will replace the other text.
Here is an example:
First with 2 ">>" lines
do shell script "echo Hey this is one line. >> /Users/Yourusername/desktop/Add.txt"
do shell script "echo And this is the second one. >> /Users/Yourusername/desktop/Add.txt"
This script will make a txt file like this:
Hey this is one line.
And this is the second one.
Now with 2 ">" lines
do shell script "echo Hey this is one line > /Users/Zl109819/desktop/Add.txt"
do shell script "echo And this is the second one > /Users/Zl109819/desktop/Add.txt"
This script will make a txt file like this:
And this is the second one.

can i add several attachments from subfolders to Mail?

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?

Resources