1
# Copyright 2011 Canonical Ltd. This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
4
"""Views for QuestionSubscription."""
8
'QuestionPortletSubscribersWithDetails',
11
from lazr.delegates import delegates
12
from lazr.restful.interfaces import IWebServiceClientRequest
13
from simplejson import dumps
14
from zope.traversing.browser import absoluteURL
16
from canonical.launchpad.webapp import (
20
from lp.answers.interfaces.question import IQuestion
21
from lp.answers.interfaces.questionsubscription import IQuestionSubscription
22
from lp.services.propertycache import cachedproperty
25
class QuestionPortletSubscribersWithDetails(LaunchpadView):
26
"""View that returns a JSON dump of subscriber details for a question."""
29
def api_request(self):
30
return IWebServiceClientRequest(self.request)
32
def direct_subscriber_data(self, question):
33
"""Get the direct subscriber data.
35
This method is isolated from the subscriber_data_js so that query
36
count testing can be done accurately and robustly.
39
details = list(question.getDirectSubscribersWithDetails())
40
for person, subscription in details:
41
can_edit = subscription.canBeUnsubscribedByUser(self.user)
42
if person.private and not can_edit:
43
# Skip private teams user is not a member of.
48
'display_name': person.displayname,
49
'web_link': canonical_url(person, rootsite='mainsite'),
50
'self_link': absoluteURL(person, self.api_request),
51
'is_team': person.is_team,
55
'subscriber': subscriber,
56
'subscription_level': 'Direct',
62
def subscriber_data_js(self):
63
"""Return subscriber_ids in a form suitable for JavaScript use."""
64
question = IQuestion(self.context)
65
data = self.direct_subscriber_data(question)
67
others = question.getIndirectSubscribers()
69
if person == self.user:
70
# Skip the current user viewing the page.
74
'display_name': person.displayname,
75
'web_link': canonical_url(person, rootsite='mainsite'),
76
'self_link': absoluteURL(person, self.api_request),
77
'is_team': person.is_team,
81
'subscriber': subscriber,
82
'subscription_level': 'Indirect',
88
"""Override the default render() to return only JSON."""
89
self.request.response.setHeader('content-type', 'application/json')
90
return self.subscriber_data_js
93
class SubscriptionAttrDecorator:
94
"""A QuestionSubscription with added attributes for HTML/JS."""
95
delegates(IQuestionSubscription, 'subscription')
97
def __init__(self, subscription):
98
self.subscription = subscription
102
return 'subscriber-%s' % self.subscription.person.id