1 # -*- coding: utf-8 -*-
3 # PubSubHubbub subscriber for mygpo
9 from django
.http
import HttpResponseNotFound
, HttpResponse
10 from django
.views
.generic
.base
import View
11 from django
.views
.decorators
.csrf
import csrf_exempt
13 from couchdbkit
.ext
.django
import *
15 from feedservice
import urlstore
16 from mygpo
.pubsub
.models
import SubscriptionError
, Subscription
17 from mygpo
.pubsub
.signals
import subscription_updated
18 from mygpo
.db
.couchdb
.pubsub
import subscription_for_topic
20 logger
= logging
.getLogger(__name__
)
23 class SubscribeView(View
):
24 """ Endpoint for Pubsubhubbub subscriptions """
27 def dispatch(self
, *args
, **kwargs
):
28 return super(SubscribeView
, self
).dispatch(*args
, **kwargs
)
30 def get(self
, request
):
31 """ Callback used by the Hub to verify the subscription request """
33 # received arguments: hub.mode, hub.topic, hub.challenge,
34 # hub.lease_seconds, hub.verify_token
35 mode
= request
.GET
.get('hub.mode')
36 feed_url
= request
.GET
.get('hub.topic')
37 challenge
= request
.GET
.get('hub.challenge')
38 lease_seconds
= request
.GET
.get('hub.lease_seconds')
39 verify_token
= request
.GET
.get('hub.verify_token')
41 logger
.debug(('received subscription-parameters: mode: %(mode)s, ' +
42 'topic: %(topic)s, challenge: %(challenge)s, lease_seconds: ' +
43 '%(lease_seconds)s, verify_token: %(verify_token)s') % \
44 dict(mode
=mode
, topic
=feed_url
, challenge
=challenge
,
45 lease_seconds
=lease_seconds
, verify_token
=verify_token
))
47 subscription
= subscription_for_topic(feed_url
)
49 if subscription
is None:
50 logger
.warn('subscription does not exist')
51 return HttpResponseNotFound()
53 if subscription
.mode
!= mode
:
54 logger
.warn('invalid mode, %s expected' % subscription
.mode
)
55 return HttpResponseNotFound()
57 if subscription
.verify_token
!= verify_token
:
58 logger
.warn('invalid verify_token, %s expected' %
59 subscribe
.verify_token
)
60 return HttpResponseNotFound()
62 subscription
.verified
= True
65 logger
.info('subscription confirmed')
66 return HttpResponse(challenge
)
69 def post(self
, request
):
70 """ Callback to notify about a feed update """
72 feed_url
= request
.GET
.get('url')
75 logger
.info('received notification without url')
76 return HttpResponse(status
=400)
78 logger
.info('received notification for %s' % feed_url
)
80 subscription
= subscription_for_topic(feed_url
)
82 if subscription
is None:
83 logger
.warn('no subscription for this URL')
84 return HttpResponse(status
=400)
86 if subscription
.mode
!= 'subscribe':
87 logger
.warn('invalid subscription mode: %s' % subscription
.mode
)
88 return HttpResponse(status
=400)
90 if not subscription
.verified
:
91 logger
.warn('the subscription has not yet been verified')
92 return HttpResponse(status
=400)
94 subscription_updated
.send(sender
=feed_url
)
96 return HttpResponse(status
=200)