post_process.redirect: Log exceptions as warnings
[rss2email.git] / rss2email / post_process / redirect.py
1 # Copyright (C) 2013 Francois Boulogne <fboulogne at april dot org>
2 #
3 # This file is part of rss2email.
4 #
5 # rss2email is free software: you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free Software
7 # Foundation, either version 2 of the License, or (at your option) version 3 of
8 # the License.
9 #
10 # rss2email is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along with
15 # rss2email.  If not, see <http://www.gnu.org/licenses/>.
16
17 """Remove redirects on the post URL.
18
19 Several websites use redirects (e.g. feedburner) for various reasons like
20 statistics. You may want to avoid this for privacy or for durability.
21
22 This hook finds and uses the real url behind redirects.
23 """
24
25 import logging
26 import re
27 import urllib
28
29 import rss2email
30
31
32 LOG = _logging.getLogger(__name__)
33
34
35 def process(feed, parsed, entry, guid, message):
36     # decode message
37     encoding = message.get_charsets()[0]
38     content = str(message.get_payload(decode=True), encoding)
39
40     links = []
41
42     # Get the link
43     link = entry['link']
44     if link:
45         links.append(link)
46
47     for enclosure in entry['enclosures']:
48         links.append(enclosure['href'])
49
50     if not links:
51         return message
52
53     # Remove the redirect and modify the content
54     timeout = rss2email.config.CONFIG['DEFAULT'].getint('feed-timeout')
55     proxy = rss2email.config.CONFIG['DEFAULT']['proxy']
56     for link in links:
57         try:
58             request = urllib.request.Request(link)
59             request.add_header('User-agent', rss2email.feed._USER_AGENT)
60             direct_link = urllib.request.urlopen(request).geturl()
61         except Exception as e:
62             LOG.warning('could not follow redirect for {}: {}'.format(
63                 linke, e))
64             continue
65         content = re.sub(re.escape(link), direct_link, content, re.MULTILINE)
66
67     # clear CTE and set message. It can be important to clear the CTE
68     # before setting the payload, since the payload is only re-encoded
69     # if CTE is not already set.
70     del message['Content-Transfer-Encoding']
71     message.set_payload(content, charset=encoding)
72
73     return message