tailog 0.3.5 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/ansi_up.js +326 -0
- data/app/assets/stylesheets/application.css +39 -0
- data/app/views/layout.erb +2 -41
- data/app/views/logs/index.erb +1 -1
- data/app/views/script/index.erb +1 -1
- data/lib/tailog/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d35ed9b90a1497b13891c073bbff1a31cf29eb20
|
4
|
+
data.tar.gz: ab0ad71cb9dfc0da95f2699c318cefa85a12e601
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f697a62734853cfff59cde5bf4f55b712b76a4715583a628d34a32e7047833d92fa721cb3f5da16d6d093f76c774a553e545f1aaff05aea73fe04a9186502694
|
7
|
+
data.tar.gz: 289eafa3b3b66d304fc1bb62be807e65c58e298d118f60a70f332ed9e3c12fdb63f35eae3351c16f9832f97fbfc4ef7ddd136c142ba5f6a87fb6360509317ba3
|
@@ -0,0 +1,326 @@
|
|
1
|
+
// ansi_up.js
|
2
|
+
// version : 1.3.0
|
3
|
+
// author : Dru Nelson
|
4
|
+
// license : MIT
|
5
|
+
// http://github.com/drudru/ansi_up
|
6
|
+
|
7
|
+
(function (Date, undefined) {
|
8
|
+
|
9
|
+
var ansi_up,
|
10
|
+
VERSION = "1.3.0",
|
11
|
+
|
12
|
+
// check for nodeJS
|
13
|
+
hasModule = (typeof module !== 'undefined'),
|
14
|
+
|
15
|
+
// Normal and then Bright
|
16
|
+
ANSI_COLORS = [
|
17
|
+
[
|
18
|
+
{ color: "8, 2, 0", 'class': "ansi-black" },
|
19
|
+
{ color: "228, 68, 41", 'class': "ansi-red" },
|
20
|
+
{ color: "0, 173, 101", 'class': "ansi-green" },
|
21
|
+
{ color: "254, 238, 0", 'class': "ansi-yellow" },
|
22
|
+
{ color: "0, 176, 234", 'class': "ansi-blue" },
|
23
|
+
{ color: "178, 128, 165", 'class': "ansi-magenta" },
|
24
|
+
{ color: "193, 233, 247", 'class': "ansi-cyan" },
|
25
|
+
{ color: "180, 177, 177", 'class': "ansi-white" }
|
26
|
+
], [
|
27
|
+
{ color: "27, 27, 27", 'class': "ansi-bright-black" },
|
28
|
+
{ color: "182, 80, 47", 'class': "ansi-bright-red" },
|
29
|
+
{ color: "141, 161, 88", 'class': "ansi-bright-green" },
|
30
|
+
{ color: "220, 175, 95", 'class': "ansi-bright-yellow" },
|
31
|
+
{ color: "126, 170, 199", 'class': "ansi-bright-blue" },
|
32
|
+
{ color: "176, 101, 152", 'class': "ansi-bright-magenta" },
|
33
|
+
{ color: "141, 220, 217", 'class': "ansi-bright-cyan" },
|
34
|
+
{ color: "217, 217, 217", 'class': "ansi-bright-white" }
|
35
|
+
]
|
36
|
+
],
|
37
|
+
|
38
|
+
// 256 Colors Palette
|
39
|
+
PALETTE_COLORS;
|
40
|
+
|
41
|
+
function Ansi_Up() {
|
42
|
+
this.fg = this.bg = this.fg_truecolor = this.bg_truecolor = null;
|
43
|
+
this.bright = 0;
|
44
|
+
}
|
45
|
+
|
46
|
+
Ansi_Up.prototype.setup_palette = function() {
|
47
|
+
PALETTE_COLORS = [];
|
48
|
+
// Index 0..15 : System color
|
49
|
+
(function() {
|
50
|
+
var i, j;
|
51
|
+
for (i = 0; i < 2; ++i) {
|
52
|
+
for (j = 0; j < 8; ++j) {
|
53
|
+
PALETTE_COLORS.push(ANSI_COLORS[i][j]['color']);
|
54
|
+
}
|
55
|
+
}
|
56
|
+
})();
|
57
|
+
|
58
|
+
// Index 16..231 : RGB 6x6x6
|
59
|
+
// https://gist.github.com/jasonm23/2868981#file-xterm-256color-yaml
|
60
|
+
(function() {
|
61
|
+
var levels = [0, 95, 135, 175, 215, 255];
|
62
|
+
var format = function (r, g, b) { return levels[r] + ', ' + levels[g] + ', ' + levels[b] };
|
63
|
+
var r, g, b;
|
64
|
+
for (r = 0; r < 6; ++r) {
|
65
|
+
for (g = 0; g < 6; ++g) {
|
66
|
+
for (b = 0; b < 6; ++b) {
|
67
|
+
PALETTE_COLORS.push(format.call(this, r, g, b));
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
})();
|
72
|
+
|
73
|
+
// Index 232..255 : Grayscale
|
74
|
+
(function() {
|
75
|
+
var level = 8;
|
76
|
+
var format = function(level) { return level + ', ' + level + ', ' + level };
|
77
|
+
var i;
|
78
|
+
for (i = 0; i < 24; ++i, level += 10) {
|
79
|
+
PALETTE_COLORS.push(format.call(this, level));
|
80
|
+
}
|
81
|
+
})();
|
82
|
+
};
|
83
|
+
|
84
|
+
Ansi_Up.prototype.escape_for_html = function (txt) {
|
85
|
+
return txt.replace(/[&<>]/gm, function(str) {
|
86
|
+
if (str == "&") return "&";
|
87
|
+
if (str == "<") return "<";
|
88
|
+
if (str == ">") return ">";
|
89
|
+
});
|
90
|
+
};
|
91
|
+
|
92
|
+
Ansi_Up.prototype.linkify = function (txt) {
|
93
|
+
return txt.replace(/(https?:\/\/[^\s]+)/gm, function(str) {
|
94
|
+
return "<a href=\"" + str + "\">" + str + "</a>";
|
95
|
+
});
|
96
|
+
};
|
97
|
+
|
98
|
+
Ansi_Up.prototype.ansi_to_html = function (txt, options) {
|
99
|
+
return this.process(txt, options, true);
|
100
|
+
};
|
101
|
+
|
102
|
+
Ansi_Up.prototype.ansi_to_text = function (txt) {
|
103
|
+
var options = {};
|
104
|
+
return this.process(txt, options, false);
|
105
|
+
};
|
106
|
+
|
107
|
+
Ansi_Up.prototype.process = function (txt, options, markup) {
|
108
|
+
var self = this;
|
109
|
+
var raw_text_chunks = txt.split(/\033\[/);
|
110
|
+
var first_chunk = raw_text_chunks.shift(); // the first chunk is not the result of the split
|
111
|
+
|
112
|
+
var color_chunks = raw_text_chunks.map(function (chunk) {
|
113
|
+
return self.process_chunk(chunk, options, markup);
|
114
|
+
});
|
115
|
+
|
116
|
+
color_chunks.unshift(first_chunk);
|
117
|
+
|
118
|
+
return color_chunks.join('');
|
119
|
+
};
|
120
|
+
|
121
|
+
Ansi_Up.prototype.process_chunk = function (text, options, markup) {
|
122
|
+
|
123
|
+
// Are we using classes or styles?
|
124
|
+
options = typeof options == 'undefined' ? {} : options;
|
125
|
+
var use_classes = typeof options.use_classes != 'undefined' && options.use_classes;
|
126
|
+
var key = use_classes ? 'class' : 'color';
|
127
|
+
|
128
|
+
// Each 'chunk' is the text after the CSI (ESC + '[') and before the next CSI/EOF.
|
129
|
+
//
|
130
|
+
// This regex matches four groups within a chunk.
|
131
|
+
//
|
132
|
+
// The first and third groups match code type.
|
133
|
+
// We supported only SGR command. It has empty first group and 'm' in third.
|
134
|
+
//
|
135
|
+
// The second group matches all of the number+semicolon command sequences
|
136
|
+
// before the 'm' (or other trailing) character.
|
137
|
+
// These are the graphics or SGR commands.
|
138
|
+
//
|
139
|
+
// The last group is the text (including newlines) that is colored by
|
140
|
+
// the other group's commands.
|
141
|
+
var matches = text.match(/^([!\x3c-\x3f]*)([\d;]*)([\x20-\x2c]*[\x40-\x7e])([\s\S]*)/m);
|
142
|
+
|
143
|
+
if (!matches) return text;
|
144
|
+
|
145
|
+
var orig_txt = matches[4];
|
146
|
+
var nums = matches[2].split(';');
|
147
|
+
|
148
|
+
// We currently support only "SGR" (Select Graphic Rendition)
|
149
|
+
// Simply ignore if not a SGR command.
|
150
|
+
if (matches[1] !== '' || matches[3] !== 'm') {
|
151
|
+
return orig_txt;
|
152
|
+
}
|
153
|
+
|
154
|
+
if (!markup) {
|
155
|
+
return orig_txt;
|
156
|
+
}
|
157
|
+
|
158
|
+
var self = this;
|
159
|
+
|
160
|
+
while (nums.length > 0) {
|
161
|
+
var num_str = nums.shift();
|
162
|
+
var num = parseInt(num_str);
|
163
|
+
|
164
|
+
if (isNaN(num) || num === 0) {
|
165
|
+
self.fg = self.bg = null;
|
166
|
+
self.bright = 0;
|
167
|
+
} else if (num === 1) {
|
168
|
+
self.bright = 1;
|
169
|
+
} else if (num == 39) {
|
170
|
+
self.fg = null;
|
171
|
+
} else if (num == 49) {
|
172
|
+
self.bg = null;
|
173
|
+
} else if ((num >= 30) && (num < 38)) {
|
174
|
+
self.fg = ANSI_COLORS[self.bright][(num % 10)][key];
|
175
|
+
} else if ((num >= 90) && (num < 98)) {
|
176
|
+
self.fg = ANSI_COLORS[1][(num % 10)][key];
|
177
|
+
} else if ((num >= 40) && (num < 48)) {
|
178
|
+
self.bg = ANSI_COLORS[0][(num % 10)][key];
|
179
|
+
} else if ((num >= 100) && (num < 108)) {
|
180
|
+
self.bg = ANSI_COLORS[1][(num % 10)][key];
|
181
|
+
} else if (num === 38 || num === 48) { // extend color (38=fg, 48=bg)
|
182
|
+
(function() {
|
183
|
+
var is_foreground = (num === 38);
|
184
|
+
if (nums.length >= 1) {
|
185
|
+
var mode = nums.shift();
|
186
|
+
if (mode === '5' && nums.length >= 1) { // palette color
|
187
|
+
var palette_index = parseInt(nums.shift());
|
188
|
+
if (palette_index >= 0 && palette_index <= 255) {
|
189
|
+
if (!use_classes) {
|
190
|
+
if (!PALETTE_COLORS) {
|
191
|
+
self.setup_palette.call(self);
|
192
|
+
}
|
193
|
+
if (is_foreground) {
|
194
|
+
self.fg = PALETTE_COLORS[palette_index];
|
195
|
+
} else {
|
196
|
+
self.bg = PALETTE_COLORS[palette_index];
|
197
|
+
}
|
198
|
+
} else {
|
199
|
+
var klass = (palette_index >= 16)
|
200
|
+
? ('ansi-palette-' + palette_index)
|
201
|
+
: ANSI_COLORS[palette_index > 7 ? 1 : 0][palette_index % 8]['class'];
|
202
|
+
if (is_foreground) {
|
203
|
+
self.fg = klass;
|
204
|
+
} else {
|
205
|
+
self.bg = klass;
|
206
|
+
}
|
207
|
+
}
|
208
|
+
}
|
209
|
+
} else if(mode === '2' && nums.length >= 3) { // true color
|
210
|
+
var r = parseInt(nums.shift());
|
211
|
+
var g = parseInt(nums.shift());
|
212
|
+
var b = parseInt(nums.shift());
|
213
|
+
if ((r >= 0 && r <= 255) && (g >= 0 && g <= 255) && (b >= 0 && b <= 255)) {
|
214
|
+
var color = r + ', ' + g + ', ' + b;
|
215
|
+
if (!use_classes) {
|
216
|
+
if (is_foreground) {
|
217
|
+
self.fg = color;
|
218
|
+
} else {
|
219
|
+
self.bg = color;
|
220
|
+
}
|
221
|
+
} else {
|
222
|
+
if (is_foreground) {
|
223
|
+
self.fg = 'ansi-truecolor';
|
224
|
+
self.fg_truecolor = color;
|
225
|
+
} else {
|
226
|
+
self.bg = 'ansi-truecolor';
|
227
|
+
self.bg_truecolor = color;
|
228
|
+
}
|
229
|
+
}
|
230
|
+
}
|
231
|
+
}
|
232
|
+
}
|
233
|
+
})();
|
234
|
+
}
|
235
|
+
}
|
236
|
+
|
237
|
+
if ((self.fg === null) && (self.bg === null)) {
|
238
|
+
return orig_txt;
|
239
|
+
} else {
|
240
|
+
var styles = [];
|
241
|
+
var classes = [];
|
242
|
+
var data = {};
|
243
|
+
var render_data = function (data) {
|
244
|
+
var fragments = [];
|
245
|
+
var key;
|
246
|
+
for (key in data) {
|
247
|
+
if (data.hasOwnProperty(key)) {
|
248
|
+
fragments.push('data-' + key + '="' + this.escape_for_html(data[key]) + '"');
|
249
|
+
}
|
250
|
+
}
|
251
|
+
return fragments.length > 0 ? ' ' + fragments.join(' ') : '';
|
252
|
+
};
|
253
|
+
|
254
|
+
if (self.fg) {
|
255
|
+
if (use_classes) {
|
256
|
+
classes.push(self.fg + "-fg");
|
257
|
+
if (self.fg_truecolor !== null) {
|
258
|
+
data['ansi-truecolor-fg'] = self.fg_truecolor;
|
259
|
+
self.fg_truecolor = null;
|
260
|
+
}
|
261
|
+
} else {
|
262
|
+
styles.push("color:rgb(" + self.fg + ")");
|
263
|
+
}
|
264
|
+
}
|
265
|
+
if (self.bg) {
|
266
|
+
if (use_classes) {
|
267
|
+
classes.push(self.bg + "-bg");
|
268
|
+
if (self.bg_truecolor !== null) {
|
269
|
+
data['ansi-truecolor-bg'] = self.bg_truecolor;
|
270
|
+
self.bg_truecolor = null;
|
271
|
+
}
|
272
|
+
} else {
|
273
|
+
styles.push("background-color:rgb(" + self.bg + ")");
|
274
|
+
}
|
275
|
+
}
|
276
|
+
if (use_classes) {
|
277
|
+
return '<span class="' + classes.join(' ') + '"' + render_data.call(self, data) + '>' + orig_txt + '</span>';
|
278
|
+
} else {
|
279
|
+
return '<span style="' + styles.join(';') + '"' + render_data.call(self, data) + '>' + orig_txt + '</span>';
|
280
|
+
}
|
281
|
+
}
|
282
|
+
};
|
283
|
+
|
284
|
+
// Module exports
|
285
|
+
ansi_up = {
|
286
|
+
|
287
|
+
escape_for_html: function (txt) {
|
288
|
+
var a2h = new Ansi_Up();
|
289
|
+
return a2h.escape_for_html(txt);
|
290
|
+
},
|
291
|
+
|
292
|
+
linkify: function (txt) {
|
293
|
+
var a2h = new Ansi_Up();
|
294
|
+
return a2h.linkify(txt);
|
295
|
+
},
|
296
|
+
|
297
|
+
ansi_to_html: function (txt, options) {
|
298
|
+
var a2h = new Ansi_Up();
|
299
|
+
return a2h.ansi_to_html(txt, options);
|
300
|
+
},
|
301
|
+
|
302
|
+
ansi_to_text: function (txt) {
|
303
|
+
var a2h = new Ansi_Up();
|
304
|
+
return a2h.ansi_to_text(txt);
|
305
|
+
},
|
306
|
+
|
307
|
+
ansi_to_html_obj: function () {
|
308
|
+
return new Ansi_Up();
|
309
|
+
}
|
310
|
+
};
|
311
|
+
|
312
|
+
// CommonJS module is defined
|
313
|
+
if (hasModule) {
|
314
|
+
module.exports = ansi_up;
|
315
|
+
}
|
316
|
+
/*global ender:false */
|
317
|
+
if (typeof window !== 'undefined' && typeof ender === 'undefined') {
|
318
|
+
window.ansi_up = ansi_up;
|
319
|
+
}
|
320
|
+
/*global define:false */
|
321
|
+
if (typeof define === "function" && define.amd) {
|
322
|
+
define("ansi_up", [], function () {
|
323
|
+
return ansi_up;
|
324
|
+
});
|
325
|
+
}
|
326
|
+
})(Date);
|
@@ -0,0 +1,39 @@
|
|
1
|
+
body {
|
2
|
+
font-family: "Lucida Console", Monaco, monospace;
|
3
|
+
padding-top: 20px;
|
4
|
+
padding-bottom: 20px;
|
5
|
+
}
|
6
|
+
|
7
|
+
p {
|
8
|
+
white-space: pre-wrap;
|
9
|
+
margin: 0;
|
10
|
+
}
|
11
|
+
|
12
|
+
.content-hover p:hover {
|
13
|
+
background: #EEE;
|
14
|
+
}
|
15
|
+
|
16
|
+
.dl-horizontal dt {
|
17
|
+
width: 320px;
|
18
|
+
padding-right: 20px;
|
19
|
+
}
|
20
|
+
|
21
|
+
.dl-horizontal dd {
|
22
|
+
margin-left: 320px;
|
23
|
+
}
|
24
|
+
|
25
|
+
.dl-hover dt:hover + dd, .dl-hover dd:hover {
|
26
|
+
background: #EEE;
|
27
|
+
}
|
28
|
+
|
29
|
+
.script select.form-control {
|
30
|
+
display: inline-block;
|
31
|
+
width: 100px;
|
32
|
+
}
|
33
|
+
|
34
|
+
.divider {
|
35
|
+
display: block;
|
36
|
+
margin: 10px 0 20px;
|
37
|
+
color: #a94442;
|
38
|
+
border-bottom: 3px dashed #d9534f;
|
39
|
+
}
|
data/app/views/layout.erb
CHANGED
@@ -4,48 +4,9 @@
|
|
4
4
|
<title>TAILOG</title>
|
5
5
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
|
6
6
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.form/3.51/jquery.form.js"></script>
|
7
|
+
<script type="text/javascript" src="javascripts/ansi_up.js"></script>
|
7
8
|
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css">
|
8
|
-
<
|
9
|
-
body {
|
10
|
-
font-family: "Lucida Console", Monaco, monospace;
|
11
|
-
padding-top: 20px;
|
12
|
-
padding-bottom: 20px;
|
13
|
-
}
|
14
|
-
|
15
|
-
p {
|
16
|
-
white-space: pre-wrap;
|
17
|
-
margin: 0;
|
18
|
-
}
|
19
|
-
|
20
|
-
.content-hover p:hover {
|
21
|
-
background: #EEE;
|
22
|
-
}
|
23
|
-
|
24
|
-
.dl-horizontal dt {
|
25
|
-
width: 320px;
|
26
|
-
padding-right: 20px;
|
27
|
-
}
|
28
|
-
|
29
|
-
.dl-horizontal dd {
|
30
|
-
margin-left: 320px;
|
31
|
-
}
|
32
|
-
|
33
|
-
.dl-hover dt:hover + dd, .dl-hover dd:hover {
|
34
|
-
background: #EEE;
|
35
|
-
}
|
36
|
-
|
37
|
-
.script select.form-control {
|
38
|
-
display: inline-block;
|
39
|
-
width: 100px;
|
40
|
-
}
|
41
|
-
|
42
|
-
.divider {
|
43
|
-
display: block;
|
44
|
-
margin: 10px 0 20px;
|
45
|
-
color: #a94442;
|
46
|
-
border-bottom: 3px dashed #d9534f;
|
47
|
-
}
|
48
|
-
</style>
|
9
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/application.css">
|
49
10
|
</head>
|
50
11
|
<body>
|
51
12
|
|
data/app/views/logs/index.erb
CHANGED
@@ -38,7 +38,7 @@
|
|
38
38
|
var shouldScrollToBottom = $window.scrollTop() + $window.height() == $document.height();
|
39
39
|
$content
|
40
40
|
.append('<span class="text-info">' + data.server_hostname + ' - ' + data.file_size + '</span>')
|
41
|
-
.append(data.content);
|
41
|
+
.append(ansi_up.ansi_to_html(data.content));
|
42
42
|
|
43
43
|
if (shouldScrollToBottom) {
|
44
44
|
$window.scrollTop($document.height() - $window.height());
|
data/app/views/script/index.erb
CHANGED
data/lib/tailog/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tailog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bbtfr
|
@@ -50,6 +50,8 @@ files:
|
|
50
50
|
- LICENSE.md
|
51
51
|
- README.md
|
52
52
|
- Rakefile
|
53
|
+
- app/assets/javascripts/ansi_up.js
|
54
|
+
- app/assets/stylesheets/application.css
|
53
55
|
- app/views/env.erb
|
54
56
|
- app/views/error.erb
|
55
57
|
- app/views/layout.erb
|