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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bed4b833ec200a7e4269205379ff12118ee364c9
4
- data.tar.gz: 1bf60094a6d36fc79843f6ed0cecf6670d1ea78e
3
+ metadata.gz: 56b9028533b252ce83872884a332a85d344f7dc0
4
+ data.tar.gz: 670049b263e5c25aa3222311033546af65dfce6b
5
5
  SHA512:
6
- metadata.gz: df7817192ebf16acc8fac4dcea7029d2f8bfb44c3d95dbcff8606913000802b281f46d511aa242907908ea7bb5c876d24e67b4ab8a5a5e1c0595251525853ff2
7
- data.tar.gz: 335bea07ac31c3252cce066f3cc8fba41e75e39153652d469d47d34d9a6d115b6931d99f54d296bda0328e1dcb92514a2e982c9f7c170852f9e9cb93fa8010d9
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
- { type =>
55
- { '_timestamp' => { 'enabled' => true, 'path' => 'dataetime' },
56
- '_id' => { 'path' => 'uid' } } }
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 = {})
@@ -0,0 +1,6 @@
1
+ module SlackScratcher
2
+ module Error
3
+ class TokenNotSet < StandardError
4
+ end
5
+ end
6
+ end
@@ -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
@@ -0,0 +1,8 @@
1
+ module SlackScratcher
2
+ module Helper
3
+ def self.index_data(dataset, column)
4
+ dataset.map { |data| { data[column] => data } }.inject({}, :merge)
5
+ end
6
+ end
7
+ end
8
+
@@ -5,56 +5,95 @@ module SlackScratcher
5
5
  class Api
6
6
  include Enumerable
7
7
 
8
- WAIT_TIME = 15
8
+ WAIT_TIME = 1
9
9
 
10
- def initalize
11
-
10
+ def initialize(token = nil)
11
+ authenticate_slack(token)
12
12
  end
13
13
 
14
14
  def each(adapter)
15
- active_channels do |channel|
16
- wait
17
- from = adapter.time_of_channel_last_log(channel.name)
18
- to = 'now'
19
- yield channel_history(channel, from, to)
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 channels
26
- result = Slack.channels_list['channels']
27
- fail SlackScratcher::Error::ApiError unless result['ok'] == true
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
- result.map { |ch| { id: ch['id'], name: ch['name'] } }
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
- result = Slack.channels_list['channels']
34
- fail SlackScratcher::Error::ApiError unless result['ok'] == true
59
+ wait
35
60
 
36
- result.select { |ch| ch['is_archived'] == false }
37
- .map { |ch| { id: ch['id'], name: ch['name'] } }
61
+ response = validate_response(Slack.channels_list)
62
+ index_channels filter_active_channels(response['channels'])
38
63
  end
39
64
 
40
- def user_info(user_id)
41
- result = Slack.users_info(user: user_id)
42
- fail SlackScratcher::Error::ApiError unless result['ok'] == true
65
+ def filter_active_channels(data)
66
+ data.select { |channel| channel['is_archived'] == false }
67
+ end
43
68
 
44
- result
69
+ def index_channels(data)
70
+ data.map { |channel| { id: channel['id'], name: channel['name'] } }
45
71
  end
46
72
 
47
- def channel_history(channel, from, to = Time.now)
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: channel,
50
- oldest: from.to_i,
51
- latest: to.to_i
84
+ channel: channel_id,
85
+ oldest: from,
86
+ latest: to,
87
+ count: 1000
52
88
  }
53
89
 
54
- result = Slack.channels_history(attrs)
55
- fail SlackScratcher::Error::ApiError unless result['ok'] == true
90
+ validate_response Slack.channels_history(attrs), :messages
91
+ end
56
92
 
57
- result
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
- chats = SlackScratcher::Model::Chats.new(logs, channel, @users)
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
- channels.inject([]) do |arr, channel|
57
+ channel_dirs.inject([]) do |arr, channel|
64
58
  arr + log_files(channel)
65
59
  end
66
60
  end
67
61
 
68
- def channels
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['user']) unless user
27
+ user = find_user(log) unless user
28
28
 
29
- log['name'] = user['name']
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['user']}"
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(user)
57
- result = @users[user]
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
- @loader.each do |data, file|
12
- @adapter.send data
13
- SlackScratcher.logger.info "* #{file} is routed."
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
@@ -1,3 +1,3 @@
1
1
  module SlackScratcher
2
- VERSION = '0.0.1'
2
+ VERSION = '0.1'
3
3
  end
@@ -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.0.1
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-13 00:00:00.000000000 Z
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
@@ -1,16 +0,0 @@
1
- module SlackScratcher
2
- class Collector
3
- def initialize(loader, adapter)
4
- @loader = loader
5
- @adapter = adapter
6
- end
7
-
8
- def collect_loop
9
- loop do
10
- @loader.each(@adapter) do |data|
11
- @adapter.send data
12
- end
13
- end
14
- end
15
- end
16
- end