summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYann Rouillard <yann@pleiades.fr.eu.org>2013-12-08 17:40:33 +0100
committerPatrick Totzke <patricktotzke@gmail.com>2014-08-02 17:29:33 +0200
commit1912b7cdedc3ffb88ba953e4e8877fdec6c38893 (patch)
treed80fc9c459d25ddfc57735a49d80cb0951908c4a
parent6e1990f019fee1cf01af1c63e6f18607da672296 (diff)
Move email_as_string function from crypto to helper module
The email_as_string function, and the related RFC3156_canonicalize function, are now used by the ForwardCommand and are not specific anymore to the crypto routine. So we move them to the global helper module. fix an import removal mistake while moving email_as_string function: StringIO was not only used by email_as_string
-rw-r--r--alot/commands/envelope.py5
-rw-r--r--alot/commands/thread.py4
-rw-r--r--alot/crypto.py51
-rw-r--r--alot/db/envelope.py4
-rw-r--r--alot/helper.py59
5 files changed, 63 insertions, 60 deletions
diff --git a/alot/commands/envelope.py b/alot/commands/envelope.py
index b67231b7..b90816d2 100644
--- a/alot/commands/envelope.py
+++ b/alot/commands/envelope.py
@@ -19,6 +19,7 @@ from alot import crypto
from alot.commands import Command, registerCommand
from alot.commands import globals
from alot.helper import string_decode
+from alot.helper import email_as_string
from alot.settings import settings
from alot.utils.booleanaction import BooleanAction
from alot.db.errors import DatabaseError
@@ -130,7 +131,7 @@ class SaveCommand(Command):
# store mail locally
# add Date header
mail['Date'] = email.Utils.formatdate(localtime=True)
- path = account.store_draft_mail(crypto.email_as_string(mail))
+ path = account.store_draft_mail(email_as_string(mail))
msg = 'draft saved successfully'
@@ -201,7 +202,7 @@ class SendCommand(Command):
try:
self.mail = self.envelope.construct_mail()
self.mail['Date'] = email.Utils.formatdate(localtime=True)
- self.mail = crypto.email_as_string(self.mail)
+ self.mail = email_as_string(self.mail)
except GPGProblem, e:
ui.clear_notify([clearme])
ui.notify(e.message, priority='error')
diff --git a/alot/commands/thread.py b/alot/commands/thread.py
index 04fadeeb..ca73c75f 100644
--- a/alot/commands/thread.py
+++ b/alot/commands/thread.py
@@ -21,7 +21,6 @@ from alot.commands.globals import MoveCommand
from alot.commands.globals import CommandCanceled
from alot.commands.envelope import SendCommand
from alot import completion
-from alot import crypto
from alot.db.utils import decode_header
from alot.db.utils import encode_header
from alot.db.utils import extract_headers
@@ -32,6 +31,7 @@ from alot.db.errors import DatabaseROError
from alot.settings import settings
from alot.helper import parse_mailcap_nametemplate
from alot.helper import split_commandstring
+from alot.helper import email_as_string
from alot.utils.booleanaction import BooleanAction
from alot.completion import ContactsCompleter
@@ -315,7 +315,7 @@ class ForwardCommand(Command):
original_mail = Message()
original_mail.set_type('message/rfc822')
original_mail['Content-Disposition'] = 'attachment'
- original_mail.set_payload(crypto.email_as_string(mail))
+ original_mail.set_payload(email_as_string(mail))
envelope.attach(Attachment(original_mail))
# copy subject
diff --git a/alot/crypto.py b/alot/crypto.py
index 1270485d..4c74f1bf 100644
--- a/alot/crypto.py
+++ b/alot/crypto.py
@@ -4,41 +4,11 @@
import re
import os
-from email.generator import Generator
from cStringIO import StringIO
from alot.errors import GPGProblem, GPGCode
-from email.mime.multipart import MIMEMultipart
import gpgme
-def email_as_string(mail):
- """
- Converts the given message to a string, without mangling "From" lines
- (like as_string() does).
-
- :param mail: email to convert to string
- :rtype: str
- """
- fp = StringIO()
- g = Generator(fp, mangle_from_=False, maxheaderlen=78)
- g.flatten(mail)
- as_string = RFC3156_canonicalize(fp.getvalue())
-
- if isinstance(mail, MIMEMultipart):
- # Get the boundary for later
- boundary = mail.get_boundary()
-
- # Workaround for http://bugs.python.org/issue14983:
- # Insert a newline before the outer mail boundary so that other mail
- # clients can verify the signature when sending an email which contains
- # attachments.
- as_string = re.sub(r'--(\r\n)--' + boundary,
- '--\g<1>\g<1>--' + boundary,
- as_string, flags=re.MULTILINE)
-
- return as_string
-
-
def _hash_algo_name(hash_algo):
"""
Re-implements GPGME's hash_algo_name as long as pygpgme doesn't wrap that
@@ -85,27 +55,6 @@ def RFC3156_micalg_from_algo(hash_algo):
return 'pgp-' + hash_algo.lower()
-def RFC3156_canonicalize(text):
- """
- Canonicalizes plain text (MIME-encoded usually) according to RFC3156.
-
- This function works as follows (in that order):
-
- 1. Convert all line endings to \\\\r\\\\n (DOS line endings).
- 2. Ensure the text ends with a newline (\\\\r\\\\n).
- 3. Encode all occurences of "From " at the beginning of a line
- to "From=20" in order to prevent other mail programs to replace
- this with "> From" (to avoid MBox conflicts) and thus invalidate
- the signature.
-
- :param text: text to canonicalize (already encoded as quoted-printable)
- :rtype: str
- """
- text = re.sub("\r?\n", "\r\n", text)
- if not text.endswith("\r\n"):
- text += "\r\n"
- text = re.sub("^From ", "From=20", text, flags=re.MULTILINE)
- return text
def get_key(keyid, validate=False, encrypt=False, sign=False):
diff --git a/alot/db/envelope.py b/alot/db/envelope.py
index a9c4fc7c..6550baeb 100644
--- a/alot/db/envelope.py
+++ b/alot/db/envelope.py
@@ -184,7 +184,7 @@ class Envelope(object):
inner_msg = textpart
if self.sign:
- plaintext = crypto.email_as_string(inner_msg)
+ plaintext = helper.email_as_string(inner_msg)
logging.debug('signing plaintext: ' + plaintext)
try:
@@ -229,7 +229,7 @@ class Envelope(object):
unencrypted_msg = inner_msg
if self.encrypt:
- plaintext = crypto.email_as_string(unencrypted_msg)
+ plaintext = helper.email_as_string(unencrypted_msg)
logging.debug('encrypting plaintext: ' + plaintext)
try:
diff --git a/alot/helper.py b/alot/helper.py
index 6eceeed9..fb95f706 100644
--- a/alot/helper.py
+++ b/alot/helper.py
@@ -11,16 +11,18 @@ import email
import mimetypes
import os
import re
+from email.generator import Generator
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
+from email.mime.multipart import MIMEMultipart
import urwid
import magic
from twisted.internet import reactor
from twisted.internet.protocol import ProcessProtocol
from twisted.internet.defer import Deferred
-import StringIO
+from cStringIO import StringIO
import logging
@@ -337,8 +339,8 @@ def call_cmd_async(cmdlist, stdin=None, env=None):
class _EverythingGetter(ProcessProtocol):
def __init__(self, deferred):
self.deferred = deferred
- self.outBuf = StringIO.StringIO()
- self.errBuf = StringIO.StringIO()
+ self.outBuf = StringIO()
+ self.errBuf = StringIO()
self.outReceived = self.outBuf.write
self.errReceived = self.errBuf.write
@@ -589,3 +591,54 @@ def mailto_to_envelope(mailto_str):
from alot.db.envelope import Envelope
headers, body = parse_mailto(mailto_str)
return Envelope(bodytext=body, headers=headers)
+
+
+def RFC3156_canonicalize(text):
+ """
+ Canonicalizes plain text (MIME-encoded usually) according to RFC3156.
+
+ This function works as follows (in that order):
+
+ 1. Convert all line endings to \\\\r\\\\n (DOS line endings).
+ 2. Ensure the text ends with a newline (\\\\r\\\\n).
+ 3. Encode all occurences of "From " at the beginning of a line
+ to "From=20" in order to prevent other mail programs to replace
+ this with "> From" (to avoid MBox conflicts) and thus invalidate
+ the signature.
+
+ :param text: text to canonicalize (already encoded as quoted-printable)
+ :rtype: str
+ """
+ text = re.sub("\r?\n", "\r\n", text)
+ if not text.endswith("\r\n"):
+ text += "\r\n"
+ text = re.sub("^From ", "From=20", text, flags=re.MULTILINE)
+ return text
+
+
+def email_as_string(mail):
+ """
+ Converts the given message to a string, without mangling "From" lines
+ (like as_string() does).
+
+ :param mail: email to convert to string
+ :rtype: str
+ """
+ fp = StringIO()
+ g = Generator(fp, mangle_from_=False, maxheaderlen=78)
+ g.flatten(mail)
+ as_string = RFC3156_canonicalize(fp.getvalue())
+
+ if isinstance(mail, MIMEMultipart):
+ # Get the boundary for later
+ boundary = mail.get_boundary()
+
+ # Workaround for http://bugs.python.org/issue14983:
+ # Insert a newline before the outer mail boundary so that other mail
+ # clients can verify the signature when sending an email which contains
+ # attachments.
+ as_string = re.sub(r'--(\r\n)--' + boundary,
+ '--\g<1>\g<1>--' + boundary,
+ as_string, flags=re.MULTILINE)
+
+ return as_string