goshrine_bot 0.1.1 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -0
- data/README.rdoc +5 -6
- data/TODO.txt +2 -1
- data/goshrine_bot.gemspec +3 -1
- data/goshrine_bot.yml +21 -3
- data/lib/goshrine_bot/client.rb +41 -54
- data/lib/goshrine_bot/cookies.rb +45 -0
- data/lib/goshrine_bot/faye_auth_ext.rb +17 -0
- data/lib/goshrine_bot/faye_transport_patch.rb +43 -0
- data/lib/goshrine_bot/game.rb +3 -3
- data/lib/goshrine_bot/runner.rb +1 -1
- data/lib/goshrine_bot.rb +11 -5
- metadata +35 -41
- data/lib/goshrine_bot/faye/channel.rb +0 -143
- data/lib/goshrine_bot/faye/client.rb +0 -283
- data/lib/goshrine_bot/faye/connection.rb +0 -122
- data/lib/goshrine_bot/faye/error.rb +0 -44
- data/lib/goshrine_bot/faye/grammar.rb +0 -58
- data/lib/goshrine_bot/faye/namespace.rb +0 -20
- data/lib/goshrine_bot/faye/rack_adapter.rb +0 -115
- data/lib/goshrine_bot/faye/server.rb +0 -266
- data/lib/goshrine_bot/faye/timeouts.rb +0 -21
- data/lib/goshrine_bot/faye/transport.rb +0 -123
- data/lib/goshrine_bot/faye.rb +0 -36
- data/lib/goshrine_bot/httpclient.rb +0 -288
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm ruby-1.9.2-p180
|
data/README.rdoc
CHANGED
@@ -15,13 +15,12 @@ The GTP protocol is documented here: http://www.lysator.liu.se/~gunnar/gtp/
|
|
15
15
|
|
16
16
|
* Create a normal account on goshrine for your bot.
|
17
17
|
* Email feedback@goshrine.com with the account name, and request that it be changed to a bot account.
|
18
|
-
*
|
19
|
-
* Create a database.yml file in the following format:
|
18
|
+
* Create a goshrine_bot.yml file in the following format, substituting your bot's login info :
|
20
19
|
|
21
|
-
botname:
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
botname:
|
21
|
+
:login: yourbotlogin
|
22
|
+
:password: yourbotpassword
|
23
|
+
:gtp_cmd_line: gnugo --mode gtp --level 1
|
25
24
|
|
26
25
|
* Run goshrine_bot botname
|
27
26
|
|
data/TODO.txt
CHANGED
data/goshrine_bot.gemspec
CHANGED
@@ -21,7 +21,9 @@ SPEC = Gem::Specification.new do |s|
|
|
21
21
|
END_DESCRIPTION
|
22
22
|
|
23
23
|
s.add_dependency('eventmachine', '>= 0.12.10')
|
24
|
-
s.add_dependency('
|
24
|
+
s.add_dependency('em-http-request', '=1.0.0.beta.3')
|
25
|
+
s.add_dependency('faye', '>= 0.5.5')
|
26
|
+
s.add_dependency('json', '>= 1.5.0')
|
25
27
|
|
26
28
|
s.add_development_dependency "rspec"
|
27
29
|
|
data/goshrine_bot.yml
CHANGED
@@ -1,5 +1,23 @@
|
|
1
|
-
|
2
|
-
:login:
|
3
|
-
:password:
|
1
|
+
gnugo:
|
2
|
+
:login: gnugo
|
3
|
+
:password: atk2sih
|
4
|
+
:gtp_cmd_line: gnugo --mode gtp
|
5
|
+
|
6
|
+
easy_gnugo:
|
7
|
+
:login: EasyGnuGo
|
8
|
+
:password: jasj308jrke
|
9
|
+
:gtp_cmd_line: gnugo --mode gtp --level 1
|
10
|
+
:debug: false
|
11
|
+
|
12
|
+
local_gnugo:
|
13
|
+
:server_url: http://localhost:5730
|
14
|
+
:login: gnugo
|
15
|
+
:password: testpass
|
4
16
|
:gtp_cmd_line: gnugo --mode gtp --level 1
|
17
|
+
:debug: false
|
5
18
|
|
19
|
+
mogo:
|
20
|
+
:login: mogo
|
21
|
+
:password: a0ij45o3i
|
22
|
+
:gtp_cmd_line: /home/pete/MoGo_release3/mogo --19 --dontDisplay 1
|
23
|
+
:debug: false
|
data/lib/goshrine_bot/client.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module GoshrineBot
|
3
2
|
|
4
3
|
class Client
|
@@ -13,7 +12,6 @@ module GoshrineBot
|
|
13
12
|
@login = options[:login]
|
14
13
|
@gtp_cmd_line = options[:gtp_cmd_line]
|
15
14
|
@connected = false
|
16
|
-
@cookie = ""
|
17
15
|
@games = {}
|
18
16
|
end
|
19
17
|
|
@@ -25,30 +23,19 @@ module GoshrineBot
|
|
25
23
|
@my_user_id
|
26
24
|
end
|
27
25
|
|
28
|
-
def parse_cookie(headers)
|
29
|
-
cookies = []
|
30
|
-
headers.each do |h|
|
31
|
-
if h.match(/^Set-Cookie: /)
|
32
|
-
pieces = h[12..-1].split("=")
|
33
|
-
cookies << "#{pieces[0]}=#{pieces[1].split(";").first}";
|
34
|
-
end
|
35
|
-
end
|
36
|
-
@cookie = cookies.join("; ") + ';'
|
37
|
-
end
|
38
|
-
|
39
26
|
def login(&blk)
|
40
27
|
# login
|
41
28
|
http = http_post('/sessions/create', {'login' => @login, 'password' => @password})
|
42
|
-
http.callback {
|
43
|
-
|
44
|
-
if response[:status].to_i == 401
|
29
|
+
http.callback {
|
30
|
+
if http.response_header.status == 401
|
45
31
|
puts "Invalid Login or Password"
|
46
32
|
EventMachine::stop
|
47
33
|
else
|
48
|
-
|
49
|
-
|
34
|
+
user = JSON.parse(http.response)
|
35
|
+
puts "Got #{user.inspect}"
|
50
36
|
@queue_id = user['queue_id']
|
51
37
|
@my_user_id = user['id']
|
38
|
+
@faye_token = user['faye_token']
|
52
39
|
if user['user_type'] != 'bot'
|
53
40
|
puts "Account #{user['login']} is not registered as a robot!"
|
54
41
|
EventMachine::stop
|
@@ -63,36 +50,33 @@ module GoshrineBot
|
|
63
50
|
}
|
64
51
|
end
|
65
52
|
|
66
|
-
def http_post(
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
:port => @base_url.port,
|
78
|
-
:contenttype => contenttype,
|
79
|
-
:request => url,
|
80
|
-
:verb => 'POST',
|
81
|
-
:content => data,
|
82
|
-
:custom_headers => headers)
|
53
|
+
def http_post(path, data = nil)
|
54
|
+
conn = EM::HttpRequest.new("#{@base_url}#{path}")
|
55
|
+
conn.use CookiePersist
|
56
|
+
headers = {'Accept' => 'application/json'}
|
57
|
+
|
58
|
+
http = conn.post(:head => headers, :body => data)
|
59
|
+
|
60
|
+
http.headers { |head|
|
61
|
+
CookiePersist.cookies << head[EM::HttpClient::SET_COOKIE]
|
62
|
+
}
|
63
|
+
http
|
83
64
|
end
|
84
65
|
|
85
|
-
def http_get(
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
66
|
+
def http_get(path)
|
67
|
+
conn = EM::HttpRequest.new("#{@base_url}#{path}")
|
68
|
+
conn.use CookiePersist
|
69
|
+
|
70
|
+
http = conn.get(:head => {'Accept' => 'application/json'})
|
71
|
+
|
72
|
+
http.headers { |head|
|
73
|
+
CookiePersist.cookies << head[EM::HttpClient::SET_COOKIE]
|
74
|
+
}
|
75
|
+
http
|
92
76
|
end
|
93
77
|
|
94
78
|
def subscribe
|
95
|
-
@
|
79
|
+
@faye_client.subscribe("/user/private/" + @queue_id) do |m|
|
96
80
|
msg_type = m["type"]
|
97
81
|
case msg_type
|
98
82
|
when 'match_requested'
|
@@ -104,14 +88,18 @@ module GoshrineBot
|
|
104
88
|
end
|
105
89
|
#@msg_queue_in.push(doc)
|
106
90
|
end
|
107
|
-
@
|
91
|
+
@faye_client.subscribe("/room/1") do |m|
|
108
92
|
#@msg_queue_in.push(doc)
|
109
93
|
end
|
110
94
|
end
|
111
95
|
|
112
96
|
def run
|
113
97
|
login {
|
114
|
-
|
98
|
+
puts "Starting faye client"
|
99
|
+
@faye_client = Faye::Client.new((@base_url + '/events').to_s, :cookie => @cookie)
|
100
|
+
if @faye_token
|
101
|
+
@faye_client.add_extension(FayeAuthExt.new(@my_user_id, @faye_token))
|
102
|
+
end
|
115
103
|
subscribe
|
116
104
|
load_existing_games {
|
117
105
|
EM::add_periodic_timer( 60 ) {
|
@@ -125,10 +113,9 @@ module GoshrineBot
|
|
125
113
|
|
126
114
|
def load_existing_games(&blk)
|
127
115
|
http = http_get('/game/active')
|
128
|
-
http.callback {
|
116
|
+
http.callback {
|
129
117
|
#puts "Got #{response.inspect}"
|
130
|
-
|
131
|
-
games = JSON.parse(response[:content])
|
118
|
+
games = JSON.parse(http.response)
|
132
119
|
puts "#{games.count} game(s) in progress"
|
133
120
|
games.each do |game_attrs|
|
134
121
|
game = GameInProgress.new(self)
|
@@ -146,10 +133,10 @@ module GoshrineBot
|
|
146
133
|
def add_game(game)
|
147
134
|
@games[game.game_id] = game
|
148
135
|
game.make_move # does nothing if its not our turn, or the game is not started
|
149
|
-
@
|
136
|
+
@faye_client.subscribe("/game/private/" + game.token + '/' + @queue_id) do |m|
|
150
137
|
game.private_message(m)
|
151
138
|
end
|
152
|
-
@
|
139
|
+
@faye_client.subscribe("/game/play/" + game.token) do |m|
|
153
140
|
game.play_message(m)
|
154
141
|
end
|
155
142
|
end
|
@@ -157,8 +144,8 @@ module GoshrineBot
|
|
157
144
|
def handle_match_accept(token)
|
158
145
|
game = GameInProgress.new(self)
|
159
146
|
http = http_get("/g/#{token}")
|
160
|
-
http.callback {
|
161
|
-
attrs = JSON.parse(response
|
147
|
+
http.callback {
|
148
|
+
attrs = JSON.parse(http.response)
|
162
149
|
game.update_from_game_list(attrs)
|
163
150
|
add_game(game)
|
164
151
|
}
|
@@ -168,8 +155,8 @@ module GoshrineBot
|
|
168
155
|
game = GameInProgress.new(self)
|
169
156
|
game.update_from_match_request(request)
|
170
157
|
http = http_get("/match/accept?id=#{game.challenge_id}")
|
171
|
-
http.callback {
|
172
|
-
attrs = JSON.parse(response
|
158
|
+
http.callback {
|
159
|
+
attrs = JSON.parse(http.response)
|
173
160
|
game.update_from_game_list(attrs)
|
174
161
|
add_game(game)
|
175
162
|
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Borrowed from HTTParty, a great rubygem from John Nunemaker (thanks!)
|
2
|
+
class CookieHash < Hash #:nodoc:
|
3
|
+
CLIENT_COOKIES = %w{path expires domain path secure HTTPOnly HttpOnly}
|
4
|
+
|
5
|
+
def add_cookies(value)
|
6
|
+
case value
|
7
|
+
when Hash
|
8
|
+
merge!(value)
|
9
|
+
when String
|
10
|
+
value.split('; ').each do |cookie|
|
11
|
+
array = cookie.split('=')
|
12
|
+
self[array[0].to_sym] = array[1]
|
13
|
+
end
|
14
|
+
else
|
15
|
+
raise "add_cookies only takes a Hash or a String"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_cookie_string
|
20
|
+
delete_if { |k, v| CLIENT_COOKIES.include?(k.to_s) }.collect { |k, v| "#{k}=#{v}" }.join("; ")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class CookiePersist
|
25
|
+
def self.cookies
|
26
|
+
Thread.current[:cookies] ||= []
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.cookie_hash
|
30
|
+
CookieHash.new.tap { |hsh|
|
31
|
+
cookies.uniq.each { |c| hsh.add_cookies(c) }
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.request(head, body)
|
36
|
+
head['cookie'] = cookie_hash.to_cookie_string
|
37
|
+
#puts "Sending cookies: #{head['cookie']}"
|
38
|
+
[head, body]
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.response(resp)
|
42
|
+
resp
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class FayeAuthExt
|
2
|
+
def initialize(user_id, token)
|
3
|
+
@user_id = user_id
|
4
|
+
@token = token
|
5
|
+
end
|
6
|
+
|
7
|
+
def outgoing(message, callback)
|
8
|
+
# Add ext field if it's not present
|
9
|
+
message['ext'] ||= {}
|
10
|
+
|
11
|
+
# Set the auth token
|
12
|
+
message['ext']['authToken'] = "#{@user_id}:#{@token}"
|
13
|
+
|
14
|
+
# Carry on and send the message to the server
|
15
|
+
callback.call(message)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'em-http'
|
2
|
+
require 'em-http/version'
|
3
|
+
require 'json'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
module Faye
|
7
|
+
|
8
|
+
class HttpTransport < Transport
|
9
|
+
|
10
|
+
def request(message, timeout)
|
11
|
+
retry_block = retry_block(message, timeout)
|
12
|
+
|
13
|
+
content = JSON.unparse(message)
|
14
|
+
params = {
|
15
|
+
:head => {
|
16
|
+
'Content-Type' => 'application/json',
|
17
|
+
'host' => URI.parse(@endpoint).host,
|
18
|
+
'Content-Length' => content.length
|
19
|
+
},
|
20
|
+
:body => content,
|
21
|
+
:timeout => -1 # for em-http-request < 1.0
|
22
|
+
}
|
23
|
+
if EventMachine::HttpRequest::VERSION.split('.')[0].to_i >= 1
|
24
|
+
options = { # for em-http-request >= 1.0
|
25
|
+
:inactivity_timeout => 0, # connection inactivity (post-setup) timeout (0 = disable timeout)
|
26
|
+
}
|
27
|
+
request = EventMachine::HttpRequest.new(@endpoint, options).post(params)
|
28
|
+
else
|
29
|
+
request = EventMachine::HttpRequest.new(@endpoint).post(params)
|
30
|
+
end
|
31
|
+
request.callback do
|
32
|
+
begin
|
33
|
+
receive(JSON.parse(request.response))
|
34
|
+
rescue
|
35
|
+
retry_block.call
|
36
|
+
end
|
37
|
+
end
|
38
|
+
request.errback { retry_block.call }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
data/lib/goshrine_bot/game.rb
CHANGED
@@ -38,7 +38,7 @@ module GoshrineBot
|
|
38
38
|
handle_move(m["data"])
|
39
39
|
#puts "Going to update board"
|
40
40
|
when 'resignedBy'
|
41
|
-
puts "Game resigned by
|
41
|
+
puts "Game resigned by opponent."
|
42
42
|
stop_gtp_client
|
43
43
|
when 'updateForUndo'
|
44
44
|
# TODO - handle undos?
|
@@ -180,8 +180,8 @@ module GoshrineBot
|
|
180
180
|
rgo_coord = gtp_coord_to_goshrine_coord(response_move.upcase, board_size)
|
181
181
|
http = @client.http_post("/game/#{token}/move/#{rgo_coord}")
|
182
182
|
end
|
183
|
-
http.callback {
|
184
|
-
if
|
183
|
+
http.callback {
|
184
|
+
if http.response_header.status == 200
|
185
185
|
self.moves << [my_color, response_move]
|
186
186
|
else
|
187
187
|
puts "Could not make move: #{response.inspect}"
|
data/lib/goshrine_bot/runner.rb
CHANGED
data/lib/goshrine_bot.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'json'
|
3
3
|
require 'eventmachine'
|
4
|
+
require 'em-http'
|
5
|
+
require 'faye'
|
6
|
+
require 'logger'
|
4
7
|
|
5
8
|
module GoshrineBot
|
6
9
|
|
7
|
-
VERSION = "0.1.
|
10
|
+
VERSION = "0.1.5"
|
8
11
|
|
9
12
|
STDOUT.sync = true
|
10
13
|
|
@@ -14,12 +17,15 @@ module GoshrineBot
|
|
14
17
|
gtp_stdio_client
|
15
18
|
runner
|
16
19
|
game
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
cookies
|
21
|
+
faye_transport_patch
|
22
|
+
faye_auth_ext
|
23
|
+
core_ext/hash
|
21
24
|
].each do |lib|
|
22
25
|
require File.join(ROOT, 'goshrine_bot', lib)
|
23
26
|
end
|
24
27
|
|
28
|
+
#Faye.logger = Logger.new(STDOUT)
|
29
|
+
#Faye::Logging.log_level = :debug
|
30
|
+
|
25
31
|
end
|
metadata
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: goshrine_bot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 1
|
8
|
-
- 1
|
9
|
-
version: 0.1.1
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.5
|
10
6
|
platform: ruby
|
11
7
|
authors:
|
12
8
|
- Pete Schwamb
|
@@ -14,8 +10,7 @@ autorequire:
|
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
12
|
|
17
|
-
date:
|
18
|
-
default_executable:
|
13
|
+
date: 2011-05-18 00:00:00 Z
|
19
14
|
dependencies:
|
20
15
|
- !ruby/object:Gem::Dependency
|
21
16
|
name: eventmachine
|
@@ -25,41 +20,53 @@ dependencies:
|
|
25
20
|
requirements:
|
26
21
|
- - ">="
|
27
22
|
- !ruby/object:Gem::Version
|
28
|
-
segments:
|
29
|
-
- 0
|
30
|
-
- 12
|
31
|
-
- 10
|
32
23
|
version: 0.12.10
|
33
24
|
type: :runtime
|
34
25
|
version_requirements: *id001
|
35
26
|
- !ruby/object:Gem::Dependency
|
36
|
-
name:
|
27
|
+
name: em-http-request
|
37
28
|
prerelease: false
|
38
29
|
requirement: &id002 !ruby/object:Gem::Requirement
|
39
30
|
none: false
|
40
31
|
requirements:
|
41
|
-
- - "
|
32
|
+
- - "="
|
42
33
|
- !ruby/object:Gem::Version
|
43
|
-
|
44
|
-
- 1
|
45
|
-
- 4
|
46
|
-
- 6
|
47
|
-
version: 1.4.6
|
34
|
+
version: 1.0.0.beta.3
|
48
35
|
type: :runtime
|
49
36
|
version_requirements: *id002
|
50
37
|
- !ruby/object:Gem::Dependency
|
51
|
-
name:
|
38
|
+
name: faye
|
52
39
|
prerelease: false
|
53
40
|
requirement: &id003 !ruby/object:Gem::Requirement
|
54
41
|
none: false
|
55
42
|
requirements:
|
56
43
|
- - ">="
|
57
44
|
- !ruby/object:Gem::Version
|
58
|
-
|
59
|
-
|
45
|
+
version: 0.5.5
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id003
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: json
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 1.5.0
|
57
|
+
type: :runtime
|
58
|
+
version_requirements: *id004
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: rspec
|
61
|
+
prerelease: false
|
62
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
60
67
|
version: "0"
|
61
68
|
type: :development
|
62
|
-
version_requirements: *
|
69
|
+
version_requirements: *id005
|
63
70
|
description: The GoShrine bot client is a library that allows you connect a local Go playing program that speaks GTP (like gnugo) to http://goshrine.com.
|
64
71
|
email:
|
65
72
|
- pete@schwamb.net
|
@@ -70,6 +77,7 @@ extensions: []
|
|
70
77
|
extra_rdoc_files: []
|
71
78
|
|
72
79
|
files:
|
80
|
+
- .rvmrc
|
73
81
|
- History.txt
|
74
82
|
- Manifest.txt
|
75
83
|
- README.rdoc
|
@@ -80,23 +88,13 @@ files:
|
|
80
88
|
- goshrine_bot.yml
|
81
89
|
- lib/goshrine_bot.rb
|
82
90
|
- lib/goshrine_bot/client.rb
|
91
|
+
- lib/goshrine_bot/cookies.rb
|
83
92
|
- lib/goshrine_bot/core_ext/hash.rb
|
84
|
-
- lib/goshrine_bot/
|
85
|
-
- lib/goshrine_bot/
|
86
|
-
- lib/goshrine_bot/faye/client.rb
|
87
|
-
- lib/goshrine_bot/faye/connection.rb
|
88
|
-
- lib/goshrine_bot/faye/error.rb
|
89
|
-
- lib/goshrine_bot/faye/grammar.rb
|
90
|
-
- lib/goshrine_bot/faye/namespace.rb
|
91
|
-
- lib/goshrine_bot/faye/rack_adapter.rb
|
92
|
-
- lib/goshrine_bot/faye/server.rb
|
93
|
-
- lib/goshrine_bot/faye/timeouts.rb
|
94
|
-
- lib/goshrine_bot/faye/transport.rb
|
93
|
+
- lib/goshrine_bot/faye_auth_ext.rb
|
94
|
+
- lib/goshrine_bot/faye_transport_patch.rb
|
95
95
|
- lib/goshrine_bot/game.rb
|
96
96
|
- lib/goshrine_bot/gtp_stdio_client.rb
|
97
|
-
- lib/goshrine_bot/httpclient.rb
|
98
97
|
- lib/goshrine_bot/runner.rb
|
99
|
-
has_rdoc: true
|
100
98
|
homepage: http://github.com/ps2/goshrine_bot
|
101
99
|
licenses: []
|
102
100
|
|
@@ -110,21 +108,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
110
108
|
requirements:
|
111
109
|
- - ">="
|
112
110
|
- !ruby/object:Gem::Version
|
113
|
-
segments:
|
114
|
-
- 0
|
115
111
|
version: "0"
|
116
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
113
|
none: false
|
118
114
|
requirements:
|
119
115
|
- - ">="
|
120
116
|
- !ruby/object:Gem::Version
|
121
|
-
segments:
|
122
|
-
- 0
|
123
117
|
version: "0"
|
124
118
|
requirements: []
|
125
119
|
|
126
120
|
rubyforge_project:
|
127
|
-
rubygems_version: 1.
|
121
|
+
rubygems_version: 1.8.2
|
128
122
|
signing_key:
|
129
123
|
specification_version: 3
|
130
124
|
summary: A client to connect GTP go programs to GoShrine
|