mirror of
https://github.com/valitydev/redash.git
synced 2024-11-07 09:28:51 +00:00
Merge pull request #484 from alexanderlz/master
Feature: Google Spreadsheets support (alpha)
This commit is contained in:
commit
58a005c71b
@ -154,7 +154,9 @@
|
||||
|
||||
updateSchema();
|
||||
$scope.dataSource = _.find($scope.dataSources, function(ds) { return ds.id == $scope.query.data_source_id; });
|
||||
$scope.executeQuery();
|
||||
if ($scope.query.query) {
|
||||
$scope.executeQuery();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.setVisualizationTab = function (visualization) {
|
||||
|
116
redash/query_runner/google_spreadsheets.py
Normal file
116
redash/query_runner/google_spreadsheets.py
Normal file
@ -0,0 +1,116 @@
|
||||
import json
|
||||
import logging
|
||||
import sys
|
||||
from redash.query_runner import *
|
||||
from redash.utils import JSONEncoder
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
import gspread
|
||||
from oauth2client.client import SignedJwtAssertionCredentials
|
||||
from dateutil import parser
|
||||
enabled = True
|
||||
except ImportError:
|
||||
logger.warning("Missing dependencies. Please install gspread, dateutil and oauth2client.")
|
||||
logger.warning("You can use pip: pip install gspread dateutil oauth2client")
|
||||
|
||||
enabled = False
|
||||
|
||||
|
||||
def _load_key(filename):
|
||||
with open(filename, "rb") as f:
|
||||
return json.loads(f.read())
|
||||
|
||||
|
||||
def _guess_type(value):
|
||||
try:
|
||||
val = int(value)
|
||||
return TYPE_INTEGER, val
|
||||
except ValueError:
|
||||
pass
|
||||
try:
|
||||
val = float(value)
|
||||
return TYPE_FLOAT, val
|
||||
except ValueError:
|
||||
pass
|
||||
if str(value).lower() in ('true', 'false'):
|
||||
return TYPE_BOOLEAN, bool(value)
|
||||
try:
|
||||
val = parser.parse(value)
|
||||
return TYPE_DATETIME, val
|
||||
except ValueError:
|
||||
pass
|
||||
return TYPE_STRING, value
|
||||
|
||||
|
||||
class GoogleSpreadsheet(BaseQueryRunner):
|
||||
HEADER_INDEX = 0
|
||||
|
||||
@classmethod
|
||||
def annotate_query(cls):
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def type(cls):
|
||||
return "google_spreadsheets"
|
||||
|
||||
@classmethod
|
||||
def enabled(cls):
|
||||
return enabled
|
||||
|
||||
@classmethod
|
||||
def configuration_schema(cls):
|
||||
return {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'credentialsFilePath': {
|
||||
'type': 'string',
|
||||
'title': 'Credentials File Path'
|
||||
}
|
||||
},
|
||||
'required': ['credentialsFilePath']
|
||||
}
|
||||
|
||||
def __init__(self, configuration_json):
|
||||
super(GoogleSpreadsheet, self).__init__(configuration_json)
|
||||
|
||||
def _get_spreadsheet_service(self):
|
||||
scope = [
|
||||
'https://spreadsheets.google.com/feeds',
|
||||
]
|
||||
|
||||
cred_file = _load_key(self.configuration['credentialsFilePath'])
|
||||
credentials = SignedJwtAssertionCredentials(cred_file['client_email'], cred_file["private_key"], scope=scope)
|
||||
spreadsheetservice = gspread.authorize(credentials)
|
||||
return spreadsheetservice
|
||||
|
||||
def run_query(self, query):
|
||||
logger.debug("Spreadsheet is about to execute query: %s", query)
|
||||
values = query.split("|")
|
||||
key = values[0] #key of the spreadsheet
|
||||
worksheet_num = 0 if len(values != 2) else int(values[1])# if spreadsheet contains more than one worksheet - this is the number of it
|
||||
try:
|
||||
spreadsheet_service = self._get_spreadsheet_service()
|
||||
spreadsheet = spreadsheet_service.open_by_key(key)
|
||||
worksheets = spreadsheet.worksheets()
|
||||
all_data = worksheets[worksheet_num].get_all_values()
|
||||
column_names = []
|
||||
columns = []
|
||||
for j, column_name in enumerate(all_data[self.HEADER_INDEX]):
|
||||
column_names.append(column_name)
|
||||
columns.append({
|
||||
'name': column_name,
|
||||
'friendly_name': column_name,
|
||||
'type': _guess_type(all_data[self.HEADER_INDEX+1][j])
|
||||
})
|
||||
rows = [dict(zip(column_names, row)) for row in all_data[self.HEADER_INDEX+1:]]
|
||||
data = {'columns': columns, 'rows': rows}
|
||||
json_data = json.dumps(data, cls=JSONEncoder)
|
||||
error = None
|
||||
except Exception as e:
|
||||
raise sys.exc_info()[1], None, sys.exc_info()[2]
|
||||
|
||||
return json_data, error
|
||||
|
||||
register(GoogleSpreadsheet)
|
@ -92,6 +92,7 @@ ACCESS_CONTROL_ALLOW_HEADERS = os.environ.get("REDASH_CORS_ACCESS_CONTROL_ALLOW_
|
||||
# Query Runners
|
||||
QUERY_RUNNERS = array_from_string(os.environ.get("REDASH_ENABLED_QUERY_RUNNERS", ",".join([
|
||||
'redash.query_runner.big_query',
|
||||
'redash.query_runner.google_spreadsheets',
|
||||
'redash.query_runner.graphite',
|
||||
'redash.query_runner.mongodb',
|
||||
'redash.query_runner.mysql',
|
||||
|
Loading…
Reference in New Issue
Block a user