Source code for aristotle_mdr.views.downloads

from django.apps import apps
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.conf import settings
from django.core.exceptions import PermissionDenied, ImproperlyConfigured
from django.core.urlresolvers import reverse
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.shortcuts import render, redirect, get_object_or_404
from django.template import RequestContext, TemplateDoesNotExist
from django.template.defaultfilters import slugify
from django.template.loader import select_template
from django.utils.translation import ugettext_lazy as _
import re

from aristotle_mdr.perms import user_can_view
from aristotle_mdr import perms
from aristotle_mdr.utils import cache_per_item_user
from aristotle_mdr import forms as MDRForms
from aristotle_mdr import models as MDR
from aristotle_mdr.views import get_if_user_can_view
from aristotle_mdr.utils.downloads import get_download_module

import logging

logger = logging.getLogger(__name__)
logger.debug("Logging started for " + __name__)

PAGES_PER_RELATED_ITEM = 15


[docs]def download(request, download_type, iid=None): """ By default, ``aristotle_mdr.views.download`` is called whenever a URL matches the pattern defined in ``aristotle_mdr.urls_aristotle``:: download/(?P<download_type>[a-zA-Z0-9\-\.]+)/(?P<iid>\d+)/? This is passed into ``download`` which resolves the item id (``iid``), and determines if a user has permission to view the requested item with that id. If a user is allowed to download this file, ``download`` iterates through each download type defined in ``ARISTOTLE_DOWNLOADS``. A download option tuple takes the following form form:: ('file_type','display_name','font_awesome_icon_name','module_name'), With ``file_type`` allowing only ASCII alphanumeric and underscores, ``display_name`` can be any valid python string, ``font_awesome_icon_name`` can be any Font Awesome icon and ``module_name`` is the name of the python module that provides a downloader for this file type. For example, included with Aristotle-MDR is a PDF downloader which has the download definition tuple:: ('pdf','PDF','fa-file-pdf-o','aristotle_mdr'), Where a ``file_type`` multiple is defined multiple times, **the last matching instance in the tuple is used**. Next, the module that is defined for a ``file_type`` is dynamically imported using ``exec``, and is wrapped in a ``try: except`` block to catch any exceptions. If the ``module_name`` does not match the regex ``^[a-zA-Z0-9\_]+$`` ``download`` raises an exception. If the module is able to be imported, ``downloader.py`` from the given module is imported, this file **MUST** have a ``download`` function defined which returns a Django ``HttpResponse`` object of some form. """ item = MDR._concept.objects.get_subclass(pk=iid) item = get_if_user_can_view(item.__class__, request.user, iid) if not item: if request.user.is_anonymous(): return redirect(reverse('friendly_login') + '?next=%s' % request.path) else: raise PermissionDenied downloadOpts = getattr(settings, 'ARISTOTLE_DOWNLOADS', "") module_name = "" for d in downloadOpts: dt = d[0] if dt == download_type: module_name = d[3] if not re.search('^[a-zA-Z0-9\-\.]+$', download_type): # pragma: no cover # Invalid download_type raise registry_exceptions.BadDownloadTypeAbbreviation("Download type can only be composed of letters, numbers, hyphens or periods.") if module_name: downloader = get_download_module(module_name) try: return downloader.download(request, download_type, item) except TemplateDoesNotExist: debug = getattr(settings, 'DEBUG') if debug: raise raise Http404 raise Http404
def bulk_download(request, download_type, items=None): """ By default, ``aristotle_mdr.views.bulk_download`` is called whenever a URL matches the pattern defined in ``aristotle_mdr.urls_aristotle``:: bulk_download/(?P<download_type>[a-zA-Z0-9\-\.]+)/? This is passed into ``bulk_download`` which takes the items GET arguments from the request and determines if a user has permission to view the requested items. For any items the user can download they are exported in the desired format as described in ``aristotle_mdr.views.download``. If the requested module is able to be imported, ``downloader.py`` from the given module is imported, this file **MUST** have a ``bulk_download`` function defined which returns a Django ``HttpResponse`` object of some form. """ items=[] for iid in request.GET.getlist('items'): item = MDR._concept.objects.get_subclass(pk=iid) item = get_if_user_can_view(item.__class__, request.user, iid) items.append(item) downloadOpts = getattr(settings, 'ARISTOTLE_DOWNLOADS', "") module_name = "" for d in downloadOpts: dt = d[0] if dt == download_type: module_name = d[3] if not re.search('^[a-zA-Z0-9\-\.]+$', download_type): # pragma: no cover # Invalid download_type raise registry_exceptions.BadDownloadTypeAbbreviation("Download type can only be composed of letters, numbers, hyphens or periods.") if module_name: downloader = get_download_module(module_name) try: return downloader.bulk_download(request, download_type, items) except TemplateDoesNotExist: debug = getattr(settings, 'DEBUG') if debug: raise raise Http404 raise Http404