octoevent 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.md +4 -0
- data/lib/OctoEvent.rb +118 -0
- data/lib/helper.rb +17 -0
- data/lib/storage.rb +10 -0
- metadata +67 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2013 Peng Sun
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
Software), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/lib/OctoEvent.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'httpclient'
|
2
|
+
require 'json'
|
3
|
+
require_relative 'helper'
|
4
|
+
|
5
|
+
class OctoEvent
|
6
|
+
GITHUB_EVENT_API_END_POINT = "https://api.github.com/%s/events"
|
7
|
+
|
8
|
+
attr_accessor :config_url
|
9
|
+
attr_accessor :parsing_block
|
10
|
+
attr_accessor :target_array
|
11
|
+
attr_accessor :client_id
|
12
|
+
attr_accessor :client_secret
|
13
|
+
attr_accessor :etag_hash
|
14
|
+
attr_accessor :last_event_hash
|
15
|
+
attr_accessor :sleep_period
|
16
|
+
|
17
|
+
def initialize *args, &block
|
18
|
+
@etag_hash = Hash.new "" # a hash for etags
|
19
|
+
@last_event_hash = Hash.new "" # a hash for last event
|
20
|
+
|
21
|
+
@sleep_period = 1
|
22
|
+
|
23
|
+
case args.size
|
24
|
+
when 1
|
25
|
+
# Using a remote url to serve as the config json
|
26
|
+
# Benefits? We can dynamiclly change it!
|
27
|
+
# Also needs to pass in a block that does what it takes to trim the json
|
28
|
+
@clnt = HTTPClient.new
|
29
|
+
@config_url = args[0]
|
30
|
+
@parsing_block = block
|
31
|
+
when 3
|
32
|
+
# For a single target who shell never change, just provide it with github login & type
|
33
|
+
name, type, etag = args
|
34
|
+
@config_url = nil
|
35
|
+
path = path_for name, type
|
36
|
+
target_array << path
|
37
|
+
@etag_hash[path] = etag
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def github_key_pair client_id, client_secret
|
42
|
+
@client_id = client_id
|
43
|
+
@client_secret = client_secret
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
"Grab events for #{target_array}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def target_array
|
51
|
+
@target_array ||= []
|
52
|
+
end
|
53
|
+
|
54
|
+
def grab event_types, &block
|
55
|
+
raise "nothing to do if there's no block" unless block
|
56
|
+
|
57
|
+
acceptable_events = event_types.parse_event_types
|
58
|
+
while true # this is a worker dyno
|
59
|
+
update_target if @config_url
|
60
|
+
|
61
|
+
result = {}
|
62
|
+
target_array.each do |target|
|
63
|
+
events = events_for target, acceptable_events
|
64
|
+
result[target] = events unless events.empty?
|
65
|
+
end
|
66
|
+
|
67
|
+
block.call result unless result.empty? # send the result to client unless it's empty
|
68
|
+
|
69
|
+
sleep sleep_period
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
# Composed path for github
|
75
|
+
def path_for name, type
|
76
|
+
"#{type}s/#{name}"
|
77
|
+
end
|
78
|
+
|
79
|
+
# Use json as config to make the users dynamiclly changable
|
80
|
+
def update_target
|
81
|
+
obj = JSON.load(@clnt.get(@config_url).body) || []
|
82
|
+
obj = @parsing_block.call(obj) if @parsing_block
|
83
|
+
|
84
|
+
obj.each do |target|
|
85
|
+
name = target["name"]
|
86
|
+
type = target["type"]
|
87
|
+
target_array << "#{type}s/#{name}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Get events for a single target
|
92
|
+
def events_for target, event_types
|
93
|
+
url = GITHUB_EVENT_API_END_POINT % target
|
94
|
+
etag = @etag_hash[target]
|
95
|
+
last_event = @last_event_hash[target]
|
96
|
+
|
97
|
+
events_to_send = []
|
98
|
+
page = 1
|
99
|
+
while page <= 10
|
100
|
+
result = @clnt.get(url, {client_id: @client_id, client_secret: @client_secret}, {"If-None-Match" => etag})
|
101
|
+
break unless result.status_code == 200
|
102
|
+
events = JSON.load result.body
|
103
|
+
if page == 1 # etag and last event should be set when querying the very first page
|
104
|
+
@etag_hash[target] = result.header["etag"]
|
105
|
+
@last_event_hash[target] = events[0]
|
106
|
+
end
|
107
|
+
|
108
|
+
events.each do |event|
|
109
|
+
return events_to_send if last_event == event # no need to proceed
|
110
|
+
events_to_send << event if event_types.accept? event
|
111
|
+
end
|
112
|
+
|
113
|
+
page += 1
|
114
|
+
end
|
115
|
+
|
116
|
+
events_to_send
|
117
|
+
end
|
118
|
+
end
|
data/lib/helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Helper methods
|
2
|
+
|
3
|
+
# Mixin helper to parse the accpetable strings
|
4
|
+
class String
|
5
|
+
def parse_event_types
|
6
|
+
self.split(",").map {|str| "#{str.strip.capitalize}Event"}
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
# Mixin helper to test if we should accept this event
|
11
|
+
class Array
|
12
|
+
def accept? event
|
13
|
+
return true if self.include? "AllEvent"
|
14
|
+
return false unless event.has_key? "type"
|
15
|
+
self.include? event["type"]
|
16
|
+
end
|
17
|
+
end
|
data/lib/storage.rb
ADDED
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: octoevent
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Peng Sun
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: httpclient
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.3.3
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.3.3
|
30
|
+
description: ! ' Grab activity events for you from Octocat
|
31
|
+
|
32
|
+
'
|
33
|
+
email: voidmain1313113@gmail.com
|
34
|
+
executables: []
|
35
|
+
extensions: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
files:
|
38
|
+
- README.md
|
39
|
+
- LICENSE
|
40
|
+
- lib/helper.rb
|
41
|
+
- lib/OctoEvent.rb
|
42
|
+
- lib/storage.rb
|
43
|
+
homepage: https://github.com/void-main/OctoEvent
|
44
|
+
licenses: []
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
requirements: []
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 1.8.24
|
64
|
+
signing_key:
|
65
|
+
specification_version: 3
|
66
|
+
summary: Grab activity events for you from Octocat
|
67
|
+
test_files: []
|