1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
diff -Naur orig/CHANGELOG new/CHANGELOG
--- orig/CHANGELOG 2020-08-31 18:03:24.000000000 +0300
+++ new/CHANGELOG 2020-09-05 16:09:45.000000000 +0300
@@ -1,4 +1,7 @@
UNRELEASED
+ * Improve log messages
+ * Remove documentation of `smtp-ssl-protocol` as this option was dropped in 2016
+ * Stop forging SMTP and sendmail envelope sender (#134)
v3.12.2 (2020-08-31)
* Fix bug `AttributeError: 'NoneType' object has no attribute 'close'` (#126)
diff -Naur orig/r2e.1 new/r2e.1
--- orig/r2e.1 2020-08-31 18:03:24.000000000 +0300
+++ new/r2e.1 2020-09-05 16:09:45.000000000 +0300
@@ -253,8 +253,6 @@
SMTP server
.IP smtp-ssl
Connect to the SMTP server using SSL
-.IP smtp-ssl-protocol
-TLS/SSL version to use on STARTTLS when not using 'smtp-ssl'.
.RE
.SS IMAP configuration
.IP imap-auth
diff -Naur orig/rss2email/__init__.py new/rss2email/__init__.py
--- orig/rss2email/__init__.py 2020-08-31 18:03:24.000000000 +0300
+++ new/rss2email/__init__.py 2020-09-05 16:09:45.000000000 +0300
@@ -26,7 +26,7 @@
import sys as _sys
-__version__ = '3.12.2'
+__version__ = '3.12.1'
__url__ = 'https://github.com/rss2email/rss2email'
__author__ = 'The rss2email maintainers'
__email__ = 'rss2email@tremily.us'
diff -Naur orig/rss2email/config.py new/rss2email/config.py
--- orig/rss2email/config.py 2020-08-31 18:03:24.000000000 +0300
+++ new/rss2email/config.py 2020-09-05 16:09:45.000000000 +0300
@@ -83,11 +83,11 @@
# Transfer-Encoding. For local mailing it is safe and
# convenient to use 8bit.
('use-8bit', str(False)),
- # True: Only use the 'from' address.
+ # True: Only use the 'from' address. Overrides the use-publisher-email setting.
# False: Use the email address specified by the feed, when possible.
('force-from', str(False)),
- # True: Use the publisher's email if you can't find the author's.
- # False: Just use the 'from' email instead.
+ # True: Use author's email if found, or use publisher's email if found, or use the 'from' setting.
+ # False: Use author's email if found, or use the 'from' setting.
('use-publisher-email', str(False)),
# If empty, only use the feed email address rather than
# friendly name plus email address. Available attributes may
@@ -132,7 +132,7 @@
# because the old entries will not be recorded under their new
# link-based ids.
('trust-link', str(False)),
- # If 'trust-guid' or 'trust-link' is True, this settings allows to receive
+ # If 'trust-guid' or 'trust-link' is True, this setting allows to receive
# a new email message in reply to the previous one when the post changes.
('reply-changes', str(False)),
# To most correctly encode emails with international
diff -Naur orig/rss2email/email.py new/rss2email/email.py
--- orig/rss2email/email.py 2020-08-31 18:03:24.000000000 +0300
+++ new/rss2email/email.py 2020-09-05 16:09:45.000000000 +0300
@@ -151,7 +151,7 @@
message[key] = _Header(value, encoding)
return message
-def smtp_send(sender, recipient, message, config=None, section='DEFAULT'):
+def smtp_send(recipient, message, config=None, section='DEFAULT'):
if config is None:
config = _config.CONFIG
server = config.get(section, 'smtp-server')
@@ -190,7 +190,7 @@
except Exception as e:
raise _error.SMTPAuthenticationError(
server=server, username=username)
- smtp.send_message(message, sender, recipient.split(','))
+ smtp.send_message(message, config.get(section, 'from'), recipient.split(','))
smtp.quit()
def imap_send(message, config=None, section='DEFAULT'):
@@ -345,12 +345,12 @@
else:
return bytesio.getvalue()
-def sendmail_send(sender, recipient, message, config=None, section='DEFAULT'):
+def sendmail_send(recipient, message, config=None, section='DEFAULT'):
if config is None:
config = _config.CONFIG
message_bytes = _flatten(message)
sendmail = config.get(section, 'sendmail')
- sender_name,sender_addr = _parseaddr(sender)
+ sender_name,sender_addr = _parseaddr(config.get(section, 'from'))
_LOG.debug(
'sending message to {} via {}'.format(recipient, sendmail))
try:
@@ -366,11 +366,11 @@
except Exception as e:
raise _error.SendmailError() from e
-def send(sender, recipient, message, config=None, section='DEFAULT'):
+def send(recipient, message, config=None, section='DEFAULT'):
protocol = config.get(section, 'email-protocol')
if protocol == 'smtp':
smtp_send(
- sender=sender, recipient=recipient, message=message,
+ recipient=recipient, message=message,
config=config, section=section)
elif protocol == 'imap':
imap_send(message=message, config=config, section=section)
@@ -378,5 +378,5 @@
maildir_send(message=message, config=config, section=section)
else:
sendmail_send(
- sender=sender, recipient=recipient, message=message,
+ recipient=recipient, message=message,
config=config, section=section)
diff -Naur orig/rss2email/error.py new/rss2email/error.py
--- orig/rss2email/error.py 2020-08-31 18:03:24.000000000 +0300
+++ new/rss2email/error.py 2020-09-05 16:09:45.000000000 +0300
@@ -42,15 +42,14 @@
class TimeoutError (RSS2EmailError):
- def __init__(self, time_limited_function, message=None):
- if message is None:
- if time_limited_function.error is not None:
- message = (
- 'error while running time limited function: {}'.format(
- time_limited_function.error[1]))
- else:
- message = '{} second timeout exceeded'.format(
- time_limited_function.timeout)
+ def __init__(self, time_limited_function):
+ if time_limited_function.error is not None:
+ message = (
+ 'error while running time limited function in {}: {}'.format(
+ time_limited_function.name, time_limited_function.error[1]))
+ else:
+ message = '{} second timeout exceeded in {}'.format(
+ time_limited_function.timeout, time_limited_function.name)
super(TimeoutError, self).__init__(message=message)
self.time_limited_function = time_limited_function
@@ -148,8 +147,9 @@
class InvalidFeedConfig (FeedError):
def __init__(self, setting, feed, message=None, **kwargs):
if not message:
- message = "invalid feed configuration {}".format(
- {setting: getattr(feed, setting)})
+ message = (
+ "invalid feed configuration '{setting}' in {feed}".format(
+ setting=getattr(feed, setting), feed=feed))
super(InvalidFeedConfig, self).__init__(
feed=feed, message=message, **kwargs)
self.setting = setting
diff -Naur orig/rss2email/feed.py new/rss2email/feed.py
--- orig/rss2email/feed.py 2020-08-31 18:03:24.000000000 +0300
+++ new/rss2email/feed.py 2020-09-05 16:09:45.000000000 +0300
@@ -373,7 +373,7 @@
kwargs = {}
if proxy:
kwargs['handlers'] = [_urllib_request.ProxyHandler({'http':proxy})]
- f = _util.TimeLimitedFunction(timeout, _feedparser.parse)
+ f = _util.TimeLimitedFunction('feed {}'.format(self.name), timeout, _feedparser.parse)
return f(self.url, self.etag, modified=self.modified, **kwargs)
def _process(self, parsed):
@@ -773,9 +773,9 @@
if entry.get('summary_detail', None):
contents.append(entry.summary_detail)
if self.html_mail:
- types = ['text/html', 'text/plain']
+ types = ['application/xhtml+xml', 'text/html', 'text/plain']
else:
- types = ['text/plain', 'text/html']
+ types = ['text/plain', 'text/html', 'application/xhtml+xml']
for content_type in types:
for content in contents:
if content['type'] == content_type:
@@ -871,7 +871,7 @@
section = self.section
if section not in self.config:
section = 'DEFAULT'
- _email.send(sender=sender, recipient=self.to, message=message,
+ _email.send(recipient=self.to, message=message,
config=self.config, section=section)
def run(self, send=True):
diff -Naur orig/rss2email/feeds.py new/rss2email/feeds.py
--- orig/rss2email/feeds.py 2020-08-31 18:03:24.000000000 +0300
+++ new/rss2email/feeds.py 2020-09-05 16:09:45.000000000 +0300
@@ -239,11 +239,10 @@
def load(self, require=False):
_LOG.debug('load feed configuration from {}'.format(self.configfiles))
if self.configfiles:
- self.read_configfiles = self.config.read(self.configfiles)
+ read_configfiles = self.config.read(self.configfiles)
else:
- self.read_configfiles = []
- _LOG.debug('loaded configuration from {}'.format(
- self.read_configfiles))
+ read_configfiles = []
+ _LOG.debug('loaded configuration from {}'.format(read_configfiles))
self._load_feeds(require=require)
def _load_feeds(self, require):
diff -Naur orig/rss2email/util.py new/rss2email/util.py
--- orig/rss2email/util.py 2020-08-31 18:03:24.000000000 +0300
+++ new/rss2email/util.py 2020-09-05 16:09:45.000000000 +0300
@@ -35,19 +35,20 @@
>>> def sleeping_return(sleep, x):
... time.sleep(sleep)
... return x
- >>> TimeLimitedFunction(0.5, sleeping_return)(0.1, 'x')
+ >>> TimeLimitedFunction('sleeping', 0.5, sleeping_return)(0.1, 'x')
'x'
- >>> TimeLimitedFunction(0.5, sleeping_return)(10, 'y')
+ >>> TimeLimitedFunction('sleeping', 0.5, sleeping_return)(10, 'y')
Traceback (most recent call last):
...
- rss2email.error.TimeoutError: 0.5 second timeout exceeded
- >>> TimeLimitedFunction(0.5, time.sleep)('x')
+ rss2email.error.TimeoutError: 0.5 second timeout exceeded in sleeping
+ >>> TimeLimitedFunction('sleep', 0.5, time.sleep)('x')
Traceback (most recent call last):
...
- rss2email.error.TimeoutError: error while running time limited function: a float is required
+ rss2email.error.TimeoutError: error while running time limited function in sleep: a float is required
"""
- def __init__(self, timeout, target, **kwargs):
+ def __init__(self, name, timeout, target, **kwargs):
super(TimeLimitedFunction, self).__init__(target=target, daemon=True, **kwargs)
+ self.name = name
self.timeout = timeout
self.result = None
self.error = None
|