I'm running an applescript to extract all the email adress from all the messages in my boss's inbox and it freezes on his computer and works fine on mine.
my computer is running Snow leopard with mail 4.6 and his is running Lion with mail 5.3 if that makes any difference.
Also my inbox only has around 400 mails since i don't usually use mail and only got those messages to test the script and his has over 60 000.
The script ran through my email in around 20 seconds and on his took 2 minutes to do 40 then froze.
I was wondering if there was anything wrong with the code that could cause it to freeze in his higher version or due to the increase in email present.
On another note i know that writing them all one by one is probably counter-productive because the script i adapted this from was sorting the adresses and removing duplicates before writing them to the file but i thought that due to the large number of mails that it would speed the process and use less memory to just write them. PLus the counters helps to know where the script is at.
here is the code :
tell application "Finder" to set ptd to path to documents folder as string
set theFile to ptd & "extracted3.txt"
set theFileID to open for access theFile with write permission
set counter to 0
tell application "Mail"
set selectionMessage to selection -- just select the first message in the folder
set thisMessage to item 1 of selectionMessage
set theseMessages to (every message in (mailbox of thisMessage))
repeat with eachMessage in theseMessages
try
set counter to counter + 1
set theFrom to (extract address from sender of eachMessage)
set theFromName to (extract name from sender of eachMessage)
set theFromTemp to theFrom & "," & theFromName & "," & counter
write theFromTemp & return to theFileID as «class utf8»
if (address of to recipient) of eachMessage is not {} then
repeat with i from 1 to count of to recipient of eachMessage
set theTo to (address of to recipient i) of eachMessage as string
set theToName to (name of to recipient i) of eachMessage as string
set theToTemp to theTo & "," & theToName & "," & counter
write theToTemp & return to theFileID as «class utf8»
end repeat
end if
if (address of cc recipient) of eachMessage is not {} then
repeat with i from 1 to count of cc recipient of eachMessage
set theCC to (address of cc recipient i) of eachMessage as string
set theCCName to (name of cc recipient i) of eachMessage as string
set theCCTemp to theCC & "," & theCCName & "," & counter
write theCCTemp & return to theFileID as «class utf8»
end repeat
end if
end try
end repeat
end tell
close access theFileID
EDIT: after further thought, I removed the first script I posted. My thought is the problem you are seeing is because you are getting 60,000+ emails at once in this line...
set theseMessages to (every message in (mailbox of thisMessage))
So the idea is to just get a bunch at a time. I use the variable writeEveryXMessages to specify that you should get 500 messages at a time, and on each loop we get the next 500 until finished.
NOTE: I modified your code to be a little more efficient and fixed a few possible bugs, for example the write command is no longer in the Mail tell block of code. Also it now writes those 500 messages to file at one time. This script works on Mountain Lion and Mail v6.2. It should work for you too.
I hope this fixes your problem! Good luck.
set theFile to (path to documents folder as text) & "extracted3.txt"
set writeEveryXMessages to 500
set counter to 1
try
set theFileID to open for access file theFile with write permission
tell application "Mail"
set selectedMessage to item 1 of (get selection)
set theMailbox to mailbox of selectedMessage
set messageCount to count of messages in theMailbox
end tell
repeat
set endCount to counter + writeEveryXMessages
if endCount is greater than messageCount then set endCount to messageCount
set theString to ""
tell application "Mail"
set theseMessages to messages counter thru endCount of theMailbox
end tell
repeat with eachMessage in theseMessages
set theFromTemp to ""
set theToTemp to ""
set theCCTemp to ""
try
tell application "Mail"
tell eachMessage
set theSender to sender
set toRecipients to to recipients
set ccRecipients to cc recipients
end tell
set theFrom to extract address from theSender
set theFromName to extract name from theSender
set theFromTemp to "From: " & theFrom & "," & theFromName & "," & counter & return
if toRecipients is not {} then
repeat with toRecipient in toRecipients
try
set theTo to address of toRecipient
set theToName to name of toRecipient
set theToTemp to theToTemp & " To: " & theTo & "," & theToName & "," & counter & return
end try
end repeat
end if
if ccRecipients is not {} then
repeat with ccRecipient in ccRecipients
try
set theCC to address of ccRecipient
set theCCName to name of ccRecipient
set theCCTemp to theCCTemp & " CC: " & theCC & "," & theCCName & "," & counter & return
end try
end repeat
end if
end tell
set theString to theString & theFromTemp & theToTemp & theCCTemp & return
end try
set counter to counter + 1
end repeat
write theString to theFileID as «class utf8»
if counter is greater than or equal to messageCount then
set theString to ""
exit repeat
end if
end repeat
close access theFileID
on error theError
log theError
try
close access file theFile
end try
end try
Related
I use SQL Server Agent Jobs/DTS packages, coded in ActiveX Script/VBScript.
It works fine.
But there are some issues I would need help at the moment:
First: Is there a possibility to send an html email out of the ActiveX Script code in the DTS Step?
My company doesn't want to buy a separate commercial DLL for sending smtp email .. like JMail for example.
I know there are many such DLLs I could buy which can be used to send an email using VB or other languages.
But we don't have the money for such external components.
Could I use SQL Server Database Mail?
... but it is necessary to send the mails in html ...
Is there a possibility to create a new *.txt, *.csv or *.xlsx file from the ActiveX Script/VBScript code in the DTS Step?
I would like to copy the html email body code (a string which I built in the ActiveX Script code) into these files and attach them to the email I send out of the script code. So the user/recipient gets the html content embedded in the email body and separate in files too.
Thanks in advance for your help.
Tommy
This code works. PLUS it displays any errors which tell you why it didn't work.
Set emailObj = CreateObject("CDO.Message")
emailObj.From = "dc#gmail.com"
emailObj.To = "dc#gmail.com"
emailObj.Subject = "Test CDO"
emailObj.TextBody = "Test CDO"
emailObj.AddAttachment "C:/Users/User/Desktop/err.fff"
Set emailConfig = emailObj.Configuration
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.gmail.com"
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 465
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = true
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendusername") = "dc"
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "Ss"
emailConfig.Fields.Update
On Error Resume Next
emailObj.Send
If err.number = 0 then
Msgbox "Done"
Else
Msgbox err.number & " " & err.description
err.clear
End If
Also your account at www.gmail.com needs to be set to allow SMTP access (if using gmail as many are who do this).
The configuration info comes from Outlook Express (last in WinXP, renamed to Windows Mail in Vista, and dropped from Win7 and later). This shows default configuration on your computer. You may need to install Windows Live Mail. You also have to turn on the SMTP service in Windows Features.
Set emailConfig = emailObj.Configuration
On Error Resume Next
For Each fld in emailConfig.Fields
Text = Text & vbcrlf & fld.name & " = " & fld
If err.number <> 0 then
Text = Text & vbcrlf & fld.name & " = Error - probably trying to read password - not allowed"
err.clear
End If
Next
Msgbox Replace(Text, "http://schemas.microsoft.com", "")
Also CDO for Windows 2000 is not always included in all editions/versions of windows. See http://support.microsoft.com/en-au/kb/171440.
.
I'm trying to make a shortcut via an automater service that will move the selected file(s) up a directory. It goes as follows:
Get Selected Finder Items
Get Value of Variable Path
Run Applescript:
on join(someList, delimiter)
set prevTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to delimiter
set output to "" & someList
set AppleScript's text item delimiters to prevTIDs
return output
end join
to split(someText, delimiter)
set AppleScript's text item delimiters to delimiter
set someText to someText's text items
set AppleScript's text item delimiters to {""}
return someText
end split
on run {input, parameters}
set pathToMe to POSIX path of (item 1 of input as text)
set newPath to split(pathToMe, "/")
set revPath to reverse of newPath
set restList to rest of revPath
set restList to rest of restList
set joinPath to join(reverse of restList, "/")
set source to POSIX file joinPath
return source
end run
Set Value of Variable Parent
Move Finder Items To Parent
The Applescript parses the first file path in the Path in order to find the item's grandparent, returning it as a POSIX file string. The problem is that the "Move Finder" action only accepts Files/Folders. How can I select the target parent folder with the resulting string in order to pass it to the "Move Finder" action?
Things I've tried:
Using mv in a Run Bash Script: the Run Applescript action doesn't seem to return anything to the Run Bash Script; set to input as arguments, "$#" is always empty.
Doing a tell finder in Run Applescript. No error or warning, just nothing happens.
Manually setting the value of the parent variable.
Thanks in advance!
return a path of type alias in a list instead of a posix file
on run {input, parameters}
set pathToMe to (item 1 of input) as text
set f to my getParent(pathToMe, ":")
return {f as alias}
end run
to getParent(someText, delimiter)
set prevTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to delimiter
set n to -2
if someText ends with ":" then set n to -3
set t to text 1 thru text item n of someText
set AppleScript's text item delimiters to prevTIDs
return t
end getParent
I prefer to do this all in applescript so try this code. I didn't test it but it should work. You can still add this to automator with an applescript action but you don't need all the other actions. It will do everything itself. Good luck.
tell application "Finder"
set theSelection to get selection
set parentFolder to container of (item 1 of theSelection)
move theSelection to parentFolder
end tell
I'm new to Applescript and working on an app that runs in the background, and I want it to send email updates every so often WITHOUT mail.app.
I've tried googling this numerous times, and while this is the closest I've found, I don't know how to use a Python script. This app needs to work no matter what Mac OSX it is installed in, including Computers without Python. Is that possible?
I have often wanted to do the same thing and struggled myself. I ultimately landed on a python option. Python is supported back to OS X 10.5 and comes preinstalled on many of the newer versions of OS X. Is there some reason you don't feel you can use it? Are you supporting OS 10.4.x or older machines?
If they python option is still a possible option, I've included an example of how to use it here.
property PyMail : "/Users/TBD/Documents/Sample_Python_Email/PyMail.py" -- PATH TO PYTHON MAIL SCRIPT
on run
set emailTo to "youraddress#somedomain.com" -- MULTIPLE ADDRESS SHOULD BE A COMMA DELIMITED STRING LIKE THIS -- "address1#gmail.com, address2#hotmail.com"
set emailFrom to "Your Name <your.name#somedomain.com>"
set subject to "Demo Email"
set message to "Hi user,
I hope things are going well"
set pathToAttchment to "/Users/TBD/Desktop/prof.jpg" -- POSIX PATH TO FILE, LEAVE AS EMPTY STRING FOR NO ATTACHMENT
set username to "smtpusername" -- MAY OR MAY NOT BE REQUIRED IN YOUR CASE
sendPyMail(emailTo, emailFrom, subject, message, pathToAttchment, username)
end run
on sendPyMail(emailTo, emailFrom, subject, message, attachment, username)
try
do shell script "python " & quoted form of PyMail & " " & quoted form of emailTo & " " & quoted form of emailFrom & " " & quoted form of subject & " " & quoted form of message & " " & quoted form of attachment & " " & quoted form of username
return true
on error
return false
end try
end sendPyMail
Here is the python script (just copy and past it into a text editor and save as PyMail.py. You'll need to change the smtp server and possibly add the password that goes with the username you're supplying...
import sys
SMTP_TO = sys.argv[1]
SMTP_TO = SMTP_TO.split(',')
SMTP_FROM = sys.argv[2]
SUBJECT = sys.argv[3]
MESSAGE = sys.argv[4]
TEXT_FILENAME = sys.argv[5]
SMTP_USERNAME = sys.argv[6]
SMTP_SERVER = 'smtp.domainx.com'
SMTP_PORT = 25
SMTP_PASSWORD = ''
# now construct the message
import smtplib, email
from email import encoders
import os
msg = email.MIMEMultipart.MIMEMultipart()
body = email.MIMEText.MIMEText(MESSAGE)
if TEXT_FILENAME != "":
attachment = email.MIMEBase.MIMEBase('text', 'plain')
attachment.set_payload(open(TEXT_FILENAME).read())
attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(TEXT_FILENAME))
encoders.encode_base64(attachment)
msg.attach(body)
if TEXT_FILENAME != "":
msg.attach(attachment)
msg.add_header('From', SMTP_FROM)
msg.add_header('To', ';'.join(SMTP_TO))
msg.add_header('Subject', SUBJECT)
mailer = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
mailer.sendmail(SMTP_FROM, SMTP_TO, msg.as_string())
mailer.close()
Run this in Terminal
echo "this is the body" | mail -s "this is the subject" "to#address"
Note: This assumes you have a locally installed MTA
Your AppleScript would be:
do shell script "echo 'this is the body' | mail -s 'this is the subject' 'to#address'"
Knowing nothing about python, I used TextWrangler and cut and paste the two scripts above.
The second one crashes at line 1, returning a syntax error, as follows:
line 1
property PyMail : "/Users/.../PyMail.py" -- PATH TO PYTHON MAIL SCRIPT
^
SyntaxError: invalid syntax
The carrot pointer is under the 'l' in 'PyMail'.
I commented out line 1, and it returned the same message for line 3.
I have a table in a Microsoft Word document that I want to insert into the middle of a message in an Outlook email. When I manually copy the table into an email draft, it preserves the formatting, but when I don't, the formatting changes into a list-style. For example, this is what the table would look like:
9898 Apple color
1394 Banana blue
with borders, but in the email that gets sent, it shows up as
9898
Apple
Color
1394
Banana
Blue
I had to add in extra lines above because Stack Overflow wasn't showing it as each element on an separate line.
Within my code, I've taken the table and concatenated it within the string that forms the message of the email. I think this may be the problem, but I'm not sure how to change this to separately include the table. Here is my code:
message = "Dear " & owner & ", " & vbCrLf & vbCrLf
message = message & "Here is the data we have: " & vbCrLf
message = message & vbCrLf & vbCrLf & textToTable(fileName, file)
message = message & "Can you please email us back with the updated data?"
message = message & vbCrLf & vbCrLf & "Thank you."
Set MyItem = ol.CreateItem(0)
With MyItem
.To = me
.CC = ""
.BCC = ""
.Subject = "Table"
.BodyFormat = 3
.Body = message
.Send
End With
I used a lot of the code here in my textToTable function, which seems to work as intended. The only problem is getting Outlook to preserve formatting of the table; does anyone have any suggestions as to how to do this? Thank you so much!
You are setting the plain text Body property. Create an HTML table and assign the HTMLBody property to a property formatted HTML string.
I want a batch file program to get email.
For example I have a text file main.txt with some data
I want this to my mail id. Can you please help me in this programming.
Thanks in advance.
If you've got an email server you can send the emails to, I'd first recommend Blat as mentioned by PA's comment.
If you're running Microsoft Outlook email client, you can drive that with a VBScript script - not strictly a batch file but VBScript is generally part of Windows. Of course you can use a batch file to call the vbscript file with the right parameters.
(I've used this technique to schedule things in Outlook - schedule sending an email with a particular subject at a particular time.)
'SendMail.vbs
option explicit
' Script for sending mails to myself, with given subject and optionally file contents for body
' Note this only works with particular Schedule service settings, i.e.,
' it has to log on as me and have access to the Desktop
dim fso, f, oMailItem, oOlApp
' Create the mail
Set oOlApp = CreateObject("Outlook.Application")
Set oMailItem = oOlApp.CreateItem(0) '0 = olMailItem
oMailItem.Subject = WScript.Arguments(0)
oMailItem.Recipients.Add ("receiver.name#somemailserver.com")
if WScript.Arguments.Count > 1 then
Set fso = CreateObject("Scripting.FileSystemObject")
set f = fso.OpenTextFile(WScript.Arguments(1), 1 )
oMailItem.Body = f.ReadAll
f.Close
end if
oMailItem.Send
set f = nothing
set oMailItem = nothing
set oOlApp = nothing
Call it with a command like
sendmail.vbs My_Subject_Line contents_file.txt