octoevent 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +4 -0
  3. data/lib/OctoEvent.rb +118 -0
  4. data/lib/helper.rb +17 -0
  5. data/lib/storage.rb +10 -0
  6. 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
@@ -0,0 +1,4 @@
1
+ OctoEvent
2
+ =========
3
+
4
+ Fetches the events of Github at your command.
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
@@ -0,0 +1,10 @@
1
+ # Providing a universal API for different storages
2
+
3
+ class Storage
4
+ end
5
+
6
+ class CouchDBStorage < Storage
7
+ end
8
+
9
+ class LocalFSStorage < Storage
10
+ end
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: []