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
, \
19 set_subscription_verified
21 logger
= logging
.getLogger(__name__
)
24 class SubscribeView(View
):
25 """ Endpoint for Pubsubhubbub subscriptions """
28 def dispatch(self
, *args
, **kwargs
):
29 return super(SubscribeView
, self
).dispatch(*args
, **kwargs
)
31 def get(self
, request
):
32 """ Callback used by the Hub to verify the subscription request """
34 # received arguments: hub.mode, hub.topic, hub.challenge,
35 # hub.lease_seconds, hub.verify_token
36 mode
= request
.GET
.get('hub.mode')
37 feed_url
= request
.GET
.get('hub.topic')
38 challenge
= request
.GET
.get('hub.challenge')
39 lease_seconds
= request
.GET
.get('hub.lease_seconds')
40 verify_token
= request
.GET
.get('hub.verify_token')
42 logger
.debug(('received subscription-parameters: mode: %(mode)s, ' +
43 'topic: %(topic)s, challenge: %(challenge)s, lease_seconds: ' +
44 '%(lease_seconds)s, verify_token: %(verify_token)s') % \
45 dict(mode
=mode
, topic
=feed_url
, challenge
=challenge
,
46 lease_seconds
=lease_seconds
, verify_token
=verify_token
))
48 subscription
= subscription_for_topic(feed_url
)
50 if subscription
is None:
51 logger
.warn('subscription does not exist')
52 return HttpResponseNotFound()
54 if subscription
.mode
!= mode
:
55 logger
.warn('invalid mode, %s expected' % subscription
.mode
)
56 return HttpResponseNotFound()
58 if subscription
.verify_token
!= verify_token
:
59 logger
.warn('invalid verify_token, %s expected' %
60 subscribe
.verify_token
)
61 return HttpResponseNotFound()
63 set_subscription_verified(subscription
)
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)