slack_log_viewer 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1d77551b39e196d038bc4b293736ec657ed97df3
4
+ data.tar.gz: 509a077510b64a7d2b0ba520527f053dac78b5be
5
+ SHA512:
6
+ metadata.gz: 308cd8b98fabe79bdfdd77864f072bc33ebe94de46ba79c8387a5e0d10d767cbb7c9f0564746660a85dd44cffb33b5052bf6da2dcfe1df191345b3a0ffbf18d4
7
+ data.tar.gz: 98dde0d140f435980261c71f18c503bc131ef4bf70f6352d12a02cf6bfd2187cd657ac9771fe5bfb34a649f6c490ee850412300e427ff6978071708c9646ee35
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ ./static
2
+ ./node_modules
3
+ *.gem
4
+ /data
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # A sample Gemfile
2
+ source 'https://rubygems.org'
3
+
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ slack_log_viewer (0.1.0)
5
+ haml (~> 4.0)
6
+ sinatra (~> 1.4)
7
+ twemoji (~> 2.1)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ haml (4.0.7)
13
+ tilt
14
+ mini_portile2 (2.0.0)
15
+ nokogiri (1.6.7.2)
16
+ mini_portile2 (~> 2.0.0.rc2)
17
+ rack (1.6.4)
18
+ rack-protection (1.5.3)
19
+ rack
20
+ sinatra (1.4.7)
21
+ rack (~> 1.5)
22
+ rack-protection (~> 1.4)
23
+ tilt (>= 1.3, < 3)
24
+ tilt (2.0.2)
25
+ twemoji (2.1.1)
26
+ nokogiri (~> 1.6.2)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ bundler
33
+ slack_log_viewer!
34
+
35
+ BUNDLED WITH
36
+ 1.10.6
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # Slack Log Viewer
2
+
3
+ Simple web interface for exploring Slack log.
4
+
5
+ # Usage
6
+
7
+ ```sh
8
+ # Installing slack_log_viewer
9
+ $ gem install slack_log_viewer
10
+
11
+ # Before run server, check your log data
12
+ $ ls <SLACK_LOG_DIR>
13
+ channel1/ channel2/ channels.json users.json ...
14
+
15
+ # help command show help message for slack-log-viewer command
16
+ $ slack-log-viewer --help
17
+ Usage: slack-log-viewer [options]
18
+ -d LOG_DIR Set directory which has log data
19
+ -p PORT_NUMBER Specify Port number
20
+ -h HOST Specify host address
21
+
22
+ # Below command runs slack-log-viewer server
23
+ $ slack-log-viewer -d <SLACK_LOG_DIR>
24
+ [2016-01-30 22:33:01] INFO WEBrick 1.3.1
25
+ [2016-01-30 22:33:01] INFO ruby 2.2.3 (2015-08-18) [x86_64-darwin14]
26
+ == Sinatra (v1.4.7) has taken the stage on 4567 for development with backup from WEBrick
27
+ [2016-01-30 22:33:01] INFO WEBrick::HTTPServer#start: pid=35157 port=4567
28
+ ```
29
+
30
+ Browse `localhost:4567`. Port number can be set by `-p` option.
31
+
32
+ # Screenshot
33
+
34
+ ![some logs](http://i.imgur.com/qQQoPuW.png)
35
+ ![attachments](http://i.imgur.com/QMh79D8.png)
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'slack_log_viewer'
5
+
6
+ options = {
7
+ log_dir: '.',
8
+ port_number: 4567,
9
+ host_address: '0.0.0.0'
10
+ }
11
+
12
+ parser = OptionParser.new
13
+
14
+ parser.on('-d LOG_DIR', 'Set directory which has log data') do |dir|
15
+ options[:log_dir] = dir
16
+ end
17
+
18
+ parser.on('-p PORT_NUMBER', 'Specify Port number') do |port|
19
+ options[:port_number] = port
20
+ end
21
+
22
+ parser.on('-h HOST', 'Specify host address') do |host|
23
+ options[:host_address] = host
24
+ end
25
+
26
+ parser.parse!
27
+
28
+ SlackLogViewer.set :log_dir, options[:log_dir]
29
+ SlackLogViewer.set :port, options[:port_number]
30
+ SlackLogViewer.set :bind, options[:host_address]
31
+ SlackLogViewer.run!
@@ -0,0 +1,116 @@
1
+ require 'sinatra/base'
2
+ require 'json'
3
+ require 'twemoji'
4
+ require 'CGI'
5
+
6
+ # Main class of Slack Log Viewer. Sinatra app.
7
+ #
8
+ # @since 0.1
9
+ class SlackLogViewer < Sinatra::Base
10
+ set :public_folder, File.dirname(__FILE__) + '/node_modules'
11
+ set :public_folder, File.dirname(__FILE__) + '/static'
12
+
13
+ before do
14
+ files = ['users.json', 'channels.json']
15
+
16
+ unless request.path_info =~ /not_log_dir/
17
+ unless files.all? { |file| File.exist?(settings.log_dir + '/' + file) }
18
+ redirect '/not_log_dir'
19
+ end
20
+ end
21
+ end
22
+
23
+ get '/' do
24
+ locals = { channels: channels }
25
+ haml :index, locals: locals
26
+ end
27
+
28
+ get '/channels/:channel' do
29
+ locals = {
30
+ channels: channels,
31
+ channel: params[:channel],
32
+ dates: dates(params[:channel])
33
+ }
34
+
35
+ haml :channel, locals: locals
36
+ end
37
+
38
+ get '/channels/:channel/:day' do
39
+ indexed_dates = dates(params[:channel])
40
+ today_index = indexed_dates.find_index do |day|
41
+ day == params[:day]
42
+ end
43
+ prev_day = indexed_dates[today_index - 1]
44
+ next_day = indexed_dates[today_index + 1]
45
+
46
+ locals = {
47
+ channels: channels,
48
+ channel: params[:channel],
49
+ dates: indexed_dates,
50
+ day: params[:day],
51
+ prev_day: prev_day,
52
+ next_day: next_day,
53
+ logs: logs(params[:channel], params[:day])
54
+ }
55
+
56
+ haml :day, locals: locals
57
+ end
58
+
59
+ get '/not_log_dir' do
60
+ haml :not_log_dir
61
+ end
62
+
63
+ private
64
+
65
+ def channels
66
+ Dir["#{settings.log_dir}/*"]
67
+ .select { |e| e !~ /\.json/ }
68
+ .map { |e| File.basename(e) }
69
+ end
70
+
71
+ def dates(channel)
72
+ Dir["#{settings.log_dir}/#{channel}/*"]
73
+ .map { |e| File.basename(e, '.json') }
74
+ end
75
+
76
+ def logs(channel, day)
77
+ parse(File.read("#{settings.log_dir}/#{channel}/#{day}.json"))
78
+ end
79
+
80
+ def parse(logs)
81
+ user_dic = users_data
82
+ ch_dic = channels_data
83
+ logs = JSON.load(logs)
84
+ logs.map do |log|
85
+ log['user'] = user_dic[log['user']]
86
+ log['raw_text'] = log['text']
87
+ log['text'] =
88
+ log['text']
89
+ .gsub(/simple_smile/, 'smile')
90
+ .gsub(/<@(.*?)(\|.*?)?>/){ "@#{user_dic[$1]['name']}" }
91
+ .gsub(/<#(.*?)(\|.*?)?>/){ $2 ? "##{$2[1..-1]}" : "##{ch_dic[$1]['name']}" }
92
+ .gsub(/<(.*?)(\|.*?)?>/, "<a href='\\1'>\\1</a>")
93
+ .gsub(/```(.*?)```/m){ "<pre>#{ $1.strip if $1 }</pre>" }
94
+ .gsub("\n", '<br />')
95
+ log
96
+ end
97
+ end
98
+
99
+ def users_data
100
+ Hash[
101
+ *JSON
102
+ .load(File.read("#{settings.log_dir}/users.json"))
103
+ .map { |user| [user['id'], user] }
104
+ .flatten
105
+ ]
106
+ end
107
+
108
+ def channels_data
109
+ Hash[
110
+ *JSON
111
+ .load(File.read("#{settings.log_dir}/channels.json"))
112
+ .map { |ch| [ch['id'], ch] }
113
+ .flatten
114
+ ]
115
+ end
116
+ end
@@ -0,0 +1,4 @@
1
+ # Version of Slack Log Viewer
2
+ class SlackLogViewer
3
+ VERSION = '0.3.0'
4
+ end
@@ -0,0 +1,106 @@
1
+ .main {
2
+ margin: 2em 1em;
3
+ }
4
+
5
+ .menu{
6
+ margin: 1em 0;
7
+ font-family: "courier new", courier, monospace;
8
+ }
9
+
10
+ .logs {
11
+ margin-top: 2em;
12
+ margin-bottom: 2em;
13
+ }
14
+
15
+ h1.today{
16
+ margin-top: 1.5em;
17
+ }
18
+
19
+ .log {
20
+ width: 100%;
21
+ padding: 0.5em 0.2em;
22
+ border-bottom: 1px solid lightgray;
23
+ vertical-align: middle;
24
+ }
25
+
26
+ .log .text{
27
+ line-height: 1.8em;
28
+ }
29
+
30
+ .log .time{
31
+ font-size: 0.7em;
32
+ color: darkgray;
33
+ }
34
+
35
+ .log .profile-image img{
36
+ vertical-align:middle;
37
+ }
38
+
39
+ .log .attachment{
40
+ border-left: 6px solid lightcoral;
41
+ margin: 1em auto;
42
+ padding: 1.2em 1em;
43
+ }
44
+
45
+ .log pre{
46
+ border-left: 6px solid lightblue;
47
+ margin: 1em auto;
48
+ padding: 1.2em 1em;
49
+
50
+ }
51
+
52
+ .log .attachment-title{
53
+ display: block;
54
+ margin: 0em auto;
55
+ }
56
+
57
+ .log .attachment-image{
58
+ float: left;
59
+ }
60
+
61
+ .log .attachment-image img{
62
+ width: 100px;
63
+ margin-right: 1em;
64
+ margin-bottom: 0.3em;
65
+ vertical-align:middle;
66
+ }
67
+
68
+ .log .attachment-text{
69
+ display: block;
70
+ font-size: 0.85em;
71
+ }
72
+
73
+ .log .attachment-video{
74
+ margin-top: 1em;
75
+ }
76
+
77
+ .log .emoji{
78
+ vertical-align:middle;
79
+ margin: 0em 0.3em;
80
+ }
81
+
82
+ .log .debug{
83
+ display: none;
84
+ margin: 1em;
85
+ padding: 1em;
86
+ font-size: 0.75em;
87
+ }
88
+
89
+ a {
90
+ color: green;
91
+ text-decoration: none;
92
+ }
93
+
94
+ a:visited {
95
+ color: purple;
96
+ }
97
+
98
+ .clear {
99
+ clear: both;
100
+ }
101
+
102
+ pre {
103
+ font-family: "courier new", courier, monospace;
104
+ overflow-x: auto;
105
+ overflow-y: auto;
106
+ }
@@ -0,0 +1,424 @@
1
+ /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
2
+
3
+ /**
4
+ * 1. Set default font family to sans-serif.
5
+ * 2. Prevent iOS and IE text size adjust after device orientation change,
6
+ * without disabling user zoom.
7
+ */
8
+
9
+ html {
10
+ font-family: sans-serif; /* 1 */
11
+ -ms-text-size-adjust: 100%; /* 2 */
12
+ -webkit-text-size-adjust: 100%; /* 2 */
13
+ }
14
+
15
+ /**
16
+ * Remove default margin.
17
+ */
18
+
19
+ body {
20
+ margin: 0;
21
+ }
22
+
23
+ /* HTML5 display definitions
24
+ ========================================================================== */
25
+
26
+ /**
27
+ * Correct `block` display not defined for any HTML5 element in IE 8/9.
28
+ * Correct `block` display not defined for `details` or `summary` in IE 10/11
29
+ * and Firefox.
30
+ * Correct `block` display not defined for `main` in IE 11.
31
+ */
32
+
33
+ article,
34
+ aside,
35
+ details,
36
+ figcaption,
37
+ figure,
38
+ footer,
39
+ header,
40
+ hgroup,
41
+ main,
42
+ menu,
43
+ nav,
44
+ section,
45
+ summary {
46
+ display: block;
47
+ }
48
+
49
+ /**
50
+ * 1. Correct `inline-block` display not defined in IE 8/9.
51
+ * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
52
+ */
53
+
54
+ audio,
55
+ canvas,
56
+ progress,
57
+ video {
58
+ display: inline-block; /* 1 */
59
+ vertical-align: baseline; /* 2 */
60
+ }
61
+
62
+ /**
63
+ * Prevent modern browsers from displaying `audio` without controls.
64
+ * Remove excess height in iOS 5 devices.
65
+ */
66
+
67
+ audio:not([controls]) {
68
+ display: none;
69
+ height: 0;
70
+ }
71
+
72
+ /**
73
+ * Address `[hidden]` styling not present in IE 8/9/10.
74
+ * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.
75
+ */
76
+
77
+ [hidden],
78
+ template {
79
+ display: none;
80
+ }
81
+
82
+ /* Links
83
+ ========================================================================== */
84
+
85
+ /**
86
+ * Remove the gray background color from active links in IE 10.
87
+ */
88
+
89
+ a {
90
+ background-color: transparent;
91
+ }
92
+
93
+ /**
94
+ * Improve readability of focused elements when they are also in an
95
+ * active/hover state.
96
+ */
97
+
98
+ a:active,
99
+ a:hover {
100
+ outline: 0;
101
+ }
102
+
103
+ /* Text-level semantics
104
+ ========================================================================== */
105
+
106
+ /**
107
+ * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
108
+ */
109
+
110
+ abbr[title] {
111
+ border-bottom: 1px dotted;
112
+ }
113
+
114
+ /**
115
+ * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
116
+ */
117
+
118
+ b,
119
+ strong {
120
+ font-weight: bold;
121
+ }
122
+
123
+ /**
124
+ * Address styling not present in Safari and Chrome.
125
+ */
126
+
127
+ dfn {
128
+ font-style: italic;
129
+ }
130
+
131
+ /**
132
+ * Address variable `h1` font-size and margin within `section` and `article`
133
+ * contexts in Firefox 4+, Safari, and Chrome.
134
+ */
135
+
136
+ h1 {
137
+ font-size: 2em;
138
+ margin: 0.67em 0;
139
+ }
140
+
141
+ /**
142
+ * Address styling not present in IE 8/9.
143
+ */
144
+
145
+ mark {
146
+ background: #ff0;
147
+ color: #000;
148
+ }
149
+
150
+ /**
151
+ * Address inconsistent and variable font size in all browsers.
152
+ */
153
+
154
+ small {
155
+ font-size: 80%;
156
+ }
157
+
158
+ /**
159
+ * Prevent `sub` and `sup` affecting `line-height` in all browsers.
160
+ */
161
+
162
+ sub,
163
+ sup {
164
+ font-size: 75%;
165
+ line-height: 0;
166
+ position: relative;
167
+ vertical-align: baseline;
168
+ }
169
+
170
+ sup {
171
+ top: -0.5em;
172
+ }
173
+
174
+ sub {
175
+ bottom: -0.25em;
176
+ }
177
+
178
+ /* Embedded content
179
+ ========================================================================== */
180
+
181
+ /**
182
+ * Remove border when inside `a` element in IE 8/9/10.
183
+ */
184
+
185
+ img {
186
+ border: 0;
187
+ }
188
+
189
+ /**
190
+ * Correct overflow not hidden in IE 9/10/11.
191
+ */
192
+
193
+ svg:not(:root) {
194
+ overflow: hidden;
195
+ }
196
+
197
+ /* Grouping content
198
+ ========================================================================== */
199
+
200
+ /**
201
+ * Address margin not present in IE 8/9 and Safari.
202
+ */
203
+
204
+ figure {
205
+ margin: 1em 40px;
206
+ }
207
+
208
+ /**
209
+ * Address differences between Firefox and other browsers.
210
+ */
211
+
212
+ hr {
213
+ box-sizing: content-box;
214
+ height: 0;
215
+ }
216
+
217
+ /**
218
+ * Contain overflow in all browsers.
219
+ */
220
+
221
+ pre {
222
+ overflow: auto;
223
+ }
224
+
225
+ /**
226
+ * Address odd `em`-unit font size rendering in all browsers.
227
+ */
228
+
229
+ code,
230
+ kbd,
231
+ pre,
232
+ samp {
233
+ font-family: monospace, monospace;
234
+ font-size: 1em;
235
+ }
236
+
237
+ /* Forms
238
+ ========================================================================== */
239
+
240
+ /**
241
+ * Known limitation: by default, Chrome and Safari on OS X allow very limited
242
+ * styling of `select`, unless a `border` property is set.
243
+ */
244
+
245
+ /**
246
+ * 1. Correct color not being inherited.
247
+ * Known issue: affects color of disabled elements.
248
+ * 2. Correct font properties not being inherited.
249
+ * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
250
+ */
251
+
252
+ button,
253
+ input,
254
+ optgroup,
255
+ select,
256
+ textarea {
257
+ color: inherit; /* 1 */
258
+ font: inherit; /* 2 */
259
+ margin: 0; /* 3 */
260
+ }
261
+
262
+ /**
263
+ * Address `overflow` set to `hidden` in IE 8/9/10/11.
264
+ */
265
+
266
+ button {
267
+ overflow: visible;
268
+ }
269
+
270
+ /**
271
+ * Address inconsistent `text-transform` inheritance for `button` and `select`.
272
+ * All other form control elements do not inherit `text-transform` values.
273
+ * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
274
+ * Correct `select` style inheritance in Firefox.
275
+ */
276
+
277
+ button,
278
+ select {
279
+ text-transform: none;
280
+ }
281
+
282
+ /**
283
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
284
+ * and `video` controls.
285
+ * 2. Correct inability to style clickable `input` types in iOS.
286
+ * 3. Improve usability and consistency of cursor style between image-type
287
+ * `input` and others.
288
+ */
289
+
290
+ button,
291
+ html input[type="button"], /* 1 */
292
+ input[type="reset"],
293
+ input[type="submit"] {
294
+ -webkit-appearance: button; /* 2 */
295
+ cursor: pointer; /* 3 */
296
+ }
297
+
298
+ /**
299
+ * Re-set default cursor for disabled elements.
300
+ */
301
+
302
+ button[disabled],
303
+ html input[disabled] {
304
+ cursor: default;
305
+ }
306
+
307
+ /**
308
+ * Remove inner padding and border in Firefox 4+.
309
+ */
310
+
311
+ button::-moz-focus-inner,
312
+ input::-moz-focus-inner {
313
+ border: 0;
314
+ padding: 0;
315
+ }
316
+
317
+ /**
318
+ * Address Firefox 4+ setting `line-height` on `input` using `!important` in
319
+ * the UA stylesheet.
320
+ */
321
+
322
+ input {
323
+ line-height: normal;
324
+ }
325
+
326
+ /**
327
+ * It's recommended that you don't attempt to style these elements.
328
+ * Firefox's implementation doesn't respect box-sizing, padding, or width.
329
+ *
330
+ * 1. Address box sizing set to `content-box` in IE 8/9/10.
331
+ * 2. Remove excess padding in IE 8/9/10.
332
+ */
333
+
334
+ input[type="checkbox"],
335
+ input[type="radio"] {
336
+ box-sizing: border-box; /* 1 */
337
+ padding: 0; /* 2 */
338
+ }
339
+
340
+ /**
341
+ * Fix the cursor style for Chrome's increment/decrement buttons. For certain
342
+ * `font-size` values of the `input`, it causes the cursor style of the
343
+ * decrement button to change from `default` to `text`.
344
+ */
345
+
346
+ input[type="number"]::-webkit-inner-spin-button,
347
+ input[type="number"]::-webkit-outer-spin-button {
348
+ height: auto;
349
+ }
350
+
351
+ /**
352
+ * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
353
+ * 2. Address `box-sizing` set to `border-box` in Safari and Chrome.
354
+ */
355
+
356
+ input[type="search"] {
357
+ -webkit-appearance: textfield; /* 1 */
358
+ box-sizing: content-box; /* 2 */
359
+ }
360
+
361
+ /**
362
+ * Remove inner padding and search cancel button in Safari and Chrome on OS X.
363
+ * Safari (but not Chrome) clips the cancel button when the search input has
364
+ * padding (and `textfield` appearance).
365
+ */
366
+
367
+ input[type="search"]::-webkit-search-cancel-button,
368
+ input[type="search"]::-webkit-search-decoration {
369
+ -webkit-appearance: none;
370
+ }
371
+
372
+ /**
373
+ * Define consistent border, margin, and padding.
374
+ */
375
+
376
+ fieldset {
377
+ border: 1px solid #c0c0c0;
378
+ margin: 0 2px;
379
+ padding: 0.35em 0.625em 0.75em;
380
+ }
381
+
382
+ /**
383
+ * 1. Correct `color` not being inherited in IE 8/9/10/11.
384
+ * 2. Remove padding so people aren't caught out if they zero out fieldsets.
385
+ */
386
+
387
+ legend {
388
+ border: 0; /* 1 */
389
+ padding: 0; /* 2 */
390
+ }
391
+
392
+ /**
393
+ * Remove default vertical scrollbar in IE 8/9/10/11.
394
+ */
395
+
396
+ textarea {
397
+ overflow: auto;
398
+ }
399
+
400
+ /**
401
+ * Don't inherit the `font-weight` (applied by a rule above).
402
+ * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
403
+ */
404
+
405
+ optgroup {
406
+ font-weight: bold;
407
+ }
408
+
409
+ /* Tables
410
+ ========================================================================== */
411
+
412
+ /**
413
+ * Remove most spacing between table cells.
414
+ */
415
+
416
+ table {
417
+ border-collapse: collapse;
418
+ border-spacing: 0;
419
+ }
420
+
421
+ td,
422
+ th {
423
+ padding: 0;
424
+ }
@@ -0,0 +1,7 @@
1
+ .menu.menu-channels
2
+ - locals[:channels].each do |ch|
3
+ %a{href: '/channels/' + ch}= ch
4
+
5
+ .menu.menu-days
6
+ - locals[:dates].each do |day|
7
+ %a{href: "/channels/#{locals[:channel]}/#{day}"}= day
@@ -0,0 +1,18 @@
1
+ .menu.menu-channels
2
+ - locals[:channels].each do |ch|
3
+ %a{href: '/channels/' + ch}= ch
4
+
5
+ .menu.menu-days
6
+ - locals[:dates].each do |day|
7
+ %a{href: "/channels/#{locals[:channel]}/#{day}"}= day
8
+
9
+ %h1.today
10
+ = locals[:day].gsub("-", ". ") + "."
11
+
12
+ %div.logs
13
+ - locals[:logs].each do |log|
14
+ = haml :"./partials/log", locals: {log: log}
15
+
16
+ .menu.navigation
17
+ %a{href: "/channels/#{locals[:channel]}/#{prev_day}"}= "< #{prev_day}"
18
+ %a{href: "/channels/#{locals[:channel]}/#{next_day}"}= "#{next_day} >"
@@ -0,0 +1,3 @@
1
+ .menu.menu-channels
2
+ - locals[:channels].each do |ch|
3
+ %a{href: './channels/' + ch}= ch
@@ -0,0 +1,10 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %link{ "rel" => "stylesheet", "href" => "/stylesheets/normalize.css", "type" => "text/css" }
5
+ %link{ "rel" => "stylesheet", "href" => "/stylesheets/main.css", "type" => "text/css" }
6
+ %body
7
+ .main
8
+ .menu.home-menu
9
+ %a{ href: '/' } Home
10
+ = yield
@@ -0,0 +1 @@
1
+ Current directory dosen't have Salck log data.
@@ -0,0 +1,38 @@
1
+ - if attachment["image_url"]
2
+ %span.attachment-image
3
+ %a{href: attachment["fron_url"]}
4
+ %img{src: attachment["image_url"]}
5
+
6
+ - if attachment["thumb_url"]
7
+ %span.attachment-image
8
+ %a{href: attachment["fron_url"]}
9
+ %img{src: attachment["thumb_url"]}
10
+
11
+ %span.attachment-title
12
+ - if attachment["from_url"]
13
+ %a{href: attachment["from_url"]}
14
+ - if attachment["title"]
15
+ = attachment["title"]
16
+ - else
17
+ - if attachment["from_url"].length < 50
18
+ = attachment["from_url"]
19
+ - else
20
+ = attachment["from_url"][0..49] + "..."
21
+
22
+ - if attachment["text"]
23
+ %span.attachment-text
24
+ = attachment["text"]
25
+
26
+ .clear
27
+
28
+ - if attachment["video_html"]
29
+ %div.attachment-video
30
+ = attachment["video_html"]
31
+
32
+ %div.clear
33
+ -# - if attachment["title_link"]
34
+ -# (
35
+ -# = attachment["service_name"]
36
+ -# = " - "
37
+ -# = attachment["title"]
38
+ -# )
@@ -0,0 +1,23 @@
1
+ %a{name: log["ts"].to_s}
2
+ %div.log
3
+ - if log["user"]
4
+ %span.user
5
+ %span.profile-image{onclick: "target = document.getElementById('debug-#{log["ts"]}'); target.style.display = target.style.display === 'none' ? 'block' : 'none'"}
6
+ %img{src: log["user"]["profile"]["image_24"]}
7
+ = log["user"]["name"]
8
+ %span.time
9
+ %a{href: "#" + log["ts"].to_s}
10
+ = Time.at(log["ts"].to_i).strftime("%H:%M:%S")
11
+ = ":"
12
+
13
+ %span.text
14
+ = preserve Twemoji.parse(log["text"])
15
+
16
+ - if log["attachments"]
17
+ %div.attachment
18
+ - log["attachments"].each do |attachment|
19
+ = haml :"./partials/attachment", locals: {attachment: attachment}
20
+
21
+ %div{class: ["debug"], id: ["debug-#{log["ts"]}"]}
22
+ %pre
23
+ = preserve JSON.pretty_generate(log)
@@ -0,0 +1,26 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require 'slack_log_viewer/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'slack_log_viewer'
8
+ spec.version = ::SlackLogViewer::VERSION
9
+ spec.platform = Gem::Platform::RUBY
10
+ spec.authors = ['Daekwon Kim']
11
+ spec.email = ['i-am-not-a-machine@nacyot.com']
12
+ spec.homepage = 'https://github.com/nacyot/slack_log_viewer'
13
+ spec.summary = 'Slack log viewer'
14
+ spec.description = 'Slack log viewer'
15
+ spec.license = 'MIT'
16
+
17
+ spec.add_development_dependency 'bundler'
18
+
19
+ spec.add_dependency 'sinatra', '~> 1.4'
20
+ spec.add_dependency 'haml', '~> 4.0'
21
+ spec.add_dependency 'twemoji', '~> 2.1'
22
+
23
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) }
24
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
25
+ spec.require_paths = %w( lib )
26
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: slack_log_viewer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Daekwon Kim
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sinatra
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: haml
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: twemoji
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.1'
69
+ description: Slack log viewer
70
+ email:
71
+ - i-am-not-a-machine@nacyot.com
72
+ executables:
73
+ - slack-log-viewer
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - README.md
81
+ - bin/slack-log-viewer
82
+ - lib/slack_log_viewer.rb
83
+ - lib/slack_log_viewer/version.rb
84
+ - lib/static/stylesheets/main.css
85
+ - lib/static/stylesheets/normalize.css
86
+ - lib/views/channel.haml
87
+ - lib/views/day.haml
88
+ - lib/views/index.haml
89
+ - lib/views/layout.haml
90
+ - lib/views/not_log_dir.haml
91
+ - lib/views/partials/attachment.haml
92
+ - lib/views/partials/log.haml
93
+ - slack_log_viewer.gemspec
94
+ homepage: https://github.com/nacyot/slack_log_viewer
95
+ licenses:
96
+ - MIT
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 2.4.5.1
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: Slack log viewer
118
+ test_files: []