home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 October / maximum-cd-2011-10.iso / DiscContents / LibO_3.4.1_Win_x86_install_multi.exe / libreoffice1.cab / mailmerge.py < prev    next >
Encoding:
Python Source  |  2011-06-24  |  14.4 KB  |  442 lines

  1. # Caolan McNamara caolanm@redhat.com
  2. # a simple email mailmerge component
  3.  
  4. # manual installation for hackers, not necessary for users
  5. # cp mailmerge.py /usr/lib/libreoffice/program
  6. # cd /usr/lib/libreoffice/program
  7. # ./unopkg add --shared mailmerge.py
  8. # edit ~/.openoffice.org2/user/registry/data/org/openoffice/Office/Writer.xcu
  9. # and change EMailSupported to as follows...
  10. #  <prop oor:name="EMailSupported" oor:type="xs:boolean">
  11. #   <value>true</value>
  12. #  </prop>
  13.  
  14. import unohelper
  15. import uno
  16. import re
  17.  
  18. #to implement com::sun::star::mail::XMailServiceProvider
  19. #and
  20. #to implement com.sun.star.mail.XMailMessage
  21.  
  22. from com.sun.star.mail import XMailServiceProvider
  23. from com.sun.star.mail import XMailService
  24. from com.sun.star.mail import XSmtpService
  25. from com.sun.star.mail import XConnectionListener
  26. from com.sun.star.mail import XAuthenticator
  27. from com.sun.star.mail import XMailMessage
  28. from com.sun.star.mail.MailServiceType import SMTP
  29. from com.sun.star.mail.MailServiceType import POP3
  30. from com.sun.star.mail.MailServiceType import IMAP
  31. from com.sun.star.uno import XCurrentContext
  32. from com.sun.star.lang import IllegalArgumentException
  33. from com.sun.star.lang import EventObject
  34. from com.sun.star.mail import SendMailMessageFailedException
  35.  
  36. from email.MIMEBase import MIMEBase
  37. from email.Message import Message
  38. from email import Encoders
  39. from email.Header import Header
  40. from email.MIMEMultipart import MIMEMultipart
  41. from email.Utils import formatdate
  42. from email.Utils import parseaddr
  43.  
  44. import sys, smtplib, imaplib, poplib
  45. dbg = False
  46.  
  47. class PyMailSMTPService(unohelper.Base, XSmtpService):
  48.     def __init__( self, ctx ):
  49.         self.ctx = ctx
  50.         self.listeners = []
  51.         self.supportedtypes = ('Insecure', 'Ssl')
  52.         self.server = None
  53.         self.connectioncontext = None
  54.         self.notify = EventObject()
  55.         if dbg:
  56.             print >> sys.stderr, "PyMailSMPTService init"
  57.     def addConnectionListener(self, xListener):
  58.         if dbg:
  59.             print >> sys.stderr, "PyMailSMPTService addConnectionListener"
  60.         self.listeners.append(xListener)
  61.     def removeConnectionListener(self, xListener):
  62.         if dbg:
  63.             print >> sys.stderr, "PyMailSMPTService removeConnectionListener"
  64.         self.listeners.remove(xListener)
  65.     def getSupportedConnectionTypes(self):
  66.         if dbg:
  67.             print >> sys.stderr, "PyMailSMPTService getSupportedConnectionTypes"
  68.         return self.supportedtypes
  69.     def connect(self, xConnectionContext, xAuthenticator):
  70.         self.connectioncontext = xConnectionContext
  71.         if dbg:
  72.             print >> sys.stderr, "PyMailSMPTService connect"
  73.         server = xConnectionContext.getValueByName("ServerName")
  74.         if dbg:
  75.             print >> sys.stderr, server
  76.         port = xConnectionContext.getValueByName("Port")
  77.         if dbg:
  78.             print >> sys.stderr, port
  79.         self.server = smtplib.SMTP(server, port)
  80.         if dbg:
  81.             self.server.set_debuglevel(1)
  82.         connectiontype = xConnectionContext.getValueByName("ConnectionType")
  83.         if dbg:
  84.             print >> sys.stderr, connectiontype
  85.         if connectiontype == 'Ssl':
  86.             self.server.ehlo()
  87.             self.server.starttls()
  88.             self.server.ehlo()
  89.  
  90.         user = xAuthenticator.getUserName().encode('ascii')
  91.         password = xAuthenticator.getPassword().encode('ascii')
  92.         if user != '':
  93.             if dbg:
  94.                 print >> sys.stderr, 'Logging in, username of', user
  95.             self.server.login(user, password)
  96.  
  97.         for listener in self.listeners:
  98.             listener.connected(self.notify)
  99.     def disconnect(self):
  100.         if dbg:
  101.             print >> sys.stderr, "PyMailSMPTService disconnect"
  102.         if self.server:
  103.             self.server.quit()
  104.             self.server = None
  105.         for listener in self.listeners:
  106.             listener.disconnected(self.notify)
  107.     def isConnected(self):
  108.         if dbg:
  109.             print >> sys.stderr, "PyMailSMPTService isConnected"
  110.         return self.server != None
  111.     def getCurrentConnectionContext(self):
  112.         if dbg:
  113.             print >> sys.stderr, "PyMailSMPTService getCurrentConnectionContext"
  114.         return self.connectioncontext
  115.     def sendMailMessage(self, xMailMessage):
  116.         COMMASPACE = ', '
  117.  
  118.         if dbg:
  119.             print >> sys.stderr, "PyMailSMPTService sendMailMessage"
  120.         recipients = xMailMessage.getRecipients()
  121.         sendermail = xMailMessage.SenderAddress
  122.         sendername = xMailMessage.SenderName
  123.         subject = xMailMessage.Subject
  124.         ccrecipients = xMailMessage.getCcRecipients()
  125.         bccrecipients = xMailMessage.getBccRecipients()
  126.         if dbg:
  127.             print >> sys.stderr, "PyMailSMPTService subject", subject
  128.             print >> sys.stderr, "PyMailSMPTService from", sendername.encode('utf-8')
  129.             print >> sys.stderr, "PyMailSMTPService from", sendermail
  130.             print >> sys.stderr, "PyMailSMPTService send to", recipients
  131.  
  132.         attachments = xMailMessage.getAttachments()
  133.  
  134.         textmsg = Message()
  135.  
  136.         content = xMailMessage.Body
  137.         flavors = content.getTransferDataFlavors()
  138.         if dbg:
  139.             print >> sys.stderr, "PyMailSMPTService flavors len", len(flavors)
  140.  
  141.         #Use first flavor that's sane for an email body
  142.         for flavor in flavors:
  143.             if flavor.MimeType.find('text/html') != -1 or flavor.MimeType.find('text/plain') != -1:
  144.                 if dbg:
  145.                     print >> sys.stderr, "PyMailSMPTService mimetype is", flavor.MimeType
  146.                 textbody = content.getTransferData(flavor)
  147.                 try:
  148.                     textbody = textbody.value
  149.                 except:
  150.                     pass
  151.                 textbody = textbody.encode('utf-8')
  152.  
  153.                 if len(textbody):
  154.                     mimeEncoding = re.sub("charset=.*", "charset=UTF-8", flavor.MimeType)
  155.                     if mimeEncoding.find('charset=UTF-8') == -1:
  156.                         mimeEncoding = mimeEncoding + "; charset=UTF-8"
  157.                     textmsg['Content-Type'] = mimeEncoding
  158.                     textmsg['MIME-Version'] = '1.0'
  159.                     textmsg.set_payload(textbody)
  160.  
  161.                 break
  162.  
  163.         if (len(attachments)):
  164.             msg = MIMEMultipart()
  165.             msg.epilogue = ''
  166.             msg.attach(textmsg)
  167.         else:
  168.             msg = textmsg
  169.  
  170.         hdr = Header(sendername, 'utf-8')
  171.         hdr.append('<'+sendermail+'>','us-ascii')
  172.         msg['Subject'] = subject
  173.         msg['From'] = hdr
  174.         msg['To'] = COMMASPACE.join(recipients)
  175.         if len(ccrecipients):
  176.             msg['Cc'] = COMMASPACE.join(ccrecipients)
  177.         if xMailMessage.ReplyToAddress != '':
  178.             msg['Reply-To'] = xMailMessage.ReplyToAddress
  179.  
  180.         mailerstring = "LibreOffice via Caolan's mailmerge component"
  181.         try:
  182.             ctx = uno.getComponentContext() 
  183.             aConfigProvider = ctx.ServiceManager.createInstance("com.sun.star.configuration.ConfigurationProvider")
  184.             prop = uno.createUnoStruct('com.sun.star.beans.PropertyValue')
  185.             prop.Name = "nodepath"
  186.             prop.Value = "/org.openoffice.Setup/Product"
  187.             aSettings = aConfigProvider.createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess",
  188.                 (prop,))
  189.             mailerstring = aSettings.getByName("ooName") + " " + \
  190.                 aSettings.getByName("ooSetupVersion") + " via Caolan's mailmerge component"
  191.         except:
  192.             pass
  193.         
  194.         msg['X-Mailer'] = mailerstring
  195.         msg['Date'] = formatdate(localtime=True)
  196.  
  197.         for attachment in attachments:
  198.             content = attachment.Data
  199.             flavors = content.getTransferDataFlavors()
  200.             flavor = flavors[0]
  201.             ctype = flavor.MimeType
  202.             maintype, subtype = ctype.split('/', 1)
  203.             msgattachment = MIMEBase(maintype, subtype)
  204.             data = content.getTransferData(flavor)
  205.             msgattachment.set_payload(data)
  206.             Encoders.encode_base64(msgattachment)
  207.             msgattachment.add_header('Content-Disposition', 'attachment', \
  208.                 filename=attachment.ReadableName)
  209.             msg.attach(msgattachment)
  210.  
  211.         uniquer = {}
  212.         for key in recipients:
  213.             uniquer[key] = True
  214.         if len(ccrecipients):
  215.             for key in ccrecipients:
  216.                 uniquer[key] = True
  217.         if len(bccrecipients):
  218.             for key in bccrecipients:
  219.                 uniquer[key] = True
  220.         truerecipients = uniquer.keys()
  221.  
  222.         if dbg:
  223.             print >> sys.stderr, "PyMailSMPTService recipients are", truerecipients
  224.  
  225.         self.server.sendmail(sendermail, truerecipients, msg.as_string())
  226.  
  227. class PyMailIMAPService(unohelper.Base, XMailService):
  228.     def __init__( self, ctx ):
  229.         self.ctx = ctx
  230.         self.listeners = []
  231.         self.supportedtypes = ('Insecure', 'Ssl')
  232.         self.server = None
  233.         self.connectioncontext = None
  234.         self.notify = EventObject()
  235.         if dbg:
  236.             print >> sys.stderr, "PyMailIMAPService init"
  237.     def addConnectionListener(self, xListener):
  238.         if dbg:
  239.             print >> sys.stderr, "PyMailIMAPService addConnectionListener"
  240.         self.listeners.append(xListener)
  241.     def removeConnectionListener(self, xListener):
  242.         if dbg:
  243.             print >> sys.stderr, "PyMailIMAPService removeConnectionListener"
  244.         self.listeners.remove(xListener)
  245.     def getSupportedConnectionTypes(self):
  246.         if dbg:
  247.             print >> sys.stderr, "PyMailIMAPService getSupportedConnectionTypes"
  248.         return self.supportedtypes
  249.     def connect(self, xConnectionContext, xAuthenticator):
  250.         if dbg:
  251.             print >> sys.stderr, "PyMailIMAPService connect"
  252.  
  253.         self.connectioncontext = xConnectionContext
  254.         server = xConnectionContext.getValueByName("ServerName")
  255.         if dbg:
  256.             print >> sys.stderr, server
  257.         port = xConnectionContext.getValueByName("Port")
  258.         if dbg:
  259.             print >> sys.stderr, port
  260.         connectiontype = xConnectionContext.getValueByName("ConnectionType")
  261.         if dbg:
  262.             print >> sys.stderr, connectiontype
  263.         print >> sys.stderr, "BEFORE"
  264.         if connectiontype == 'Ssl':
  265.             self.server = imaplib.IMAP4_SSL(server, port)
  266.         else:
  267.             self.server = imaplib.IMAP4(server, port)
  268.         print >> sys.stderr, "AFTER"
  269.             
  270.         user = xAuthenticator.getUserName().encode('ascii')
  271.         password = xAuthenticator.getPassword().encode('ascii')
  272.         if user != '':
  273.             if dbg:
  274.                 print >> sys.stderr, 'Logging in, username of', user
  275.             self.server.login(user, password)
  276.  
  277.         for listener in self.listeners:
  278.             listener.connected(self.notify)
  279.     def disconnect(self):
  280.         if dbg:
  281.             print >> sys.stderr, "PyMailIMAPService disconnect"
  282.         if self.server:
  283.             self.server.logout()
  284.             self.server = None
  285.         for listener in self.listeners:
  286.             listener.disconnected(self.notify)
  287.     def isConnected(self):
  288.         if dbg:
  289.             print >> sys.stderr, "PyMailIMAPService isConnected"
  290.         return self.server != None
  291.     def getCurrentConnectionContext(self):
  292.         if dbg:
  293.             print >> sys.stderr, "PyMailIMAPService getCurrentConnectionContext"
  294.         return self.connectioncontext
  295.  
  296. class PyMailPOP3Service(unohelper.Base, XMailService):
  297.     def __init__( self, ctx ):
  298.         self.ctx = ctx
  299.         self.listeners = []
  300.         self.supportedtypes = ('Insecure', 'Ssl')
  301.         self.server = None
  302.         self.connectioncontext = None
  303.         self.notify = EventObject()
  304.         if dbg:
  305.             print >> sys.stderr, "PyMailPOP3Service init"
  306.     def addConnectionListener(self, xListener):
  307.         if dbg:
  308.             print >> sys.stderr, "PyMailPOP3Service addConnectionListener"
  309.         self.listeners.append(xListener)
  310.     def removeConnectionListener(self, xListener):
  311.         if dbg:
  312.             print >> sys.stderr, "PyMailPOP3Service removeConnectionListener"
  313.         self.listeners.remove(xListener)
  314.     def getSupportedConnectionTypes(self):
  315.         if dbg:
  316.             print >> sys.stderr, "PyMailPOP3Service getSupportedConnectionTypes"
  317.         return self.supportedtypes
  318.     def connect(self, xConnectionContext, xAuthenticator):
  319.         if dbg:
  320.             print >> sys.stderr, "PyMailPOP3Service connect"
  321.  
  322.         self.connectioncontext = xConnectionContext
  323.         server = xConnectionContext.getValueByName("ServerName")
  324.         if dbg:
  325.             print >> sys.stderr, server
  326.         port = xConnectionContext.getValueByName("Port")
  327.         if dbg:
  328.             print >> sys.stderr, port
  329.         connectiontype = xConnectionContext.getValueByName("ConnectionType")
  330.         if dbg:
  331.             print >> sys.stderr, connectiontype
  332.         print >> sys.stderr, "BEFORE"
  333.         if connectiontype == 'Ssl':
  334.             self.server = poplib.POP3_SSL(server, port)
  335.         else:
  336.             self.server = poplib.POP3(server, port)
  337.         print >> sys.stderr, "AFTER"
  338.             
  339.         user = xAuthenticator.getUserName().encode('ascii')
  340.         password = xAuthenticator.getPassword().encode('ascii')
  341.         if dbg:
  342.             print >> sys.stderr, 'Logging in, username of', user
  343.         self.server.user(user)
  344.         self.server.pass_(user, password)
  345.  
  346.         for listener in self.listeners:
  347.             listener.connected(self.notify)
  348.     def disconnect(self):
  349.         if dbg:
  350.             print >> sys.stderr, "PyMailPOP3Service disconnect"
  351.         if self.server:
  352.             self.server.quit()
  353.             self.server = None
  354.         for listener in self.listeners:
  355.             listener.disconnected(self.notify)
  356.     def isConnected(self):
  357.         if dbg:
  358.             print >> sys.stderr, "PyMailPOP3Service isConnected"
  359.         return self.server != None
  360.     def getCurrentConnectionContext(self):
  361.         if dbg:
  362.             print >> sys.stderr, "PyMailPOP3Service getCurrentConnectionContext"
  363.         return self.connectioncontext
  364.  
  365. class PyMailServiceProvider(unohelper.Base, XMailServiceProvider):
  366.     def __init__( self, ctx ):
  367.         if dbg:
  368.             print >> sys.stderr, "PyMailServiceProvider init"
  369.         self.ctx = ctx
  370.     def create(self, aType):
  371.         if dbg:
  372.             print >> sys.stderr, "PyMailServiceProvider create with", aType
  373.         if aType == SMTP:
  374.             return PyMailSMTPService(self.ctx);
  375.         elif aType == POP3:
  376.             return PyMailPOP3Service(self.ctx);
  377.         elif aType == IMAP:
  378.             return PyMailIMAPService(self.ctx);
  379.         else:
  380.             print >> sys.stderr, "PyMailServiceProvider, unknown TYPE", aType
  381.  
  382. class PyMailMessage(unohelper.Base, XMailMessage):
  383.     def __init__( self, ctx, sTo='', sFrom='', Subject='', Body=None, aMailAttachment=None ):
  384.         if dbg:
  385.             print >> sys.stderr, "PyMailMessage init"
  386.         self.ctx = ctx
  387.  
  388.         self.recipients = sTo,
  389.         self.ccrecipients = ()
  390.         self.bccrecipients = ()
  391.         self.aMailAttachments = ()
  392.         if aMailAttachment != None:
  393.             self.aMailAttachments = aMailAttachment, 
  394.  
  395.         self.SenderName, self.SenderAddress = parseaddr(sFrom)
  396.         self.ReplyToAddress = sFrom
  397.         self.Subject = Subject
  398.         self.Body = Body
  399.         if dbg:
  400.             print >> sys.stderr, "post PyMailMessage init"
  401.     def addRecipient( self, recipient ):
  402.         if dbg:
  403.             print >> sys.stderr, "PyMailMessage.addRecipient", recipient
  404.         self.recipients = self.recipients, recipient
  405.     def addCcRecipient( self, ccrecipient ):
  406.         if dbg:
  407.             print >> sys.stderr, "PyMailMessage.addCcRecipient", ccrecipient
  408.         self.ccrecipients = self.ccrecipients, ccrecipient
  409.     def addBccRecipient( self, bccrecipient ):
  410.         if dbg:
  411.             print >> sys.stderr, "PyMailMessage.addBccRecipient", bccrecipient
  412.         self.bccrecipients = self.bccrecipients, bccrecipient
  413.     def getRecipients( self ):
  414.         if dbg:
  415.             print >> sys.stderr, "PyMailMessage.getRecipients", self.recipients
  416.         return self.recipients
  417.     def getCcRecipients( self ):
  418.         if dbg:
  419.             print >> sys.stderr, "PyMailMessage.getCcRecipients", self.ccrecipients
  420.         return self.ccrecipients
  421.     def getBccRecipients( self ):
  422.         if dbg:
  423.             print >> sys.stderr, "PyMailMessage.getBccRecipients", self.bccrecipients
  424.         return self.bccrecipients
  425.     def addAttachment( self, aMailAttachment ):
  426.         if dbg:
  427.             print >> sys.stderr, "PyMailMessage.addAttachment"
  428.         self.aMailAttachments = self.aMailAttachments, aMailAttachment
  429.     def getAttachments( self ):
  430.         if dbg:
  431.             print >> sys.stderr, "PyMailMessage.getAttachments"
  432.         return self.aMailAttachments
  433.  
  434. # pythonloader looks for a static g_ImplementationHelper variable
  435. g_ImplementationHelper = unohelper.ImplementationHelper()
  436. g_ImplementationHelper.addImplementation( \
  437.     PyMailServiceProvider, "org.openoffice.pyuno.MailServiceProvider",
  438.         ("com.sun.star.mail.MailServiceProvider",),)
  439. g_ImplementationHelper.addImplementation( \
  440.     PyMailMessage, "org.openoffice.pyuno.MailMessage",
  441.         ("com.sun.star.mail.MailMessage",),)
  442.