slack_scratcher 0.0.1 → 0.1
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/lib/slack_scratcher/adapter/elasticsearch.rb +33 -4
- data/lib/slack_scratcher/error/token_not_set.rb +6 -0
- data/lib/slack_scratcher/error.rb +1 -0
- data/lib/slack_scratcher/helper.rb +8 -0
- data/lib/slack_scratcher/loader/api.rb +66 -27
- data/lib/slack_scratcher/loader/file.rb +5 -11
- data/lib/slack_scratcher/model/chats.rb +21 -8
- data/lib/slack_scratcher/router.rb +21 -3
- data/lib/slack_scratcher/version.rb +1 -1
- data/lib/slack_scratcher.rb +5 -1
- metadata +32 -3
- data/lib/slack_scratcher/collector.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56b9028533b252ce83872884a332a85d344f7dc0
|
4
|
+
data.tar.gz: 670049b263e5c25aa3222311033546af65dfce6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a65adf9dc0a91ad769aabfc1b7cf82133c95f19de544f3f368cdf20ab1444c2986e46928e0f1689dc05f8f0651da514c63174a71d1be2b12bff56b904247f408
|
7
|
+
data.tar.gz: 3ecb3d72f1f036f4c13ae7e706c82c094d75930c2d89d7ee5f8c657e6c0dd9052142df94bb831d021ca8264682825f66a141a981cb4c7982ac89b767eb79b7e4
|
@@ -18,7 +18,11 @@ module SlackScratcher
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def timestamp_of_last_channel_log(channel_name)
|
21
|
-
|
21
|
+
request_body = create_body(query_for_last_log(channel_name))
|
22
|
+
log = @client.search request_body
|
23
|
+
|
24
|
+
return 0 if log['hits']['total'] == 0
|
25
|
+
log['hits']['hits'][0]['_source']['ts']
|
22
26
|
end
|
23
27
|
|
24
28
|
def ready_index
|
@@ -51,9 +55,34 @@ module SlackScratcher
|
|
51
55
|
end
|
52
56
|
|
53
57
|
def mapping
|
54
|
-
{
|
55
|
-
|
56
|
-
'
|
58
|
+
{
|
59
|
+
type => {
|
60
|
+
'_timestamp' => {
|
61
|
+
'enabled' => true,
|
62
|
+
'path' => 'dataetime'
|
63
|
+
},
|
64
|
+
'_id' => {
|
65
|
+
'path' => 'uid'
|
66
|
+
},
|
67
|
+
'_routing' => {
|
68
|
+
'required' => true,
|
69
|
+
'path' => 'channel_id'
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def query_for_last_log(channel_name)
|
76
|
+
{
|
77
|
+
size: 1,
|
78
|
+
sort:
|
79
|
+
[ { datetime: { order: 'desc' } }],
|
80
|
+
query: {
|
81
|
+
match: {
|
82
|
+
channel: channel_name
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
57
86
|
end
|
58
87
|
|
59
88
|
def create_body(body = {})
|
@@ -3,5 +3,6 @@ module SlackScratcher
|
|
3
3
|
autoload :UserNotFoundError, 'slack_scratcher/error/user_not_found_error'
|
4
4
|
autoload :SlackApiError, 'slack_scratcher/error/slack_api_error'
|
5
5
|
autoload :FileNotFound, 'slack_scratcher/error/file_not_found'
|
6
|
+
autoload :TokenNotSet, 'slack_scratcher/error/token_not_set'
|
6
7
|
end
|
7
8
|
end
|
@@ -5,56 +5,95 @@ module SlackScratcher
|
|
5
5
|
class Api
|
6
6
|
include Enumerable
|
7
7
|
|
8
|
-
WAIT_TIME =
|
8
|
+
WAIT_TIME = 1
|
9
9
|
|
10
|
-
def
|
11
|
-
|
10
|
+
def initialize(token = nil)
|
11
|
+
authenticate_slack(token)
|
12
12
|
end
|
13
13
|
|
14
14
|
def each(adapter)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
yield
|
15
|
+
@users || set_users
|
16
|
+
|
17
|
+
active_channels.each do |channel|
|
18
|
+
from = adapter.timestamp_of_last_channel_log(channel[:name])
|
19
|
+
yield parse_log(channel, from), channel
|
20
20
|
end
|
21
|
+
|
22
|
+
true
|
21
23
|
end
|
22
24
|
|
23
25
|
private
|
24
26
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
27
|
+
def set_users
|
28
|
+
@users = users
|
29
|
+
SlackScratcher.logger.info "* Users list refreshed"
|
30
|
+
end
|
31
|
+
|
32
|
+
def check_users(logs)
|
33
|
+
logs
|
34
|
+
.select { |log| log.key? 'user' }
|
35
|
+
.map { |log| log['user'] }
|
36
|
+
.any? { |user| @users[user].nil? }
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_log(channel, from)
|
40
|
+
logs = channel_history(channel[:id], from)
|
41
|
+
if check_users(logs)
|
42
|
+
set_users
|
43
|
+
end
|
44
|
+
SlackScratcher::Model::Chats.new(logs, channel, @users).refined_data
|
45
|
+
end
|
28
46
|
|
29
|
-
|
47
|
+
def authenticate_slack(token)
|
48
|
+
token ||= ENV['SLACK_TOKEN']
|
49
|
+
fail SlackScratcher::Error::TokenNotSet unless token
|
50
|
+
Slack.configure { |config| config.token = token }
|
51
|
+
end
|
52
|
+
|
53
|
+
def channels
|
54
|
+
response = validate_response(Slack.channels_list)
|
55
|
+
index_channels response['channels']
|
30
56
|
end
|
31
57
|
|
32
58
|
def active_channels
|
33
|
-
|
34
|
-
fail SlackScratcher::Error::ApiError unless result['ok'] == true
|
59
|
+
wait
|
35
60
|
|
36
|
-
|
37
|
-
|
61
|
+
response = validate_response(Slack.channels_list)
|
62
|
+
index_channels filter_active_channels(response['channels'])
|
38
63
|
end
|
39
64
|
|
40
|
-
def
|
41
|
-
|
42
|
-
|
65
|
+
def filter_active_channels(data)
|
66
|
+
data.select { |channel| channel['is_archived'] == false }
|
67
|
+
end
|
43
68
|
|
44
|
-
|
69
|
+
def index_channels(data)
|
70
|
+
data.map { |channel| { id: channel['id'], name: channel['name'] } }
|
45
71
|
end
|
46
72
|
|
47
|
-
def
|
73
|
+
def users
|
74
|
+
wait
|
75
|
+
|
76
|
+
user_list = validate_response(Slack.users_list, :members)
|
77
|
+
SlackScratcher::Helper.index_data user_list, 'id'
|
78
|
+
end
|
79
|
+
|
80
|
+
def channel_history(channel_id, from, to = Time.now)
|
81
|
+
wait
|
82
|
+
|
48
83
|
attrs = {
|
49
|
-
channel:
|
50
|
-
oldest: from
|
51
|
-
latest: to
|
84
|
+
channel: channel_id,
|
85
|
+
oldest: from,
|
86
|
+
latest: to,
|
87
|
+
count: 1000
|
52
88
|
}
|
53
89
|
|
54
|
-
|
55
|
-
|
90
|
+
validate_response Slack.channels_history(attrs), :messages
|
91
|
+
end
|
56
92
|
|
57
|
-
|
93
|
+
def validate_response(response, key = nil)
|
94
|
+
fail SlackScratcher::Error::ApiError unless response['ok'] == true
|
95
|
+
return response unless key
|
96
|
+
response[key.to_s]
|
58
97
|
end
|
59
98
|
|
60
99
|
def wait
|
@@ -13,7 +13,7 @@ module SlackScratcher
|
|
13
13
|
@channels = channels
|
14
14
|
end
|
15
15
|
|
16
|
-
def each
|
16
|
+
def each(_ = nil)
|
17
17
|
files.each do |file|
|
18
18
|
yield parse_log_file(file), file
|
19
19
|
end
|
@@ -39,11 +39,7 @@ module SlackScratcher
|
|
39
39
|
fail SlackScratcher::Error::FileNotFound unless ::File.exist? target
|
40
40
|
|
41
41
|
channels = Oj.load(::File.read(target))
|
42
|
-
index_data channels, index_column
|
43
|
-
end
|
44
|
-
|
45
|
-
def index_data(dataset, column)
|
46
|
-
dataset.map { |data| { data[column] => data } }.inject({}, :merge)
|
42
|
+
SlackScratcher::Helper.index_data channels, index_column
|
47
43
|
end
|
48
44
|
|
49
45
|
def channel_info(log_file)
|
@@ -54,18 +50,16 @@ module SlackScratcher
|
|
54
50
|
def parse_log_file(log_file)
|
55
51
|
channel = channel_info(log_file)
|
56
52
|
logs = Oj.load(::File.read(log_file))
|
57
|
-
|
58
|
-
|
59
|
-
chats.refined_data
|
53
|
+
SlackScratcher::Model::Chats.new(logs, channel, @users).refined_data
|
60
54
|
end
|
61
55
|
|
62
56
|
def files
|
63
|
-
|
57
|
+
channel_dirs.inject([]) do |arr, channel|
|
64
58
|
arr + log_files(channel)
|
65
59
|
end
|
66
60
|
end
|
67
61
|
|
68
|
-
def
|
62
|
+
def channel_dirs
|
69
63
|
Dir["#{@target}/*/"]
|
70
64
|
end
|
71
65
|
|
@@ -24,9 +24,9 @@ module SlackScratcher
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def refine_data(log)
|
27
|
-
user = find_user(log
|
27
|
+
user = find_user(log) unless user
|
28
28
|
|
29
|
-
log['
|
29
|
+
log['username'] = user['name']
|
30
30
|
log['profile_image'] = user['profile']['image_32']
|
31
31
|
log['text'] = refine_text(log['text'])
|
32
32
|
log['channel'] = @channel[:name]
|
@@ -36,13 +36,10 @@ module SlackScratcher
|
|
36
36
|
log['uid'] = create_uid(log)
|
37
37
|
|
38
38
|
log
|
39
|
-
rescue SlackScratcher::Error::UserNotFoundError
|
40
|
-
user = { 'user' => 'undefined' }
|
41
|
-
user['profile'] = { 'image_32' => '' }
|
42
39
|
end
|
43
40
|
|
44
41
|
def create_uid(log)
|
45
|
-
"#{log['datetime']}-#{log['channel_id']}-#{log['
|
42
|
+
"#{log['datetime']}-#{log['channel_id']}-#{log['username']}"
|
46
43
|
end
|
47
44
|
|
48
45
|
def refine_text(text)
|
@@ -53,11 +50,27 @@ module SlackScratcher
|
|
53
50
|
.gsub(%r{<(http(s)?://.*?)>}) { $1 }
|
54
51
|
end
|
55
52
|
|
56
|
-
def find_user(
|
57
|
-
|
53
|
+
def find_user(log)
|
54
|
+
return bot_user(log) if log.key?('username')
|
55
|
+
|
56
|
+
result = @users[log['user']]
|
58
57
|
|
59
58
|
fail SlackScratcher::Error::UserNotFoundError if result.nil?
|
60
59
|
result
|
60
|
+
rescue SlackScratcher::Error::UserNotFoundError
|
61
|
+
unknown_user
|
62
|
+
end
|
63
|
+
|
64
|
+
def undefined_user
|
65
|
+
user = { 'name' => '_unknown_' }
|
66
|
+
user['profile'] = { 'image_32' => '' }
|
67
|
+
user
|
68
|
+
end
|
69
|
+
|
70
|
+
def bot_user(log)
|
71
|
+
user = { 'name' => log['username'] }
|
72
|
+
user['profile'] = { 'image_32' => log['icons']['image_48'] }
|
73
|
+
user
|
61
74
|
end
|
62
75
|
end
|
63
76
|
end
|
@@ -6,11 +6,29 @@ module SlackScratcher
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def route
|
9
|
+
ready
|
10
|
+
_route
|
11
|
+
end
|
12
|
+
|
13
|
+
def route_loop
|
14
|
+
ready
|
15
|
+
loop { _route }
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def ready
|
9
21
|
@adapter.ready_index
|
22
|
+
end
|
10
23
|
|
11
|
-
|
12
|
-
|
13
|
-
|
24
|
+
def _route
|
25
|
+
@loader.each(@adapter) do |data, metadata|
|
26
|
+
if data.empty?
|
27
|
+
SlackScratcher.logger.info "* #{metadata} is empty. Nothing happen."
|
28
|
+
else
|
29
|
+
@adapter.send data
|
30
|
+
SlackScratcher.logger.info "* #{metadata} is routed."
|
31
|
+
end
|
14
32
|
end
|
15
33
|
end
|
16
34
|
end
|
data/lib/slack_scratcher.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
$LOAD_PATH.unshift File.dirname(__FILE__)
|
2
2
|
require 'logger'
|
3
|
+
require 'dotenv'
|
4
|
+
require 'faraday'
|
5
|
+
|
6
|
+
Dotenv.load
|
3
7
|
|
4
8
|
module SlackScratcher
|
5
9
|
autoload :Model, 'slack_scratcher/model'
|
6
10
|
autoload :Loader, 'slack_scratcher/loader'
|
7
11
|
autoload :Adapter, 'slack_scratcher/adapter'
|
8
12
|
autoload :Router, 'slack_scratcher/router'
|
9
|
-
autoload :Collector, 'slack_scratcher/collector'
|
10
13
|
autoload :Error, 'slack_scratcher/error'
|
14
|
+
autoload :Helper, 'slack_scratcher/helper'
|
11
15
|
|
12
16
|
def self.logger
|
13
17
|
@logger ||= ::Logger.new(STDOUT)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slack_scratcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.1'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daekwon Kim
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: elasticsearch
|
@@ -52,6 +52,34 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: faraday
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.9.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.9.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: dotenv
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: guard
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -148,11 +176,12 @@ files:
|
|
148
176
|
- lib/slack_scratcher/adapter.rb
|
149
177
|
- lib/slack_scratcher/adapter/elasticsearch.rb
|
150
178
|
- lib/slack_scratcher/adapter/file.rb
|
151
|
-
- lib/slack_scratcher/collector.rb
|
152
179
|
- lib/slack_scratcher/error.rb
|
153
180
|
- lib/slack_scratcher/error/file_not_found.rb
|
154
181
|
- lib/slack_scratcher/error/slack_api_error.rb
|
182
|
+
- lib/slack_scratcher/error/token_not_set.rb
|
155
183
|
- lib/slack_scratcher/error/user_not_found_error.rb
|
184
|
+
- lib/slack_scratcher/helper.rb
|
156
185
|
- lib/slack_scratcher/loader.rb
|
157
186
|
- lib/slack_scratcher/loader/api.rb
|
158
187
|
- lib/slack_scratcher/loader/file.rb
|