Git Product home page Git Product logo

muttdown's Introduction

muttdown

Build Status

muttdown is a sendmail-replacement designed for use with the mutt email client which will transparently compile annotated text/plain mail into text/html using the Markdown standard. It will recursively walk the MIME tree and compile any text/plain or text/markdown part which begins with the sigil "!m" into Markdown, which it will insert alongside the original in a multipart/alternative container.

It's also smart enough not to break multipart/signed.

For example, the following tree before parsing:

- multipart/mixed
 |
 -- multipart/signed
 |
 ---- text/markdown
 |
 ---- application/pgp-signature
 |
 -- image/png

Will get compiled into

- multipart/mixed
 |
 -- multipart/alternative
 |
 ---- text/html
 |
 ---- multipart/signed
 |
 ------ text/markdown
 |
 ------ application/pgp-signature
 |
 -- image/png

Configuration

Muttdown's configuration file is written using YAML. Example:

smtp_host: smtp.gmail.com
smtp_port: 587
smtp_ssl: false
smtp_username: [email protected]
smtp_password: foo
css_file: ~/.muttdown.css

If you prefer not to put your password in plaintext in a configuration file, you can instead specify the smtp_password_command parameter to invoke a shell command to lookup your password. The command should output your password, followed by a newline, and no other text. On OS X, the following invocation will extract a generic "Password" entry with the application set to "mutt" and the title set to "[email protected]":

smtp_password_command: security find-generic-password -w -s mutt -a [email protected]

NOTE: If smtp_ssl is set to False, muttdown will do a non-SSL session and then invoke STARTTLS. If smtp_ssl is set to True, muttdown will do an SSL session from the get-go. There is no option to send mail in plaintext.

The css_file should be regular CSS styling blocks; we use pynliner to inline all CSS rules for maximum client compatibility.

Muttdown can also send its mail using the native sendmail if you have that set up (instead of doing SMTP itself). To do so, just leave the smtp options in the config file blank, set the sendmail option to the fully-qualified path to your sendmail binary, and run muttdown with the -s flag

Installation

Install muttdown with pip install muttdown or by downloading this package and running python setup.py install. You will need the PyYAML and Python-Markdown libraries, as specified in requirements.txt. This should work with Python 2.7 or Python 3.5+.

Usage

Invoke as

muttdown -c /path/to/config -f "from_address" -- "to_address" [more to addresses...]

Send a RFC822 formatted mail on stdin.

If the config path is not passed, it will assume ~/.muttdown.yaml.

muttdown's People

Contributors

nottwo avatar roguelazer avatar ssgelm 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

muttdown's Issues

Don't pass arguments to ArgumentParser since it fails with Python 3.5

Hi

Calling ArgumentParser with version parameter doesn't work when running under python 3.5, so I patched it out.

I don't see any regression when applying the patch and running with Python 2.7

--- a/muttdown/main.py
+++ b/muttdown/main.py
@@ -122,7 +122,7 @@ def smtp_connection(c):
 
 
 def main():
-    parser = argparse.ArgumentParser(version='%s %s' % (__name__, __version__))
+    parser = argparse.ArgumentParser()
     parser.add_argument(                                                                                                                                                                     
         '-c', '--config_file', default=os.path.expanduser('~/.muttdown.yaml'),                                                                                                               
         type=argparse.FileType('r'), required=False,                        

String vs Bytes Error

On python 3.7 running on arch linux, a simple string piped to muttdown via echo on commandline does not parse properly, raising an error that a bytes object is expected, not string. The email still sends but is blank, unfortunately. The offending line seems to be main.py(166):

proc.communicate(rebuilt.as_string())

And I got it work by changing that line to:

proc.communicate(rebuilt.as_string().encode())

Attachments in signed messages don't show up in Thunderbird

Invoked on a signed message with attachments, muttdown creates a MIME tree as follows:

I  1 <no description>           [multipa/alternativ, 7bit, 111K]
I  2 ├─><no description>        [multipa/signed, 7bit, 110K]
I  3 │ ├─><no description>      [multipa/mixed, 7bit, 109K]
I  4 │ │ ├─><no description>    [text/plain, quoted, utf-8, 0,4K]
A  5 │ │ └─>Brochure.pdf        [applica/pdf, base64, 108K]
I  6 │ └─>PGP signature         [applica/pgp-signat, 7bit, 1,1K]
I  7 └─><no description>        [text/html, quoted, utf-8, 0,7K]

This works fine with mutt, obviously, and Gmail also seems to be okay with it, but Thunderbird doesn't give access to the attachments, and in a way that makes sense, because I am advertising the text/html part that contains no attachments as a better alternative (better because later in the tree, cf. RFC 1341) to the whole multipart/signed container.

Short of duplicating the attachments or invalidating signatures, can you think of another means to address this?

Would like to try it but install fails

% pip install --upgrade Markdown PyYAML pynliner 12:06
Requirement already up-to-date: Markdown in /usr/local/lib/python2.7/site-packages
Requirement already up-to-date: PyYAML in /usr/local/lib/python2.7/site-packages
Requirement already up-to-date: pynliner in /usr/local/lib/python2.7/site-packages
Requirement already up-to-date: BeautifulSoup<4.0,>=3.2.1 in /usr/local/lib/python2.7/site-packages (from pynliner)
Requirement already up-to-date: cssutils>=0.9.7 in /usr/local/lib/python2.7/site-packages (from pynliner)
% pip install muttdown 12:07
Collecting muttdown
Using cached muttdown-0.1.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "", line 20, in
File "/private/var/folders/g1/mvjqb71n3b1cwv6vb7_wv7hm0000z8/T/pip-build-nOX96W/muttdown/setup.py", line 29, in
install_requires, dependency_links = get_install_requirements()
File "/private/var/folders/g1/mvjqb71n3b1cwv6vb7_wv7hm0000z8/T/pip-build-nOX96W/muttdown/setup.py", line 20, in get_install_requirements
for ir in parse_requirements('requirements.txt', options=opts):
File "/usr/local/lib/python2.7/site-packages/pip/req/req_file.py", line 70, in parse_requirements
"parse_requirements() missing 1 required keyword argument: "
TypeError: parse_requirements() missing 1 required keyword argument: 'session'

----------------------------------------

Command "python setup.py egg_info" failed with error code 1 in /private/var/folders/g1/mvjqb71n3b1cwv6vb7_wv7hm0000z8/T/pip-build-nOX96W/muttdown

Error when trying to run gpg command as smtp_password_command

Hello, I've just switched machines and have been setting things up as I usually have them. I seem to be having an issue with the smtp_password_command parameter. My yaml file looks like this:

smtp_host: smtp.gmail.com
smtp_port: 465
smtp_ssl: true
smtp_username: [email protected]
smtp_password_command: gpg -d --no-tty /home/jacklenox/.passwd/gmail.gpg

But when I try to send an email, I get the following error.

Traceback (most recent call last):
  File "/home/jacklenox/.local/bin/muttdown", line 11, in <module>
    sys.exit(main())
  File "/home/jacklenox/.local/lib/python3.6/site-packages/muttdown/main.py",
line 169, in main
    conn = smtp_connection(c)
  File "/home/jacklenox/.local/lib/python3.6/site-packages/muttdown/main.py",
line 120, in smtp_connection
    conn.login(c.smtp_username, c.smtp_password)
  File "/home/jacklenox/.local/lib/python3.6/site-packages/muttdown/config.py",
line 104, in smtp_password
    return check_output(self._config['smtp_password_command'],
shell=True).rstrip('\n')
TypeError: a bytes-like object is required, not 'str'

If I replace smtp_password_command with the decrypted smtp_password, everything works fine. And if I try to run the GPG command on its own, equally everything works.

Any thoughts?

Doesn't build MIME tree as stated

From README a tree like this:

- multipart/mixed
 |
 -- text/markdown
 |
 -- image/png

Should result in a tree like:

- multipart/mixed
 |
 -- multipart/alternative
 |
 ---- text/html
 |
 ---- text/markdown
 |
 -- image/png

But I couldn't see how that could happen given the current source code, I've then tested it, and as expected the resulting tree is actually:

- multipart/alternative
 |
 -- multipart/mixed
 |
 ---- text/markdown
 |
 ---- image/png
 |
 -- multipart/mixed
 |
 ---- text/html
 |
 ---- image/png

This is bad because it duplicates attachments.

Cut a release

Hi

I'd like to update muttdown's debian package but i'd rather package a release instead of an snapshot, if you don't plan to ever do releases again its fine i'll package snapshots.

Just want to be on the same page as you, thanks!

Feature Request: Config option to always compile to text/html (i.e. without !m sigil)?

I've been looking for something like muttdown for years now, and am so pleased to have found it! Thanks so much for you work, really.

I'd like to be able to configure muttdown to compile every single email I write into multipart/alternative without having to prefix messages with !m. Is there any chance you'd be willing to add a config or command line option to that effect? I'd take a stab myself, but I haven't had much of a chance to work with Python yet, and I suspect my contributions wouldn't be exemplary or idiomatic.

Please support Content-Type: * markup=markdown

The MIME type text/markdown is not defined. The way to represent Markdown text is:

Content-Type: text/plain; charset="utf-8"; markup="markdown"

It would be great if that were supported too. In this case, I don't think it's necessary to require a !m sigil. What do you think?

text/html part of email coming through blank

Hello @Roguelazer, me again. I've recently upgraded my computer and have set everything up how I used to have it for sending email via muttdown. I'm having a peculiar issue where it just doesn't seem to be working as expected. The email body I'm receiving looks like this (i.e. I essentially receive the email as plain text without any HTML formatting):

...

--===============4829967231339153806==
MIME-Version: 1.0
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: base64

PGgxPlRlc3Q8L2gxPgo8aDI+VGVzdCAyPC9oMj4KPGRpdiBjbGFzcz0ic2lnbmF0dXJlIiBzdHls
ZT0iZm9udC1zaXplOiBzbWFsbCI+PHA+LS0gPGJyIC8+PC9wPjwvZGl2Pg==
--===============4829967231339153806==
MIME-Version: 1.0
Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="vwujxq2xnjm7mti2"
Content-Disposition: inline

--vwujxq2xnjm7mti2
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

!m
# Test
## Test 2
--=20

--vwujxq2xnjm7mti2
Content-Type: application/pgp-signature; name="signature.asc"

...

Any help much appreciated. Thank you. 🙏

UnicodeEncodeError for non-ASCII characters in body

Sending an email with a smartquote (U+2019) in the subject works fine:

$ muttdown -c /home/rlue/.config/muttdown.yml -f "[email protected]" -- "[email protected]"
Subject: What’s the big idea

Lorem ipsum dolor

But if that smartquote appears in the body, then sending the email fails:

$ muttdown -c /home/rlue/.config/muttdown.yml -f "[email protected]" -- "[email protected]"
Subject: Lorem ipsum dolor

What’s the big idea?
Traceback (most recent call last):
  File "/usr/local/bin/muttdown", line 10, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.7/dist-packages/muttdown/main.py", line 189, in main
    conn.sendmail(args.envelope_from, args.addresses, rebuilt.as_string())
  File "/usr/lib/python3.7/smtplib.py", line 855, in sendmail
    msg = _fix_eols(msg).encode('ascii')
UnicodeEncodeError: 'ascii' codec can't encode character '\u2019' in position 38: ordinal not in range(128)

Using muttdown 0.3.4, as provided by Debian testing.

Most header information seems to be going missing somewhere

Hello, I don't send a huge amount of email from Mutt so I'm not sure how long this has been going on, but I've recently realised that when I send emails, almost all the header information appears to get discarded. At the receiving end I can't see the "Subject", or the full "From" name (just the raw email address is shown there). Emails sent via Muttdown also don't appear to be including my PGP electronic signature. Interestingly, the email in my "Sent items" looks exactly as it should and includes the PGP signature.

If I take Muttdown out of the picture, everything seems to be working fine.

I'm running Neomutt 20180716.

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.