161 lines
6.7 KiB
Python
161 lines
6.7 KiB
Python
import requests
|
|
import requests.exceptions
|
|
import logging
|
|
import json
|
|
|
|
from django.conf import settings
|
|
from django.db import models
|
|
from django.utils.translation import ugettext_lazy as _
|
|
from django.template.defaultfilters import slugify
|
|
from django.core.cache import cache
|
|
from django import template
|
|
from django.forms import models as model_forms, Select
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
from combo.data.models import CellBase
|
|
from combo.data.library import register_cell_class
|
|
|
|
from .forms import SubscriptionsManageForm
|
|
|
|
|
|
@register_cell_class
|
|
class SubscriptionsManageCell(CellBase):
|
|
passerelle_url = models.URLField(verbose_name=_('Subscriptions service url'),
|
|
max_length=128)
|
|
resources_restrictions = models.TextField(verbose_name=_('resources restrictions'), blank=True)
|
|
transports_restrictions = models.TextField(verbose_name=_('transports restrictions'), blank=True)
|
|
|
|
__resources_restrictions = None
|
|
__transports_restrictions = None
|
|
|
|
template_name = 'subscriptions/subscriptions.html'
|
|
|
|
class Meta:
|
|
verbose_name = _('Manage your subscriptions')
|
|
|
|
def get_default_form_class(self):
|
|
model_fields = ('passerelle_url', 'resources_restrictions',
|
|
'transports_restrictions')
|
|
try:
|
|
return model_forms.modelform_factory(self.__class__, fields=model_fields,
|
|
widgets={'passerelle_url': Select(choices=settings.COMBO_SUBSCRIPTIONS)})
|
|
except AttributeError:
|
|
return model_forms.modelform_factory(self.__class__, fields=model_fields)
|
|
|
|
|
|
def simplify(self, name):
|
|
return slugify(name.strip())
|
|
|
|
def get_resources_restrictions(self):
|
|
if self.__resources_restrictions is None:
|
|
self.__resources_restrictions = []
|
|
for name in filter(None, map(self.simplify, self.resources_restrictions.strip().split(','))):
|
|
self.__resources_restrictions.append(name)
|
|
return self.__resources_restrictions
|
|
|
|
def get_transports_restrictions(self):
|
|
if self.__transports_restrictions is None:
|
|
self.__transports_restrictions = []
|
|
for name in filter(None, map(self.simplify, self.transports_restrictions.strip().split(','))):
|
|
self.__transports_restrictions.append(name)
|
|
return self.__transports_restrictions
|
|
|
|
|
|
def check_resource(self, resource):
|
|
restrictions = self.get_resources_restrictions()
|
|
if restrictions and self.simplify(resource) not in restrictions:
|
|
return False
|
|
return True
|
|
|
|
def check_transport(self, transport):
|
|
restrictions = self.get_transports_restrictions()
|
|
if restrictions and self.simplify(transport) not in restrictions:
|
|
return False
|
|
return True
|
|
|
|
def key(self, **kwargs):
|
|
return 'passerelle_register_subscriptions_'+slugify(self.passerelle_url+repr(sorted(kwargs.iteritems())))
|
|
|
|
def get_subscriptions(self, **kwargs):
|
|
key = self.key(**kwargs)
|
|
early_response = cache.get(key)
|
|
if early_response is not None:
|
|
logger.debug('got subscriptions from cache')
|
|
return early_response
|
|
http_response = requests.get(self.passerelle_url, params=kwargs)
|
|
json_response = http_response.json()
|
|
if json_response['err'] == 0:
|
|
logger.debug('got subscriptions from %s: %r', self.passerelle_url,
|
|
json_response['data'])
|
|
cache.set(key, json_response['data'])
|
|
return json_response['data']
|
|
else:
|
|
logger.error('got subscriptions from %(url)s failed: %(json)r',
|
|
{ 'url': self.passerelle_url,
|
|
'json': json_response })
|
|
return []
|
|
|
|
def set_subscriptions(self, subscriptions, **kwargs):
|
|
old_subscriptions = self.get_subscriptions(**kwargs)
|
|
index = {}
|
|
for subscription in subscriptions:
|
|
index[subscription['name']] = subscription
|
|
post = []
|
|
for subscription in old_subscriptions:
|
|
new_defined = set(subscription['transports']['defined'])
|
|
if self.simplify(subscription['name']) in index:
|
|
new_subscription = index[subscription['name']]
|
|
for transport in subscription['transports']['available']:
|
|
stransport = self.simplify(transport)
|
|
if self.check_transport(transport):
|
|
if stransport in new_subscription['transports']:
|
|
new_defined.add(transport)
|
|
else:
|
|
new_defined.discard(transport)
|
|
post.append(dict(name=subscription['name'],
|
|
transports=list(new_defined)))
|
|
headers = {'Content-type': 'application/json', 'Accept': 'application/json'}
|
|
try:
|
|
response = requests.post(self.passerelle_url, params=kwargs,
|
|
data=json.dumps(post), headers=headers)
|
|
response.raise_for_status()
|
|
except requests.exceptions.HTTPError:
|
|
logger.error(u'set subscriptions on %s returned an HTTP error code: %s',
|
|
response.request.url, response.status_code)
|
|
except requests.exceptions.RequestException, e:
|
|
logger.error(u'set subscriptions on %s failed with exception: %s',
|
|
response.request.url, e)
|
|
else:
|
|
logger.debug(u'set subscriptions on %s: post %r', response.request.url,
|
|
post)
|
|
logger.debug(u'set subscriptions on %s: response %r',
|
|
response.request.url, response.content)
|
|
cache.delete(self.key(**kwargs))
|
|
if response.json()['err'] != 0:
|
|
logger.error(u'set subscriptions on %s returned an error: %r',
|
|
response.request.url, response.json())
|
|
|
|
def render(self, context):
|
|
cell_name = 'subscription_cell_%s' % self.id
|
|
plugin_template = template.loader.get_template(self.template_name)
|
|
request = context.get('request')
|
|
if request.method == 'POST' and cell_name in request.POST:
|
|
form = SubscriptionsManageForm(request.POST, instance=self,
|
|
request=request)
|
|
form.save()
|
|
else:
|
|
form = SubscriptionsManageForm(instance=self, request=request)
|
|
context['instance'] = self
|
|
context['form'] = form
|
|
context['submit_name'] = cell_name
|
|
return plugin_template.render(context)
|
|
|
|
def __unicode__(self):
|
|
return u'<SubscriptionsManagePlugin %s>' % self.passerelle_url
|
|
|
|
def is_relevant(self, context):
|
|
# the cell is only relevant for connected users
|
|
return bool(context.get('user').is_authenticated())
|