combo/combo/apps/wcs/models.py

322 lines
12 KiB
Python

# 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 <http://www.gnu.org/licenses/>.
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)