Mercurial > hg
annotate mercurial/mail.py @ 52148:1dbbb957bbe6 stable
run-tests: add a --hg-wheel options to test a pre-built wheel
This will be useful to test the wheel we intend to publish.
A future changeset will integrate this in the CI.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Sun, 27 Oct 2024 08:54:48 +0100 |
parents | f4733654f144 |
children |
rev | line source |
---|---|
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
1 # mail.py - mail sending bits for mercurial |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
2 # |
46819
d4ba4d51f85f
contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents:
46683
diff
changeset
|
3 # Copyright 2006 Olivia Mackall <olivia@selenic.com> |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
4 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
7948
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
7 |
51863
f4733654f144
typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents:
51290
diff
changeset
|
8 from __future__ import annotations |
25957
ae21d51bdc43
mail: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25842
diff
changeset
|
9 |
19790
53f16f4aff33
mail: correct import of email module
Augie Fackler <raf@durin42.com>
parents:
19050
diff
changeset
|
10 import email |
30089
040f23ed6963
mail: take --encoding and HGENCODING into account
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
30072
diff
changeset
|
11 import email.charset |
43156
0e6a7ce81dde
py3: use email.generator.BytesGenerator in patch.split()
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
43117
diff
changeset
|
12 import email.generator |
30072
87b8e40eb812
mail: handle renamed email.Header
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29285
diff
changeset
|
13 import email.header |
34310
2d0c306a88c2
mail: encode long unicode lines in emails properly (issue5687)
Igor Ippolitov <iippolitov@gmail.com>
parents:
33499
diff
changeset
|
14 import email.message |
38332
7b12a2d2eedc
py3: ditch email.parser.BytesParser which appears to be plain crap
Yuya Nishihara <yuya@tcha.org>
parents:
37469
diff
changeset
|
15 import email.parser |
7b12a2d2eedc
py3: ditch email.parser.BytesParser which appears to be plain crap
Yuya Nishihara <yuya@tcha.org>
parents:
37469
diff
changeset
|
16 import io |
25957
ae21d51bdc43
mail: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25842
diff
changeset
|
17 import os |
ae21d51bdc43
mail: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25842
diff
changeset
|
18 import smtplib |
ae21d51bdc43
mail: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25842
diff
changeset
|
19 import socket |
ae21d51bdc43
mail: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25842
diff
changeset
|
20 import time |
ae21d51bdc43
mail: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25842
diff
changeset
|
21 |
51285
9d3721552b6c
pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
22 from typing import ( |
9d3721552b6c
pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
23 Any, |
9d3721552b6c
pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
24 List, |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
25 Optional, |
51285
9d3721552b6c
pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
26 Tuple, |
9d3721552b6c
pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
27 Union, |
9d3721552b6c
pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
28 ) |
9d3721552b6c
pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
29 |
25957
ae21d51bdc43
mail: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25842
diff
changeset
|
30 from .i18n import _ |
43089
c59eb1560c44
py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43085
diff
changeset
|
31 from .pycompat import ( |
c59eb1560c44
py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43085
diff
changeset
|
32 open, |
c59eb1560c44
py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43085
diff
changeset
|
33 ) |
25957
ae21d51bdc43
mail: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25842
diff
changeset
|
34 from . import ( |
ae21d51bdc43
mail: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25842
diff
changeset
|
35 encoding, |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26098
diff
changeset
|
36 error, |
36047
1407c42b302c
py3: pass system string to email.message.Message.set_type()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35151
diff
changeset
|
37 pycompat, |
25957
ae21d51bdc43
mail: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25842
diff
changeset
|
38 sslutil, |
ae21d51bdc43
mail: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25842
diff
changeset
|
39 util, |
ae21d51bdc43
mail: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25842
diff
changeset
|
40 ) |
37084
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36120
diff
changeset
|
41 from .utils import ( |
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37084
diff
changeset
|
42 procutil, |
37084
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36120
diff
changeset
|
43 stringutil, |
46907
ffd3e823a7e5
urlutil: extract `url` related code from `util` into the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46819
diff
changeset
|
44 urlutil, |
37084
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36120
diff
changeset
|
45 ) |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
46 |
43625
8d9e2c2b6058
mail: add type hints for pytype
Denis Laxalde <denis@laxalde.org>
parents:
43624
diff
changeset
|
47 |
18885
cf1304fbc184
smtp: add the class to verify the certificate of the SMTP server for STARTTLS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17428
diff
changeset
|
48 class STARTTLS(smtplib.SMTP): |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
49 """Derived class to verify the peer certificate for STARTTLS. |
18885
cf1304fbc184
smtp: add the class to verify the certificate of the SMTP server for STARTTLS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17428
diff
changeset
|
50 |
cf1304fbc184
smtp: add the class to verify the certificate of the SMTP server for STARTTLS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17428
diff
changeset
|
51 This class allows to pass any keyword arguments to SSL socket creation. |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
52 """ |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
53 |
29251
31acc78c632a
mail: remove use of sslkwargs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29248
diff
changeset
|
54 def __init__(self, ui, host=None, **kwargs): |
18885
cf1304fbc184
smtp: add the class to verify the certificate of the SMTP server for STARTTLS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17428
diff
changeset
|
55 smtplib.SMTP.__init__(self, **kwargs) |
29248
e6de6ef3e426
sslutil: remove ui from sslkwargs (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29227
diff
changeset
|
56 self._ui = ui |
28935
a4c5c23de1d3
mail: retain hostname for sslutil.wrapsocket (issue5203)
timeless <timeless@mozdev.org>
parents:
28341
diff
changeset
|
57 self._host = host |
18885
cf1304fbc184
smtp: add the class to verify the certificate of the SMTP server for STARTTLS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17428
diff
changeset
|
58 |
50376
1c7453f2bb57
mail: add a missing argument to properly override starttls
Matt Harbison <matt_harbison@yahoo.com>
parents:
49051
diff
changeset
|
59 def starttls(self, keyfile=None, certfile=None, context=None): |
43169
3941e7063d03
py3: call SMTP.has_extn() with an str
Denis Laxalde <denis@laxalde.org>
parents:
43156
diff
changeset
|
60 if not self.has_extn("starttls"): |
50377
174290adfc4a
mail: unbyteify the SMTPException message
Matt Harbison <matt_harbison@yahoo.com>
parents:
50376
diff
changeset
|
61 msg = "STARTTLS extension not supported by server" |
18885
cf1304fbc184
smtp: add the class to verify the certificate of the SMTP server for STARTTLS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17428
diff
changeset
|
62 raise smtplib.SMTPException(msg) |
43170
a1801ee97840
py3: call SMTP.docmd() with an str
Denis Laxalde <denis@laxalde.org>
parents:
43169
diff
changeset
|
63 (resp, reply) = self.docmd("STARTTLS") |
18885
cf1304fbc184
smtp: add the class to verify the certificate of the SMTP server for STARTTLS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17428
diff
changeset
|
64 if resp == 220: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
65 self.sock = sslutil.wrapsocket( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
66 self.sock, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
67 keyfile, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
68 certfile, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
69 ui=self._ui, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
70 serverhostname=self._host, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
71 ) |
43171
54b06bec8914
py3: use socket.makefile() instead of dropped smtplib.SSLFakeFile
Denis Laxalde <denis@laxalde.org>
parents:
43170
diff
changeset
|
72 self.file = self.sock.makefile("rb") |
18885
cf1304fbc184
smtp: add the class to verify the certificate of the SMTP server for STARTTLS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17428
diff
changeset
|
73 self.helo_resp = None |
cf1304fbc184
smtp: add the class to verify the certificate of the SMTP server for STARTTLS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17428
diff
changeset
|
74 self.ehlo_resp = None |
cf1304fbc184
smtp: add the class to verify the certificate of the SMTP server for STARTTLS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17428
diff
changeset
|
75 self.esmtp_features = {} |
cf1304fbc184
smtp: add the class to verify the certificate of the SMTP server for STARTTLS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17428
diff
changeset
|
76 self.does_esmtp = 0 |
cf1304fbc184
smtp: add the class to verify the certificate of the SMTP server for STARTTLS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17428
diff
changeset
|
77 return (resp, reply) |
cf1304fbc184
smtp: add the class to verify the certificate of the SMTP server for STARTTLS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17428
diff
changeset
|
78 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
79 |
26673 | 80 class SMTPS(smtplib.SMTP): |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
81 """Derived class to verify the peer certificate for SMTPS. |
18886
14a60a0f7122
smtp: add the class to verify the certificate of the SMTP server for SMTPS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18885
diff
changeset
|
82 |
26673 | 83 This class allows to pass any keyword arguments to SSL socket creation. |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
84 """ |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
85 |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
86 def __init__(self, ui, keyfile=None, certfile=None, host=None, **kwargs): |
26673 | 87 self.keyfile = keyfile |
88 self.certfile = certfile | |
89 smtplib.SMTP.__init__(self, **kwargs) | |
28935
a4c5c23de1d3
mail: retain hostname for sslutil.wrapsocket (issue5203)
timeless <timeless@mozdev.org>
parents:
28341
diff
changeset
|
90 self._host = host |
26673 | 91 self.default_port = smtplib.SMTP_SSL_PORT |
29248
e6de6ef3e426
sslutil: remove ui from sslkwargs (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29227
diff
changeset
|
92 self._ui = ui |
26673 | 93 |
94 def _get_socket(self, host, port, timeout): | |
95 if self.debuglevel > 0: | |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
96 self._ui.debug(b'connect: %r\n' % ((host, port),)) |
26673 | 97 new_socket = socket.create_connection((host, port), timeout) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
98 new_socket = sslutil.wrapsocket( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
99 new_socket, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
100 self.keyfile, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
101 self.certfile, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
102 ui=self._ui, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
103 serverhostname=self._host, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
104 ) |
43506
9f70512ae2cf
cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents:
43498
diff
changeset
|
105 self.file = new_socket.makefile('rb') |
26673 | 106 return new_socket |
18886
14a60a0f7122
smtp: add the class to verify the certificate of the SMTP server for SMTPS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18885
diff
changeset
|
107 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
108 |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
109 def _pyhastls() -> bool: |
39025
569d662816de
mail: modernize check for Python-with-TLS
Augie Fackler <augie@google.com>
parents:
39024
diff
changeset
|
110 """Returns true iff Python has TLS support, false otherwise.""" |
569d662816de
mail: modernize check for Python-with-TLS
Augie Fackler <augie@google.com>
parents:
39024
diff
changeset
|
111 try: |
569d662816de
mail: modernize check for Python-with-TLS
Augie Fackler <augie@google.com>
parents:
39024
diff
changeset
|
112 import ssl |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
113 |
39025
569d662816de
mail: modernize check for Python-with-TLS
Augie Fackler <augie@google.com>
parents:
39024
diff
changeset
|
114 getattr(ssl, 'HAS_TLS', False) |
569d662816de
mail: modernize check for Python-with-TLS
Augie Fackler <augie@google.com>
parents:
39024
diff
changeset
|
115 return True |
569d662816de
mail: modernize check for Python-with-TLS
Augie Fackler <augie@google.com>
parents:
39024
diff
changeset
|
116 except ImportError: |
569d662816de
mail: modernize check for Python-with-TLS
Augie Fackler <augie@google.com>
parents:
39024
diff
changeset
|
117 return False |
569d662816de
mail: modernize check for Python-with-TLS
Augie Fackler <augie@google.com>
parents:
39024
diff
changeset
|
118 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
119 |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
120 def _smtp(ui): |
5973
ea77f6f77514
patchbomb: undo backout and fix bugs in the earlier patch
Matt Mackall <mpm@selenic.com>
parents:
5947
diff
changeset
|
121 '''build an smtp connection and return a function to send mail''' |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
122 local_hostname = ui.config(b'smtp', b'local_hostname') |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
123 tls = ui.config(b'smtp', b'tls') |
13201
f05250572467
smtp: fix for server doesn't support starttls extension
Zhigang Wang <zhigang.x.wang@oracle.com>
parents:
12091
diff
changeset
|
124 # backward compatible: when tls = true, we use starttls. |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
125 starttls = tls == b'starttls' or stringutil.parsebool(tls) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
126 smtps = tls == b'smtps' |
39025
569d662816de
mail: modernize check for Python-with-TLS
Augie Fackler <augie@google.com>
parents:
39024
diff
changeset
|
127 if (starttls or smtps) and not _pyhastls(): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
128 raise error.Abort(_(b"can't use TLS: Python SSL support not installed")) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
129 mailhost = ui.config(b'smtp', b'host') |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
130 if not mailhost: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
131 raise error.Abort(_(b'smtp.host not configured - cannot send mail')) |
18888
19d489404d79
smtp: verify the certificate of the SMTP server for STARTTLS/SMTPS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18886
diff
changeset
|
132 if smtps: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
133 ui.note(_(b'(using smtps)\n')) |
29251
31acc78c632a
mail: remove use of sslkwargs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29248
diff
changeset
|
134 s = SMTPS(ui, local_hostname=local_hostname, host=mailhost) |
18888
19d489404d79
smtp: verify the certificate of the SMTP server for STARTTLS/SMTPS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18886
diff
changeset
|
135 elif starttls: |
29251
31acc78c632a
mail: remove use of sslkwargs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29248
diff
changeset
|
136 s = STARTTLS(ui, local_hostname=local_hostname, host=mailhost) |
18888
19d489404d79
smtp: verify the certificate of the SMTP server for STARTTLS/SMTPS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18886
diff
changeset
|
137 else: |
19d489404d79
smtp: verify the certificate of the SMTP server for STARTTLS/SMTPS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18886
diff
changeset
|
138 s = smtplib.SMTP(local_hostname=local_hostname) |
19050
601c1e226889
smtp: use 465 as default port for SMTPS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18916
diff
changeset
|
139 if smtps: |
601c1e226889
smtp: use 465 as default port for SMTPS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18916
diff
changeset
|
140 defaultport = 465 |
601c1e226889
smtp: use 465 as default port for SMTPS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18916
diff
changeset
|
141 else: |
601c1e226889
smtp: use 465 as default port for SMTPS
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
18916
diff
changeset
|
142 defaultport = 25 |
46907
ffd3e823a7e5
urlutil: extract `url` related code from `util` into the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46819
diff
changeset
|
143 mailport = urlutil.getport(ui.config(b'smtp', b'port', defaultport)) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
144 ui.note(_(b'sending mail: smtp host %s, port %d\n') % (mailhost, mailport)) |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
145 s.connect(host=mailhost, port=mailport) |
13201
f05250572467
smtp: fix for server doesn't support starttls extension
Zhigang Wang <zhigang.x.wang@oracle.com>
parents:
12091
diff
changeset
|
146 if starttls: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
147 ui.note(_(b'(using starttls)\n')) |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
148 s.ehlo() |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
149 s.starttls() |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
150 s.ehlo() |
29285
63a3749147af
mail: unsupport smtp.verifycert (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29251
diff
changeset
|
151 if starttls or smtps: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
152 ui.note(_(b'(verifying remote certificate)\n')) |
29285
63a3749147af
mail: unsupport smtp.verifycert (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29251
diff
changeset
|
153 sslutil.validatesocket(s.sock) |
46991
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
154 |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
155 try: |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
156 _smtp_login(ui, s, mailhost, mailport) |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
157 except smtplib.SMTPException as inst: |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
158 raise error.Abort(stringutil.forcebytestr(inst)) |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
159 |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
160 def send(sender, recipients, msg): |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
161 try: |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
162 return s.sendmail(sender, recipients, msg) |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
163 except smtplib.SMTPRecipientsRefused as inst: |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
164 recipients = [r[1] for r in inst.recipients.values()] |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
165 raise error.Abort(b'\n' + b'\n'.join(recipients)) |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
166 except smtplib.SMTPException as inst: |
46992
5fa019ceb499
mail: force SMTPException to bytes before wrapping in error.Abort
Matt Harbison <matt_harbison@yahoo.com>
parents:
46991
diff
changeset
|
167 raise error.Abort(stringutil.forcebytestr(inst)) |
46991
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
168 |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
169 return send |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
170 |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
171 |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
172 def _smtp_login(ui, smtp, mailhost, mailport): |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
173 """A hook for the keyring extension to perform the actual SMTP login. |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
174 |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
175 An already connected SMTP object of the proper type is provided, based on |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
176 the current configuration. The host and port to which the connection was |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
177 established are provided for accessibility, since the SMTP object doesn't |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
178 provide an accessor. ``smtplib.SMTPException`` is raised on error. |
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
179 """ |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
180 username = ui.config(b'smtp', b'username') |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
181 password = ui.config(b'smtp', b'password') |
43172
9145abd8b96d
py3: decode username and password before SMTP login
Denis Laxalde <denis@laxalde.org>
parents:
43171
diff
changeset
|
182 if username: |
9145abd8b96d
py3: decode username and password before SMTP login
Denis Laxalde <denis@laxalde.org>
parents:
43171
diff
changeset
|
183 if password: |
9145abd8b96d
py3: decode username and password before SMTP login
Denis Laxalde <denis@laxalde.org>
parents:
43171
diff
changeset
|
184 password = encoding.strfromlocal(password) |
9145abd8b96d
py3: decode username and password before SMTP login
Denis Laxalde <denis@laxalde.org>
parents:
43171
diff
changeset
|
185 else: |
9145abd8b96d
py3: decode username and password before SMTP login
Denis Laxalde <denis@laxalde.org>
parents:
43171
diff
changeset
|
186 password = ui.getpass() |
45929
87e7dd8e7734
ui: ensure `getpass()` returns bytes
Matt Harbison <matt_harbison@yahoo.com>
parents:
43825
diff
changeset
|
187 if password is not None: |
87e7dd8e7734
ui: ensure `getpass()` returns bytes
Matt Harbison <matt_harbison@yahoo.com>
parents:
43825
diff
changeset
|
188 password = encoding.strfromlocal(password) |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
189 if username and password: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
190 ui.note(_(b'(authenticating to mail server as %s)\n') % username) |
43172
9145abd8b96d
py3: decode username and password before SMTP login
Denis Laxalde <denis@laxalde.org>
parents:
43171
diff
changeset
|
191 username = encoding.strfromlocal(username) |
46991
83c0d144ef8d
mail: split out the SMTP login to allow the keyring extension to wrap it
Matt Harbison <matt_harbison@yahoo.com>
parents:
46982
diff
changeset
|
192 smtp.login(username, password) |
5947
528c986f0162
Backed out changeset dc6ed2736c81
Bryan O'Sullivan <bos@serpentine.com>
parents:
5866
diff
changeset
|
193 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
194 |
5973
ea77f6f77514
patchbomb: undo backout and fix bugs in the earlier patch
Matt Mackall <mpm@selenic.com>
parents:
5947
diff
changeset
|
195 def _sendmail(ui, sender, recipients, msg): |
ea77f6f77514
patchbomb: undo backout and fix bugs in the earlier patch
Matt Mackall <mpm@selenic.com>
parents:
5947
diff
changeset
|
196 '''send mail using sendmail.''' |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
197 program = ui.config(b'email', b'method') |
43096
813aa8cc55d4
patchbomb: use procutil.shellquote() instead of shlex to escape email address
Yuya Nishihara <yuya@tcha.org>
parents:
43089
diff
changeset
|
198 |
813aa8cc55d4
patchbomb: use procutil.shellquote() instead of shlex to escape email address
Yuya Nishihara <yuya@tcha.org>
parents:
43089
diff
changeset
|
199 def stremail(x): |
813aa8cc55d4
patchbomb: use procutil.shellquote() instead of shlex to escape email address
Yuya Nishihara <yuya@tcha.org>
parents:
43089
diff
changeset
|
200 return procutil.shellquote(stringutil.email(encoding.strtolocal(x))) |
813aa8cc55d4
patchbomb: use procutil.shellquote() instead of shlex to escape email address
Yuya Nishihara <yuya@tcha.org>
parents:
43089
diff
changeset
|
201 |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
202 cmdline = b'%s -f %s %s' % ( |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
203 program, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
204 stremail(sender), |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
205 b' '.join(map(stremail, recipients)), |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
206 ) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
207 ui.note(_(b'sending mail: %s\n') % cmdline) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
208 fp = procutil.popen(cmdline, b'wb') |
37458
00e4bd97b095
procutil: always popen() in binary mode
Yuya Nishihara <yuya@tcha.org>
parents:
37120
diff
changeset
|
209 fp.write(util.tonativeeol(msg)) |
5973
ea77f6f77514
patchbomb: undo backout and fix bugs in the earlier patch
Matt Mackall <mpm@selenic.com>
parents:
5947
diff
changeset
|
210 ret = fp.close() |
ea77f6f77514
patchbomb: undo backout and fix bugs in the earlier patch
Matt Mackall <mpm@selenic.com>
parents:
5947
diff
changeset
|
211 if ret: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
212 raise error.Abort( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
213 b'%s %s' |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
214 % ( |
43825
8f26dd09aa78
mail: use procutil.shellsplit instead of bytes.split to parse command
Julien Cristau <jcristau@debian.org>
parents:
43773
diff
changeset
|
215 os.path.basename(procutil.shellsplit(program)[0]), |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
216 procutil.explainexit(ret), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
217 ) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
218 ) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
219 |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
220 |
15560
cc58c228503e
mail: mbox handling as a part of mail handling, refactored from patchbomb
Mads Kiilerich <mads@kiilerich.com>
parents:
14965
diff
changeset
|
221 def _mbox(mbox, sender, recipients, msg): |
cc58c228503e
mail: mbox handling as a part of mail handling, refactored from patchbomb
Mads Kiilerich <mads@kiilerich.com>
parents:
14965
diff
changeset
|
222 '''write mails to mbox''' |
46997
106402245301
mail: add a TODO about proper mbox locking
Matt Harbison <matt_harbison@yahoo.com>
parents:
46992
diff
changeset
|
223 # TODO: use python mbox library for proper locking |
46982
d467bae86b2d
mail: use a context manager when writing to mbox
Matt Harbison <matt_harbison@yahoo.com>
parents:
46907
diff
changeset
|
224 with open(mbox, b'ab+') as fp: |
d467bae86b2d
mail: use a context manager when writing to mbox
Matt Harbison <matt_harbison@yahoo.com>
parents:
46907
diff
changeset
|
225 # Should be time.asctime(), but Windows prints 2-characters day |
d467bae86b2d
mail: use a context manager when writing to mbox
Matt Harbison <matt_harbison@yahoo.com>
parents:
46907
diff
changeset
|
226 # of month instead of one. Make them print the same thing. |
d467bae86b2d
mail: use a context manager when writing to mbox
Matt Harbison <matt_harbison@yahoo.com>
parents:
46907
diff
changeset
|
227 date = time.strftime('%a %b %d %H:%M:%S %Y', time.localtime()) |
d467bae86b2d
mail: use a context manager when writing to mbox
Matt Harbison <matt_harbison@yahoo.com>
parents:
46907
diff
changeset
|
228 fp.write( |
d467bae86b2d
mail: use a context manager when writing to mbox
Matt Harbison <matt_harbison@yahoo.com>
parents:
46907
diff
changeset
|
229 b'From %s %s\n' |
d467bae86b2d
mail: use a context manager when writing to mbox
Matt Harbison <matt_harbison@yahoo.com>
parents:
46907
diff
changeset
|
230 % (encoding.strtolocal(sender), encoding.strtolocal(date)) |
d467bae86b2d
mail: use a context manager when writing to mbox
Matt Harbison <matt_harbison@yahoo.com>
parents:
46907
diff
changeset
|
231 ) |
d467bae86b2d
mail: use a context manager when writing to mbox
Matt Harbison <matt_harbison@yahoo.com>
parents:
46907
diff
changeset
|
232 fp.write(msg) |
d467bae86b2d
mail: use a context manager when writing to mbox
Matt Harbison <matt_harbison@yahoo.com>
parents:
46907
diff
changeset
|
233 fp.write(b'\n\n') |
15560
cc58c228503e
mail: mbox handling as a part of mail handling, refactored from patchbomb
Mads Kiilerich <mads@kiilerich.com>
parents:
14965
diff
changeset
|
234 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
235 |
15560
cc58c228503e
mail: mbox handling as a part of mail handling, refactored from patchbomb
Mads Kiilerich <mads@kiilerich.com>
parents:
14965
diff
changeset
|
236 def connect(ui, mbox=None): |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
237 """make a mail connection. return a function to send mail. |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
238 call as sendmail(sender, list-of-recipients, msg).""" |
15560
cc58c228503e
mail: mbox handling as a part of mail handling, refactored from patchbomb
Mads Kiilerich <mads@kiilerich.com>
parents:
14965
diff
changeset
|
239 if mbox: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
240 open(mbox, b'wb').close() |
15560
cc58c228503e
mail: mbox handling as a part of mail handling, refactored from patchbomb
Mads Kiilerich <mads@kiilerich.com>
parents:
14965
diff
changeset
|
241 return lambda s, r, m: _mbox(mbox, s, r, m) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
242 if ui.config(b'email', b'method') == b'smtp': |
5947
528c986f0162
Backed out changeset dc6ed2736c81
Bryan O'Sullivan <bos@serpentine.com>
parents:
5866
diff
changeset
|
243 return _smtp(ui) |
5973
ea77f6f77514
patchbomb: undo backout and fix bugs in the earlier patch
Matt Mackall <mpm@selenic.com>
parents:
5947
diff
changeset
|
244 return lambda s, r, m: _sendmail(ui, s, r, m) |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
245 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
246 |
15561
ca572e94d8e7
notify: add option for writing to mbox
Mads Kiilerich <mads@kiilerich.com>
parents:
15560
diff
changeset
|
247 def sendmail(ui, sender, recipients, msg, mbox=None): |
ca572e94d8e7
notify: add option for writing to mbox
Mads Kiilerich <mads@kiilerich.com>
parents:
15560
diff
changeset
|
248 send = connect(ui, mbox=mbox) |
5973
ea77f6f77514
patchbomb: undo backout and fix bugs in the earlier patch
Matt Mackall <mpm@selenic.com>
parents:
5947
diff
changeset
|
249 return send(sender, recipients, msg) |
4489
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
250 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
251 |
4489
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
252 def validateconfig(ui): |
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
253 '''determine if we have enough config data to try sending email.''' |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
254 method = ui.config(b'email', b'method') |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
255 if method == b'smtp': |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
256 if not ui.config(b'smtp', b'host'): |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
257 raise error.Abort( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
258 _( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
259 b'smtp specified as email transport, ' |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
260 b'but no smtp host configured' |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
261 ) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
262 ) |
4489
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
263 else: |
49051
1d6c6ad645e1
mail: don't complain about a multi-word email.method
Julien Cristau <jcristau@debian.org>
parents:
48883
diff
changeset
|
264 command = procutil.shellsplit(method) |
1d6c6ad645e1
mail: don't complain about a multi-word email.method
Julien Cristau <jcristau@debian.org>
parents:
48883
diff
changeset
|
265 command = command[0] if command else b'' |
1d6c6ad645e1
mail: don't complain about a multi-word email.method
Julien Cristau <jcristau@debian.org>
parents:
48883
diff
changeset
|
266 if not (command and procutil.findexe(command)): |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
267 raise error.Abort( |
49051
1d6c6ad645e1
mail: don't complain about a multi-word email.method
Julien Cristau <jcristau@debian.org>
parents:
48883
diff
changeset
|
268 _(b'%r specified as email transport, but not in PATH') % command |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
269 ) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
270 |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
271 |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
272 def codec2iana(cs: str) -> str: |
47062
f38bf44e077f
black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents:
46997
diff
changeset
|
273 ''' ''' |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
274 cs = email.charset.Charset(cs).input_charset.lower() |
30089
040f23ed6963
mail: take --encoding and HGENCODING into account
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
30072
diff
changeset
|
275 |
040f23ed6963
mail: take --encoding and HGENCODING into account
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
30072
diff
changeset
|
276 # "latin1" normalizes to "iso8859-1", standard calls for "iso-8859-1" |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
277 if cs.startswith("iso") and not cs.startswith("iso-"): |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
278 return "iso-" + cs[3:] |
30089
040f23ed6963
mail: take --encoding and HGENCODING into account
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
30072
diff
changeset
|
279 return cs |
040f23ed6963
mail: take --encoding and HGENCODING into account
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
30072
diff
changeset
|
280 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
281 |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
282 def mimetextpatch( |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
283 s: bytes, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
284 subtype: str = 'plain', |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
285 display: bool = False, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
286 ) -> email.message.Message: |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
287 """Return MIME message suitable for a patch. |
30089
040f23ed6963
mail: take --encoding and HGENCODING into account
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
30072
diff
changeset
|
288 Charset will be detected by first trying to decode as us-ascii, then utf-8, |
040f23ed6963
mail: take --encoding and HGENCODING into account
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
30072
diff
changeset
|
289 and finally the global encodings. If all those fail, fall back to |
040f23ed6963
mail: take --encoding and HGENCODING into account
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
30072
diff
changeset
|
290 ISO-8859-1, an encoding with that allows all byte sequences. |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
291 Transfer encodings will be used if necessary.""" |
8332
3e544c074459
patchbomb: quoted-printable encode overly long lines
Rocco Rutte <pdmef@gmx.net>
parents:
8312
diff
changeset
|
292 |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
293 cs = [ |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
294 'us-ascii', |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
295 'utf-8', |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
296 pycompat.sysstr(encoding.encoding), |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
297 pycompat.sysstr(encoding.fallbackencoding), |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
298 ] |
30089
040f23ed6963
mail: take --encoding and HGENCODING into account
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
30072
diff
changeset
|
299 if display: |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
300 cs = ['us-ascii'] |
30089
040f23ed6963
mail: take --encoding and HGENCODING into account
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
30072
diff
changeset
|
301 for charset in cs: |
8332
3e544c074459
patchbomb: quoted-printable encode overly long lines
Rocco Rutte <pdmef@gmx.net>
parents:
8312
diff
changeset
|
302 try: |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
303 s.decode(charset) |
30089
040f23ed6963
mail: take --encoding and HGENCODING into account
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
30072
diff
changeset
|
304 return mimetextqp(s, subtype, codec2iana(charset)) |
8332
3e544c074459
patchbomb: quoted-printable encode overly long lines
Rocco Rutte <pdmef@gmx.net>
parents:
8312
diff
changeset
|
305 except UnicodeDecodeError: |
30089
040f23ed6963
mail: take --encoding and HGENCODING into account
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
30072
diff
changeset
|
306 pass |
8332
3e544c074459
patchbomb: quoted-printable encode overly long lines
Rocco Rutte <pdmef@gmx.net>
parents:
8312
diff
changeset
|
307 |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
308 return mimetextqp(s, subtype, "iso-8859-1") |
15562
a82b6038ff08
mail: use quoted-printable for mime encoding to avoid too long lines (issue3075)
Mads Kiilerich <mads@kiilerich.com>
parents:
15561
diff
changeset
|
309 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
310 |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
311 def mimetextqp( |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
312 body: bytes, subtype: str, charset: str |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
313 ) -> email.message.Message: |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
314 """Return MIME message. |
17424
e7cfe3587ea4
fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents:
15562
diff
changeset
|
315 Quoted-printable transfer encoding will be used if necessary. |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
316 """ |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
317 cs = email.charset.Charset(charset) |
34310
2d0c306a88c2
mail: encode long unicode lines in emails properly (issue5687)
Igor Ippolitov <iippolitov@gmail.com>
parents:
33499
diff
changeset
|
318 msg = email.message.Message() |
43627
af3e341dbf03
mail: use a native string for "subtype" value
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
43626
diff
changeset
|
319 msg.set_type('text/' + subtype) |
34310
2d0c306a88c2
mail: encode long unicode lines in emails properly (issue5687)
Igor Ippolitov <iippolitov@gmail.com>
parents:
33499
diff
changeset
|
320 |
15562
a82b6038ff08
mail: use quoted-printable for mime encoding to avoid too long lines (issue3075)
Mads Kiilerich <mads@kiilerich.com>
parents:
15561
diff
changeset
|
321 for line in body.splitlines(): |
a82b6038ff08
mail: use quoted-printable for mime encoding to avoid too long lines (issue3075)
Mads Kiilerich <mads@kiilerich.com>
parents:
15561
diff
changeset
|
322 if len(line) > 950: |
34310
2d0c306a88c2
mail: encode long unicode lines in emails properly (issue5687)
Igor Ippolitov <iippolitov@gmail.com>
parents:
33499
diff
changeset
|
323 cs.body_encoding = email.charset.QP |
15562
a82b6038ff08
mail: use quoted-printable for mime encoding to avoid too long lines (issue3075)
Mads Kiilerich <mads@kiilerich.com>
parents:
15561
diff
changeset
|
324 break |
a82b6038ff08
mail: use quoted-printable for mime encoding to avoid too long lines (issue3075)
Mads Kiilerich <mads@kiilerich.com>
parents:
15561
diff
changeset
|
325 |
41405
9b3be572ff0c
mail: document behavior of Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39108
diff
changeset
|
326 # On Python 2, this simply assigns a value. Python 3 inspects |
9b3be572ff0c
mail: document behavior of Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39108
diff
changeset
|
327 # body and does different things depending on whether it has |
9b3be572ff0c
mail: document behavior of Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39108
diff
changeset
|
328 # encode() or decode() attributes. We can get the old behavior |
9b3be572ff0c
mail: document behavior of Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39108
diff
changeset
|
329 # if we pass a str and charset is None and we call set_charset(). |
9b3be572ff0c
mail: document behavior of Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39108
diff
changeset
|
330 # But we may get into trouble later due to Python attempting to |
9b3be572ff0c
mail: document behavior of Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39108
diff
changeset
|
331 # encode/decode using the registered charset (or attempting to |
9b3be572ff0c
mail: document behavior of Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39108
diff
changeset
|
332 # use ascii in the absence of a charset). |
34310
2d0c306a88c2
mail: encode long unicode lines in emails properly (issue5687)
Igor Ippolitov <iippolitov@gmail.com>
parents:
33499
diff
changeset
|
333 msg.set_payload(body, cs) |
2d0c306a88c2
mail: encode long unicode lines in emails properly (issue5687)
Igor Ippolitov <iippolitov@gmail.com>
parents:
33499
diff
changeset
|
334 |
8332
3e544c074459
patchbomb: quoted-printable encode overly long lines
Rocco Rutte <pdmef@gmx.net>
parents:
8312
diff
changeset
|
335 return msg |
7191
d14212218582
mail: mime-encode patches that are utf-8
Christian Ebert <blacktrash@gmx.net>
parents:
7114
diff
changeset
|
336 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
337 |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
338 def _charsets(ui: Any) -> List[str]: |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
339 '''Obtains charsets to send mail parts not containing patches.''' |
43625
8d9e2c2b6058
mail: add type hints for pytype
Denis Laxalde <denis@laxalde.org>
parents:
43624
diff
changeset
|
340 charsets = [ |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
341 pycompat.sysstr(cs.lower()) |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
342 for cs in ui.configlist(b'email', b'charsets') |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
343 ] |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
344 fallbacks = [ |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
345 pycompat.sysstr(encoding.fallbackencoding.lower()), |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
346 pycompat.sysstr(encoding.encoding.lower()), |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
347 'utf-8', |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
348 ] |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
349 for cs in fallbacks: # find unique charsets while keeping order |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
350 if cs not in charsets: |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
351 charsets.append(cs) |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
352 return [cs for cs in charsets if not cs.endswith('ascii')] |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
353 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
354 |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
355 def _encode(ui: Any, s: bytes, charsets: List[str]) -> Tuple[bytes, str]: |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
356 """Returns (converted) string, charset tuple. |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
357 Finds out best charset by cycling through sendcharsets in descending |
7948
de377b1a9a84
move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents:
7195
diff
changeset
|
358 order. Tries both encoding and fallbackencoding for input. Only as |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
359 last resort send as is in fake ascii. |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
360 Caveat: Do not use for mail parts containing patches!""" |
39023
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
361 sendcharsets = charsets or _charsets(ui) |
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
362 if not isinstance(s, bytes): |
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
363 # We have unicode data, which we need to try and encode to |
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
364 # some reasonable-ish encoding. Try the encodings the user |
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
365 # wants, and fall back to garbage-in-ascii. |
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
366 for ocs in sendcharsets: |
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
367 try: |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
368 return s.encode(ocs), ocs |
39023
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
369 except UnicodeEncodeError: |
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
370 pass |
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
371 except LookupError: |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
372 ui.warn( |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
373 _(b'ignoring invalid sendcharset: %s\n') |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
374 % pycompat.sysbytes(ocs) |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
375 ) |
39023
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
376 else: |
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
377 # Everything failed, ascii-armor what we've got and send it. |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
378 return s.encode('ascii', 'backslashreplace'), 'us-ascii' |
39023
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
379 # We have a bytes of unknown encoding. We'll try and guess a valid |
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
380 # encoding, falling back to pretending we had ascii even though we |
858fe9625dab
mail: fix _encode to be more correct on Python 3
Augie Fackler <augie@google.com>
parents:
38332
diff
changeset
|
381 # know that's wrong. |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
382 try: |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
383 s.decode('ascii') |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
384 except UnicodeDecodeError: |
7948
de377b1a9a84
move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents:
7195
diff
changeset
|
385 for ics in (encoding.encoding, encoding.fallbackencoding): |
43330
910827a2cb20
py3: decode encoding literal before passing to .decode()
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
43326
diff
changeset
|
386 ics = pycompat.sysstr(ics) |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
387 try: |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
388 u = s.decode(ics) |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
389 except UnicodeDecodeError: |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
390 continue |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
391 for ocs in sendcharsets: |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
392 try: |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
393 return u.encode(ocs), ocs |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
394 except UnicodeEncodeError: |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
395 pass |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
396 except LookupError: |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
397 ui.warn( |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
398 _(b'ignoring invalid sendcharset: %s\n') |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
399 % pycompat.sysbytes(ocs) |
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
400 ) |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
401 # if ascii, or all conversion attempts fail, send (broken) ascii |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
402 return s, 'us-ascii' |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
403 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
404 |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
405 def headencode( |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
406 ui: Any, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
407 s: Union[bytes, str], |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
408 charsets: Optional[List[str]] = None, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
409 display: bool = False, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
410 ) -> str: |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
411 '''Returns RFC-2047 compliant header from given string.''' |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
412 if not display: |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
413 # split into words? |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
414 s, cs = _encode(ui, s, charsets) |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
415 return email.header.Header(s, cs).encode() |
43575
67b4439c09b2
mail: let headencode() return a native string
Denis Laxalde <denis@laxalde.org>
parents:
43506
diff
changeset
|
416 return encoding.strfromlocal(s) |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
417 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
418 |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
419 def _addressencode( |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
420 ui: Any, name: str, addr: str, charsets: Optional[List[str]] = None |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
421 ) -> str: |
43628
ddb5d097d561
mail: move strtolocal call in _addressencode()
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
43627
diff
changeset
|
422 addr = encoding.strtolocal(addr) |
43575
67b4439c09b2
mail: let headencode() return a native string
Denis Laxalde <denis@laxalde.org>
parents:
43506
diff
changeset
|
423 name = headencode(ui, name, charsets) |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
424 try: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
425 acc, dom = addr.split(b'@') |
39107
c2327bb3505d
mail: call s.decode('ascii') explicitly to see if s is an ascii bytes
Yuya Nishihara <yuya@tcha.org>
parents:
39106
diff
changeset
|
426 acc.decode('ascii') |
39108
d2d89d31cbb5
mail: convert encoding.encoding to sysstr
Yuya Nishihara <yuya@tcha.org>
parents:
39107
diff
changeset
|
427 dom = dom.decode(pycompat.sysstr(encoding.encoding)).encode('idna') |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
428 addr = b'%s@%s' % (acc, dom) |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
429 except UnicodeDecodeError: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
430 raise error.Abort(_(b'invalid email address: %s') % addr) |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
431 except ValueError: |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
432 try: |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
433 # too strict? |
39107
c2327bb3505d
mail: call s.decode('ascii') explicitly to see if s is an ascii bytes
Yuya Nishihara <yuya@tcha.org>
parents:
39106
diff
changeset
|
434 addr.decode('ascii') |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
435 except UnicodeDecodeError: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
436 raise error.Abort(_(b'invalid local address: %s') % addr) |
43576
14b96072797d
mail: let addressencode() / addrlistencode() return native strings
Denis Laxalde <denis@laxalde.org>
parents:
43575
diff
changeset
|
437 return email.utils.formataddr((name, encoding.strfromlocal(addr))) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
438 |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
439 |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
440 def addressencode( |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
441 ui: Any, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
442 address: bytes, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
443 charsets: Optional[List[str]] = None, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
444 display: bool = False, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
445 ) -> str: |
9948
e5b44a7986d0
mail: add parseaddrlist() function for parsing many addresses at once
Marti Raudsepp <marti@juffo.org>
parents:
9715
diff
changeset
|
446 '''Turns address into RFC-2047 compliant header.''' |
e5b44a7986d0
mail: add parseaddrlist() function for parsing many addresses at once
Marti Raudsepp <marti@juffo.org>
parents:
9715
diff
changeset
|
447 if display or not address: |
43576
14b96072797d
mail: let addressencode() / addrlistencode() return native strings
Denis Laxalde <denis@laxalde.org>
parents:
43575
diff
changeset
|
448 return encoding.strfromlocal(address or b'') |
39024
eabdf3c25b8b
mail: cope with Py3 unicode antics on email addresses
Augie Fackler <augie@google.com>
parents:
39023
diff
changeset
|
449 name, addr = email.utils.parseaddr(encoding.strfromlocal(address)) |
43628
ddb5d097d561
mail: move strtolocal call in _addressencode()
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
43627
diff
changeset
|
450 return _addressencode(ui, name, addr, charsets) |
9948
e5b44a7986d0
mail: add parseaddrlist() function for parsing many addresses at once
Marti Raudsepp <marti@juffo.org>
parents:
9715
diff
changeset
|
451 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
452 |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
453 def addrlistencode( |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
454 ui: Any, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
455 addrs: List[bytes], |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
456 charsets: Optional[List[str]] = None, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
457 display: bool = False, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
458 ) -> List[str]: |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
459 """Turns a list of addresses into a list of RFC-2047 compliant headers. |
9948
e5b44a7986d0
mail: add parseaddrlist() function for parsing many addresses at once
Marti Raudsepp <marti@juffo.org>
parents:
9715
diff
changeset
|
460 A single element of input list may contain multiple addresses, but output |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
461 always has one address per item""" |
43577
599e25add437
mail: convert addr to str early in addrlistencode()
Denis Laxalde <denis@laxalde.org>
parents:
43576
diff
changeset
|
462 straddrs = [] |
39024
eabdf3c25b8b
mail: cope with Py3 unicode antics on email addresses
Augie Fackler <augie@google.com>
parents:
39023
diff
changeset
|
463 for a in addrs: |
43506
9f70512ae2cf
cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents:
43498
diff
changeset
|
464 assert isinstance(a, bytes), '%r unexpectedly not a bytestr' % a |
43577
599e25add437
mail: convert addr to str early in addrlistencode()
Denis Laxalde <denis@laxalde.org>
parents:
43576
diff
changeset
|
465 straddrs.append(encoding.strfromlocal(a)) |
9948
e5b44a7986d0
mail: add parseaddrlist() function for parsing many addresses at once
Marti Raudsepp <marti@juffo.org>
parents:
9715
diff
changeset
|
466 if display: |
43577
599e25add437
mail: convert addr to str early in addrlistencode()
Denis Laxalde <denis@laxalde.org>
parents:
43576
diff
changeset
|
467 return [a.strip() for a in straddrs if a.strip()] |
9948
e5b44a7986d0
mail: add parseaddrlist() function for parsing many addresses at once
Marti Raudsepp <marti@juffo.org>
parents:
9715
diff
changeset
|
468 |
e5b44a7986d0
mail: add parseaddrlist() function for parsing many addresses at once
Marti Raudsepp <marti@juffo.org>
parents:
9715
diff
changeset
|
469 result = [] |
43577
599e25add437
mail: convert addr to str early in addrlistencode()
Denis Laxalde <denis@laxalde.org>
parents:
43576
diff
changeset
|
470 for name, addr in email.utils.getaddresses(straddrs): |
9948
e5b44a7986d0
mail: add parseaddrlist() function for parsing many addresses at once
Marti Raudsepp <marti@juffo.org>
parents:
9715
diff
changeset
|
471 if name or addr: |
43628
ddb5d097d561
mail: move strtolocal call in _addressencode()
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
43627
diff
changeset
|
472 r = _addressencode(ui, name, addr, charsets) |
39106
ebf54a34b7b7
mail: pass in addr to _addressencode() in bytes
Yuya Nishihara <yuya@tcha.org>
parents:
39105
diff
changeset
|
473 result.append(r) |
39105
f68ad9b4a43b
mail: remove redundant bytesurl() from addrlistencode()
Yuya Nishihara <yuya@tcha.org>
parents:
39039
diff
changeset
|
474 return result |
9948
e5b44a7986d0
mail: add parseaddrlist() function for parsing many addresses at once
Marti Raudsepp <marti@juffo.org>
parents:
9715
diff
changeset
|
475 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
476 |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
477 def mimeencode( |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
478 ui: Any, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
479 s: bytes, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
480 charsets: Optional[List[str]] = None, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
481 display: bool = False, |
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
482 ) -> email.message.Message: |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
483 """creates mime text object, encodes it if needed, and sets |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45929
diff
changeset
|
484 charset and transfer-encoding accordingly.""" |
43626
bdb0ddab7bb3
mail: let all charset values be native strings
Denis Laxalde <denis@laxalde.org>
parents:
43625
diff
changeset
|
485 cs = 'us-ascii' |
7114
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
486 if not display: |
30e49d54c537
mail: add methods to handle non-ascii chars
Christian Ebert <blacktrash@gmx.net>
parents:
6548
diff
changeset
|
487 s, cs = _encode(ui, s, charsets) |
43627
af3e341dbf03
mail: use a native string for "subtype" value
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
43626
diff
changeset
|
488 return mimetextqp(s, 'plain', cs) |
28341
8286f551b7ee
patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents:
27619
diff
changeset
|
489 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
490 |
48883
f0c445a8e324
mail: delete conditional code for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
491 Generator = email.generator.BytesGenerator |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
492 |
43353
fdc3af52305b
mail: black wants to add this blank line
Augie Fackler <augie@google.com>
parents:
43330
diff
changeset
|
493 |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
494 def parse(fp: Any) -> email.message.Message: |
48883
f0c445a8e324
mail: delete conditional code for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
495 ep = email.parser.Parser() |
f0c445a8e324
mail: delete conditional code for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
496 # disable the "universal newlines" mode, which isn't binary safe. |
f0c445a8e324
mail: delete conditional code for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
497 # I have no idea if ascii/surrogateescape is correct, but that's |
f0c445a8e324
mail: delete conditional code for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
498 # what the standard Python email parser does. |
f0c445a8e324
mail: delete conditional code for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
499 fp = io.TextIOWrapper( |
f0c445a8e324
mail: delete conditional code for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
500 fp, encoding='ascii', errors='surrogateescape', newline=chr(10) |
f0c445a8e324
mail: delete conditional code for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
501 ) |
f0c445a8e324
mail: delete conditional code for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
502 try: |
f0c445a8e324
mail: delete conditional code for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
503 return ep.parse(fp) |
f0c445a8e324
mail: delete conditional code for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
504 finally: |
f0c445a8e324
mail: delete conditional code for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
505 fp.detach() |
43156
0e6a7ce81dde
py3: use email.generator.BytesGenerator in patch.split()
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
43117
diff
changeset
|
506 |
38332
7b12a2d2eedc
py3: ditch email.parser.BytesParser which appears to be plain crap
Yuya Nishihara <yuya@tcha.org>
parents:
37469
diff
changeset
|
507 |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
508 def parsebytes(data: bytes) -> email.message.Message: |
48883
f0c445a8e324
mail: delete conditional code for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
509 ep = email.parser.BytesParser() |
f0c445a8e324
mail: delete conditional code for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
510 return ep.parsebytes(data) |
43326
ef81de93143e
py3: use a BytesParser in notify extension
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
43325
diff
changeset
|
511 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
43019
diff
changeset
|
512 |
51287
f15cb5111a1e
pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51285
diff
changeset
|
513 def headdecode(s: Union[email.header.Header, bytes]) -> bytes: |
28341
8286f551b7ee
patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents:
27619
diff
changeset
|
514 '''Decodes RFC-2047 header''' |
8286f551b7ee
patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents:
27619
diff
changeset
|
515 uparts = [] |
30072
87b8e40eb812
mail: handle renamed email.Header
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29285
diff
changeset
|
516 for part, charset in email.header.decode_header(s): |
28341
8286f551b7ee
patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents:
27619
diff
changeset
|
517 if charset is not None: |
8286f551b7ee
patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents:
27619
diff
changeset
|
518 try: |
8286f551b7ee
patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents:
27619
diff
changeset
|
519 uparts.append(part.decode(charset)) |
8286f551b7ee
patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents:
27619
diff
changeset
|
520 continue |
43324
866bd2cf764b
mail: catch LookupError in headdecode()
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
43172
diff
changeset
|
521 except (UnicodeDecodeError, LookupError): |
28341
8286f551b7ee
patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents:
27619
diff
changeset
|
522 pass |
37469
7edf68862fe3
py3: work around weird handling of bytes/unicode in decode_header()
Yuya Nishihara <yuya@tcha.org>
parents:
37463
diff
changeset
|
523 # On Python 3, decode_header() may return either bytes or unicode |
7edf68862fe3
py3: work around weird handling of bytes/unicode in decode_header()
Yuya Nishihara <yuya@tcha.org>
parents:
37463
diff
changeset
|
524 # depending on whether the header has =?<charset>? or not |
7edf68862fe3
py3: work around weird handling of bytes/unicode in decode_header()
Yuya Nishihara <yuya@tcha.org>
parents:
37463
diff
changeset
|
525 if isinstance(part, type(u'')): |
7edf68862fe3
py3: work around weird handling of bytes/unicode in decode_header()
Yuya Nishihara <yuya@tcha.org>
parents:
37463
diff
changeset
|
526 uparts.append(part) |
7edf68862fe3
py3: work around weird handling of bytes/unicode in decode_header()
Yuya Nishihara <yuya@tcha.org>
parents:
37463
diff
changeset
|
527 continue |
28341
8286f551b7ee
patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents:
27619
diff
changeset
|
528 try: |
8286f551b7ee
patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents:
27619
diff
changeset
|
529 uparts.append(part.decode('UTF-8')) |
8286f551b7ee
patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents:
27619
diff
changeset
|
530 continue |
8286f551b7ee
patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents:
27619
diff
changeset
|
531 except UnicodeDecodeError: |
8286f551b7ee
patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents:
27619
diff
changeset
|
532 pass |
8286f551b7ee
patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents:
27619
diff
changeset
|
533 uparts.append(part.decode('ISO-8859-1')) |
31447
067add650129
encoding: factor out unicode variants of from/tolocal()
Yuya Nishihara <yuya@tcha.org>
parents:
30325
diff
changeset
|
534 return encoding.unitolocal(u' '.join(uparts)) |