[PATCH] Change in core[libreoffice-4-0]: make emailmerge work with python3 and python2 at the same ti...
Caolán McNamara (via_Code_Review)
gerrit at gerrit.libreoffice.org
Wed Jan 16 04:39:59 PST 2013
Hi,
I have submitted a patch for review:
https://gerrit.libreoffice.org/1713
To pull it, you can do:
git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/13/1713/1
make emailmerge work with python3 and python2 at the same time
squashed single 4-0 backport commit to sync 4-0 mailmerge.py
with that of current master to get a mailmerge.py that works
with python3 and python2, and successfully
a) sends utf-8 plain text
b) html
c) odt, pdf, doc attachments
(cherry picked from commit c25bee9ca3c3015c46c8fcb28654e5bed8a4d912)
i118736 - i118787 : fix XMailMessage implementation in mailmerge.py
(cherry picked from commit 4166969f3b8ed05e91c10a724ce7bd39074012a1)
(cherry picked from commit 3f2f92b753474883b5cd97aff3e00ac55fd23f3f)
i118791 - Encode ReadableName in UTF-8 only when necessary
(cherry picked from commit a5cefd4007be4789f550ee559aa832ddb04c2dc3)
i118814 - Allow set connection timeout in Mail API
(cherry picked from commit 8a324a3ba599bee03311e5f6ba6e1c83edc1e343)
make emailmerge work for me with python3
(cherry picked from commit e48a060eb80b76c943e7dbd815b63429905a14b6)
Change-Id: I6289b522513a2fc86e261c85a04ca9c89fd55b63
---
A scripting/source/pyprov/mailmerge.README
M scripting/source/pyprov/mailmerge.py
2 files changed, 110 insertions(+), 62 deletions(-)
diff --git a/scripting/source/pyprov/mailmerge.README b/scripting/source/pyprov/mailmerge.README
new file mode 100644
index 0000000..6b4fb5b
--- /dev/null
+++ b/scripting/source/pyprov/mailmerge.README
@@ -0,0 +1,18 @@
+Easiest way I find to test this is to...
+
+1)
+
+a) install fakemail and run it
+b) tools->options->writer->mail merge email
+c) localhost 8025
+
+2)
+
+a) type some text into writer that will exercise utf-8, e.g. "Caolán's test"
+b) tools->mail merge wizard->next->email message->select address book
+c) create, add one user with your own email address, ok
+d) next, next, text, send merged document as email
+e) and test all of plain text, html and the various attachment options
+
+fake mail will dump the mail it gets into its pwd, if all that works, you can
+then try with your own normal mail server.
diff --git a/scripting/source/pyprov/mailmerge.py b/scripting/source/pyprov/mailmerge.py
index c606143..18b476c 100755
--- a/scripting/source/pyprov/mailmerge.py
+++ b/scripting/source/pyprov/mailmerge.py
@@ -11,6 +11,8 @@
# <value>true</value>
# </prop>
+from __future__ import print_function
+
import unohelper
import uno
import re
@@ -36,11 +38,14 @@
from email.mime.base import MIMEBase
from email.message import Message
+from email.charset import Charset
+from email.charset import QP
from email.encoders import encode_base64
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.utils import formatdate
from email.utils import parseaddr
+from socket import _GLOBAL_DEFAULT_TIMEOUT
import sys, smtplib, imaplib, poplib
dbg = False
@@ -59,42 +64,51 @@
self.supportedtypes = ('Insecure', 'Ssl')
self.server = None
self.connectioncontext = None
- self.notify = EventObject()
+ self.notify = EventObject(self)
if dbg:
- print("PyMailSMPTService init", file=dbgout)
+ print("PyMailSMTPService init", file=dbgout)
def addConnectionListener(self, xListener):
if dbg:
- print("PyMailSMPTService addConnectionListener", file=dbgout)
+ print("PyMailSMTPService addConnectionListener", file=dbgout)
self.listeners.append(xListener)
def removeConnectionListener(self, xListener):
if dbg:
- print("PyMailSMPTService removeConnectionListener", file=dbgout)
+ print("PyMailSMTPService removeConnectionListener", file=dbgout)
self.listeners.remove(xListener)
def getSupportedConnectionTypes(self):
if dbg:
- print("PyMailSMPTService getSupportedConnectionTypes", file=dbgout)
+ print("PyMailSMTPService getSupportedConnectionTypes", file=dbgout)
return self.supportedtypes
def connect(self, xConnectionContext, xAuthenticator):
self.connectioncontext = xConnectionContext
if dbg:
- print("PyMailSMPTService connect", file=dbgout)
+ print("PyMailSMTPService connect", file=dbgout)
server = xConnectionContext.getValueByName("ServerName")
if dbg:
- print(server, file=dbgout)
+ print("ServerName: " + server, file=dbgout)
port = int(xConnectionContext.getValueByName("Port"))
if dbg:
- print(port, file=dbgout)
- self.server = smtplib.SMTP(server, port)
+ print("Port: " + str(port), file=dbgout)
+ tout = xConnectionContext.getValueByName("Timeout")
+ if dbg:
+ print(isinstance(tout,int), file=dbgout)
+ if not isinstance(tout,int):
+ tout = _GLOBAL_DEFAULT_TIMEOUT
+ if dbg:
+ print("Timeout: " + str(tout), file=dbgout)
+ self.server = smtplib.SMTP(server, port,timeout=tout)
+
#stderr not available for us under windows, but
#set_debuglevel outputs there, and so throw
#an exception under windows on debugging mode
#with this enabled
if dbg and os.name != 'nt':
self.server.set_debuglevel(1)
+
connectiontype = xConnectionContext.getValueByName("ConnectionType")
if dbg:
- print(connectiontype, file=dbgout)
- if connectiontype == 'Ssl':
+ print("ConnectionType: " + connectiontype, file=dbgout)
+ if connectiontype.upper() == 'SSL':
self.server.ehlo()
self.server.starttls()
self.server.ehlo()
@@ -106,14 +120,14 @@
user = user.encode('ascii')
password = password.encode('ascii')
if dbg:
- print("Logging in, username of" + user, file=dbgout)
+ print("Logging in, username of: " + user, file=dbgout)
self.server.login(user, password)
for listener in self.listeners:
listener.connected(self.notify)
def disconnect(self):
if dbg:
- print("PyMailSMPTService disconnect", file=dbgout)
+ print("PyMailSMTPService disconnect", file=dbgout)
if self.server:
self.server.quit()
self.server = None
@@ -121,17 +135,17 @@
listener.disconnected(self.notify)
def isConnected(self):
if dbg:
- print("PyMailSMPTService isConnected", file=dbgout)
+ print("PyMailSMTPService isConnected", file=dbgout)
return self.server != None
def getCurrentConnectionContext(self):
if dbg:
- print("PyMailSMPTService getCurrentConnectionContext", file=dbgout)
+ print("PyMailSMTPService getCurrentConnectionContext", file=dbgout)
return self.connectioncontext
def sendMailMessage(self, xMailMessage):
COMMASPACE = ', '
if dbg:
- print("PyMailSMPTService sendMailMessage", file=dbgout)
+ print("PyMailSMTPService sendMailMessage", file=dbgout)
recipients = xMailMessage.getRecipients()
sendermail = xMailMessage.SenderAddress
sendername = xMailMessage.SenderName
@@ -139,10 +153,10 @@
ccrecipients = xMailMessage.getCcRecipients()
bccrecipients = xMailMessage.getBccRecipients()
if dbg:
- print("PyMailSMPTService subject " + subject, file=dbgout)
- print("PyMailSMPTService from " + sendername.encode('utf-8'), file=dbgout)
- print("PyMailSMTPService from " + sendermail, file=dbgout)
- print("PyMailSMPTService send to " + recipients, file=dbgout)
+ print("PyMailSMTPService subject: " + subject, file=dbgout)
+ print("PyMailSMTPService from: " + sendername, file=dbgout)
+ print("PyMailSMTPService from: " + sendermail, file=dbgout)
+ print("PyMailSMTPService send to: %s" % (recipients,), file=dbgout)
attachments = xMailMessage.getAttachments()
@@ -151,19 +165,14 @@
content = xMailMessage.Body
flavors = content.getTransferDataFlavors()
if dbg:
- print("PyMailSMPTService flavors len " + len(flavors), file=dbgout)
+ print("PyMailSMTPService flavors len: %d" % (len(flavors),), file=dbgout)
#Use first flavor that's sane for an email body
for flavor in flavors:
if flavor.MimeType.find('text/html') != -1 or flavor.MimeType.find('text/plain') != -1:
if dbg:
- print("PyMailSMPTService mimetype is " + flavor.MimeType, file=dbgout)
+ print("PyMailSMTPService mimetype is: " + flavor.MimeType, file=dbgout)
textbody = content.getTransferData(flavor)
- try:
- textbody = textbody.value
- except:
- pass
- textbody = textbody.encode('utf-8')
if len(textbody):
mimeEncoding = re.sub("charset=.*", "charset=UTF-8", flavor.MimeType)
@@ -171,7 +180,16 @@
mimeEncoding = mimeEncoding + "; charset=UTF-8"
textmsg['Content-Type'] = mimeEncoding
textmsg['MIME-Version'] = '1.0'
- textmsg.set_payload(textbody)
+
+ textbody = textbody.encode('utf-8')
+ if sys.version >= '3':
+ #http://stackoverflow.com/questions/9403265/how-do-i-use-python-3-2-email-module-to-send-unicode-messages-encoded-in-utf-8-w
+ textbody = textbody.decode('iso8859-1')
+ c = Charset('utf-8')
+ c.body_encoding = QP
+ textmsg.set_payload(textbody, c)
+ else:
+ textmsg.set_payload(textbody)
break
@@ -194,7 +212,7 @@
mailerstring = "LibreOffice via Caolan's mailmerge component"
try:
- ctx = uno.getComponentContext()
+ ctx = uno.getComponentContext()
aConfigProvider = ctx.ServiceManager.createInstance("com.sun.star.configuration.ConfigurationProvider")
prop = uno.createUnoStruct('com.sun.star.beans.PropertyValue')
prop.Name = "nodepath"
@@ -205,7 +223,7 @@
aSettings.getByName("ooSetupVersion") + " via Caolan's mailmerge component"
except:
pass
-
+
msg['X-Mailer'] = mailerstring
msg['Date'] = formatdate(localtime=True)
@@ -217,10 +235,15 @@
maintype, subtype = ctype.split('/', 1)
msgattachment = MIMEBase(maintype, subtype)
data = content.getTransferData(flavor)
- msgattachment.set_payload(data)
+ msgattachment.set_payload(data.value)
encode_base64(msgattachment)
+ fname = attachment.ReadableName
+ try:
+ fname.encode('ascii')
+ except:
+ fname = ('utf-8','',fname.encode('utf-8'))
msgattachment.add_header('Content-Disposition', 'attachment', \
- filename=attachment.ReadableName)
+ filename=fname)
msg.attach(msgattachment)
uniquer = {}
@@ -235,7 +258,7 @@
truerecipients = uniquer.keys()
if dbg:
- print("PyMailSMPTService recipients are " + truerecipients, file=dbgout)
+ print(("PyMailSMTPService recipients are: ", truerecipients), file=dbgout)
self.server.sendmail(sendermail, truerecipients, msg.as_string())
@@ -246,7 +269,7 @@
self.supportedtypes = ('Insecure', 'Ssl')
self.server = None
self.connectioncontext = None
- self.notify = EventObject()
+ self.notify = EventObject(self)
if dbg:
print("PyMailIMAPService init", file=dbgout)
def addConnectionListener(self, xListener):
@@ -276,12 +299,12 @@
if dbg:
print(connectiontype, file=dbgout)
print("BEFORE", file=dbgout)
- if connectiontype == 'Ssl':
+ if connectiontype.upper() == 'SSL':
self.server = imaplib.IMAP4_SSL(server, port)
else:
self.server = imaplib.IMAP4(server, port)
print("AFTER", file=dbgout)
-
+
user = xAuthenticator.getUserName()
password = xAuthenticator.getPassword()
if user != '':
@@ -289,7 +312,7 @@
user = user.encode('ascii')
password = password.encode('ascii')
if dbg:
- print("Logging in, username of" + user, file=dbgout)
+ print("Logging in, username of: " + user, file=dbgout)
self.server.login(user, password)
for listener in self.listeners:
@@ -318,7 +341,7 @@
self.supportedtypes = ('Insecure', 'Ssl')
self.server = None
self.connectioncontext = None
- self.notify = EventObject()
+ self.notify = EventObject(self)
if dbg:
print("PyMailPOP3Service init", file=dbgout)
def addConnectionListener(self, xListener):
@@ -348,10 +371,17 @@
if dbg:
print(connectiontype, file=dbgout)
print("BEFORE", file=dbgout)
- if connectiontype == 'Ssl':
+ if connectiontype.upper() == 'SSL':
self.server = poplib.POP3_SSL(server, port)
else:
- self.server = poplib.POP3(server, port)
+ tout = xConnectionContext.getValueByName("Timeout")
+ if dbg:
+ print(isinstance(tout,int), file=dbgout)
+ if not isinstance(tout,int):
+ tout = _GLOBAL_DEFAULT_TIMEOUT
+ if dbg:
+ print("Timeout: " + str(tout), file=dbgout)
+ self.server = poplib.POP3(server, port, timeout=tout)
print("AFTER", file=dbgout)
user = xAuthenticator.getUserName()
@@ -360,9 +390,9 @@
user = user.encode('ascii')
password = password.encode('ascii')
if dbg:
- print("Logging in, username of" + user, file=dbgout)
+ print("Logging in, username of: " + user, file=dbgout)
self.server.user(user)
- self.server.pass_(user, password)
+ self.server.pass_(password)
for listener in self.listeners:
listener.connected(self.notify)
@@ -390,7 +420,7 @@
self.ctx = ctx
def create(self, aType):
if dbg:
- print("PyMailServiceProvider create with " + aType, file=dbgout)
+ print("PyMailServiceProvider create with", aType, file=dbgout)
if aType == SMTP:
return PyMailSMTPService(self.ctx);
elif aType == POP3:
@@ -406,12 +436,12 @@
print("PyMailMessage init", file=dbgout)
self.ctx = ctx
- self.recipients = (sTo,)
- self.ccrecipients = ()
- self.bccrecipients = ()
- self.aMailAttachments = ()
+ self.recipients = [sTo]
+ self.ccrecipients = []
+ self.bccrecipients = []
+ self.aMailAttachments = []
if aMailAttachment != None:
- self.aMailAttachments = (aMailAttachment,)
+ self.aMailAttachments.append(aMailAttachment)
self.SenderName, self.SenderAddress = parseaddr(sFrom)
self.ReplyToAddress = sFrom
@@ -421,36 +451,36 @@
print("post PyMailMessage init", file=dbgout)
def addRecipient( self, recipient ):
if dbg:
- print("PyMailMessage.addRecipient " + recipient, file=dbgout)
- self.recipients = self.recipients + (recipient,)
+ print("PyMailMessage.addRecipient: " + recipient, file=dbgout)
+ self.recipients.append(recipient)
def addCcRecipient( self, ccrecipient ):
if dbg:
- print("PyMailMessage.addCcRecipient " + ccrecipient, file=dbgout)
- self.ccrecipients = self.ccrecipients + (ccrecipient,)
+ print("PyMailMessage.addCcRecipient: " + ccrecipient, file=dbgout)
+ self.ccrecipients.append(ccrecipient)
def addBccRecipient( self, bccrecipient ):
if dbg:
- print("PyMailMessage.addBccRecipient " + bccrecipient, file=dbgout)
- self.bccrecipients = self.bccrecipients + (bccrecipient,)
+ print("PyMailMessage.addBccRecipient: " + bccrecipient, file=dbgout)
+ self.bccrecipients.append(bccrecipient)
def getRecipients( self ):
if dbg:
- print("PyMailMessage.getRecipients " + self.recipients, file=dbgout)
- return self.recipients
+ print("PyMailMessage.getRecipients: " + self.recipients, file=dbgout)
+ return tuple(self.recipients)
def getCcRecipients( self ):
if dbg:
- print("PyMailMessage.getCcRecipients " + self.ccrecipients, file=dbgout)
- return self.ccrecipients
+ print("PyMailMessage.getCcRecipients: " + self.ccrecipients, file=dbgout)
+ return tuple(self.ccrecipients)
def getBccRecipients( self ):
if dbg:
- print("PyMailMessage.getBccRecipients " + self.bccrecipients, file=dbgout)
- return self.bccrecipients
+ print("PyMailMessage.getBccRecipients: " + self.bccrecipients, file=dbgout)
+ return tuple(self.bccrecipients)
def addAttachment( self, aMailAttachment ):
if dbg:
print("PyMailMessage.addAttachment", file=dbgout)
- self.aMailAttachments = self.aMailAttachments + (aMailAttachment,)
+ self.aMailAttachments.append(aMailAttachment)
def getAttachments( self ):
if dbg:
print("PyMailMessage.getAttachments", file=dbgout)
- return self.aMailAttachments
+ return tuple(self.aMailAttachments)
# pythonloader looks for a static g_ImplementationHelper variable
g_ImplementationHelper = unohelper.ImplementationHelper()
--
To view, visit https://gerrit.libreoffice.org/1713
To unsubscribe, visit https://gerrit.libreoffice.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6289b522513a2fc86e261c85a04ca9c89fd55b63
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: libreoffice-4-0
Gerrit-Owner: Caolán McNamara <caolanm at redhat.com>
More information about the LibreOffice
mailing list