Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Christopher Valles
2014-02-25 18:15:24 +00:00
10 changed files with 65 additions and 77 deletions

View File

@@ -1,3 +0,0 @@
cookbook 'apt'
cookbook 'postgresql'
cookbook 'redash', git: 'git@github.com:EverythingMe/chef-redash.git'

View File

@@ -46,14 +46,8 @@ It's very likely that in the future we will switch to [D3.js](http://d3js.org/)
## Getting Started
1. Download the [latest release](https://github.com/everythingme/redash/releases).
2. Make sure you have `Python` v2.7, `pip`, PostgreSQL and Redis installed.
3. Install Python requirements: `pip install -r requirements.txt`.
4. Make a copy of the examples settings file: `cp redash/settings_example.py redash/settings.py` and edit the relevant settings.
5. Create database: `./manage.py database create_tables`.
6. Start the web server: `./manage.py runserver`.
7. Start the worker: `./manage.py runworker`.
8. Open `http://localhost:5000/` and query away.
* [Setting up re:dash on Heroku in 5 minutes](https://github.com/EverythingMe/redash/wiki/Setting-up-re:dash-on-Heroku-in-5-minutes)
* [Setting re:dash on your own server (Ubuntu)](https://github.com/EverythingMe/redash/wiki/Setting-re:dash-on-your-own-server-(Ubuntu))
**Need help setting re:dash or one of the dependencies up?** Ping @arikfr on the IRC #redash channel or send a message to the [mailing list](https://groups.google.com/forum/#!forum/redash-users), and he will gladly help.

60
Vagrantfile vendored
View File

@@ -1,60 +0,0 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = '2'
POSTGRES_PASSWORD = 'securepass'
# Currently, chef postgress cookbook works with cleartext paswords,
# unless the password begins with 'md5'
# See https://github.com/hw-cookbooks/postgresql/issues/95
require "digest/md5"
postgres_password_md5 = 'md5'+Digest::MD5.hexdigest(POSTGRES_PASSWORD+'postgres')
# After starting the vagrant machine, the application is accessible via the URL
# http://localhost:9999
HOST_PORT_TO_FORWARD_TO_REDASH = 9999
# Deploy direcly the code in parent dir; Don't download a release tarball
live_testing_deployment = true
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = 'ubuntu-precise-cloudimg-amd64'
config.vm.box_url = 'http://cloud-images.ubuntu.com/vagrant/precise/current/precise-server-cloudimg-amd64-vagrant-disk1.box'
if config.respond_to? :cache
config.cache.auto_detect = true
end
config.berkshelf.enabled = true
config.omnibus.chef_version = :latest
config.vm.network 'forwarded_port', guest: 8888, host: HOST_PORT_TO_FORWARD_TO_REDASH
if live_testing_deployment
config.vm.synced_folder "..", "/opt/redash"
end
config.vm.provision :chef_solo do |chef|
# run apt-get update before anything else (specifically postgresql)..
chef.add_recipe 'apt'
chef.add_recipe 'redash::redis_for_redash'
chef.add_recipe 'postgresql::client'
chef.add_recipe 'postgresql::server'
chef.add_recipe 'redash::redash_pg_schema'
chef.add_recipe 'redash::redash'
# chef.log_level = :debug
chef.json = {
'apt' => { 'compiletime' => true },
'postgresql' => { 'password' => {'postgres' => postgres_password_md5 } },
'redash' => { 'db' => {'host' => 'localhost',
'user' => 'postgres',
'password' => POSTGRES_PASSWORD },
'allow' => {'google_app_domain' => 'gmail.com',
'admins' => ['joe@egmail.com','jack@gmail.com']},
'install_tarball' => !live_testing_deployment,
'user' => live_testing_deployment ? 'vagrant' : 'redash'}
}
end
end

View File

@@ -1,8 +1,46 @@
(function () {
var DashboardCtrl = function ($scope, $routeParams, $http, Dashboard) {
var DashboardCtrl = function ($scope, $routeParams, $http, $timeout, Dashboard) {
$scope.refreshEnabled = false;
$scope.refreshRate = 60;
$scope.dashboard = Dashboard.get({slug: $routeParams.dashboardSlug}, function(dashboard) {
$scope.$parent.pageTitle = dashboard.name;
});
var autoRefresh = function() {
if ($scope.refreshEnabled) {
$timeout(function() {
Dashboard.get({slug: $routeParams.dashboardSlug}, function(dashboard) {
var newWidgets = _.groupBy(_.flatten(dashboard.widgets), 'id');
_.each($scope.dashboard.widgets, function(row) {
_.each(row, function(widget, i) {
var newWidget = newWidgets[widget.id];
if (newWidget && newWidget[0].visualization.query.latest_query_data_id != widget.visualization.query.latest_query_data_id ) {
row[i] = newWidget[0];
}
});
});
autoRefresh();
});
}, $scope.refreshRate);
};
}
$scope.triggerRefresh = function(){
$scope.refreshEnabled = !$scope.refreshEnabled;
if ($scope.refreshEnabled) {
var refreshRate = _.min(_.flatten($scope.dashboard.widgets), function(widget) {
return widget.visualization.query.ttl;
}).visualization.query.ttl;
$scope.refreshRate = _.max([120, refreshRate * 2])*1000;
autoRefresh();
}
};
};
var WidgetCtrl = function ($scope, $http, $location, Query) {
@@ -143,6 +181,7 @@
$scope.refreshOptions = [
{value: -1, name: 'No Refresh'},
{value: 60, name: 'Every minute'},
]
_.each(_.range(1, 13), function(i) {
@@ -390,7 +429,7 @@
}
angular.module('redash.controllers', [])
.controller('DashboardCtrl', ['$scope', '$routeParams', '$http', 'Dashboard', DashboardCtrl])
.controller('DashboardCtrl', ['$scope', '$routeParams', '$http', '$timeout', 'Dashboard', DashboardCtrl])
.controller('WidgetCtrl', ['$scope', '$http', '$location', 'Query', WidgetCtrl])
.controller('QueriesCtrl', ['$scope', '$http', '$location', '$filter', 'Query', QueriesCtrl])
.controller('QueryFiddleCtrl', ['$scope', '$window', '$location', '$routeParams', '$http', '$location', 'growl', 'notifications', 'Query', 'Visualization', QueryFiddleCtrl])

View File

@@ -213,4 +213,8 @@ to add those CSS styles here. */
color: white;
background-color: #FF8080;
border-radius: 50%;
}
visualization-renderer > div {
overflow: scroll;
}

View File

@@ -4,6 +4,8 @@
<div class="container">
<h2 id="dashboard_title">
{{dashboard.name}}
<button type="button" class="btn btn-default btn-xs" ng-class="{active: refreshEnabled}" tooltip="Enable/Disable Auto Refresh" ng-click="triggerRefresh()"><span class="glyphicon glyphicon-refresh"></span></button>
<span ng-show="dashboard.canEdit()">
<button type="button" class="btn btn-default btn-xs" data-toggle="modal" href="#edit_dashboard_dialog" tooltip="Edit Dashboard (Name/Layout)"><span
class="glyphicon glyphicon-cog"></span></button>

View File

@@ -33,7 +33,11 @@ def json_representation(data, code, headers=None):
redis_url = urlparse.urlparse(settings.REDIS_URL)
redis_connection = redis.StrictRedis(host=redis_url.hostname, port=redis_url.port, db=0, password=redis_url.password)
if redis_url.path:
redis_db = redis_url.path[1]
else:
redis_db = 0
redis_connection = redis.StrictRedis(host=redis_url.hostname, port=redis_url.port, db=redis_db, password=redis_url.password)
from redash import data
data_manager = data.Manager(redis_connection, db)

View File

@@ -158,7 +158,12 @@ class Manager(object):
runner = query_runner_mysql.mysql(connection_string)
elif connection_type == 'graphite':
from redash.data import query_runner_graphite
runner = query_runner_graphite.graphite(connection_string)
connection_params = json.loads(connection_string)
if connection_params['auth']:
connection_params['auth'] = tuple(connection_params['auth'])
else:
connection_params['auth'] = None
runner = query_runner_graphite.graphite(connection_params)
else:
from redash.data import query_runner
runner = query_runner.redshift(connection_string)

View File

@@ -43,7 +43,10 @@ def mysql(connection_string):
cursor.close()
except MySQLdb.Error, e:
json_data = None
error = e.message
error = e.args[1]
except KeyboardInterrupt:
error = "Query cancelled by user."
json_data = None
except Exception as e:
raise sys.exc_info()[1], None, sys.exc_info()[2]
finally:

View File

@@ -39,7 +39,7 @@ CONNECTION_ADAPTER = os.environ.get("REDASH_CONNECTION_ADAPTER", "pg")
# Connection string for the database that is used to run queries against. Examples:
# -- mysql: CONNECTION_STRING = "Server=;User=;Pwd=;Database="
# -- pg: CONNECTION_STRING = "user= password= host= port=5439 dbname="
# -- graphite: CONNECTION_STRING = {'url': 'https://graphite.yourcompany.com', 'auth': ('user', 'password'), 'verify': True}
# -- graphite: CONNECTION_STRING = {"url": "https://graphite.yourcompany.com", "auth": ["user", "password"], "verify": true}
CONNECTION_STRING = os.environ.get("REDASH_CONNECTION_STRING", "user= password= host= port=5439 dbname=")
# Connection settings for re:dash's own database (where we store the queries, results, etc)