slack_log_viewer 0.3.0

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 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: []