[Models] refactor QuerySets and Managers
[mygpo.git] / mygpo / pubsub / __init__.py
blobd94ae94bff9314bcae48cca325720840843dd337
1 # -*- coding: utf-8 -*-
3 # PubSubHubbub subscriber mygpo
7 import urllib
8 import urllib2
9 import logging
11 from django.core.urlresolvers import reverse
13 logger = logging.getLogger(__name__)
16 def subscribe(feedurl, huburl, base_url, mode='subscribe'):
17 """ Subscribe to the feed at a Hub """
19 from mygpo.pubsub.models import Subscription, SubscriptionError
20 from mygpo.db.couchdb.pubsub import subscription_for_topic
21 from couchdbkit.ext.django import *
22 logger.info('subscribing for {feed} at {hub}'.format(feed=feedurl,
23 hub=huburl))
24 verify = 'sync'
26 subscription = subscription_for_topic(feedurl)
27 if subscription is None:
28 subscription = Subscription()
29 subscription.verify_token = random_token()
31 if subscription.mode == mode:
32 if subscription.verified:
33 logger.info('subscription already exists')
34 return
36 else:
37 logger.info('subscription exists but has wrong mode: ' +
38 'old: %(oldmode)s, new: %(newmode)s. Overwriting.' %
39 dict(oldmode=subscription.mode, newmode=mode))
41 subscription.url = feedurl
42 subscription.mode = mode
43 subscription.save()
45 data = {
46 "hub.callback": callback_url(feedurl, base_url),
47 "hub.mode": mode,
48 "hub.topic": feedurl,
49 "hub.verify": verify,
50 "hub.verify_token": subscription.verify_token,
53 data = urllib.urlencode(data.items())
54 logger.debug('sending request: %s' % repr(data))
56 resp = None
58 try:
59 resp = urllib2.urlopen(huburl, data)
60 except urllib2.HTTPError, e:
61 if e.code != 204: # we actually expect a 204 return code
62 msg = 'Could not send subscription to Hub: HTTP Error %d: %s' % (e.code, e.reason)
63 logger.warn(msg)
64 raise SubscriptionError(msg)
65 except Exception, e:
66 raise
67 msg = 'Could not send subscription to Hub: %s' % repr(e)
68 logger.warn(msg)
69 raise SubscriptionError(msg)
71 if resp:
72 status = resp.code
73 if status != 204:
74 logger.warn('received incorrect status %d' % status)
75 raise SubscriptionError('Subscription has not been accepted by '
76 'the Hub')
79 def callback_url(feedurl, base_url):
80 callback = reverse('pubsub-subscribe')
81 param = urllib.urlencode([('url', feedurl)])
82 return '{base}{callback}?{param}'.format(base=base_url, callback=callback,
83 param=param)
86 def random_token(length=32):
87 import random
88 import string
89 return "".join(random.sample(string.letters+string.digits, length))