cinch-bgg 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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.2"
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
 
@@ -7,25 +7,74 @@ module Cinch
7
7
  class Bgg
8
8
  include Cinch::Plugin
9
9
 
10
- match /bgg (.+)/i, method: :bgg
11
- match /bgguser (.+)/i, method: :bgguser
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
- results = search_bgg(title)
15
- if results == "not found"
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, name)
27
- user = search_for_user(name)
28
- m.reply "#{m.user.nick}: #{user.name} - Collection: #{user.collection.size} - Top 5: #{user.top_games.first(5).join(", ")} - http://boardgamegeek.com/user/#{user.name}"
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
- response = "not found"
93
+ m.reply "\"#{search_string}\" not found", true
46
94
  elsif search_results.size > 50
47
- response = "too big"
95
+ m.reply "\"#{search_string}\" was too broad of a search term", true
48
96
  else
49
- response = search_results.map do |id|
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?("data/#{game_id}.xml")
58
- open("data/games/#{game_id}.xml", "wb") do |file|
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("data/games/#{game_id}.xml"))
113
+ Nokogiri::XML(File.open("#{@data_dir}#{GAMES_SUBDIR}/#{game_id}.xml"))
65
114
  end
66
115
 
67
- def search_for_user(name)
68
- user_xml = Nokogiri::XML(open("http://boardgamegeek.com/xmlapi2/user?name=#{name}&hot=1&top=1").read)
69
- collection_xml = Nokogiri::XML(open("http://boardgamegeek.com/xmlapi2/collection?username=#{name}&own=1").read)
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"]] = g.css("name")[0].content
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.2
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-06-16 00:00:00.000000000Z
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: &70356809562460 !ruby/object:Gem::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: *70356809562460
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: &70356809561980 !ruby/object:Gem::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: *70356809561980
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: cinch-bgg
67
- rubygems_version: 1.8.6
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