cinch-bgg 0.0.2 → 0.0.3
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.
- data/.gitignore +1 -0
- data/cinch-bgg.gemspec +1 -3
- data/lib/cinch/plugins/bgg.rb +113 -25
- metadata +19 -8
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/cinch-bgg.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "cinch-bgg"
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.3"
|
6
6
|
s.platform = Gem::Platform::RUBY
|
7
7
|
s.authors = ["Caitlin Woodward"]
|
8
8
|
s.email = ["caitlin@caitlinwoodward.me"]
|
@@ -10,8 +10,6 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.summary = %q{Gives Cinch IRC bots access to BoardGameGeek data}
|
11
11
|
s.description = %q{Gives Cinch IRC bots access to BoardGameGeek data}
|
12
12
|
|
13
|
-
s.rubyforge_project = "cinch-bgg"
|
14
|
-
|
15
13
|
s.add_dependency("cinch", "~> 2.0")
|
16
14
|
s.add_dependency("nokogiri", "~> 1.5.2")
|
17
15
|
|
data/lib/cinch/plugins/bgg.rb
CHANGED
@@ -7,25 +7,74 @@ module Cinch
|
|
7
7
|
class Bgg
|
8
8
|
include Cinch::Plugin
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
USERS_FILE = "users_list"
|
11
|
+
USERS_SUBDIR = "users"
|
12
|
+
GAMES_SUBDIR = "games"
|
13
|
+
|
14
|
+
match /bgg (.+)/i, method: :bgg
|
15
|
+
match /bggme/i, method: :bggself
|
16
|
+
match /bgguser (.+)/i, method: :bgguser
|
17
|
+
match /bgguser -u (.+)/i, method: :bggactualuser
|
18
|
+
|
19
|
+
match /link_bgg (.+)/i, method: :link_to_bgg
|
20
|
+
|
21
|
+
match /whohas (.+)/i, method: :who_has_game
|
22
|
+
|
23
|
+
def initialize(*args)
|
24
|
+
super
|
25
|
+
|
26
|
+
@data_dir = config[:data_dir]
|
27
|
+
@community = load_community
|
28
|
+
end
|
12
29
|
|
13
30
|
def bgg(m, title)
|
14
|
-
|
15
|
-
|
16
|
-
m.reply "#{m.user.nick}: \"#{title}\" not found"
|
17
|
-
elsif results == "too big"
|
18
|
-
m.reply "#{m.user.nick}: \"#{title}\" was too broad of a search term"
|
19
|
-
else
|
20
|
-
game = results.sort{ |x, y| x.rank <=> y.rank }.first
|
31
|
+
game = search_bgg(m, title)
|
32
|
+
unless game.nil?
|
21
33
|
m.reply "#{m.user.nick}: #{game.name} (#{game.year}) - #{game.rating} - Rank: #{game.game_rank} - Designer: #{game.designers.join(", ")} - Mechanics: #{game.mechanics.join(", ")} - " <<
|
22
34
|
"http://boardgamegeek.com/boardgame/#{game.id}"
|
23
35
|
end
|
24
36
|
end
|
25
37
|
|
26
|
-
def bgguser(m,
|
27
|
-
|
28
|
-
|
38
|
+
def bgguser(m, nick)
|
39
|
+
unless nick.start_with?("-u ")
|
40
|
+
if self.in_community?(nick)
|
41
|
+
name = self.find_bgg_by_irc(nick)
|
42
|
+
user = search_for_user(name)
|
43
|
+
m.reply "#{user.name} - Collection: #{user.collection.size} - Top 5: #{user.top_games.first(5).join(", ")} - http://boardgamegeek.com/user/#{user.name}", true
|
44
|
+
else
|
45
|
+
m.reply "There's no \"#{nick}\" in the community. To link yourself and join the community, \"!link_bgg bgg_username\". To search by actual bgg username, \"!bgguser -u bgg_username\".", true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def bggself(m)
|
51
|
+
self.bgguser(m.user.nick)
|
52
|
+
end
|
53
|
+
|
54
|
+
def bggactualuser(m, nick)
|
55
|
+
user = search_for_user(nick)
|
56
|
+
m.reply "#{user.name} - Collection: #{user.collection.size} - Top 5: #{user.top_games.first(5).join(", ")} - http://boardgamegeek.com/user/#{user.name}", true
|
57
|
+
end
|
58
|
+
|
59
|
+
def link_to_bgg(m, username)
|
60
|
+
@community[m.user.nick] = username
|
61
|
+
File.open("#{@data_dir}#{USERS_FILE}", 'w') do |file|
|
62
|
+
@community.each do |irc_nick, bgg_name|
|
63
|
+
file.write("#{irc_nick},#{bgg_name}\n")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
m.reply "You are now added to the community!", true
|
67
|
+
end
|
68
|
+
|
69
|
+
def who_has_game(m, title)
|
70
|
+
game = search_bgg(m, title)
|
71
|
+
unless game.nil?
|
72
|
+
community = @community.dup
|
73
|
+
community.each{ |irc, bgg| community[irc] = search_for_user(bgg, { :id => game.id, :use_cache => true }) }
|
74
|
+
|
75
|
+
community.keep_if{ |irc, user| user.collection.include? game.id.to_s }
|
76
|
+
m.reply "Owning \"#{game.name}\": #{community.keys.join(", ")}", true
|
77
|
+
end
|
29
78
|
end
|
30
79
|
|
31
80
|
#--------------------------------------------------------------------------------
|
@@ -33,43 +82,77 @@ module Cinch
|
|
33
82
|
#--------------------------------------------------------------------------------
|
34
83
|
protected
|
35
84
|
|
36
|
-
def search_bgg(search_string)
|
85
|
+
def search_bgg(m, search_string)
|
37
86
|
search_results_xml = Nokogiri::XML(open("http://boardgamegeek.com/xmlapi2/search?query=#{search_string.gsub(" ", "%20")}&type=boardgame&exact=1").read)
|
38
87
|
if search_results_xml.css('items')[0]['total'] == "0"
|
39
88
|
search_results_xml = Nokogiri::XML(open("http://boardgamegeek.com/xmlapi2/search?query=#{search_string.gsub(" ", "%20")}&type=boardgame").read)
|
40
89
|
end
|
41
90
|
search_results = search_results_xml.css('item').map { |i| i['id'].to_i }
|
42
91
|
|
43
|
-
# this is dumb, find a better way
|
44
92
|
if search_results.empty?
|
45
|
-
|
93
|
+
m.reply "\"#{search_string}\" not found", true
|
46
94
|
elsif search_results.size > 50
|
47
|
-
|
95
|
+
m.reply "\"#{search_string}\" was too broad of a search term", true
|
48
96
|
else
|
49
|
-
|
97
|
+
results = search_results.map do |id|
|
50
98
|
Game.new(id, get_info_for_game(id))
|
51
99
|
end
|
100
|
+
response = results.sort{ |x, y| x.rank <=> y.rank }.first
|
52
101
|
end
|
53
102
|
response
|
54
103
|
end
|
55
104
|
|
56
105
|
def get_info_for_game(game_id)
|
57
|
-
unless File.exists?("
|
58
|
-
open("
|
106
|
+
unless File.exists?("#{@data_dir}#{GAMES_SUBDIR}/#{game_id}.xml")
|
107
|
+
open("#{@data_dir}#{GAMES_SUBDIR}/#{game_id}.xml", "wb") do |file|
|
59
108
|
open("http://boardgamegeek.com/xmlapi2/thing?id=#{game_id}&stats=1") do |uri|
|
60
109
|
file.write(uri.read)
|
61
110
|
end
|
62
111
|
end
|
63
112
|
end
|
64
|
-
Nokogiri::XML(File.open("
|
113
|
+
Nokogiri::XML(File.open("#{@data_dir}#{GAMES_SUBDIR}/#{game_id}.xml"))
|
65
114
|
end
|
66
115
|
|
67
|
-
def search_for_user(name)
|
68
|
-
|
69
|
-
|
116
|
+
def search_for_user(name, collection_options = {})
|
117
|
+
use_cache = collection_options[:use_cache] || false
|
118
|
+
game_id = collection_options[:id] || nil
|
119
|
+
|
120
|
+
search_game_id_str = (game_id.nil? ? "" : "&id=#{game_id}")
|
121
|
+
user_xml = Nokogiri::XML(open("http://boardgamegeek.com/xmlapi2/user?name=#{name}&hot=1&top=1#{search_game_id_str}").read)
|
122
|
+
collection_xml = get_collection_data_for_user(name, use_cache)
|
70
123
|
User.new(name, user_xml, collection_xml)
|
71
124
|
end
|
72
125
|
|
126
|
+
def get_collection_data_for_user(name, using_cache = false)
|
127
|
+
file_url = "#{@data_dir}#{USERS_SUBDIR}/#{name}.xml"
|
128
|
+
unless using_cache
|
129
|
+
open(file_url, "w") do |file|
|
130
|
+
open("http://boardgamegeek.com/xmlapi2/collection?username=#{name}&own=1&stats=1") do |uri|
|
131
|
+
file.write(uri.read)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
Nokogiri::XML(File.open(file_url))
|
136
|
+
end
|
137
|
+
|
138
|
+
def load_community
|
139
|
+
users_file = File.open("#{@data_dir}#{USERS_FILE}")
|
140
|
+
users = {}
|
141
|
+
users_file.lines.each do |line|
|
142
|
+
nicks = line.gsub("\n", "").split(",")
|
143
|
+
users[nicks.first] = nicks.last
|
144
|
+
end
|
145
|
+
users
|
146
|
+
end
|
147
|
+
|
148
|
+
def find_bgg_by_irc(irc_nick)
|
149
|
+
@community[irc_nick]
|
150
|
+
end
|
151
|
+
|
152
|
+
def in_community?(irc_nick)
|
153
|
+
self.find_bgg_by_irc(irc_nick) != nil
|
154
|
+
end
|
155
|
+
|
73
156
|
end
|
74
157
|
|
75
158
|
class Game
|
@@ -77,7 +160,7 @@ module Cinch
|
|
77
160
|
|
78
161
|
NOT_RANKED_RANK = 10001
|
79
162
|
|
80
|
-
def initialize(id, xml)
|
163
|
+
def initialize(id, xml)
|
81
164
|
self.id = id
|
82
165
|
self.rating = xml.css('statistics ratings average')[0]['value'].to_f
|
83
166
|
self.rank = xml.css('statistics ratings ranks rank')[0]["value"]
|
@@ -111,7 +194,12 @@ module Cinch
|
|
111
194
|
self.hot_games = user_xml.css("hot item").map{ |g| g["name"] }
|
112
195
|
self.collection = {}
|
113
196
|
collection_xml.css("items item").each do |g|
|
114
|
-
self.collection[g["objectid"]]
|
197
|
+
self.collection[g["objectid"]] = {}
|
198
|
+
self.collection[g["objectid"]]["name"] = g.css("name")[0].content
|
199
|
+
self.collection[g["objectid"]]["for_trade"] = g.css("status fortrade")[0]
|
200
|
+
self.collection[g["objectid"]]["want"] = g.css("status want")[0]
|
201
|
+
self.collection[g["objectid"]]["plays"] = g.css("numplays")[0].content.to_i
|
202
|
+
self.collection[g["objectid"]]["ratings"] = g.css("stats")[0].css("rating")[0]['value']
|
115
203
|
end
|
116
204
|
end
|
117
205
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cinch-bgg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cinch
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: '2.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.0'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: nokogiri
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ~>
|
@@ -32,7 +37,12 @@ dependencies:
|
|
32
37
|
version: 1.5.2
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.5.2
|
36
46
|
description: Gives Cinch IRC bots access to BoardGameGeek data
|
37
47
|
email:
|
38
48
|
- caitlin@caitlinwoodward.me
|
@@ -40,6 +50,7 @@ executables: []
|
|
40
50
|
extensions: []
|
41
51
|
extra_rdoc_files: []
|
42
52
|
files:
|
53
|
+
- .gitignore
|
43
54
|
- Gemfile
|
44
55
|
- README.md
|
45
56
|
- cinch-bgg.gemspec
|
@@ -63,8 +74,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
63
74
|
- !ruby/object:Gem::Version
|
64
75
|
version: '0'
|
65
76
|
requirements: []
|
66
|
-
rubyforge_project:
|
67
|
-
rubygems_version: 1.8.
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 1.8.24
|
68
79
|
signing_key:
|
69
80
|
specification_version: 3
|
70
81
|
summary: Gives Cinch IRC bots access to BoardGameGeek data
|