diff --git a/woodwind/models.py b/woodwind/models.py index 6d9e75a..27873b0 100644 --- a/woodwind/models.py +++ b/woodwind/models.py @@ -111,6 +111,7 @@ class Feed(db.Model): push_hub = db.Column(db.String(512)) push_topic = db.Column(db.String(512)) push_verified = db.Column(db.Boolean) + push_expiry = db.Column(db.DateTime) last_pinged = db.Column(db.DateTime) def get_feed_code(self): diff --git a/woodwind/push.py b/woodwind/push.py index f76e7ad..9e932d2 100644 --- a/woodwind/push.py +++ b/woodwind/push.py @@ -24,14 +24,18 @@ def notify(feed_id): mode = request.args.get('hub.mode') topic = request.args.get('hub.topic') challenge = request.args.get('hub.challenge') + lease_seconds = request.args.get('hub.lease_seconds') current_app.logger.debug( - 'PuSH verification. feed=%r, mode=%s, topic=%s, challenge=%s', - feed, mode, topic, challenge) + 'PuSH verification. feed=%r, mode=%s, topic=%s, challenge=%s, lease_seconds=%s', + feed, mode, topic, challenge, lease_seconds) if mode == 'subscribe' and topic == feed.push_topic: current_app.logger.debug( 'PuSH verify subscribe for feed=%r, topic=%s', feed, topic) feed.push_verified = True + if lease_seconds: + feed.push_expiry = datetime.datetime.utcnow() \ + + datetime.timedelta(seconds=int(lease_seconds)) db.session.commit() return challenge elif mode == 'unsubscribe' and topic != feed.push_topic: diff --git a/woodwind/tasks.py b/woodwind/tasks.py index 463ea6d..c354565 100644 --- a/woodwind/tasks.py +++ b/woodwind/tasks.py @@ -133,12 +133,13 @@ def check_push_subscription(session, feed, response): 'hub.mode': mode, 'hub.topic': topic, 'hub.callback': build_callback_url(), - 'hub.verify': 'async', # backcompat with 0.3 + 'hub.verify': 'async', # backcompat with 0.3 # TODO secret should only be used over HTTPS # 'hub.secret': secret, }) logger.debug('%s response %r', mode, r) + expiry = feed.push_expiry old_hub = feed.push_hub old_topic = feed.push_topic hub = response.links.get('hub', {}).get('url') @@ -165,13 +166,15 @@ def check_push_subscription(session, feed, response): topic = next((link['href'] for link in links if 'self' in link['rel']), None) - if hub != old_hub or topic != old_topic or not feed.push_verified: + if ((expiry and expiry - datetime.datetime.utcnow() <= UPDATE_INTERVAL) + or hub != old_hub or topic != old_topic or not feed.push_verified): feed.push_hub = hub feed.push_topic = topic feed.push_verified = False + feed.push_expiry = None session.commit() - if old_hub and old_topic: + if old_hub and old_topic and hub != old_hub and topic != old_topic: send_request('unsubscribe', old_hub, old_topic) if hub and topic: