Skip to content

Commit 216b778

Browse files
committed
feat: Save feed URL on redirect
Also adds test for saving feed URL on redirect.
1 parent 19f58c7 commit 216b778

File tree

4 files changed

+49
-10
lines changed

4 files changed

+49
-10
lines changed

rss2email/command.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def run(feeds, args):
9494
interval = interval
9595
))
9696
_time.sleep(interval)
97-
feed.run(send=args.send, clean=args.clean)
97+
feed.run(send=args.send, clean=args.clean, save_config=args.save_config)
9898
except _error.RSS2EmailError as e:
9999
e.log()
100100
last_server = current_server

rss2email/feed.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -397,9 +397,9 @@ def _fetch(self):
397397
f = _util.TimeLimitedFunction('feed {}'.format(self.name), timeout, _feedparser.parse)
398398
return f(self.url, self.etag, modified=self.modified, agent=self.user_agent, **kwargs)
399399

400-
def _process(self, parsed):
400+
def _process(self, parsed, save_config=False):
401401
_LOG.info('process {}'.format(self))
402-
self._check_for_errors(parsed)
402+
self._check_for_errors(parsed, save_config=save_config)
403403
for entry in reversed(parsed.entries):
404404
_LOG.debug('processing {}'.format(entry.get('id', 'no-id')))
405405
processed = self._process_entry(parsed=parsed, entry=entry)
@@ -413,15 +413,16 @@ def _process(self, parsed):
413413
continue
414414
yield processed
415415

416-
def _check_for_errors(self, parsed):
416+
def _check_for_errors(self, parsed, save_config=False):
417417
warned = False
418418
status = getattr(parsed, 'status', 200)
419419
_LOG.debug('HTTP status {}'.format(status))
420420
if status in [301, 308]:
421421
_LOG.info('redirect {} from {} to {}'.format(
422422
self.name, self.url, parsed['url']))
423423
self.url = parsed['url']
424-
# TODO: `url` is not saved -- add config option to call feeds.save_config() in run command
424+
if save_config:
425+
self.save_to_config()
425426
elif status == 304:
426427
_LOG.info('skipping {}: feed was not modified since last update'.format(
427428
self.name, self.url))
@@ -928,7 +929,7 @@ def _send(self, sender, message):
928929
_email.send(recipient=self.to, message=message,
929930
config=self.config, section=section)
930931

931-
def run(self, send=True, clean=False):
932+
def run(self, send=True, clean=False, save_config=False):
932933
"""Fetch and process the feed, mailing entry emails.
933934
934935
>>> feed = Feed(
@@ -969,7 +970,7 @@ def run(self, send=True, clean=False):
969970
raise _error.InvalidDigestType(type)
970971
digest = self._new_digest()
971972
seen = []
972-
for (guid, state, sender, message) in self._process(parsed):
973+
for (guid, state, sender, message) in self._process(parsed, save_config=save_config):
973974
_LOG.debug('new message: {}'.format(message['Subject']))
974975
seen.append((guid, state))
975976
self._append_to_digest(digest=digest, message=message)
@@ -984,7 +985,7 @@ def run(self, send=True, clean=False):
984985
for (guid, state) in seen:
985986
self.seen[guid] = state
986987
else:
987-
for (guid, state, sender, message) in self._process(parsed):
988+
for (guid, state, sender, message) in self._process(parsed, save_config=save_config):
988989
_LOG.debug('new message: {}'.format(message['Subject']))
989990
if send:
990991
self._send(sender=sender, message=message)

rss2email/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ def run(*args, **kwargs):
112112
default=True, action='store_const', const=False,
113113
help="fetch feeds, but don't send email")
114114
run_parser.add_argument(
115-
'--clean', action='store_true',
116-
help='clean old feed entries')
115+
'--save-config', action='store_true',
116+
help='save feed configuration changes (e.g. new URL after a redirect)')
117117
run_parser.add_argument(
118118
'index', nargs='*',
119119
help='feeds to fetch (defaults to fetching all feeds)')

test/test.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,22 @@ def do_GET(self):
256256
finally:
257257
httpd.server_close()
258258

259+
def webserver_for_test_redirect(queue, status_code):
260+
class RedirectHandler(NoLogHandler):
261+
def do_GET(self):
262+
self.send_response(status_code)
263+
self.send_header('Location', '/disqus/feed.rss')
264+
self.end_headers()
265+
266+
httpd = http.server.HTTPServer(('', 0), RedirectHandler)
267+
try:
268+
port = httpd.server_address[1]
269+
queue.put(port)
270+
while queue.get() != "stop":
271+
httpd.handle_request()
272+
finally:
273+
httpd.server_close()
274+
259275
class TestFetch(unittest.TestCase):
260276
"Retrieving feeds from servers"
261277
def test_delay(self):
@@ -419,6 +435,28 @@ def test_cache_control(self):
419435

420436
queue.put("stop")
421437

438+
def test_redirect(self):
439+
"Saves feed URL on redirect"
440+
cfg = """[DEFAULT]
441+
442+
443+
queue = multiprocessing.Queue()
444+
webserver_proc = multiprocessing.Process(target=webserver_for_test_redirect, args=(queue, 301))
445+
webserver_proc.start()
446+
port = queue.get()
447+
448+
with ExecContext(cfg) as ctx:
449+
ctx.call("add", 'test', 'http://127.0.0.1:{port}/redirect'.format(port = port))
450+
451+
queue.put("next")
452+
ctx.call("run", "--no-send", "--save-config")
453+
454+
with open(ctx.cfg_path, 'r') as f:
455+
config = f.read()
456+
self.assertIn("url = http://127.0.0.1:{port}/disqus/feed.rss".format(port=port), config)
457+
458+
queue.put("stop")
459+
422460

423461
def webserver_for_test_send(queue):
424462
httpd = http.server.HTTPServer(('', 0), NoLogHandler)

0 commit comments

Comments
 (0)