Skip to content

Instantly share code, notes, and snippets.

@brianmed
Last active October 5, 2016 10:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save brianmed/91729319550afcb9498c23aa289dea7e to your computer and use it in GitHub Desktop.
Save brianmed/91729319550afcb9498c23aa289dea7e to your computer and use it in GitHub Desktop.
Mojolicious::Lite app that can tail a file
use Mojolicious::Lite;
use Mojo::Util qw(secure_compare);
use Mojo::JSON qw(encode_json);
use Mojo::IOLoop::Tail;
# Authentication
under(sub {
my $c = shift;
# Have access
return 1 if secure_compare(
$c->req->url->to_abs->userinfo,
'user:fnord'
);
# No credentials
my $auth = $c->req->url->to_abs->userinfo || '';
unless ($auth) {
$c->res->headers->www_authenticate("Basic realm=Joy");
$c->res->code(401);
$c->rendered;
return undef;
}
# Do not have access
$c->render(json =>
{status => "error", data => { message => "Credentials mis-match" }}
);
return undef;
});
websocket '/contents' => sub {
my $c = shift;
$c->inactivity_timeout(3600);
$c->on(message => sub {
my ($c, $msg) = @_;
my $tail = $c->stash("tail", Mojo::IOLoop::Tail->new(file => $msg))->stash("tail");
$tail->on(oneline => sub {
my $tail = shift;
my $line = shift;
$c->send(encode_json({ line => $line }));
});
$tail->run;
});
$c->on(finish => sub {
$c->stash("tail", undef);
});
} => "contents";
get '/' => sub {
my $c = shift;
$c->render(text => "Try " . $c->url_for("/")->to_abs . "tmp/filename.txt");
};
get '/*file' => sub {
my $c = shift;
$c->render(template => "index", file => $c->param("file"));
};
app->start;
__DATA__
@@ index.html.ep
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Tail</title>
<link rel="stylesheet" type="text/css" href="">
<script id="sap-ui-bootstrap" src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" type="text/javascript" data-sap-ui-libs="sap.ui.core,sap.ui.commons,sap.ui.table" data-sap-ui-theme="sap_goldreflection">
</script>
<script>
var aColumnData = [{
columnId: "line"
}];
var aData = [];
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData({
columns: aColumnData,
rows: aData
});
var oTable = new sap.ui.table.Table({
title: "/<%= stash('file') %>",
showNoData : true,
visibleRowCount: 50
});
oTable.setModel(oModel);
oTable.bindColumns("/columns", function(index, context) {
var sColumnId = context.getObject().columnId;
return new sap.ui.table.Column({
id : sColumnId,
label: sColumnId,
template: sColumnId,
sortProperty: sColumnId,
filterProperty: sColumnId,
});
});
oTable.bindRows("/rows");
oTable.placeAt("content");
</script>
</head>
% my $url = url_for('contents');
<script>
var ws = new WebSocket('<%= $url->to_abs %>');
ws.onmessage = function (event) {
var data = oModel.getData();
data = data.rows.unshift(JSON.parse(event.data));
oModel.setData(data, true);
};
ws.onopen = function (event) { ws.send("/<%= stash('file') %>"); };
</script>
<body class="sapUiBody" id="body" role="application">
<div id="content"></div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment