147 lines
4.8 KiB
Python
147 lines
4.8 KiB
Python
# combo - content management system
|
|
# Copyright (C) 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 requests
|
|
from requests.exceptions import RequestException
|
|
import urlparse
|
|
|
|
from django.conf import settings
|
|
|
|
|
|
def get_requests_params():
|
|
return getattr(settings, 'CUBES_REQUEST_PARAMS', {})
|
|
|
|
|
|
def get_cubes():
|
|
try:
|
|
r = requests.get(urlparse.urljoin(settings.CUBES_URL, 'cubes'), **get_requests_params)
|
|
except RequestException:
|
|
return []
|
|
try:
|
|
return r.json()
|
|
except ValueError:
|
|
return []
|
|
|
|
|
|
def get_cube(name):
|
|
model_url = urlparse.urljoin(settings.CUBES_URL, 'cube/%s/model' % name)
|
|
try:
|
|
r = requests.get(model_url, **get_requests_params)
|
|
except RequestException:
|
|
return None
|
|
try:
|
|
return r.json()
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
def get_drilldown(name):
|
|
cube = get_cube(name)
|
|
if not cube:
|
|
return []
|
|
l = []
|
|
for dimension in cube.get('dimensions', []):
|
|
dim_name = dimension['name']
|
|
dim_label = dimension.get('label') or dim_name
|
|
if dimension.get('levels'):
|
|
levels = {}
|
|
for level in dimension['levels']:
|
|
levels[level['name']] = level.get('label') or level['name']
|
|
if dimension.get('hierarchies'):
|
|
for hierarchy in dimension['hierarchies']:
|
|
h_name = hierarchy['name']
|
|
h_label = hierarchy.get('label') or h_name
|
|
if h_name == 'default':
|
|
h_label = ''
|
|
for level in hierarchy['levels']:
|
|
labels = filter(None, [dim_label, h_label, levels[level]])
|
|
label = ' - '.join(labels)
|
|
name = '%s@%s:%s' % (dim_name, h_name, level)
|
|
l.append((name, label))
|
|
else:
|
|
raise NotImplementedError
|
|
else:
|
|
l.append((dim_name, dim_label))
|
|
return l
|
|
|
|
|
|
def compute_levels(cube, drilldown, key_refs=None, label_refs=None):
|
|
from .utils import get_attribute_ref
|
|
dim = drilldown.split('@')[0]
|
|
hier = drilldown.split('@')[1].split(':')[0]
|
|
lev = drilldown.split(':')[1]
|
|
|
|
for dimension in cube['dimensions']:
|
|
if dimension['name'] != dim:
|
|
continue
|
|
level_label_refs = {}
|
|
level_key_refs = {}
|
|
for level in dimension['levels']:
|
|
level_key_refs[level['name']] = get_attribute_ref(level, level['key'])
|
|
level_label_refs[level['name']] = get_attribute_ref(level, level['label_attribute'])
|
|
for hierarchy in dimension['hierarchies']:
|
|
if hierarchy['name'] != hier:
|
|
continue
|
|
for level in hierarchy['levels']:
|
|
if key_refs is not None:
|
|
key_refs.append(level_key_refs[level])
|
|
if label_refs is not None:
|
|
label_refs.append(level_label_refs[level])
|
|
if level == lev:
|
|
break
|
|
break
|
|
break
|
|
|
|
|
|
def get_aggregate(name, aggregate1, drilldown1, drilldown2, other_parameters=None):
|
|
if not name:
|
|
return None
|
|
cube = get_cube(name)
|
|
aggregate_url = urlparse.urljoin(settings.CUBES_URL, 'cube/%s/aggregate' % name)
|
|
if not aggregate1:
|
|
return None
|
|
try:
|
|
params = {'aggregate': aggregate1}
|
|
drilldowns = []
|
|
key_refs = []
|
|
if drilldown1:
|
|
compute_levels(cube, drilldown1, key_refs=key_refs)
|
|
drilldowns.append(drilldown1)
|
|
if drilldown2:
|
|
compute_levels(cube, drilldown2, key_refs=key_refs)
|
|
drilldowns.append(drilldown2)
|
|
if drilldowns:
|
|
params['drilldown'] = drilldowns
|
|
|
|
if key_refs:
|
|
params['order'] = key_refs
|
|
if other_parameters:
|
|
params.update(other_parameters)
|
|
|
|
r = requests.get(aggregate_url, params=params, **get_requests_params)
|
|
except RequestException:
|
|
return None
|
|
try:
|
|
return r.json()
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
def get_attribute_ref(level, name):
|
|
for attribute in level['attributes']:
|
|
if attribute['name'] == name:
|
|
return attribute['ref']
|