fluent-plugin-github-activities 0.6.1 → 0.7.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 +4 -4
- data/README.md +40 -5
- data/fluent-plugin-github-activities.gemspec +3 -2
- data/lib/fluent/plugin/github-activities.rb +5 -3
- data/lib/fluent/plugin/github-activities/crawler.rb +260 -249
- data/lib/fluent/plugin/github-activities/users_manager.rb +45 -65
- data/lib/fluent/plugin/in_github-activities.rb +96 -78
- data/test/fixture/piroor-events.json +47 -0
- data/test/fixture/users.txt +2 -0
- data/test/plugin/test_in_github_activity.rb +85 -0
- data/test/run-test.rb +1 -0
- data/test/test_crawler.rb +132 -109
- metadata +26 -7
- data/lib/fluent/plugin/github-activities/safe_file_writer.rb +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5566e97e3de09ccc09711e64cf7fae99072925f5
|
4
|
+
data.tar.gz: b114642700ecda10abe35598ce12bbc988879176
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f2a08171cf6e4dbf37163a41d1d77185e60123377b3bfcda9f75a53e203b29eee3d6f30d50da607c6fda7dde13162028ab01ef14bf4871f5738fa1a161b7dd1
|
7
|
+
data.tar.gz: f85cc6dc814b6349c1f86d8ecd74b1f30c484aed23bb9000a011cbb43ab0e58c3af6d7d47ade7ce705a958cce6bd5735c2ea61508324491bfec5f2ef057305c7
|
data/README.md
CHANGED
@@ -6,6 +6,29 @@
|
|
6
6
|
Provides ability to watch public activities on GitHub.
|
7
7
|
This crawls GitHub activities of specified users and forward each activity as a record.
|
8
8
|
|
9
|
+
## Requirements
|
10
|
+
|
11
|
+
| fluent-plugin-github-activities | fluentd | ruby |
|
12
|
+
|---------------------------------|------------|--------|
|
13
|
+
| >= 0.7.0 | >= v0.14.0 | >= 2.1 |
|
14
|
+
| < 0.7.0 | >= v0.12.0 | >= 1.9 |
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Add this line to your application's Gemfile:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem 'fluent-plugin-github-activities'
|
22
|
+
```
|
23
|
+
|
24
|
+
And then execute:
|
25
|
+
|
26
|
+
$ bundle
|
27
|
+
|
28
|
+
Or install it yourself as:
|
29
|
+
|
30
|
+
$ gem install fluent-plugin-github-activities
|
31
|
+
|
9
32
|
## Supported activity types
|
10
33
|
|
11
34
|
* Activities related to commits
|
@@ -94,11 +117,6 @@ Then the value of the `token` field is the access key to be written to the confi
|
|
94
117
|
# Number of clients. This is `4` by default.
|
95
118
|
clients 1
|
96
119
|
|
97
|
-
# Path to a file to store timestamp of last crawled activity
|
98
|
-
# for each user. If you don't specify this option, same records
|
99
|
-
# can be forwarded after the fluentd is restarted.
|
100
|
-
pos_file /tmp/github-activities.json
|
101
|
-
|
102
120
|
# Base tag of forwarded records. It will be used as
|
103
121
|
# <base_tag>.<activity type>, like: "github-activity.push",
|
104
122
|
# "github-activity.StatusEvent", etc.
|
@@ -123,3 +141,20 @@ Then the value of the `token` field is the access key to be written to the confi
|
|
123
141
|
#include_foreign_commits true
|
124
142
|
</source>
|
125
143
|
~~~
|
144
|
+
|
145
|
+
### Breaking changes
|
146
|
+
|
147
|
+
`pos_file` is obsoleted since 0.7.0. Use storage instead as following:
|
148
|
+
|
149
|
+
```
|
150
|
+
<source>
|
151
|
+
@type github-activities
|
152
|
+
<storage>
|
153
|
+
@type local
|
154
|
+
persistent true
|
155
|
+
# or if you want to take over old pos_file,
|
156
|
+
# path parameter must be end with ".json".
|
157
|
+
# path /path/to/pos_file.json
|
158
|
+
</storage>
|
159
|
+
</source>
|
160
|
+
```
|
@@ -19,7 +19,7 @@
|
|
19
19
|
|
20
20
|
Gem::Specification.new do |spec|
|
21
21
|
spec.name = "fluent-plugin-github-activities"
|
22
|
-
spec.version = "0.
|
22
|
+
spec.version = "0.7.0"
|
23
23
|
spec.authors = ["YUKI Hiroshi"]
|
24
24
|
spec.email = ["yuki@clear-code.com"]
|
25
25
|
spec.summary = "Fluentd plugin to crawl public activities on the GitHub."
|
@@ -33,11 +33,12 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.test_files += Dir.glob("test/**/*")
|
34
34
|
spec.require_paths = ["lib"]
|
35
35
|
|
36
|
-
spec.add_runtime_dependency("fluentd", [">= 0.
|
36
|
+
spec.add_runtime_dependency("fluentd", [">= 0.14.13", "< 2"])
|
37
37
|
|
38
38
|
spec.add_development_dependency("rake")
|
39
39
|
spec.add_development_dependency("bundler")
|
40
40
|
spec.add_development_dependency("packnga", ">= 1.0.1")
|
41
41
|
spec.add_development_dependency("test-unit")
|
42
42
|
spec.add_development_dependency("test-unit-notify")
|
43
|
+
spec.add_development_dependency("webmock")
|
43
44
|
end
|
@@ -21,8 +21,10 @@ require "fluent/plugin/github-activities/users_manager"
|
|
21
21
|
require "fluent/plugin/github-activities/crawler"
|
22
22
|
|
23
23
|
module Fluent
|
24
|
-
module
|
25
|
-
|
26
|
-
|
24
|
+
module Plugin
|
25
|
+
module GithubActivities
|
26
|
+
TYPE_EVENTS = :events
|
27
|
+
TYPE_COMMIT = :commit
|
28
|
+
end
|
27
29
|
end
|
28
30
|
end
|
@@ -25,311 +25,322 @@ require "time"
|
|
25
25
|
require "fluent/plugin/github-activities/users_manager"
|
26
26
|
|
27
27
|
module Fluent
|
28
|
-
module
|
29
|
-
|
30
|
-
class
|
31
|
-
|
28
|
+
module Plugin
|
29
|
+
module GithubActivities
|
30
|
+
class Crawler
|
31
|
+
class EmptyRequestQueue < StandardError
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
-
|
34
|
+
NO_INTERVAL = 0
|
35
|
+
DEFAULT_INTERVAL = 1
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
37
|
+
RELATED_USER_IMAGE_KEY = "$github-activities-related-avatar"
|
38
|
+
RELATED_ORGANIZATION_IMAGE_KEY = "$github-activities-related-organization-logo"
|
39
|
+
RELATED_EVENT = "$github-activities-related-event"
|
39
40
|
|
40
|
-
|
41
|
-
|
41
|
+
attr_writer :on_emit
|
42
|
+
attr_reader :request_queue, :interval_for_next_request, :log, :running
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
|
44
|
+
def initialize(options={})
|
45
|
+
@users_manager = UsersManager.new(users: options[:watching_users],
|
46
|
+
pos_storage: options[:pos_storage])
|
46
47
|
|
47
|
-
|
48
|
+
@access_token = options[:access_token]
|
48
49
|
|
49
|
-
|
50
|
+
@watching_users = options[:watching_users] || []
|
50
51
|
|
51
|
-
|
52
|
-
|
52
|
+
@include_commits_from_pull_request = options[:include_commits_from_pull_request]
|
53
|
+
@include_foreign_commits = options[:include_foreign_commits]
|
53
54
|
|
54
|
-
|
55
|
+
@request_queue = options[:request_queue] || []
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
$log.debug("GithubActivities::Crawler: processing request: #{request.inspect}") if $log
|
62
|
-
if request[:process_after] and
|
63
|
-
Time.now.to_i < request[:process_after]
|
64
|
-
@request_queue.push(request)
|
65
|
-
@interval_for_next_request = NO_INTERVAL
|
66
|
-
return false
|
57
|
+
@default_interval = options[:default_interval] || DEFAULT_INTERVAL
|
58
|
+
@interval_for_next_request = @default_interval
|
59
|
+
# Fluent::PluginLogger instance
|
60
|
+
@log = options[:log]
|
61
|
+
@running = true
|
67
62
|
end
|
68
63
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
when Net::HTTPSuccess
|
78
|
-
$log.trace("GithubActivities::Crawler: Net::HTTPSuccess / request type: #{request[:type]}") if $log
|
79
|
-
body = JSON.parse(response.body)
|
80
|
-
case request[:type]
|
81
|
-
when TYPE_EVENTS
|
82
|
-
events = body
|
83
|
-
$log.trace("GithubActivities::Crawler: events size: #{events.size}") if $log
|
84
|
-
process_user_events(request[:user], events)
|
85
|
-
reserve_user_events(request[:user], :previous_response => response)
|
86
|
-
@users_manager.save_position_for(request[:user], :entity_tag => response["ETag"])
|
87
|
-
when TYPE_COMMIT
|
88
|
-
process_commit(body, request[:push])
|
64
|
+
def process_request
|
65
|
+
request = @request_queue.shift
|
66
|
+
log.debug("GithubActivities::Crawler: processing request: #{request.inspect}")
|
67
|
+
if request[:process_after] and
|
68
|
+
Time.now.to_i < request[:process_after]
|
69
|
+
@request_queue.push(request)
|
70
|
+
@interval_for_next_request = NO_INTERVAL
|
71
|
+
return false
|
89
72
|
end
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
73
|
+
|
74
|
+
uri = request_uri(request)
|
75
|
+
extra_headers = extra_request_headers(request)
|
76
|
+
|
77
|
+
log.debug("GithubActivities::Crawler: requesting to #{uri.inspect}")
|
78
|
+
response = http_get(uri, extra_headers)
|
79
|
+
log.debug("GithubActivities::Crawler: response: #{response.inspect}")
|
80
|
+
|
81
|
+
case response
|
82
|
+
when Net::HTTPSuccess
|
83
|
+
log.trace("GithubActivities::Crawler: Net::HTTPSuccess / request type: #{request[:type]}")
|
84
|
+
body = JSON.parse(response.body)
|
85
|
+
case request[:type]
|
86
|
+
when TYPE_EVENTS
|
87
|
+
events = body
|
88
|
+
log.trace("GithubActivities::Crawler: events size: #{events.size}")
|
89
|
+
process_user_events(request[:user], events)
|
90
|
+
reserve_user_events(request[:user], previous_response: response)
|
91
|
+
@users_manager.save_position_for(request[:user], entity_tag: response["ETag"])
|
92
|
+
when TYPE_COMMIT
|
93
|
+
process_commit(body, request[:push])
|
94
|
+
end
|
95
|
+
when Net::HTTPNotModified
|
96
|
+
log.trace("GithubActivities::Crawler: Net::HTTPNotModified / request type: #{request[:type]}")
|
97
|
+
case request[:type]
|
98
|
+
when TYPE_EVENTS
|
99
|
+
reserve_user_events(request[:user],
|
100
|
+
previous_response: response,
|
101
|
+
previous_entity_tag: extra_headers["If-None-Match"])
|
102
|
+
end
|
103
|
+
@interval_for_next_request = @default_interval
|
104
|
+
return true
|
105
|
+
else
|
106
|
+
log.trace("GithubActivities::Crawler: UnknownType / request type: #{request[:type]}")
|
107
|
+
case request[:type]
|
108
|
+
when TYPE_COMMIT
|
109
|
+
fake_body = {
|
110
|
+
"sha" => request[:sha],
|
111
|
+
"author" => {},
|
112
|
+
}
|
113
|
+
process_commit(fake_body, request[:push])
|
114
|
+
end
|
97
115
|
end
|
98
116
|
@interval_for_next_request = @default_interval
|
99
117
|
return true
|
100
|
-
|
101
|
-
|
102
|
-
case request[:type]
|
103
|
-
when TYPE_COMMIT
|
104
|
-
fake_body = {
|
105
|
-
"sha" => request[:sha],
|
106
|
-
"author" => {},
|
107
|
-
}
|
108
|
-
process_commit(fake_body, request[:push])
|
109
|
-
end
|
118
|
+
rescue StandardError => error
|
119
|
+
log.error(error.inspect)
|
110
120
|
end
|
111
|
-
@interval_for_next_request = @default_interval
|
112
|
-
return true
|
113
|
-
rescue StandardError => error
|
114
|
-
$log.error(error.inspect)
|
115
|
-
end
|
116
121
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
122
|
+
def request_uri(request)
|
123
|
+
uri = nil
|
124
|
+
case request[:type]
|
125
|
+
when TYPE_EVENTS
|
126
|
+
uri = user_activities(request[:user])
|
127
|
+
else
|
128
|
+
uri = request[:uri]
|
129
|
+
end
|
124
130
|
end
|
125
|
-
end
|
126
131
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
132
|
+
def extra_request_headers(request)
|
133
|
+
headers = {}
|
134
|
+
if request[:previous_entity_tag]
|
135
|
+
headers["If-None-Match"] = request[:previous_entity_tag]
|
136
|
+
elsif request[:type] == TYPE_EVENTS
|
137
|
+
position = @users_manager.position_for(request[:user])
|
138
|
+
if position
|
139
|
+
entity_tag = position["entity_tag"]
|
140
|
+
headers["If-None-Match"] = entity_tag if entity_tag
|
141
|
+
end
|
136
142
|
end
|
143
|
+
headers
|
137
144
|
end
|
138
|
-
headers
|
139
|
-
end
|
140
|
-
|
141
|
-
def reserve_user_events(user, options={})
|
142
|
-
request = @users_manager.new_events_request(user, options)
|
143
|
-
@request_queue.push(request)
|
144
|
-
end
|
145
145
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
if position and position["last_event_timestamp"]
|
150
|
-
last_event_timestamp = position["last_event_timestamp"]
|
146
|
+
def reserve_user_events(user, options={})
|
147
|
+
request = @users_manager.new_events_request(user, options)
|
148
|
+
@request_queue.push(request) if @running
|
151
149
|
end
|
152
150
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
process_user_event(user, event)
|
160
|
-
@users_manager.save_position_for(user, :last_event_timestamp => timestamp)
|
161
|
-
end
|
162
|
-
end
|
151
|
+
def process_user_events(user, events)
|
152
|
+
last_event_timestamp = UsersManager::DEFAULT_LAST_EVENT_TIMESTAMP
|
153
|
+
position = @users_manager.position_for(user)
|
154
|
+
if position and position["last_event_timestamp"]
|
155
|
+
last_event_timestamp = position["last_event_timestamp"]
|
156
|
+
end
|
163
157
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
158
|
+
events = events.sort do |a, b|
|
159
|
+
b["created_at"] <=> a["created_at"]
|
160
|
+
end
|
161
|
+
events.each do |event|
|
162
|
+
timestamp = Time.parse(event["created_at"]).to_i
|
163
|
+
next if timestamp <= last_event_timestamp
|
164
|
+
process_user_event(user, event)
|
165
|
+
@users_manager.save_position_for(user, last_event_timestamp: timestamp)
|
166
|
+
end
|
169
167
|
end
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
168
|
+
|
169
|
+
def process_user_event(user, event)
|
170
|
+
# see also: https://developer.github.com/v3/activity/events/types/
|
171
|
+
event[RELATED_USER_IMAGE_KEY] = event["actor"]["avatar_url"]
|
172
|
+
if event["org"]
|
173
|
+
event[RELATED_ORGANIZATION_IMAGE_KEY] = event["org"]["avatar_url"]
|
174
|
+
end
|
175
|
+
case event["type"]
|
176
|
+
when "PushEvent"
|
177
|
+
process_push_event(event)
|
178
|
+
when "CommitCommentEvent"
|
179
|
+
emit("commit-comment", event)
|
180
|
+
when "IssuesEvent"
|
181
|
+
process_issue_event(event)
|
182
|
+
when "IssueCommentEvent"
|
183
|
+
process_issue_or_pull_request_comment_event(event)
|
184
|
+
when "ForkEvent"
|
185
|
+
emit("fork", event)
|
186
|
+
when "PullRequestEvent"
|
187
|
+
process_pull_request_event(event)
|
188
|
+
when "CreateEvent"
|
189
|
+
process_create_event(event)
|
190
|
+
else
|
191
|
+
emit(event["type"], event)
|
192
|
+
end
|
193
|
+
rescue StandardError => error
|
194
|
+
log.fatal(error)
|
187
195
|
end
|
188
|
-
rescue StandardError => error
|
189
|
-
$log.exception(error)
|
190
|
-
end
|
191
196
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
197
|
+
def process_push_event(event)
|
198
|
+
return unless @running
|
199
|
+
payload = event["payload"]
|
200
|
+
commit_refs = payload["commits"]
|
201
|
+
if !@include_commits_from_pull_request and
|
196
202
|
push_event_from_merged_pull_request?(event)
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
203
|
+
return
|
204
|
+
end
|
205
|
+
commit_refs.reverse.each do |commit_ref|
|
206
|
+
@request_queue.push(type: TYPE_COMMIT,
|
207
|
+
uri: commit_ref["url"],
|
208
|
+
sha: commit_ref["sha"],
|
209
|
+
push: event)
|
210
|
+
end
|
211
|
+
# emit("push", event)
|
204
212
|
end
|
205
|
-
# emit("push", event)
|
206
|
-
end
|
207
213
|
|
208
|
-
|
209
|
-
|
210
|
-
|
214
|
+
def process_commit(commit, push_event)
|
215
|
+
log.debug("GithubActivities::Crawler: processing commit #{commit["sha"]}")
|
216
|
+
user = commit["author"]["login"]
|
217
|
+
|
218
|
+
if user and (@include_foreign_commits or watching_user?(user))
|
219
|
+
commit[RELATED_USER_IMAGE_KEY] = push_event["actor"]["avatar_url"]
|
220
|
+
if push_event["org"]
|
221
|
+
commit[RELATED_ORGANIZATION_IMAGE_KEY] = push_event["org"]["avatar_url"]
|
222
|
+
end
|
223
|
+
commit[RELATED_EVENT] = push_event.reject {|k, _| k == "payload" }
|
224
|
+
emit("commit", commit)
|
225
|
+
end
|
211
226
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
commit[RELATED_ORGANIZATION_IMAGE_KEY] = push_event["org"]["avatar_url"]
|
227
|
+
commit_refs = push_event["payload"]["commits"]
|
228
|
+
target_commit_ref = commit_refs.find do |commit_ref|
|
229
|
+
commit_ref["sha"] == commit["sha"]
|
216
230
|
end
|
217
|
-
commit
|
218
|
-
emit("commit", commit)
|
219
|
-
end
|
231
|
+
target_commit_ref["commit"] = commit if target_commit_ref
|
220
232
|
|
221
|
-
|
222
|
-
|
223
|
-
|
233
|
+
completely_fetched = commit_refs.all? do |commit_ref|
|
234
|
+
commit_ref["commit"]
|
235
|
+
end
|
236
|
+
emit("push", push_event) if completely_fetched
|
224
237
|
end
|
225
|
-
target_commit_ref["commit"] = commit if target_commit_ref
|
226
238
|
|
227
|
-
|
228
|
-
|
239
|
+
def watching_user?(user)
|
240
|
+
@watching_users.include?(user)
|
229
241
|
end
|
230
|
-
emit("push", push_event) if completely_fetched
|
231
|
-
end
|
232
|
-
|
233
|
-
def watching_user?(user)
|
234
|
-
@watching_users.include?(user)
|
235
|
-
end
|
236
242
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
243
|
+
def process_issue_event(event)
|
244
|
+
payload = event["payload"]
|
245
|
+
case payload["action"]
|
246
|
+
when "opened"
|
247
|
+
emit("issue-open", event)
|
248
|
+
when "closed"
|
249
|
+
emit("issue-close", event)
|
250
|
+
when "reopened"
|
251
|
+
emit("issue-reopen", event)
|
252
|
+
when "assigned"
|
253
|
+
emit("issue-assign", event)
|
254
|
+
when "unassigned"
|
255
|
+
emit("issue-unassign", event)
|
256
|
+
when "labeled"
|
257
|
+
emit("issue-label", event)
|
258
|
+
when "unlabeled"
|
259
|
+
emit("issue-unlabel", event)
|
260
|
+
end
|
254
261
|
end
|
255
|
-
end
|
256
262
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
263
|
+
def process_pull_request_event(event)
|
264
|
+
payload = event["payload"]
|
265
|
+
case payload["action"]
|
266
|
+
when "opened"
|
267
|
+
emit("pull-request", event)
|
268
|
+
when "closed"
|
269
|
+
if payload["pull_request"]["merged"]
|
270
|
+
emit("pull-request-merged", event)
|
271
|
+
else
|
272
|
+
emit("pull-request-cancelled", event)
|
273
|
+
end
|
274
|
+
when "reopened"
|
275
|
+
emit("pull-request-reopen", event)
|
267
276
|
end
|
268
|
-
when "reopened"
|
269
|
-
emit("pull-request-reopen", event)
|
270
277
|
end
|
271
|
-
end
|
272
278
|
|
273
|
-
|
279
|
+
MERGE_COMMIT_MESSAGE_PATTERN = /\AMerge pull request #\d+ from [^\/]+\/[^\/]+\n\n/
|
274
280
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
281
|
+
def push_event_from_merged_pull_request?(event)
|
282
|
+
payload = event["payload"]
|
283
|
+
inserted_requests = []
|
284
|
+
commit_refs = payload["commits"]
|
285
|
+
if MERGE_COMMIT_MESSAGE_PATTERN =~ commit_refs.last["message"]
|
286
|
+
true
|
287
|
+
else
|
288
|
+
false
|
289
|
+
end
|
283
290
|
end
|
284
|
-
end
|
285
291
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
292
|
+
def process_issue_or_pull_request_comment_event(event)
|
293
|
+
payload = event["payload"]
|
294
|
+
if payload["issue"]["pull_request"]
|
295
|
+
emit("pull-request-comment", event)
|
290
296
|
# emit("pull-request.cancel", event)
|
291
|
-
|
292
|
-
|
297
|
+
else
|
298
|
+
emit("issue-comment", event)
|
299
|
+
end
|
293
300
|
end
|
294
|
-
end
|
295
301
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
302
|
+
def process_create_event(event)
|
303
|
+
payload = event["payload"]
|
304
|
+
case payload["ref_type"]
|
305
|
+
when "branch"
|
306
|
+
emit("branch", event)
|
307
|
+
when "tag"
|
308
|
+
emit("tag", event)
|
309
|
+
end
|
303
310
|
end
|
304
|
-
end
|
305
311
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
end
|
312
|
+
def stop
|
313
|
+
@running = false
|
314
|
+
end
|
310
315
|
|
311
|
-
|
312
|
-
|
313
|
-
|
316
|
+
private
|
317
|
+
def user_activities(user)
|
318
|
+
"https://api.github.com/users/#{user}/events/public"
|
319
|
+
end
|
314
320
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
end
|
321
|
+
def user_info(user)
|
322
|
+
"https://api.github.com/users/#{user}"
|
323
|
+
end
|
319
324
|
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
extra_headers["Authorization"] = "token #{@access_token}"
|
325
|
+
def emit(tag, record)
|
326
|
+
log.trace("GithubActivities::Crawler: emit => #{tag}, #{record.inspect}")
|
327
|
+
@on_emit.call(tag, record) if @on_emit
|
324
328
|
end
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
329
|
+
|
330
|
+
def http_get(uri, extra_headers={})
|
331
|
+
parsed_uri = URI(uri)
|
332
|
+
if @access_token
|
333
|
+
extra_headers["Authorization"] = "token #{@access_token}"
|
334
|
+
end
|
335
|
+
response = nil
|
336
|
+
http = Net::HTTP.new(parsed_uri.host, parsed_uri.port)
|
337
|
+
http.use_ssl = parsed_uri.is_a?(URI::HTTPS)
|
338
|
+
http.start do |http|
|
339
|
+
http_request = Net::HTTP::Get.new(parsed_uri.path, extra_headers)
|
340
|
+
response = http.request(http_request)
|
341
|
+
end
|
342
|
+
response
|
331
343
|
end
|
332
|
-
response
|
333
344
|
end
|
334
345
|
end
|
335
346
|
end
|