Giter VIP home page Giter VIP logo

mailmerge's Introduction

Mailmerge

CI main codecov PyPI

A simple, command line mail merge tool.

mailmerge uses plain text files and the jinja2 template engine.

Table of Contents

Quickstart

$ pip install mailmerge
$ mailmerge

mailmerge will guide you through the process. Don't worry, it won't send real emails by default.

Install

System-wide install.

$ pip install mailmerge

System-wide install requiring administrator privileges. Use this if you get a Permission denied error.

$ sudo pip install mailmerge

Fedora package install.

$ sudo dnf install python3-mailmerge

Example

This example will walk you through the steps for creating a template email, database and STMP server configuration. Then, it will show how to test it before sending real emails.

Create a sample template email, database, and config

$ mailmerge --sample
Created sample template email "mailmerge_template.txt"
Created sample database "mailmerge_database.csv"
Created sample config file "mailmerge_server.conf"

Edit these files, then run mailmerge again.

Edit the SMTP server config mailmerge_server.conf

The defaults are set up for GMail. Be sure to change your username. If you use 2-factor authentication, create an app password first. Other configuration examples are in the comments of mailmerge_server.conf.

Pro-tip: SSH or VPN into your network first. Running mailmerge from the same network as the SMTP server can help you avoid spam filters and server throttling. This tip doesn't apply to Gmail.

[smtp_server]
host = smtp.gmail.com
port = 465
security = SSL/TLS
username = YOUR_USERNAME_HERE

Edit the template email message mailmerge_template.txt

The TO, SUBJECT, and FROM fields are required. The remainder is the body of the message. Use {{ }} to indicate customized parameters that will be read from the database. For example, {{email}} will be filled in from the email column of mailmerge_database.csv.

TO: {{email}}
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>

Hi, {{name}},

Your number is {{number}}.

Edit the database mailmerge_database.csv

Notice that the first line is a header that matches the parameters in the template example, for example, {{email}}.

Pro-tip: Add yourself as the first recipient. This is helpful for testing.

email,name,number
[email protected],"Myself",17
[email protected],"Bob",42

Dry run

First, dry run one email message (mailmerge defaults). This will fill in the template fields of the first email message and print it to the terminal.

$ mailmerge
>>> message 1
TO: [email protected]
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Date: Thu, 19 Dec 2019 19:49:11 -0000

Hi, Myself,

Your number is 17.
>>> sent message 1
>>> Limit was 1 message.  To remove the limit, use the --no-limit option.
>>> This was a dry run.  To send messages, use the --no-dry-run option.

If this looks correct, try a second dry run, this time with all recipients using the --no-limit option.

$ mailmerge --no-limit
>>> message 1
TO: [email protected]
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Date: Thu, 19 Dec 2019 19:49:33 -0000

Hi, Myself,

Your number is 17.
>>> sent message 1
>>> message 2
TO: [email protected]
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Date: Thu, 19 Dec 2019 19:49:33 -0000

Hi, Bob,

Your number is 42.
>>> sent message 2
>>> This was a dry run.  To send messages, use the --no-dry-run option.

Send first email

We're being extra careful in this example to avoid sending spam, so next we'll send only one real email (mailmerge default). Recall that you added yourself as the first email recipient.

$ mailmerge --no-dry-run
>>> message 1
TO: [email protected]
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Date: Thu, 19 Dec 2019 19:50:24 -0000

Hi, Myself,

Your number is 17.
>>> sent message 1
>>> Limit was 1 message.  To remove the limit, use the --no-limit option.

You may have to type your email password when prompted. (If you use GMail with 2-factor authentication, don't forget to use the app password you created while setting up the SMTP server config.)

Now, check your email and make sure the message went through. If everything looks OK, then it's time to send all the messages.

Send all emails

$ mailmerge --no-dry-run --no-limit
>>> message 1
TO: [email protected]
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Date: Thu, 19 Dec 2019 19:51:01 -0000

Hi, Myself,

Your number is 17.
>>> sent message 1
>>> message 2
TO: [email protected]
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Date: Thu, 19 Dec 2019 19:51:01 -0000

Hi, Bob,

Your number is 42.
>>> sent message 2

Advanced template example

This example will send progress reports to students. The template uses more of the advanced features of the jinja2 template engine documentation to customize messages to students.

Template mailmerge_template.txt

TO: {{email}}
SUBJECT: EECS 280 Mid-semester Progress Report
FROM: My Self <[email protected]>
REPLY-TO: My Reply Self <[email protected]>

Dear {{name}},

This email contains our record of your grades EECS 280, as well as an estimated letter grade.

Project 1: {{p1}}
Project 2: {{p2}}
Project 3: {{p3}}
Midterm exam: {{midterm}}

At this time, your estimated letter grade is {{grade}}.

{% if grade == "C-" -%}
I am concerned that if the current trend in your scores continues, you will be on the border of the pass/fail line.

I have a few suggestions for the rest of the semester.  First, it is absolutely imperative that you turn in all assignments.  Attend lecture and discussion sections.  Get started early on the programming assignments and ask for help.  Finally, plan a strategy to help you prepare well for the final exam.

The good news is that we have completed about half of the course grade, so there is an opportunity to fix this problem.  The other professors and I are happy to discuss strategies together during office hours.
{% elif grade in ["D+", "D", "D-", "E", "F"] -%}
I am writing because I am concerned about your grade in EECS 280.  My concern is that if the current trend in your scores continues, you will not pass the course.

If you plan to continue in the course, I urge you to see your instructor in office hours to discuss a plan for the remainder of the semester.  Otherwise, if you plan to drop the course, please see your academic advisor.
{% endif -%}

Database mailmerge_database.csv

Again, we'll use the best practice of making yourself the first recipient, which is helpful for testing.

email,name,p1,p2,p3,midterm,grade
[email protected],"My Self",100,100,100,100,A+
[email protected],"Borderline Name",50,50,50,50,C-
[email protected],"Failing Name",0,0,0,0,F

HTML formatting

Mailmerge supports HTML formatting.

HTML only

This example will use HTML to format an email. Add Content-Type: text/html just under the email headers, then begin your message with <html>.

Template mailmerge_template.txt

TO: {{email}}
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>
Content-Type: text/html

<html>
<body>

<p>Hi, {{name}},</p>

<p>Your number is {{number}}.</p>

<p>Sent by <a href="https://github.com/awdeorio/mailmerge">mailmerge</a></p>

</body>
</html>

HTML and plain text

This example shows how to provide both HTML and plain text versions in the same message. A user's mail reader can select either one.

Template mailmerge_template.txt

TO: {{email}}
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="boundary"

This is a MIME-encoded message. If you are seeing this, your mail
reader is old.

--boundary
Content-Type: text/plain; charset=us-ascii

Hi, {{name}},

Your number is {{number}}.

Sent by mailmerge https://github.com/awdeorio/mailmerge

--boundary
Content-Type: text/html; charset=us-ascii

<html>
<body>

<p>Hi, {{name}},</p>

<p>Your number is {{number}}.</p>

<p>Sent by <a href="https://github.com/awdeorio/mailmerge">mailmerge</a></p>

</body>
</html>

Markdown formatting

Mailmerge supports Markdown formatting by including the custom custom header Content-Type: text/markdown in the message. Mailmerge will render the markdown to HTML, then include both HTML and plain text versions in a multiplart message. A recipient's mail reader can then select either format.

Template mailmerge_template.txt

TO: {{email}}
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>
CONTENT-TYPE: text/markdown

You can add:

- Emphasis, aka italics, with *asterisks*.
- Strong emphasis, aka bold, with **asterisks**.
- Combined emphasis with **asterisks and _underscores_**.
- Unordered lists like this one.
- Ordered lists with numbers:
    1. Item 1
    2. Item 2
- Preformatted text with `backticks`.
- How about some [hyperlinks](http://bit.ly/eecs485-wn19-p6)?

# This is a heading.
## And another heading.

Here's an image not attached with the email:
![python logo not attached](http://pluspng.com/img-png/python-logo-png-open-2000.png)

Attachments

This example shows how to add attachments with a special ATTACHMENT header.

Template mailmerge_template.txt

TO: {{email}}
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>
ATTACHMENT: file1.docx
ATTACHMENT: ../file2.pdf
ATTACHMENT: /z/shared/{{name}}_submission.txt

Hi, {{name}},

This email contains three attachments.
Pro-tip: Use Jinja to customize the attachments based on your database!

Dry run to verify attachment files exist. If an attachment filename includes a template, it's a good idea to dry run with the --no-limit flag.

$ mailmerge
>>> message 1
TO: [email protected]
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>

Hi, Myself,

This email contains three attachments.
Pro-tip: Use Jinja to customize the attachments based on your database!

>>> attached /Users/awdeorio/Documents/test/file1.docx
>>> attached /Users/awdeorio/Documents/file2.pdf
>>> attached /z/shared/Myself_submission.txt
>>> sent message 1
>>> This was a dry run.  To send messages, use the --no-dry-run option.

Inline Image Attachments

This example shows how to add inline-image-attachments so that the images are rendered directly in the email body. You must add the inline-image as an attachment before referencing it in the body.

HTML Example: Template mailmerge_template.txt

TO: {{email}}
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>
Content-Type: text/html
ATTACHMENT: image.jpg
ATTACHMENT: second/image.jpg

<html>
<body>

<p>Hi, {{name}},</p>

<img alt="Sample image" src="image.jpg" />

The second image: <img alt="second" src="second/image.jpg">

<p>Sent by <a href="https://github.com/awdeorio/mailmerge">mailmerge</a></p>

</body>
</html>

Markdown Example: Template mailmerge_template.txt

TO: {{email}}
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>
ATTACHMENT: image.jpg
CONTENT-TYPE: text/markdown

Hi, {{name}},

![image alt-description](image.jpg)

Contributing

Contributions from the community are welcome! Check out the guide for contributing.

Acknowledgements

Mailmerge is written by Andrew DeOrio [email protected], http://andrewdeorio.com. Sesh Sadasivam (@seshrs) contributed many features and bug fixes.

mailmerge's People

Contributors

abtsousa avatar awdeorio avatar bexelbie avatar captn3m0 avatar james-perretta avatar jonafato avatar mikk3lro avatar mrseccubus avatar onuralpszr avatar pbchase avatar philpagel avatar robstewart57 avatar seshrs avatar thecodelearner avatar xaph 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

mailmerge's Issues

Content-Type gets overwritten to text/plain with attachment

Template:

From: [email protected]
TO: [email protected]
SUBJECT: Hello
ATTACHMENT: a.txt
CONTENT-TYPE: text/html

<html>
<body>
<p>Hi,</p>
</body>
</html>

command: mailmerge --database database.csv --template 04.tpl --output-format raw

output:

>>> message 1
Content-Type: multipart/alternative;
 boundary="===============1872202902524908882=="
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
SUBJECT: Hello
From: [email protected]
TO: [email protected]
Date: Wed, 05 Aug 2020 21:37:21 -0000

--===============1872202902524908882==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

<html>
<body>
<p>Hi,</p>
</body>
</html>
--===============1872202902524908882==
Content-Type: application/octet-stream; Name="a.txt"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="a.txt"

aGVsbG93b3JsZA==

--===============1872202902524908882==--
>>> message 1 sent
>>> Limit was 1 message.  To remove the limit, use the --no-limit option.
>>> This was a dry run.  To send messages, use the --no-dry-run option.

The important part being Content-Type: text/plain; charset="us-ascii", which is incorrect. Using a html+plaintext message works, but that is more complicated.

Rendering local image file on HTML

<!doctype html>

<head>
    <title> Page Title </title>
    <!--Meta Tags-->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!--Import Google Icon Font-->
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

    <style type="text/css">
        * {
            margin: 0;
            border: 0;
            padding: 0;
        }

        body {
            background-color: black;
            background-image: url("frame.png");
            background-repeat: no-repeat;
            background-position: center top;

        }

        img {
            max-width: 100%;
        }

        #logo,
        #logo-text {
            text-align: center;
            margin: 2%;
        }

        #logo-text {
            color: Red;
            font-family: Arial;
        }
    </style>
</head>

<body>

    <div id="wrapper">
        <header>

            <div id="logo">
                <img src="C:/title.jpg" alt="">
            </div>

            <div id="logo-text">
                <h1>Hey {{name}}</h1>
            </div>

            <div id="logo">
                <img src="dog.jpg">
            </div>
        </header>

        <footer>

        </footer>
    </div>
    <!-- Optional JavaScript -->
</body>

</html>

My image location: C:/dog.jpg
I've tried:

C:/dog.jpg
C://dog.jpg
C:\dog.jpg
C:\dog.jpg
C:dog.jpg
file://c:dog.jpg

None of them seems to work, on mail broken img link is something like:

https://ci6.googleusercontent.com/proxy/izYZCJXx-jXLHBVR1eDxUnpAW7vOzihRRVcZEfKoBzVP=s0-d-e1-ft#http://dog.jpg

How can i send images on email from my local files?

German umlauts not supported

Traceback (most recent call last):
File "/usr/bin/mailmerge", line 11, in
load_entry_point('mailmerge==1.7.0', 'console_scripts', 'mailmerge')()
File "/usr/lib/python3.6/site-packages/click/core.py", line 722, in call
return self.main(*args, **kwargs)
File "/usr/lib/python3.6/site-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/usr/lib/python3.6/site-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/lib/python3.6/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/usr/lib/python3.6/site-packages/mailmerge/main.py", line 230, in main
sendmail(message, config_filename)
File "/usr/lib/python3.6/site-packages/mailmerge/main.py", line 71, in sendmail
smtp.send_message(message)
File "/usr/lib/python3.6/smtplib.py", line 962, in send_message
g.flatten(msg_copy, linesep='\r\n')
File "/usr/lib/python3.6/email/generator.py", line 116, in flatten
self._write(msg)
File "/usr/lib/python3.6/email/generator.py", line 181, in _write
self._dispatch(msg)
File "/usr/lib/python3.6/email/generator.py", line 214, in _dispatch
meth(msg)
File "/usr/lib/python3.6/email/generator.py", line 432, in _handle_text
super(BytesGenerator,self)._handle_text(msg)
File "/usr/lib/python3.6/email/generator.py", line 249, in _handle_text
self._write_lines(payload)
File "/usr/lib/python3.6/email/generator.py", line 155, in _write_lines
self.write(line)
File "/usr/lib/python3.6/email/generator.py", line 406, in write
self._fp.write(s.encode('ascii', 'surrogateescape'))
UnicodeEncodeError: 'ascii' codec can't encode character '\xfc' in position 15: ordinal not in range(128)

HTML and Plain text

Is there a way to provide both an HTML and a plain text template? Thanks!

Log output

Log output to file. Change output file with -o/--output option. Rotate files. Always log when --no-dry-run causes real emails to be sent.

Skip messages with bad email addresses

I just started with mailmerge, fits the job perfectly. One issue I have noticed is mailmerge encountering an email address that the sendmail client function, or the server, rejects. People move jobs or email accounts get deleted from time to time.

Instead of the mailmerge failing out on a bad address, is there a method to log the failures to an error file and keep going through the csv database? Doing a manual resume and specifying the next record on the command-line can be an issue if the job is running in a window you're not monitoring in real-time.

Thanks!

Terminal output garbled

When running mail merge using arch linux with pip install on dry run mode. The terminal returns the text below

TO: ...
SUBJECT: ...
FROM: ....
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
Date: Thu, 23 Jan 2020 07:37:45 -0000

RGVhciBNcnMgQmVuIGFuZCBNcnMgV2VuZHkgRnJlbmNoCgpJIGFtIGhhcHB5IHRvIGNvbmZpcm0g
dGhhdCBMYXVyZW4gd2lsbCBiZSBpbiBteSBtZW50b3IgZ3JvdXAgdGhpcyB5ZWFyLgpJIHdpbGwg
ZW5kZWF2b3VyIHRvIGd1aWRlIHlvdXIgY2hpbGQgdGhyb3VnaG91dCB0aGUgeWVhciBhcyBzaGUg
ZW1iYXJrcyBvbiB0aGlzIGV4Y2l0aW5nIGpvdXJuZXkuIEkgaGF2ZSB0aGUgcGxlYXN1cmUgb2Yg
c2VlaW5nIExhdXJlbiBpbiBteSBDb21wdXRhdGlvbmFsIFRoaW5raW5nIGNsYXNzLCBhcyB3ZWxs
IGFzIGluIFByb2plY3QgQmFzZWQgTGVhcm5pbmcuIFRoZSBmdW5jdGlvbiBvZiBhIG1lbnRvciBp
cyB0byBndWlkZSBMYXVyZW4gdG8gYmUgc3VjY2Vzc2Z1bCBhbmQgZmVlbCB3ZWxjb21lZCB0byBv
dXIgc2Nob29sLgoKUGxlYXNlIGZlZWwgZnJlZSB0byBjb250YWN0IG1lIHNob3VsZCB5b3UgaGF2
ZSBhbnkgZ2VuZXJhbCBxdWVyaWVzIG9yIHF1ZXN0aW9ucy4KU2hvdWxkIEkgYmUgdW5hYmxlIHRv
IGFuc3dlciBhIHF1ZXN0aW9uLCBJIHdpbGwgZW5zdXJlIHRoYXQgeW91IGFyZSBkaXJlY3RlZCB0
byB0aGUgcmVsZXZhbnQgcGVyc29uLgoKU2hvdWxkIHlvdSB3aXNoIHRvIGVucXVpcmUgYWJvdXQg
YWNhZGVtaWMgbWF0dGVycyBwbGVhc2UgY29udGFjdCB0aGUgc3ViamVjdCB0ZWFjaGVyIGRpcmVj
dGx5LiBEZXRhaWxzIG9mIHRoZSBzdWJqZWN0IHRlYWNoZXJzIGNhbiBiZSBmb3VuZCBpbiBvdXIg
YWNhZGVtaWMgcmVwb3J0aW5nIHN5c3RlbSBhZGFtLnJlZGhpbGwuY28uemEuCgpBbGwgY29tbXVu
aWNhdGlvbiByZWdhcmRpbmcgc3R1ZGVudCB3ZWxsLWJlaW5nIG11c3QgYmUgZGlyZWN0ZWQgdG8g
TXIgTW9yZSAoR3JhZGUgSGVhZCkuIEFkZGl0aW9uYWxseSBwbGVhc2UgQy5DIHRoZSBtZW50b3Ig
aW4gdGhlIGFib3ZlIGNvbW11bmljYXRpb24uIFJlcXVlc3RzIGZvciBwbGFubmVkIGVhcmx5IGRl
cGFydHVyZSBtdXN0IGJlIHNlbnQgdG8gTXIgTW9yZSBiZWZvcmUgMDZoMzAgb3IgYXMgZWFybHkg
YXMgcG9zc2libGUuCgpPdXIgQSZFIHByb2dyYW1tZSBlbnN1cmVzIHRoYXQgeW91ciBjaGlsZCB3
aWxsIHdyaXRlIGEgYmktd2Vla2x5IHN0YW5kYXJkaXNlZCB0ZXN0LiBTaG91bGQgTGF1cmVuIGJl
IGFic2VudCBwbGVhc2UgZW5zdXJlIHRoYXQgYSBkb2N0b3LigJlzIG5vdGUgaXMgc2VudCB0byBN
ciBNb3JlLiBXZSByZWdyZXQgdGhhdCBzdHVkZW50cyB0aGF0IGRvIG5vdCBoYXZlIHN1aXRhYmxl
IGV4Y3VzZXMgd2lsbCByZWNlaXZlIGEgemVyby4KClBsZWFzZSBlbnN1cmUgdGhhdCBMYXVyZW4g
a2VlcHMgdXAgdG8gZGF0ZSB3aXRoIHRoZSBub3RpZmljYXRpb25zIG9uIEdvb2dsZSBDbGFzc3Jv
b20gYXMgd2VsbCBhcyBsaXN0ZW5pbmcgYXR0ZW50aXZlbHkgaW4gb3VyIHNlcGFyYXRlIG1pZGRs
ZSBzY2hvb2wgYXNzZW1ibHkuCgpMYXN0bHksIHBsZWFzZSBlbnN1cmUgdGhhdCB5b3UgYXJlIGFi
bGUgdG8gYWNjZXNzIG91ciBNaVNvY3MgY2FsZW5kYXIgaW4gb3JkZXIgdG8gIGtlZXAgdXAgdG8g
ZGF0ZSB3aXRoIGNhbXB1cyBldmVudHMuCgpLaW5kIFJlZ2FyZHMKTXIgQmVuIEZyZW5jaAoKCg==

sent message 1
Limit was 1 message. To remove the limit, use the --no-limit option.

UnicodeEncodeError in csv.py

In python 2.7, the csv module doesn't like non-ascii characters. Can mailmerge work around this? Maybe https://github.com/jdunck/python-unicodecsv is an option?

$ mailmerge --sample; sed -ie 's/Myself/étoile/' mailmerge_database.csv; mailmerge
Creating sample template email mailmerge_template.txt
Creating sample database mailmerge_database.csv
Creating sample config file mailmerge_server.conf
Edit these files, and then run mailmerge again
Traceback (most recent call last):
  File "/usr/local/bin/mailmerge", line 9, in <module>
    load_entry_point('mailmerge==1.7.2', 'console_scripts', 'mailmerge')()
  File "/Library/Python/2.7/site-packages/click-6.7-py2.7.egg/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/Library/Python/2.7/site-packages/click-6.7-py2.7.egg/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/Library/Python/2.7/site-packages/click-6.7-py2.7.egg/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Library/Python/2.7/site-packages/click-6.7-py2.7.egg/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "build/bdist.macosx-10.11-intel/egg/mailmerge/main.py", line 213, in main
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/csv.py", line 108, in next
    row = self.reader.next()
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 21: ordinal not in range(128)

Skip messages via Jinja template

The context: Using a DB as primary datasource

I'm using mailmerge, using a MySQL database as datasource.
This DB contains data and a number of custom views. Each view queries the data and returns a row for each mail to be sent with mailmerge.

As mailmerge is accepting only CSV file as input (as far as I know), and not a DB view, a little utility bash script

send_to <view> <mail_template>

is executing the DB <view> and generates a transient CSV file containing the selected rows.

The script then calls mailmerge using the path to this CSV file and a Jinja2 <mail_template> as input parameters.

Mailmerge does its job and sends a mail for each line in the CSV file. Perfect!

Issue:

Sometimes, I need to quickly send a mail to a subset of the mysql <view>. One shot. No need to reuse the query.
I could of course create/alter the DB view, but that's not as agile as I would like and could quickly lead to proliferation of views, all with their own little variations on some 'master' view.

Question:

Is is possible to use some Jinja2 tagging in the mail template, that would have as an effect to skip the current record?

Something like:

{% if condition_based_on_current_record -%}
TO: {{email}}
SUBJECT: Interesting mail
FROM: My Self <[email protected]>

Dear {{name}},

You are the lucky recipient of this email.

Best regards,

Me
{% endif -%}

If condition_based_on_current_record is true then the mail is sent.
Otherwise, the sender, recipient and message are all empty, and mailmerge would skip the record.

Thank you.

With attachments its send duplicate header of Content Type

This is the email header with attachment . Without attachment is okay

Content-Type: multipart/alternative; boundary="===============6399458286909476=="
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="===============6399458286909476=="
SUBJECT: Testing mailmerge
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
FROM: User [email protected]
TO: [email protected]
Date: Mon, 18 May 2020 18:21:03 -0000

Retry

Wait and retry in response to SMTP rate limiting. Include a configuration parameter to set the timeout.

Rate limiting option

Is there interest in a flood limit timer? For example, my ISP has a limit of 50 emails in 5 minutes. I'd love to be able to tell mailmerge this so i can just leave a process running. Perhaps something like:

mailmerge ... --pause-count=50 --pause-time=600

--pause-count = Pause after this many emails are sent - default 0
--pause-time = Pause for this long in seconds - default 0

Error condition if either is set to a negative value or if only one is set to a positive value

WDYT?

HTML based e-mail template

I Don know is this is the right way, but I want to know whether it is possible to use an html based mail als template.

CSV with BOM

It looks like Excel will sometimes save a file with Byte Order Mark (BOM). When the mailmerge database contains a BOM, it can't seem to find the first header key.

mailmerge_template.txt:

TO: {{email}}
FROM: My Self <[email protected]>

Hello {{name}}

mailmerge_database.csv:

name,email
My Name,[email protected]
$ file mailmerge_database.csv 
mailmerge_database.csv: UTF-8 Unicode (with BOM) text, with CRLF line terminators

mailmerge_database_with_BOM.csv.txt

Chardet specifies wrong encoding with emoji

Tl;dr

It looks like chardet doesn't always get the encoding right — in a message containing emoji, chardet reported (with low confidence) that the message was encoded in Windows-1252. Python throws an exception when trying to encode a string with emoji to that charset.

I don't know if there's a good fix. Can we assume that users are responsible for specifying an encoding if it's not UTF-8? (That would remove our reliance on chardet.)

The bug

Steps I followed on my Mac:

  1. Use the following mailmerge_template.txt:
TO: {{email}}
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>

Hi 😀
  1. Run mailmerge --dry-run --limit 1

I received this error:

...
File "/Users/seshrs/Documents/Git/mailmerge/mailmerge/template_message.py", line 76, in _transform_encoding
    part.set_charset(encoding)
  File "/Users/seshrs/Documents/Git/mailmerge/env/lib/python3.7/site-packages/future/backports/email/message.py", line 322, in set_charset
    self._payload = charset.body_encode(self._payload)
  File "/Users/seshrs/Documents/Git/mailmerge/env/lib/python3.7/site-packages/future/backports/email/charset.py", line 403, in body_encode
    string = string.encode(self.output_charset)
  File "/usr/local/bin/../Cellar/python/3.7.4_1/bin/../Frameworks/Python.framework/Versions/3.7/lib/python3.7/encodings/cp1252.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character '\U0001f600' in position 3: character maps to <undefined>

The cause

I set a breakpoint in the _transform_encoding function:

def _transform_encoding(self, raw_message):
"""Detect and set character encoding."""
self._message = email.parser.Parser().parsestr(raw_message)
detected = chardet.detect(bytearray(raw_message, "utf-8"))
encoding = detected["encoding"]
for part in self._message.walk():
if part.get_content_maintype() == 'multipart':
continue
part.set_charset(encoding)

And printed the contents of detected:

(Pdb++) detected
{'encoding': 'Windows-1252', 'confidence': 0.5334615384615384, 'language': ''}

I had expected 'utf-8', not 'Windows-1252'. To confirm this was the issue, I tried executing the following in Python:

>>> "hi 😀".encode('Windows-1252')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/encodings/cp1252.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character '\U0001f600' in position 3: character maps to <undefined>

(The call to part.set_charset(encoding) eventually reaches this line in the python-future code that executes something like the above.)

README diagram

Add a diagram to the README describing the mailmerge workflow.

BCC/CC support

Is it possible to add BCC/CC headers to the email template and have them handled intelligently?

When I tested this, they appeared in the message sent to the TO address but did not generate any extra emails to the bcc'd or cc'd addresses.

Ideally, extra emails should be generated by these headers, and the BCC header should mostly not appear in the output emails.

Problem with body of email

Hi,
I want to use mailmerge cause you made a great job. But I have a problem with the body of the template. Instead of :

`ATTACHMENT: classes/{{classe}}.xls

Bonjour {{name}},

En tant que PP de la classe de {{classe}}, je t'envoie la liste des codes réseau de tes eleves.
C'est ce code qu'ils utilisent pour ouvrir une session sur les ordinateurs du lycee.
A toi de les distribuer s'ils ne les ont pas deja.

Cordialement,

`
I have :

`ATTACHMENT: classes/2_A.xls
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
Date: Sat, 31 Aug 2019 15:32:22 -0000

Qm9uam91ciBNaWNoZWwsCgpFbiB0YW50IHF1ZSBQUCBkZSBsYSBjbGFzc2UgZGUgMl9BLCBqZSB0
J2Vudm9pZSBsYSBsaXN0ZSBkZXMgY29kZXMgcsODwqlzZWF1IGRlIHRlcyBlbGV2ZXMuIApDJ2Vz
dCBjZSBjb2RlIHF1J2lscyB1dGlsaXNlbnQgcG91ciBvdXZyaXIgdW5lIHNlc3Npb24gc3VyIGxl
cyBvcmRpbmF0ZXVycyBkdSBseWNlZS4gCkEgdG9pIGRlIGxlcyBkaXN0cmlidWVyIHMnaWxzIG5l
IGxlcyBvbnQgcGFzIGRlamEuCgpDb3JkaWFsZW1lbnQsCgotLSAKTWljaGVsIFZpZW5uZQpBQyAv
IElTTiAvIE5TSSAvIFNJTwpSZWZlcmVudCBudW1lcmlxdWUKTFBPIEJsYWlzZSBQYXNjYWwK
attached /home/vienne/Documents/reseau/classes/2_A.xls
sent message 0 DRY RUN
`
I have been looking but not finding. Do you have any idea? Am I dumb ?

Missing date in header

I am having trouble using mailmerge, because it does not set a date-header. That causes X-Amavis / amavisd to block it as spam. Here are the two types of error I get:

The message WAS NOT relayed to:
<-receiver->:
554 5.6.0 Bounce, id=23674-07 - BAD HEADER

This nondelivery report was generated by the program amavisd-new at host
-receiver-. Our internal reference code for your message is
23674-07/WzRLAsDqSAcp

INVALID HEADER

Missing required header field: "Date"

And

X-Virus-Scanned: amavisd-new at server3533.serverpark.dk
X-Amavis-Alert: BAD HEADER SECTION, Missing required header field: "Date"

AttributeError: 'list' object has no attribute 'decode'

Great tool! Does exactly what I am looking for.
There is just one Issue when trying to send a multipart message, I am getting this error:

mailmerge --dry-run
>>> message 0
TO: myself@mydomain.com
SUBJECT: Testing mailmerge
FROM: My Self <myself@mydomain.com>
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="outer-boundary"

This is a MIME-encoded message. If you are seeing this, your mail
reader is old.

--outer-boundary
Content-Type: text/plain; charset=us-ascii

Hi, Myself,

Your number is 17.

Sent by mailmerge https://github.com/awdeorio/mailmerge

--outer-boundary
MIME-Version: 1.0
Content-Type: multipart/related;
  type="text/html"; start="<body@here>"; boundary="inner-boundary"

--inner-boundary
Content-Type: text/html; charset=us-ascii
Content-Disposition: inline
Content-ID: <body@here>

<html>
<body>

<p>Hi, Myself,</p>

<p>Your number is 17.</p>

<p>Sent by <a href="https://github.com/awdeorio/mailmerge">mailmerge</a></p>

</body>
</html>
Traceback (most recent call last):
  File "/usr/local/bin/mailmerge", line 11, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/mailmerge/__main__.py", line 45, in cli
    config_filename=config_filename,
  File "/usr/local/lib/python2.7/site-packages/mailmerge/api.py", line 238, in main
    (text, sender, recipients) = parsemail(raw_message)
  File "/usr/local/lib/python2.7/site-packages/mailmerge/api.py", line 39, in parsemail
    message.set_charset(encoding)
  File "/usr/local/lib/python2.7/site-packages/future/backports/email/message.py", line 320, in set_charset
    cte(self)
  File "/usr/local/lib/python2.7/site-packages/future/backports/email/encoders.py", line 68, in encode_7or8bit
    orig.decode('ascii')
AttributeError: 'list' object has no attribute 'decode'

I have used the --sample flag and copied the multipart example in the Readme.
Working with plain text and pure html emails works.

Any Idea, what this could be? I would be more than happy to help if possible.

Doesn't use charset=utf-8 when using markdown

Sending a message with special characters gives good results.

TO: {{email}}
SUBJECT: Testing mailmerge
FROM: [email protected]

Hi, {{name}},
æøå

outputs

>>> encoding utf-8
>>> message 0
TO: [email protected]
SUBJECT: Testing mailmerge
FROM: [email protected]
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
Date: Fri, 13 Dec 2019 20:41:08 -0000

SGksIE15c2VsZiwKw6bDuMOl

Notice that charset here is set ut utf-8 and message renders well in email client.

But when specifying markdown:

TO: {{email}}
SUBJECT: Testing mailmerge
FROM: [email protected]
CONTENT-TYPE: text/markdown

Hi, {{name}},
æøå

It outputs

>>> encoding utf-8
>>> message 0
MIME-Version: 1.0
SUBJECT: Testing mailmerge
Date: Fri, 13 Dec 2019 20:42:22 -0000
TO: [email protected]
FROM: [email protected]
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Type: multipart/alternative; boundary="===============3629053266709230733=="

--===============3629053266709230733==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

SGksIE15c2VsZiwKw6bDuMOl

--===============3629053266709230733==
Content-Type: text/html; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

<html><body><p>SGksIE15c2VsZiwKw6bDuMOl</p></body></html>
--===============3629053266709230733==--

Notice that charset here is set ut us-ascii, and message shows up as SGksIE15c2VsZiwKw6bDuMOl in the client.

Terminal output with utf8

Decode utf-8 messages printed to stdout. The current behavior is to print base64-encoded messages, which are hard to verify.

Example

mailmerge_template.txt with unicode characters, including emoji.

TO: [email protected]
FROM: [email protected]

Laȝamon 😀 klâwen

mailmerge_database.csv:

mailmerge_server.conf:

[smtp_server]
host = open-smtp.example.com
port = 25

Running mailmerge results in the following stdout:

$ mailmerge
>>> message 0
TO: [email protected]
FROM: [email protected]
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
Date: Wed, 18 Dec 2019 15:02:04 -0000

TGHInWFtb24ga2zDondlbg==

>>> sent message 0
>>> Limit was 1 messages.  To remove the limit, use the --no-limit option.
>>> This was a dry run.  To send messages, use the --no-dry-run option.

Ideally, the output would look like this:

Running mailmerge results in the following stdout:
```console
$ mailmerge
>>> message 0
TO: [email protected]
FROM: [email protected]
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
Date: Wed, 18 Dec 2019 15:02:04 -0000

Laȝamon 😀 klâwen

>>> sent message 0
>>> Limit was 1 messages.  To remove the limit, use the --no-limit option.
>>> This was a dry run.  To send messages, use the --no-dry-run option.

Testing

  • Update existing test_main.py::test_stdout_utf8
  • Don't print attachment content, just filename. This is already the case.
  • Non-multipart message
  • HTML and plaintext multipart
  • UTF8 multipart message
  • Attachment
  • CC
  • BCC

Inline image from attachment

I was wondering if something like this would be possible:

ATTACHMENT: u4qSjQL.jpeg
![](u4qSjQL.jpeg)

I tried it, and it renders to just an image tag: <p><img alt="" src="u4qSjQL.jpeg" /></p></body></html>

Apparently, it is possible via a href that points to the cid.

Resume option

It would be nice to have a mailmerge --resume option to resume sending emails in the event of a failure.

Along with this, it would makes sense to report the database row number of a sent message. It should correspond to row number when viewing the database CSV file in a spreadsheet program.

Python2 `sendmail()` exception

Traceback (most recent call last):
  File "/usr/local/bin/mailmerge", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/mailmerge/main.py", line 182, in main
    sendmail(message, config_filename)
  File "/usr/local/lib/python2.7/site-packages/mailmerge/main.py", line 51, in sendmail
    smtp = smtplib.SMTP_SSL(sendmail.host, sendmail.port)
  File "/usr/local/Cellar/python/2.7.12/Frameworks/Python.framework/Versions/2.7/lib/python2.7/smtplib.py", line 801, in __init__
    SMTP.__init__(self, host, port, local_hostname, timeout)
  File "/usr/local/Cellar/python/2.7.12/Frameworks/Python.framework/Versions/2.7/lib/python2.7/smtplib.py", line 256, in __init__
    (code, msg) = self.connect(host, port)
  File "/usr/local/Cellar/python/2.7.12/Frameworks/Python.framework/Versions/2.7/lib/python2.7/smtplib.py", line 316, in connect
    self.sock = self._get_socket(host, port, self.timeout)
  File "/usr/local/Cellar/python/2.7.12/Frameworks/Python.framework/Versions/2.7/lib/python2.7/smtplib.py", line 806, in _get_socket
    new_socket = socket.create_connection((host, port), timeout)
  File "/usr/local/Cellar/python/2.7.12/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 557, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
socket.error: getaddrinfo() argument 2 must be integer or string

Support unencrypted SMTP

We should support more options for SMTP connections. At present, end-to-end encryption with SSL is the only option.

# Encrypted, SSL
smtp = smtplib.SMTP_SSL(host, port)

# Unencrypted
smtp = smtplib.SMTP(host, port)

# Upgrade to TLS
smtp = smtplib.SMTP(host, port)
smtp.ehlo()
smtp.starttls()
smtp.ehlo

Remove sh dependency

The sh module seems to be unmaintained (last commit was in 2017) and it is not being tested against the latest Python versions.

As of Python 3.5, much of the functionality in sh can be replicated with subprocess.run.

First, verify that a backport exists.

EDIT: The Click library's testing functionality is a better option for many of the tests that currently use sh. This SO post is helpful.

Revert header_encode work-around

PR #88 contained a work-around for a bug in future.backports.email.base64mime.header_encode that raises an exception when serializing an email message object containing a base64-encoded UTF8 header. Remove the work-around in utils.py after PythonCharmers/python-future#555 is fixed upstream.

Don't forget to bump the dependency library version in setup.py.

Support for unicode utf-8 charmaps

Using mailmerge to send mass emails is better than using any gmail extensions, since i have the ability to use advanced markdown and html
however while working with a large (5k+) csv file of job applicants, i came across an issue that people had entered their names in a localized language (eg. mandarin, etc) that sometimes didn't fit the ascii charmaps.

It would be useful to open the csv file as encoding=utf8 with errors=ignore to avoid errors like this:
'charmap' codec can't decode byte 0x9d in position 1710: character maps to <undefined>
instead of just returning true if strings are ascii.

Possibility to embed graphics

I would like to embed graphics in the mail. Currently I am able to use graphics by referring to external hosted graphics (using the img tag and src=http://....) . Is it also possible to embed these graphics in the mail?

Encoding UTF-8

mailmerge_template.txt


TO: {{email}}
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>
Content-Type: text/html; charset="utf-8"

<!doctype html>
<html lang="pt-br">

<head>
    <title> Page title </title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <style type="text/css">
        * {
            margin: 0;
            border: 0;
            padding: 0;
            color: red;

            font-family: Arial, Helvetica, sans-serif;
        }
    </style>
</head>

<body>

<h1>ççç ÇÇÇ áéíóú !.</h1>
</body>

</html>

Terminal:

>mailmerge
>>> message 0
TO: [email protected]
SUBJECT: Testing mailmerge
FROM: My Self <[email protected]>
Content-Type: text/html; charset="utf-8"

<!doctype html>
<html lang="pt-br">

<head>
    <title> Page title </title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <style type="text/css">
        * {
            margin: 0;
            border: 0;
            padding: 0;
            color: red;

            font-family: Arial, Helvetica, sans-serif;
        }
    </style>
</head>

<body>

<h1>ççç ÇÇÇ áéíóú !.</h1>
</body>

</html>
>>> encoding utf-8
>>> sent message 0 DRY RUN
>>> No attachments were sent with the emails.
>>> Limit was 1 messages.  To remove the limit, use the --no-limit option.
>>> This was a dry run.  To send messages, use the --no-dry-run option.

Recieved mail:

image

Am i doing anything wrong? What should i do to those characters appears?

Markdown Support

Instead of rewriting the message, I would like to write the text version in markdown, and have the html version auto-generated. Taking care of the multipart boundaries by hand and rewriting emails in HTML is just 😿

Improve test case coverage

Pr #53 added code coverage measurement. At the time of this writing, coverage is around 70%. Improve this by writing more tests.

test_main.py

(formerly test_mailmerge.py)

  • Test dry run
  • Test bad option combinations
  • Bad template
  • Bad database
  • Bad config
  • Bad option: --limit 1 --no-limit
  • Bad option: --limit -1
  • Attachment feature, check stdout
  • Complicated end-to-end test with TO, CC, BCC, templates everywhere, UTF8 everywhere, Markdown, attachments. Check full stdout.

test_template_message.py

  • __init__() accepts either a filename or file object
  • Test simple attachment
  • Test attachment with relative path
  • Test attachment with tilde path
  • Test attachment with template in filename
  • Test attachment header with blank value
  • Test attachment not found
  • Test body with UTF8
  • Test context with UTF8
  • Test CC and BCC
  • Test Markdown
  • Test HTML
  • Test Multipart
  • Test encoding ASCII
  • Test encoding IS8859-1
  • Test encoding UTF8

test_sendmail_client.py

  • __init__() accepts either a filename or file object
  • Test dry run
  • Test SSL/TLS security
  • Test STARTTLS security
  • Test Never security, and use a config w/o a username
  • Test close connection on error
  • Bad config

smtp sends two copies

When sending a mail under arch linux with a pip install and only sending one mail merge it appears to send the message twice.
Also using office 365 smtp server.

Unicode Support

It would be nice to have unicode support so that users with unicode names could spell them correctly.

I've been looking and it seems we could do this if we always sent a UTF-8 encoded email, easily.

WDYT?

chardet error with python36 on CentOS with EPEL

I've run a scratch EPEL build as part of working on #45

https://koji.fedoraproject.org/koji/taskinfo?taskID=35510263

This is very much NOT READY FOR PRIMETIME

Using the sample, I am getting a chardet error.

$ mailmerge
Traceback (most recent call last):
  File "/usr/bin/mailmerge", line 11, in <module>
    load_entry_point('mailmerge==1.9', 'console_scripts', 'mailmerge')()
  File "/usr/lib/python3.6/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3.6/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python3.6/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python3.6/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/lib/python3.6/site-packages/mailmerge/__main__.py", line 45, in cli
    config_filename=config_filename,
  File "/usr/lib/python3.6/site-packages/mailmerge/api.py", line 343, in main
    (message, sender, recipients) = parsemail(raw_message)
  File "/usr/lib/python3.6/site-packages/mailmerge/api.py", line 47, in parsemail
    detected = chardet.detect(bytearray(raw_message, "utf-8"))
  File "/usr/lib/python3.6/site-packages/chardet/__init__.py", line 25, in detect
    raise ValueError('Expected a bytes object, not a unicode object')
ValueError: Expected a bytes object, not a unicode object

Note: I have done only a minimal amount of debugging work so far - but figured I'd open this in case you just happened to know it (it's midnight here). I'll pick this up with or without response as I have time.

UnicodeEncodeError: 'ascii' codec can't encode character '\xe8' in position 7: ordinal not in range(128)

I have installed mailmerge via "sudo pip3 install mailmerge"
I have an UTF-8 template and an ASCII CSV file, when I dry-run:

mailmerge --dry-run --no-limit --template mailmerge/rinnovo_quota_template.txt --config mailmerge/gbiscuolo_server.conf --database /tmp/tempfile.JCuuWP50

all the messages are printed with no errors but when I run the same script using "no-dry-run"

mailmerge --no-dry-run --limit 1 --template mailmerge/rinnovo_quota_template.txt --config mailmerge/gbiscuolo_server.conf --database /tmp/tempfile.JCuuWP50

I get the SMTP password prompt, enter it, and then the following error:

  File "/usr/local/bin/mailmerge", line 11, in <module>
    sys.exit(main())
  File "/usr/lib/python3/dist-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python3/dist-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python3/dist-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/mailmerge/main.py", line 231, in main
    sendmail(message, config_filename)
  File "/usr/local/lib/python3.5/dist-packages/mailmerge/main.py", line 72, in sendmail
    smtp.send_message(message)
  File "/usr/lib/python3.5/smtplib.py", line 958, in send_message
    g.flatten(msg_copy, linesep='\r\n')
  File "/usr/lib/python3.5/email/generator.py", line 116, in flatten
    self._write(msg)
  File "/usr/lib/python3.5/email/generator.py", line 181, in _write
    self._dispatch(msg)
  File "/usr/lib/python3.5/email/generator.py", line 214, in _dispatch
    meth(msg)
  File "/usr/lib/python3.5/email/generator.py", line 432, in _handle_text
    super(BytesGenerator,self)._handle_text(msg)
  File "/usr/lib/python3.5/email/generator.py", line 249, in _handle_text
    self._write_lines(payload)
  File "/usr/lib/python3.5/email/generator.py", line 155, in _write_lines
    self.write(line)
  File "/usr/lib/python3.5/email/generator.py", line 406, in write
    self._fp.write(s.encode('ascii', 'surrogateescape'))
UnicodeEncodeError: 'ascii' codec can't encode character '\xe8' in position 7: ordinal not in range(128)

I don't know how to solve this issue: is it a problem with mailmerge or with the email library?

best regards
Giovanni

GUI Template Generator

Any thoughts on a interface such tinymce for generating the mailmerge template? Could be particularly useful for generating templates which include both plain text and html. Perhaps out of the scope of this tool but maybe a supplementary tool?

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.