Adding new download formats

While the Aristotle-MDR framework includes PDF download capability, it may be desired to download metadata stored within a registry in a variety of download formats. Rather than include these within the Aristotle-MDR core codebase, additional download formats can be developed included via the download API.

Creating a download module

A download module is just a specialised Django app that includes a specific set of files for generating downloads. The files required in your app are:

  • __init__.py - to declare the app as a python module
  • downloader.py - for defining your main download method

Other modules can be written, for example a download module may define models for recording a number of times an item is downloaded.

Writing a downloader.py module

Your downloader.py file must contain a register of download types and the metadata concept types which this module provides downloads for. This takes the form of a dictionary with keys being the download type provided, and the values define which concepts can be downloaded as that output format:

item_register = {
    'csv': {'aristotle_mdr': ['valuedomain']},
    'xls': {'aristotle_mdr': ['__all__']},
    'pdf': '__template__'
    'txt': '__all__'
}

Describing these options, this register specifies the following downloads:

  • csv provides downloads for Value Domains in the Aristotle-MDR module
  • xls provides downloads for all metadata types in the Aristotle-MDR module
  • pdf provides downloads for items in all modules, only if they have a download template
  • txt provides downloads for all metadata types in all modules

The download module must also define a method with the following signature:

def download(request, download_type, item):

This is called from Aristotle-MDR when it catches a download type that has been registered for this module. The arguments are:

  • request - the request object that was used to call the download view. The current user trying to download the item can be gotten by calling request.user.
  • download_type - a short string used to differentiate different download formats
  • item - the item to be downloaded, as retrieved from the database.

Note: If a download method is called the user has been verified to have permissions to view the requested item only. Permissions for other items will have to be checked within the download method.

For an example of how to handle multiple download formats in a single module, review the aristotle_mdr.downloader module which provides downloads in the PDF and CSV format for various content types which is linked below:

aristotle_mdr.downloader.download(request, download_type, item)[source]

Built in download method

How the download view works

aristotle_mdr.views.downloads.download(request, download_type, iid=None)[source]

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.