# combo - content management system # Copyright (C) 2014-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 . import urllib from django import template from django.db import models from django.forms import models as model_forms from django.forms import Select from django.utils.translation import ugettext_lazy as _ import cmsplugin_blurp.utils from jsonfield import JSONField from combo.data.models import CellBase from combo.data.library import register_cell_class from combo.utils import NothingInCacheException from .utils import get_wcs_json, is_wcs_enabled, get_wcs_services @register_cell_class class WcsFormCell(CellBase): formdef_reference = models.CharField(_('Form'), max_length=150) cached_title = models.CharField(_('Title'), max_length=150) cached_url = models.URLField(_('URL')) cached_json = JSONField(blank=True) is_enabled = classmethod(is_wcs_enabled) class Meta: verbose_name = _('Form Link') def get_default_form_class(self): from .forms import WcsFormCellForm return WcsFormCellForm def save(self, *args, **kwargs): if self.formdef_reference: wcs_key, form_slug = self.formdef_reference.split(':') wcs_site = get_wcs_services().get(wcs_key) forms_response_json = get_wcs_json(wcs_site.get('url'), 'json') for form in forms_response_json: slug = form.get('slug') if slug == form_slug: self.cached_title = form.get('title') self.cached_url = form.get('url') self.cached_json = form return super(WcsFormCell, self).save(*args, **kwargs) def render(self, context): formdef_template = template.loader.get_template('combo/wcs/form.html') context['slug'] = self.formdef_reference.split(':')[-1] context['title'] = self.cached_title context['url'] = self.cached_url if self.cached_json: for attribute in self.cached_json: if not attribute in context: context[attribute] = self.cached_json.get(attribute) return formdef_template.render(context) def get_additional_label(self): if not self.cached_title: return return self.cached_title class WcsCommonCategoryCell(CellBase): is_enabled = classmethod(is_wcs_enabled) category_reference = models.CharField(_('Category'), max_length=150) cached_title = models.CharField(_('Title'), max_length=150) cached_description = models.TextField(_('Description'), blank=True) cached_url = models.URLField(_('Cached URL')) class Meta: abstract = True def save(self, *args, **kwargs): if self.category_reference: wcs_key, category_slug = self.category_reference.split(':') wcs_site = get_wcs_services().get(wcs_key) categories_response_json = get_wcs_json(wcs_site.get('url'), 'categories') for category in categories_response_json.get('data'): slug = category.get('slug') if slug == category_slug: self.cached_title = category.get('title') self.cached_description = category.get('description') or '' self.cached_url = category.get('url') return super(WcsCommonCategoryCell, self).save(*args, **kwargs) def get_additional_label(self): if not self.cached_title: return return self.cached_title @register_cell_class class WcsCategoryCell(WcsCommonCategoryCell): class Meta: verbose_name = _('Category Link') def get_default_form_class(self): from .forms import WcsCategoryCellForm return WcsCategoryCellForm def render(self, context): category_template = template.loader.get_template('combo/wcs/category.html') context['slug'] = self.category_reference.split(':')[-1] context['title'] = self.cached_title context['description'] = self.cached_description context['url'] = self.cached_url return category_template.render(context) class WcsBlurpMixin(object): is_enabled = classmethod(is_wcs_enabled) user_dependant = True def get_blurp_renderer(self, context): if self.wcs_site: try: wcs_sites = {self.wcs_site: get_wcs_services()[self.wcs_site]} except KeyError: # in case of the site disappeared from settings return cmsplugin_blurp.utils.create_renderer(self.variable_name, { 'class': 'cmsplugin_blurp.renderers.template.Renderer', 'template': '' }) else: wcs_sites = get_wcs_services() sources = [] for slug, wcs_site in wcs_sites.items(): url = wcs_site.get('url') if not url.endswith('/'): url += '/' source = { 'slug': slug, 'parser_type': 'json', 'verify_certificate': False, 'allow_redirects': False, 'default': {'title': wcs_site['title'], 'base_url': url} } url += self.api_url + '?format=json' if context.get('user'): url += '&orig=%s' % wcs_site.get('orig') source['auth_mech'] = 'hmac-sha1' source['signature_key'] = str(wcs_site.get('secret', '')) if context.get('request') and hasattr(context['request'], 'session') \ and context['request'].session.get('mellon_session'): mellon = context['request'].session['mellon_session'] nameid = mellon['name_id_content'] url += '&NameID=' + urllib.quote(nameid) elif hasattr(context['user'], 'email') and context['user'].email: url += '&email=' + urllib.quote(context['user'].email) source['url'] = url sources.append(source) renderer = cmsplugin_blurp.utils.create_renderer(self.variable_name, { 'name': self._meta.verbose_name, 'class': 'cmsplugin_blurp.renderers.data_source.DictRendererWithDefault', 'sources': sources, 'template_name': self.template_name, 'refresh': 10, 'ajax': False, }) if not context.get('ajax') and not renderer.has_cached_content(context): raise NothingInCacheException() return renderer class WcsDataBaseCell(CellBase, WcsBlurpMixin): is_enabled = classmethod(is_wcs_enabled) wcs_site = models.CharField(_('Site'), max_length=50, blank=True) class Meta: abstract = True def get_default_form_class(self): if len(get_wcs_services()) == 1: return None combo_wcs_sites = [('', _('All'))] combo_wcs_sites.extend([(x, y.get('title')) for x, y in get_wcs_services().items()]) return model_forms.modelform_factory(self.__class__, fields=['wcs_site'], widgets={'wcs_site': Select(choices=combo_wcs_sites)}) def render(self, context): renderer = self.get_blurp_renderer(context) template = renderer.render_template() context = renderer.render(context) return template.render(context) @register_cell_class class WcsCurrentFormsCell(WcsDataBaseCell): api_url = 'myspace/forms' variable_name = 'current_forms' template_name = 'combo/wcs/current_forms.html' class Meta: verbose_name = _('Current Forms') @register_cell_class class WcsCurrentDraftsCell(WcsDataBaseCell): api_url = 'myspace/drafts' variable_name = 'current_drafts' template_name = 'combo/wcs/current_drafts.html' class Meta: verbose_name = _('Current Drafts') @register_cell_class class WcsFormsOfCategoryCell(WcsCommonCategoryCell, WcsBlurpMixin): ordering = models.CharField(_('Order'), max_length=20, default='', blank=True, choices=[('', _('Default')), ('alpha', _('Alphabetical')), ('popularity', _('Popularity'))]) limit = models.PositiveSmallIntegerField(_('Limit'), null=True, blank=True) class Meta: verbose_name = _('Forms of Category') variable_name = 'forms' template_name = 'combo/wcs/forms_of_category.html' def get_default_form_class(self): from .forms import WcsFormsOfCategoryCellForm return WcsFormsOfCategoryCellForm @property def wcs_site(self): return self.category_reference.split(':')[0] @property def api_url(self): return self.category_reference.split(':')[1] + '/json' def render(self, context): renderer = self.get_blurp_renderer(context) template = renderer.render_template() context = renderer.render(context) context['slug'] = self.category_reference.split(':')[-1] context['title'] = self.cached_title context['description'] = self.cached_description context['forms'] = list(context['forms'][self.wcs_site]['data']) if self.ordering == 'alpha': context['forms'] = sorted(context['forms'], lambda x, y: cmp(x.get('title'), y.get('title'))) elif self.ordering == 'popularity': context['forms'] = sorted(context['forms'], lambda x, y: -cmp(x.get('count'), y.get('count'))) if self.limit: if len(context['forms']) > self.limit: context['more_forms'] = True context['forms'] = context['forms'][:self.limit] return template.render(context) @register_cell_class class CategoriesCell(WcsDataBaseCell): api_url = 'categories' variable_name = 'form_categories' template_name = 'combo/wcs/form_categories.html' class Meta: verbose_name = _('Form Categories') def render(self, context): renderer = self.get_blurp_renderer(context) template = renderer.render_template() context = renderer.render(context) return template.render(context) @register_cell_class class TrackingCodeInputCell(CellBase): is_enabled = classmethod(is_wcs_enabled) wcs_site = models.CharField(_('Site'), max_length=50, blank=True) template_name = 'combo/wcs/tracking_code_input.html' class Meta: verbose_name = _('Tracking Code Input') def get_default_form_class(self): if len(get_wcs_services()) == 1: return None combo_wcs_sites = [(x, y.get('title')) for x, y in get_wcs_services().items()] return model_forms.modelform_factory(self.__class__, fields=['wcs_site'], widgets={'wcs_site': Select(choices=combo_wcs_sites)}) def render(self, context): tmpl = template.loader.get_template(self.template_name) if not self.wcs_site: self.wcs_site = get_wcs_services().keys()[0] context['url'] = get_wcs_services().get(self.wcs_site).get('url') return tmpl.render(context)