/usr/lib/python2.7/dist-packages/chartkick/templatetags/chartkick.py is in python-chartkick 0.5.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | from __future__ import absolute_import
import os
import ast
import json
import functools
import itertools
from django import template
from django.template import Engine
from django.template.loaders.filesystem import Loader
from ..template import CHART_HTML
from ..options import Options
register = template.Library()
class ChartNode(template.Node):
id = itertools.count()
_library = None
def __init__(self, name, variable, options=None):
self.name = name
self.variable = template.Variable(variable)
self.options = options or {}
for name, value in self.options.items():
try:
self.options[name] = ast.literal_eval(value)
except ValueError:
self.options[name] = template.Variable(value)
except SyntaxError as e:
raise template.TemplateSyntaxError(e)
def render(self, context):
for name, value in self.options.items():
if isinstance(value, template.Variable):
self.options[name] = value.resolve(context)
options = dict(id='chart-%s' % next(self.id), height='300px')
id = self.options.get('id', None) or options['id']
# apply options from chartkick.json
options.update(library=self.library(id))
# apply options from a tag
options.update(self.options)
data = json.dumps(self.variable.resolve(context))
return CHART_HTML.format(name=self.name, data=data,
options=json.dumps(options), **options)
@classmethod
def library(cls, chart_id):
if cls._library is None:
loader = Loader(Engine())
for filename in loader.get_template_sources('chartkick.json'):
if os.path.exists(filename):
oprtions = Options()
oprtions.load(filename)
cls._library = oprtions
break
else:
cls._library = Options()
return cls._library.get(chart_id, {})
def chart(name, parser, token):
args = token.split_contents()
if len(args) < 2:
raise template.TemplateSyntaxError(
'%r statement requires at least one argument' %
token.split_contents()[0])
options = None
if len(args) > 2:
if args[2] != 'with':
raise template.TemplateSyntaxError("Expected 'with' statement")
try:
options = parse_options(' '.join(args[3:]))
except ValueError:
raise template.TemplateSyntaxError('Invalid options')
return ChartNode(name=name, variable=args[1], options=options)
def parse_options(source):
"""parses chart tag options"""
options = {}
tokens = [t.strip() for t in source.split('=')]
name = tokens[0]
for token in tokens[1:-1]:
value, next_name = token.rsplit(' ', 1)
options[name.strip()] = value
name = next_name
options[name.strip()] = tokens[-1].strip()
return options
register.tag('line_chart', functools.partial(chart, 'LineChart'))
register.tag('pie_chart', functools.partial(chart, 'PieChart'))
register.tag('column_chart', functools.partial(chart, 'ColumnChart'))
register.tag('bar_chart', functools.partial(chart, 'BarChart'))
register.tag('area_chart', functools.partial(chart, 'AreaChart'))
|