This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
combo-plugin-subscriptions/combo_plugin_subscriptions/models.py

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())