1#!/usr/bin/env python3
 2
 3"""Schema retrieval."""
 4
 5import os
 6
 7from django.shortcuts import render
 8from django.urls import reverse
 9from django.http import HttpResponse
10
11from chart.project import settings
12from chart.common.exceptions import ConfigError
13from chart.common.path import Path
14
15mime_types = {'.xsd': 'application/xml',
16              '.rng': 'application/xml',
17              '.rnc': 'application/rnc'}
18
19
20def index(request):
21    """Show a table of available schemas with links to raw RNC, XSD files
22    and colourised HTML versions of RNC files.
23    """
24
25    if not settings.SCHEMA_DIR.is_dir():
26        raise ConfigError('Schema dir {d} is not a directory'.format(d=settings.SCHEMA_DIR))
27
28    schemas = []
29    for rnc_filename in settings.SCHEMA_DIR.glob('*.rnc'):
30        description = []
31        for line in rnc_filename.open('r').readlines():
32            # Extract a description from the top of the file.
33            # Only include lines starting with '#' and end at the first non-comment
34            # line.
35            sline = line.strip()
36            if sline.startswith('#'):
37                description.append(sline[1:].lstrip())
38            else:
39                break
40
41        rnc_basename = rnc_filename.name
42        schemas.append(dict(name=rnc_filename.stem.capitalize(),
43                            description=' '.join(description),
44                            rnc=rnc_basename,
45                            xsd=rnc_basename[:-3] + 'xsd',
46                            html=rnc_basename[:-3] + 'html'))
47
48    return render(request,
49                  'schemas/index.html',
50                  dict(schemas=schemas))
51
52
53def raw(request, filename):  # (unused arg) pylint: disable=W0613
54    """Return raw binary schema file."""
55    response = HttpResponse(content_type=mime_types[os.path.splitext(filename)[1]])
56    response.write(settings.SCHEMA_DIR.joinpath(filename).open('rb').read())
57    return response
58
59
60def html(request, filename):
61    """Return colourised RNC file."""
62    path = Path(filename)
63    xsd_filename = path.with_suffix('.xsd')
64    rnc_filename = path.with_suffix('.rnc')
65    from pygments import highlight
66    from pygments.lexers import get_lexer_for_filename
67    import pygments.formatters
68    # from pygments.formatters import HtmlFormatter
69    return render(
70        request,
71        'schemas/schema.html',
72        dict(
73            filename=rnc_filename,
74            xsd=reverse('schemas:raw', kwargs=dict(filename=xsd_filename.name)),
75            rnc=reverse('schemas:raw', kwargs=dict(filename=rnc_filename.name)),
76            content=highlight(
77                settings.SCHEMA_DIR.joinpath(rnc_filename).open('r').read(),
78                get_lexer_for_filename(rnc_filename.name),
79                pygments.formatters.HtmlFormatter(full=True))))