combo/combo/apps/newsletters/models.py

148 lines
5.7 KiB
Python

# combo - content management system
# Copyright (C) 2015 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import json
from requests.exceptions import RequestException, HTTPError
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.template.defaultfilters import slugify
from django.forms import models as model_forms
from django.conf import settings
from django.utils.http import urlencode
from combo.data.models import CellBase
from combo.data.library import register_cell_class
from combo.utils import requests
from .forms import NewslettersManageForm
class SubscriptionsSaveError(Exception):
pass
@register_cell_class
class NewslettersCell(CellBase):
title = models.CharField(verbose_name=_('Title'), max_length=128)
url = models.URLField(verbose_name=_('Newsletters service url'),
max_length=128)
resources_restrictions = models.CharField(_('resources restrictions'),
blank=True, max_length=1024,
help_text=_('list of resources(themes) separated by commas'))
transports_restrictions = models.CharField(_('transports restrictions'),
blank=True, max_length=1024,
help_text=_('list of transports separated by commas'))
template_name = 'newsletters/newsletters.html'
user_dependant = True
@classmethod
def is_enabled(cls):
return settings.NEWSLETTERS_CELL_ENABLED
class Meta:
verbose_name = _('Newsletters')
def get_default_form_class(self):
model_fields = ('title', 'url', 'resources_restrictions',
'transports_restrictions')
return model_forms.modelform_factory(self.__class__, fields=model_fields)
def simplify(self, name):
return slugify(name.strip())
def get_resources_restrictions(self):
return list(filter(None, map(self.simplify, self.resources_restrictions.strip().split(','))))
def get_transports_restrictions(self):
return list(filter(None, map(self.simplify, self.transports_restrictions.strip().split(','))))
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 transport not in restrictions:
return False
return True
def filter_data(self, data):
filtered = []
for item in data:
if not self.check_resource(item['text']):
continue
for t in item['transports']:
if self.check_transport(t['id']):
filtered.append(item)
return filtered
def get_newsletters(self):
endpoint = self.url + 'newsletters/'
response = requests.get(endpoint, remote_service='auto', cache_duration=60, without_user=True)
if response.ok:
json_response = response.json()
return self.filter_data(json_response['data'])
return []
def get_subscriptions(self, user, **kwargs):
endpoint = self.url + 'subscriptions/'
response = requests.get(endpoint, remote_service='auto',
user=user, cache_duration=0, params=kwargs)
if response.ok:
json_response = response.json()
return self.filter_data(json_response['data'])
return []
def set_subscriptions(self, subscriptions, user, **kwargs):
logger = logging.getLogger(__name__)
# uuid is mandatory to store subscriptions
if 'uuid' not in kwargs:
raise SubscriptionsSaveError
headers = {'Content-type': 'application/json', 'Accept': 'application/json'}
endpoint = self.url + 'subscriptions/'
try:
response = requests.post(endpoint, remote_service='auto', data=json.dumps(subscriptions),
user=user, federation_key='email', params=kwargs, headers=headers)
if not response.json()['data']:
raise SubscriptionsSaveError
except HTTPError:
logger.error(u'set subscriptions on %s returned an HTTP error code: %s',
response.request.url, response.status_code)
raise SubscriptionsSaveError
except RequestException as e:
logger.error(u'set subscriptions on %s failed with exception: %s',
endpoint, e)
raise SubscriptionsSaveError
def render(self, context):
user = context.get('user')
if user and user.is_authenticated:
form = NewslettersManageForm(instance=self, request=context['request'])
context['form'] = form
return super(NewslettersCell, self).render(context)
def is_visible(self, user=None):
if user is None or not user.is_authenticated:
return False
return super(NewslettersCell, self).is_visible(user)