Coder Social home page Coder Social logo

marrow / mailer Goto Github PK

View Code? Open in Web Editor NEW
279.0 10.0 62.0 538 KB

A light-weight, modular, message representation and mail delivery framework for Python.

License: MIT License

Python 100.00%
python email email-sender pypi cpython pypy gae imap maildir mailgun

mailer's People

Contributors

amcgregor avatar bolidecaster avatar danieloverdevest avatar dannylsl avatar dsx avatar frenzymadness avatar jamiebegin avatar jwodder avatar kute avatar nandoflorestan avatar nl5887 avatar pjcunningham avatar plaes avatar stevenbuccini avatar timgates42 avatar vitorio avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mailer's Issues

import error

hi, when i use '''from marrow.mailer import Message, Delivery''' in ipython, i got this error:

ImportError: cannot import name basestring

it looks like '''from marrow.util.compat import basestring, unicode, unicodestr, native''' in marrow/mailer/address.py, but marrow/util/compat.py not include basestring and unicodestr

so, it's error...

SMTP transport masks errors from Message

The SMTP transport can report a successful sending of a Message even though an exception is raised in send_with_smtp(). This is because of the finally: block in deliver() which may raise a TransportExhaustedException.

Embed image generated from PIL using embed() and StringIO

I am trying to generate an image and embed it in an email using embed

Get image:

    image_buffer = cStringIO.StringIO()
    im.save(image_buffer, "gif")
    imgStr = base64.b64encode(image_buffer.getvalue())

Now I use imgStr here:

   message.embed(filename+'.gif', imgStr)

But the image is broken in gmail.
screen shot 2015-03-04 at 3 27 51 pm

Any suggestions?

Configuration defaults are not documented

I was left wondering what the default settings are. I had to look in the code. Then I STILL could not figure them out. For example, most people would prefer to send utf-8 encoded messages via SMTP to localhost. If those are not the defaults, they should be.

marrow.mailer fails to load configuration directives in Python 2.6 with unicode_literals

This code throws a TypeError:

from __future__ import unicode_literals

from datetime import datetime
import logging
from marrow.mailer import Message, Delivery
logging.basicConfig(level=logging.DEBUG)

mail = Delivery({
    'manager': 'immediate',
    'transport': 'smtp',
    'transport.host': 'secure.emailsrvr.com',
    'transport.tls': 'ssl',
    'transport.username': '',
    'transport.password': '',
    'transport.pipeline': 5
})

mail.start()
mail.stop()

smtp transport needlessly calls connect

Python docs says:

If the optional host and port parameters are given, the SMTP connect() method is called with those parameters during initialization.

Therefore, connect_to_server makes an extra call to SMTP.connect. This is not only needless but wrong also. Deep within smtplib, SMTP.file is only created in getreply. And getreply is called in connect. Another call to connect, hence, will create another socket, but getreply always refers to the old file (socket).

It is debatable whether this is smtplib or marrow.mailer.transport.smtp though. I would like to see smtplib's connect refresh its file as well as sock variables. But an easier fix, one that you have control over, is to fix smtp transport ;).

immediate manager handles TransportExhaustedException as fail-in-progress exception when it is not

The offended code is quoted:

try:
    result = self.transport.deliver(message)

except TransportExhaustedException:
    log.debug("Transport exhausted, retrying.")
    self.transport.shutdown()
    self.deliver(message)

TransportExhaustedException is raised after the message has been successfully sent and no further reusing of this Transport should be attempted. The immediate manager wrongly treats that exception as there was a problem in sending the message, let's try again.

Check Python 3 compatibility.

Issues with SMTPlib and str vs. bytes header values; specifically those of the address values such as From.

Needs more research on Python 3's smtp library. On the following MIME message:

Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
From: =?utf-8?q?Alice_Bevan-McGregor?= <[email protected]>
Subject: =?utf-8?q?This_is_a_test_message=2E?=
Date: =?utf-8?q?Wed=2C_23_Nov_2011_00=3A27=3A51_-0500?=
To: =?utf-8?q?Your_Name_Here?= <[email protected]>
X-Mailer: =?utf-8?q?marrow=2Emailer_4=2E0=2E0b3?=

Testing!

I'm getting:

ERROR:marrow.mailer.transport.smtp:<[email protected]> EXCEPTION TypeError
Traceback (most recent call last):
  File "/Users/amcgregor/Projects/Marrow/src/marrow.mailer/marrow/mailer/transport/smtp.py", line 119, in send_with_smtp
    self.connection.sendmail(sender, recipients, content)
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/smtplib.py", line 741, in sendmail
    (code, resp) = self.mail(from_addr, esmtp_opts)
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/smtplib.py", line 482, in mail
    self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender), optionlist))
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/smtplib.py", line 143, in quoteaddr
    m = email.utils.parseaddr(addr)[1]
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/email/utils.py", line 192, in parseaddr
    addrs = _AddressList(addr).addresslist
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/email/_parseaddr.py", line 471, in __init__
    self.addresslist = self.getaddrlist()
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/email/_parseaddr.py", line 224, in getaddrlist
    ad = self.getaddress()
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/email/_parseaddr.py", line 234, in getaddress
    self.gotonext()
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/email/_parseaddr.py", line 207, in gotonext
    if self.field[self.pos] in self.LWS + '\n\r':
TypeError: 'in <string>' requires string as left operand, not int

Incorrect example in README

I tried to use the example given in the read me:

mailer = Mailer(dict(
        transport = dict(
                use = 'smtp',
                host = 'smtp.gmail.com',
                port = '587',
                username = username,
                password = password,
                tls = 'required',
                debug = True)))
mailer.start()

message = Message(author="[email protected]", to="[email protected]")
message.subject = "Testing Marrow Mailer"
message.plain = "This is a test."
mailer.send(message)
mailer.stop()

But i gives an exception:

Traceback (most recent call last):
  File "send_email.py", line 14, in <module>
    debug = True)))
  File "/Users/user/.virtualenvs/w1/lib/python2.7/site-packages/marrow/mailer/__init__.py", line 55, in __init__
    if isinstance(config.manager, basestring):
  File "/Users/user/.virtualenvs/w1/lib/python2.7/site-packages/marrow/util/bunch.py", line 29, in __getattr__
    raise AttributeError(name)
AttributeError: manager

So, I added manager:

mailer = Mailer(dict(
        transport = dict(
                use = 'smtp',
                host = 'smtp.gmail.com',
                port = '587',
                username = username,
                password = password,
                tls = 'required',
                debug = True),
        manager = dict()))
mailer.start()

message = Message(author="[email protected]", to="[email protected]")
message.subject = "Testing Marrow Mailer"
message.plain = "This is a test."
mailer.send(message)
mailer.stop()

And it worked.

marrow.mailer on pypi

Hi,

This is not an issue, but a question...

Is there any plan to make a new pypi release ?

The last one was done on 2011-11-23 and several bugs where fixed (release 4.0.1, 4.0.2) since then...

Using pip (or easy_install) helps maintaining apps, but I would need some stuff (notably #37)...

Sorry for asking questions in the issues...

Unable to determine manager from specification: 'immediate'

do not known why?

code as,

import sys
import logging

from marrow.mailer import Message, Delivery
sys.path.append(__file__)

logging.basicConfig(level=logging.INFO)


configuration = {
        'manager': 'immediate', #'futures'
        'manager.workers': 5,
        
        'transport': 'smtp',
        'transport.host': 'smtp.gmail.com',
        'transport.tls': 'ssl', # None=='', required, optional
        'transport.port': 465, # 25, 465 = SSL
        'transport.username': '',
        'transport.password': '',
        'transport.max_messages_per_connection': 5,
        'transport.debug': False
    }


if __name__ == '__main__':
    mail = Delivery(configuration)
    mail.start()
    
    message = Message()
    message.author = [('Alice Bevan-McGregor', '[email protected]')]
    message.to = [('Your Name Here', '[email protected]')]
    message.subject = "This is a test message."
    message.plain = "Testing!"
    
    mail.send(message)
    mail.stop()

Message without `author` or `to` goes `/dev/null`

If by mistake one creates a Message without "author" or "to", marrow.mailer 4.0 says it sends the message, actually does not try to send it (after authenticating), and does not raise an exception. I don't think this behaviour is good; I'd prefer it to throw an exception.

Add workaround for the utf8-qp bug in Python 2.6.5

from email import charset
from email.mime.text import MIMEText

charset.add_charset('utf-8', charset.SHORTEST, charset.QP, 'utf-8')
mt = MIMEText(u'\u00e4', 'plain', 'utf-8')
print bytes(mt)  # Last line should read "=C3=A4, but returns =E4 on Python 2.6.5"

This makes marrow.mailer unusable on affected Python versions, but TurboMail did not have issues there.

Setting 'manager': 'dynamic' gives ImportError: No module named concurrent

If I use the following config:

mail = Delivery({
        'manager': 'dynamic',
        …

I get the following traceback:

...
File '/home/tim/Documents/MyWebPages/arwd/projects/tg21env-dev/lib/python2.6/site-packages/marrow/mailer/__init__.py', line 62 in __init__
  self.Manager = Manager = self._load(config.manager, 'marrow.mailer.manager')
File '/home/tim/Documents/MyWebPages/arwd/projects/tg21env-dev/lib/python2.6/site-packages/marrow/mailer/__init__.py', line 86 in _load
  return entrypoint.load()
File '/home/tim/Documents/MyWebPages/arwd/projects/tg21env-dev/lib/python2.6/site-packages/pkg_resources.py', line 1991 in load
  entry = __import__(self.module_name, globals(),globals(), ['__name__'])
File '/home/tim/Documents/MyWebPages/arwd/projects/tg21env-dev/lib/python2.6/site-packages/marrow/mailer/manager/dynamic.py', line 10 in 
  from concurrent import futures
ImportError: No module named concurrent

What fixed this for me was to run:

pip install futures

So I think futures needs to be added to marrow.mailer's requirements, at least for me. I'm running marrow.mailer in a Python 2.6 virtualenvironment on Ubuntu 11.04.

futures manager does not retry failed mails

I have a futures manager whose workers option is set to 1. Its transport delivers okay the first mail. After some time, the transport is disconnected by MTA, but futures manager does not know about that. The next message is lost, because when attempting to deliver the message, transport fails. By then, a new transport is created, but the lost message is not retried.

Immediate manager eats exceptions

I forgot to set the author of the message, and I was left wondering why my message was never delivered despite not getting any errors with the immediate manager. Turns out there was an IndexError at message.py:112:

 return self.sender or self.author[0]

This exception was however silently discarded, which obviously should never happen. Instead, a friendly exception reminding me that at least one author must be set should've been raised (and delivered to my application!).

Traceback from configuration handler

Trying to use following configuration:

from marrow.mailer import Mailer
mailer = Mailer({'transport': {'use': 'mbox', 'file': '/tmp/komasu.mbox'}})

Gives me following traceback:

Traceback (most recent call last):
  File "x.py", line 2, in <module>
    mailer = Mailer({'transport': {'use': 'mbox', 'file': '/tmp/komasu.mbox'}})
  File "/home/plaes/.virtualenvs/komasu/lib/python2.7/site-packages/marrow/mailer/__init__.py", line 50, in __init__
    self.manager_config = manager_config = Bunch.partial('manager', config)
  File "/home/plaes/.virtualenvs/komasu/lib/python2.7/site-packages/marrow/util/bunch.py", line 48, in partial
    raise ValueError()
ValueError

When I add the missing manager: {} to the configuration, it complains about missing message

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.