def process(self, log=None): """ Processes all subscriptions for expiration and automatic refreshing. """ utils.lock("subscription") try: if log is None: log = logging.getLogger("subhub.subscription.process") for subscription in self.all(): if subscription.expires < datetime.now(): subscription.delete() log.info("Subscription expired %s" % subscription) elif subscription.expires - datetime.now() < timedelta(seconds=MIN_LEASE): task, created = SubscriptionTask.objects.get_or_create( callback=subscription.callback, topic=subscription.topic, verify_token=subscription.verify_token, mode="subscribe", defaults={"secret": subscription.secret}, ) if created: log.info("Refresh request for %s" % subscription) finally: utils.unlock("subscription")
def process(self, log=None): """ Processes all content distribution tasks grouped by subscriptions (i.e. a single topic for a single callback). A subscription may receive one or more accumulated entries. """ utils.lock("distribution") try: if log is None: log = logging.getLogger("subhub.distribution.process") qs = self.get_query_set().select_related("subscription").order_by("subscription") feed_cache = {} def filter_feed(url, tasks): ids = set(t.entry_id for t in tasks) feed = utils.parse_atom(url, cache=feed_cache) # feed = deepcopy(utils.parse_atom(url, cache=feed_cache)) # for element in feed.root.findall('entry'): # if element.find('id').text not in ids: # feed.root.remove(element) return feed groups = groupby(qs, lambda t: t.subscription) updates = ((s, filter_feed(s.topic, tasks)) for s, tasks in groups) def process_update(subscription, feed): if not feed.root.findall("entry"): return True body = str(feed) h = httplib2.Http(timeout=utils.HTTP_TIMEOUT) headers = {"Content-type": "application/atom+xml; charset=utf-8", "Content-length": str(len(body))} if subscription.secret: signature = hmac.new(subscription.secret.encode("utf-8"), body, sha1).hexdigest() headers["X-Hub-Signature"] = "sha1=%s" % signature try: response, body = h.request( subscription.callback.encode("utf-8"), "POST", headers=headers, body=body ) if 200 <= response.status < 300: sent_ids = [id.text for id in feed.root.findall("entry/id")] log.info("%s (%s)" % (subscription, ", ".join(sent_ids))) return True else: log.error("%s: HTTP Error %s" % (subscription, response.status)) except utils.HTTP_ERRORS, e: log.error("%s: %s" % (subscription, e)) return False results = utils.pool(process_update, updates) for result, (subscription, feed) in results: if result: self.filter(subscription=subscription).delete()
def process(self, log=None): """ Verifies all tasks in queue. """ utils.lock("subscriptiontask") try: if log is None: log = logging.getLogger("subhub.subscriptiontask.process") for task in self.all(): result, description = task.verify() if result: log.info("%s: %s" % (task, description)) else: log.error("%s (ttl=%s): %s" % (task, task.ttl, description)) finally: utils.unlock("subscriptiontask")