Beispiel #1
0
    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")
Beispiel #2
0
    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()
Beispiel #3
0
    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")