Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New macro: {{ url_param }} #2537

Merged
merged 1 commit into from
Apr 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
.. image:: _static/img/s.png

Superset's documentation
''''''''''''''''''''''''

Superset is a data exploration platform designed to be visual, intuitive
and interactive.


----------------

.. warning:: This project was originally named Panoramix, was renamed to
Expand Down
2 changes: 2 additions & 0 deletions docs/sqllab.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,5 @@ Superset's Jinja context:

.. autoclass:: superset.jinja_context.PrestoTemplateProcessor
:members:

.. autofunction:: superset.jinja_context.url_param
1 change: 1 addition & 0 deletions superset/assets/docs
Binary file added superset/assets/images/s.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion superset/assets/javascripts/SqlLab/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ export function fetchQueryResults(query) {
export function runQuery(query) {
return function (dispatch) {
dispatch(startQuery(query));
const sqlJsonUrl = '/superset/sql_json/';
const sqlJsonRequest = {
client_id: query.id,
database_id: query.dbId,
Expand All @@ -126,6 +125,7 @@ export function runQuery(query) {
tmp_table_name: query.tempTableName,
select_as_cta: query.ctas,
};
const sqlJsonUrl = '/superset/sql_json/' + location.search;
$.ajax({
type: 'POST',
dataType: 'json',
Expand Down
32 changes: 28 additions & 4 deletions superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
/* global notify */
import React from 'react';
import { Alert, Button, Col, Modal } from 'react-bootstrap';

import Select from 'react-select';
import { Table } from 'reactable';
import shortid from 'shortid';
import $ from 'jquery';
import { getExploreUrl } from '../../explorev2/exploreUtils';

const CHART_TYPES = [
{ value: 'dist_bar', label: 'Distribution - Bar Chart', requiresTime: false },
Expand Down Expand Up @@ -89,7 +91,9 @@ class VisualizeModal extends React.PureComponent {
}
}
if (!hasTime) {
hints.push('To use this chart type you need at least one column flagged as a date');
hints.push(
'To use this chart type you need at least one column ' +
'flagged as a date');
}
}
this.setState({ hints });
Expand All @@ -113,19 +117,39 @@ class VisualizeModal extends React.PureComponent {
chartType: this.state.chartType.value,
datasourceName: this.state.datasourceName,
columns: this.state.columns,
sql: this.props.query.executedSql,
sql: this.props.query.sql,
dbId: this.props.query.dbId,
};
notify.info('Creating a data source and popping a new tab');
$.ajax({
type: 'POST',
url: '/superset/sqllab_viz/',
async: false,
data: {
data: JSON.stringify(vizOptions),
},
success: (url) => {
window.open(url);
dataType: 'json',
success: resp => {
const columns = Object.keys(this.state.columns).map(k => this.state.columns[k]);
const data = JSON.parse(resp);
const mainMetric = columns.filter(d => d.agg)[0];
const mainGroupBy = columns.filter(d => d.is_dim)[0];
const formData = {
datasource: `${data.table_id}__table`,
viz_type: this.state.chartType.value,
since: '100 years ago',
limit: '0',
};
if (mainMetric) {
formData.metrics = [mainMetric.name];
formData.metric = mainMetric.name;
}
if (mainGroupBy) {
formData.groupby = mainGroupBy.name;
}
window.open(getExploreUrl(formData));
},
error: () => notify('An error occurred while creating the data source'),
});
}
changeDatasourceName(event) {
Expand Down
51 changes: 34 additions & 17 deletions superset/assets/javascripts/explorev2/exploreUtils.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,43 @@
/* eslint camelcase: 0 */
export function getExploreUrl(form_data, endpoint = 'base', force = false) {
import URI from 'urijs';

export function getExploreUrl(form_data, endpointType = 'base', force = false, curUrl = null) {
if (!form_data.datasource) {
return null;
}


// The search params from the window.location are carried through,
// but can be specified with curUrl (used for unit tests to spoof
// the window.location).
let uri = URI(window.location.search);
if (curUrl) {
uri = URI(URI(curUrl).search());
}

// Building the directory part of the URI
let directory = '/superset/explore/';
if (['json', 'csv', 'query'].indexOf(endpointType) >= 0) {
directory = '/superset/explore_json/';
}
const [datasource_id, datasource_type] = form_data.datasource.split('__');
let params = `${datasource_type}/${datasource_id}/`;
params += '?form_data=' + encodeURIComponent(JSON.stringify(form_data));
directory += `${datasource_type}/${datasource_id}/`;

// Building the querystring (search) part of the URI
const search = uri.search(true);
search.form_data = JSON.stringify(form_data);
if (force) {
params += '&force=true';
search.force = 'true';
}
if (endpointType === 'csv') {
search.csv = 'true';
}
if (endpointType === 'standalone') {
search.standalone = 'true';
}
switch (endpoint) {
case 'base':
return `/superset/explore/${params}`;
case 'json':
return `/superset/explore_json/${params}`;
case 'csv':
return `/superset/explore_json/${params}&csv=true`;
case 'standalone':
return `/superset/explore/${params}&standalone=true`;
case 'query':
return `/superset/explore_json/${params}&query=true`;
default:
return `/superset/explore/${params}`;
if (endpointType === 'query') {
search.query = 'true';
}
uri = uri.search(search).directory(directory);
return uri.toString();
}
59 changes: 59 additions & 0 deletions superset/assets/spec/javascripts/explorev2/utils_spec.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { it, describe } from 'mocha';
import { expect } from 'chai';
import URI from 'urijs';
import { getExploreUrl } from '../../../javascripts/explorev2/exploreUtils.js';

describe('utils', () => {
const formData = {
datasource: '1__table',
};
const sFormData = JSON.stringify(formData);
function compareURI(uri1, uri2) {
expect(uri1.toString()).to.equal(uri2.toString());
}

it('getExploreUrl generates proper base url', () => {
// This assertion is to show clearly the value of location.href
// in the context of unit tests.
expect(location.href).to.equal('about:blank');

compareURI(
URI(getExploreUrl(formData, 'base', false, 'http://superset.com')),
URI('/superset/explore/table/1/').search({ form_data: sFormData })
);
});
it('getExploreUrl generates proper json url', () => {
compareURI(
URI(getExploreUrl(formData, 'json', false, 'superset.com')),
URI('/superset/explore_json/table/1/').search({ form_data: sFormData })
);
});
it('getExploreUrl generates proper json forced url', () => {
compareURI(
URI(getExploreUrl(formData, 'json', true, 'superset.com')),
URI('/superset/explore_json/table/1/')
.search({ form_data: sFormData, force: 'true' })
);
});
it('getExploreUrl generates proper csv URL', () => {
compareURI(
URI(getExploreUrl(formData, 'csv', false, 'superset.com')),
URI('/superset/explore_json/table/1/')
.search({ form_data: sFormData, csv: 'true' })
);
});
it('getExploreUrl generates proper standalone URL', () => {
compareURI(
URI(getExploreUrl(formData, 'standalone', false, 'superset.com')),
URI('/superset/explore/table/1/')
.search({ form_data: sFormData, standalone: 'true' })
);
});
it('getExploreUrl preserves main URLs params', () => {
compareURI(
URI(getExploreUrl(formData, 'json', false, 'superset.com?foo=bar')),
URI('/superset/explore_json/table/1/')
.search({ foo: 'bar', form_data: sFormData })
);
});
});
17 changes: 16 additions & 1 deletion superset/jinja_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import inspect
from jinja2.sandbox import SandboxedEnvironment
from flask import request

from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
Expand All @@ -27,6 +28,18 @@
BASE_CONTEXT.update(config.get('JINJA_CONTEXT_ADDONS', {}))


def url_param(param, default=None):
"""Get a url paramater

:param param: the url parameter to lookup
:type param: str
:param default: the value to return in the absence of the parameter
:type default: str
"""
print(request.args)
return request.args.get(param, default)


class BaseTemplateProcessor(object):

"""Base class for database-specific jinja context
Expand All @@ -52,7 +65,9 @@ def __init__(self, database=None, query=None, table=None, **kwargs):
self.schema = query.schema
elif table:
self.schema = table.schema
self.context = {}
self.context = {
'url_param': url_param,
}
self.context.update(kwargs)
self.context.update(BASE_CONTEXT)
if self.engine:
Expand Down
5 changes: 4 additions & 1 deletion superset/sql_parse.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import logging

import sqlparse
from sqlparse.sql import IdentifierList, Identifier
from sqlparse.tokens import DML, Keyword, Name
from sqlparse.tokens import Keyword, Name

RESULT_OPERATIONS = {'UNION', 'INTERSECT', 'EXCEPT'}
PRECEDES_TABLE_NAME = {'FROM', 'JOIN', 'DESC', 'DESCRIBE', 'WITH'}
Expand All @@ -13,6 +15,7 @@ def __init__(self, sql_statement):
self._table_names = set()
self._alias_names = set()
# TODO: multistatement support
logging.info("Parsing with sqlparse statement {}".format(self.sql))
self._parsed = sqlparse.parse(self.sql)
for statement in self._parsed:
self.__extract_from_token(statement)
Expand Down
14 changes: 3 additions & 11 deletions superset/views/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1710,7 +1710,6 @@ def sqllab_viz(self):
SqlaTable = ConnectorRegistry.sources['table']
data = json.loads(request.form.get('data'))
table_name = data.get('datasourceName')
viz_type = data.get('chartType')
SqlaTable = ConnectorRegistry.sources['table']
table = (
db.session.query(SqlaTable)
Expand Down Expand Up @@ -1762,16 +1761,9 @@ def sqllab_viz(self):
table.columns = cols
table.metrics = metrics
db.session.commit()
params = {
'viz_type': viz_type,
'groupby': dims[0].column_name if dims else None,
'metrics': metrics[0].metric_name if metrics else None,
'metric': metrics[0].metric_name if metrics else None,
'since': '100 years ago',
'limit': '0',
}
params = "&".join([k + '=' + v for k, v in params.items() if v])
return '/superset/explore/table/{table.id}/?{params}'.format(**locals())
return self.json_response(json.dumps({
'table_id': table.id,
}))

@has_access
@expose("/table/<database_id>/<table_name>/<schema>/")
Expand Down