Skip to content

Commit

Permalink
[url shortener] initial prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
BigFunger committed Nov 24, 2015
1 parent 43b9d65 commit 25c6627
Show file tree
Hide file tree
Showing 14 changed files with 310 additions and 23 deletions.
27 changes: 17 additions & 10 deletions src/plugins/kibana/public/dashboard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ define(function (require) {
require('ui/config');
require('ui/notify');
require('ui/typeahead');
require('ui/share');

require('plugins/kibana/dashboard/directives/grid');
require('plugins/kibana/dashboard/components/panel/panel');
Expand All @@ -25,7 +26,8 @@ define(function (require) {
'kibana/courier',
'kibana/config',
'kibana/notify',
'kibana/typeahead'
'kibana/typeahead',
'kibana/share'
]);

require('ui/routes')
Expand Down Expand Up @@ -90,6 +92,7 @@ define(function (require) {
var $uiState = $scope.uiState = $state.makeStateful('uiState');

$scope.$watchCollection('state.options', function (newVal, oldVal) {
//console.log('watch state.options');
if (!angular.equals(newVal, oldVal)) $state.save();
});
$scope.$watch('state.options.darkTheme', setDarkTheme);
Expand Down Expand Up @@ -154,13 +157,15 @@ define(function (require) {
}

function setDarkTheme(enabled) {
//console.log('setDarkTheme');
var theme = Boolean(enabled) ? 'theme-dark' : 'theme-light';
chrome.removeApplicationClass(['theme-dark', 'theme-light']);
chrome.addApplicationClass(theme);
}

// update root source when filters update
$scope.$listen(queryFilter, 'update', function () {
//console.log('queryFilter update');
updateQueryOnRootSource();
$state.save();
});
Expand Down Expand Up @@ -233,15 +238,17 @@ define(function (require) {
ui: $state.options,
save: $scope.save,
addVis: $scope.addVis,
addSearch: $scope.addSearch,
shareData: function () {
return {
link: $location.absUrl(),
// This sucks, but seems like the cleanest way. Uhg.
embed: '<iframe src="' + $location.absUrl().replace('?', '?embed&') +
'" height="600" width="800"></iframe>'
};
}
addSearch: $scope.addSearch
// ,
// shareData: function () {
// //console.log('this is being called.');
// return {
// link: $location.absUrl(),
// // This sucks, but seems like the cleanest way. Uhg.
// embed: '<iframe src="' + $location.absUrl().replace('?', '?embed&') +
// '" height="600" width="800"></iframe>'
// };
// }
};

init();
Expand Down
5 changes: 3 additions & 2 deletions src/plugins/kibana/public/dashboard/partials/share.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<form role="form" class="vis-share">
<share object-type="dashboard"></share>
<!-- <form role="form" class="vis-share">
<p>
<div class="input-group">
Expand All @@ -18,4 +19,4 @@
<div class="form-control" disabled>{{opts.shareData().link}}</div>
</div>
</p>
</form>
</form> -->
3 changes: 2 additions & 1 deletion src/plugins/kibana/public/discover/controllers/discover.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ define(function (require) {
// config panel templates
$scope.configTemplate = new ConfigTemplate({
load: require('plugins/kibana/discover/partials/load_search.html'),
save: require('plugins/kibana/discover/partials/save_search.html')
save: require('plugins/kibana/discover/partials/save_search.html'),
share: require('plugins/kibana/discover/partials/share_search.html')
});

$scope.timefilter = timefilter;
Expand Down
10 changes: 10 additions & 0 deletions src/plugins/kibana/public/discover/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@
<i aria-hidden="true" class="fa fa-folder-open-o"></i>
</button>
</kbn-tooltip>
<kbn-tooltip text="Share" placement="bottom" append-to-body="1">
<button
aria-label="Share Search"
aria-haspopup="true"
aria-expanded="{{ configTemplate.is('share') }}"
ng-class="{active: configTemplate.is('share')}"
ng-click="configTemplate.toggle('share');">
<i aria-hidden="true" class="fa fa-external-link"></i>
</button>
</kbn-tooltip>
</div>
</navbar>

Expand Down
22 changes: 22 additions & 0 deletions src/plugins/kibana/public/discover/partials/share_search.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<share object-type="search"></share>
<!-- <form role="form" class="vis-share">
<p>
<div class="input-group">
<label>
Embed this dashboard
<small>Add to your html source. Note all clients must still be able to access kibana</small>
</label>
<div class="form-control" disabled>{{opts.shareData().embed}}</div>
</div>
</p>
<p>
<div class="input-group">
<label>
Share a link
</label>
<div class="form-control" disabled>{{opts.shareData().link}}</div>
</div>
</p>
</form> -->
22 changes: 22 additions & 0 deletions src/plugins/kibana/public/goto/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
define(function (require) {
var angular = require('angular');

require('ui/routes')
.when('/goto/:id', {
template: require('plugins/kibana/dashboard/index.html'),
resolve: {
dash: function (savedDashboards, Notifier, $route, $location, courier) {
return savedDashboards.get($route.current.params.id)
.catch(courier.redirectWhenMissing({
'dashboard' : '/dashboard'
}));
}
}
});

require('ui/routes')
.when('/visualize', {
redirectTo: '/visualize/step/1'
});

});
16 changes: 8 additions & 8 deletions src/plugins/kibana/public/visualize/editor/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,14 +234,14 @@ define(function (require) {
}, notify.fatal);
};

$scope.shareData = function () {
return {
link: $location.absUrl(),
// This sucks, but seems like the cleanest way. Uhg.
embed: '<iframe src="' + $location.absUrl().replace('?', '?embed&') +
'" height="600" width="800"></iframe>'
};
};
// $scope.shareData = function () {
// return {
// link: $location.absUrl(),
// // This sucks, but seems like the cleanest way. Uhg.
// embed: '<iframe src="' + $location.absUrl().replace('?', '?embed&') +
// '" height="600" width="800"></iframe>'
// };
// };

$scope.unlink = function () {
if (!$state.linked) return;
Expand Down
5 changes: 3 additions & 2 deletions src/plugins/kibana/public/visualize/editor/panels/share.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<form role="form" class="vis-share">
<share object-type="visualization"></share>
<!-- <form role="form" class="vis-share">
<p>
<div class="form-group">
Expand All @@ -19,4 +20,4 @@
</div>
</p>
</form>
</form> -->
21 changes: 21 additions & 0 deletions src/server/http/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ module.exports = function (kbnServer, server, config) {

server = kbnServer.server = new Hapi.Server();

const urlLookup = require('./urlLookup')(server);

// Create a new connection
var connectionOptions = {
host: config.get('server.host'),
Expand All @@ -29,6 +31,7 @@ module.exports = function (kbnServer, server, config) {

server.connection(connectionOptions);


// provide a simple way to expose static directories
server.decorate('server', 'exposeStaticDir', function (routePath, dirPath) {
this.route({
Expand Down Expand Up @@ -122,5 +125,23 @@ module.exports = function (kbnServer, server, config) {
}
});

server.route({
method: 'GET',
path: '/goto/{urlId}',
handler: async function (request, reply) {
const url = await urlLookup.getUrl(request.params.urlId);
reply().redirect(url);
}
});

server.route({
method: 'POST',
path: '/shorten',
handler: async function (request, reply) {
const urlId = await urlLookup.generateUrlId(request.payload.url);
reply(urlId);
}
});

return kbnServer.mixin(require('./xsrf'));
};
77 changes: 77 additions & 0 deletions src/server/http/urlLookup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const crypto = require('crypto');

export default function (server) {
async function updateMetadata(urlId, urlDoc) {
const client = server.plugins.elasticsearch.client;

try {
await client.update({
index: '.kibana',
type: 'url',
id: urlId,
body: {
doc: {
'access-date': new Date(),
'access-count': urlDoc._source['access-count'] + 1
}
}
});
} catch (err) {
console.log(err);
//swallow errors. We don't care if there is no update.
}
}

return {
async generateUrlId(url) {
const urlId = await new Promise((resolve, reject) => {
const client = server.plugins.elasticsearch.client;

// const urlId = crypto.createHash('md5')
// .update(url)
// .digest('hex');

client.index({
index: '.kibana',
type: 'url',
body: {
url,
'access-count': 0,
'create-date': new Date(),
'access-date': new Date()
}
})
.then(response => {
const urlId = response._id;
resolve(urlId);
})
.catch(err => {
reject(err);
});
});

return urlId;
},
async getUrl(urlId) {
const url = await new Promise((resolve, reject) => {
const client = server.plugins.elasticsearch.client;

client.get({
index: '.kibana',
type: 'url',
id: urlId
})
.then(response => {
const url = response._source.url;
updateMetadata(urlId, response);
resolve(url);
})
.catch(err => {
resolve('/');
});
});

return url;
}
};
};
2 changes: 2 additions & 0 deletions src/ui/public/directives/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ define(function (require) {
var tmpScope = $scope.$new();

$scope.$watch('configObject', function (newVal) {
console.log('config watch');
$scope[attr.configObject] = $scope.configObject;
});

Expand All @@ -44,6 +45,7 @@ define(function (require) {
'configSubmit',
'configTemplate.current || configTemplate'
], function () {
console.log('config watchMulti');
var tmpl = $scope.configTemplate;
if (tmpl instanceof ConfigTemplate) {
tmpl = tmpl.toString();
Expand Down
39 changes: 39 additions & 0 deletions src/ui/public/share/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<form role="form" class="vis-share">
<p>
<input type="checkbox" ng-model="shortenUrls" id="shortenUrls" />
<label for="shortenUrls">Shorten URLs</label>
</p>
<p>
<div class="input-group">
<label>
Embed this {{objectType}}
<small>Add to your html source. Note all clients must still be able to access kibana</small>
</label>
<div class="form-control" disabled ng-if="!shortenUrls">
&lt;iframe src="{{embedUrl}}" height="600" width="800"&gt;&lt;/iframe&gt;
</div>
<div class="form-control" disabled ng-if="shortenUrls && !shortUrlsLoading">
&lt;iframe src="{{shortEmbedUrl}}" height="600" width="800"&gt;&lt;/iframe&gt;
</div>
<div class="form-control" disabled ng-if="shortenUrls && shortUrlsLoading">
Generating Short URL...
</div>
</div>
</p>
<p>
<div class="input-group">
<label>
Share a link
</label>
<div class="form-control" disabled ng-if="!shortenUrls">
{{getUrl()}}
</div>
<div class="form-control" disabled ng-if="shortenUrls && !shortUrlsLoading">
{{shortUrl}}
</div>
<div class="form-control" disabled ng-if="shortenUrls && shortUrlsLoading">
Generating Short URL...
</div>
</div>
</p>
</form>
Loading

0 comments on commit 25c6627

Please sign in to comment.