cinch-bgg 0.0.1

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/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # Cinch-IMDb - IMDb.com plugin
2
+
3
+ ## Description
4
+
5
+ This plugin uses the [Film Buff gem](https://github.com/sachse/filmbuff) to access data from IMDb.com.
6
+
7
+ ## Installation
8
+
9
+ ### RubyGems
10
+
11
+ You can install the latest Cinch-IMDb gem using RubyGems
12
+
13
+ gem install cinch-imdb
14
+
15
+ ### GitHub
16
+
17
+ Alternatively you can check out the latest code directly from Github
18
+
19
+ git clone http://github.com/sachse/cinch-imdb.git
20
+
21
+ ## Usage
22
+
23
+ Install the gem and load it in your Cinch bot:
24
+
25
+ require "cinch"
26
+ require "cinch/plugins/imdb"
27
+
28
+ bot = Cinch::Bot.new do
29
+ configure do |c|
30
+ # add all required options here
31
+ c.plugins.plugins = [Cinch::Plugins::IMDb] # optionally add more plugins
32
+ end
33
+ end
34
+
35
+ bot.start
36
+
37
+ If you want to return results in other languages this is possible as well. The supported locales are "de_DE", "en_US", "es_ES", "fr_FR", "it_IT" and "pt_PT" with "en_US" being the default.
38
+
39
+ require "cinch"
40
+ require "cinch/plugins/imdb"
41
+
42
+ bot = Cinch::Bot.new do
43
+ configure do |c|
44
+ # add all required options here
45
+ c.plugins.plugins = [Cinch::Plugins::IMDb] # optionally add more plugins
46
+ c.plugins.options[Cinch::Plugins::IMDb][:locale] = "de_DE"
47
+ end
48
+ end
49
+
50
+ bot.start
51
+
52
+ ## Commands
53
+
54
+ ### imdb
55
+
56
+ By default the bot will reply with "Title (Year) - Rating/10 - IMDb link"
57
+ e.g. "The Wizard of Oz (1939) - 8.3/10 - http://www.imdb.com/title/tt0032138"
58
+
59
+ With a German locale (de_DE) the bot would instead reply with "Das zauberhafte Land (1939) - 8.3/10 - http://www.imdb.com/title/tt0032138"
60
+
61
+ If you want to change the output format this can be done in imdb.rb
62
+ The amount of information available is dependent on the Film Buff gem, which is used for accessing IMDb.com - At the time of writing the following information is accessible:
63
+
64
+ - Title
65
+ - Tagline
66
+ - Plot
67
+ - Runtime
68
+ - Rating
69
+ - Amount of votes
70
+ - Poster URL
71
+ - Genres
72
+ - Release date
73
+ - IMDb ID
74
+
75
+ ## Authors
76
+
77
+ * [Kristoffer Sachse](https://github.com/sachse)
78
+
79
+ ## Contribute
80
+
81
+ Fork the project, implement your changes in it's own branch, and send
82
+ a pull request to me. I'll gladly consider any help or ideas.
data/cinch-bgg.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "cinch-bgg"
5
+ s.version = "0.0.1"
6
+ s.platform = Gem::Platform::RUBY
7
+ s.authors = ["Caitlin Woodward"]
8
+ s.email = ["caitlin@caitlinwoodward.me"]
9
+ s.homepage = "https://github.com/caitlin/cinch-bgg"
10
+ s.summary = %q{Gives Cinch IRC bots access to BoardGameGeek data}
11
+ s.description = %q{Gives Cinch IRC bots access to BoardGameGeek data}
12
+
13
+ s.rubyforge_project = "cinch-bgg"
14
+
15
+ s.add_dependency("cinch", "~> 1.0")
16
+ s.add_dependency("nokogiri", "~> 1.5.2")
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.require_paths = ["lib"]
20
+ end
@@ -0,0 +1,120 @@
1
+ require 'cinch'
2
+ require 'open-uri'
3
+ require 'nokogiri'
4
+
5
+ module Cinch
6
+ module Plugins
7
+ class Bgg
8
+ include Cinch::Plugin
9
+
10
+ match /bgg (.+)/i, method: :bgg
11
+ match /bgguser (.+)/i, method: :bgguser
12
+
13
+ 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
21
+ m.reply "#{m.user.nick}: #{game.name} (#{game.year}) - #{game.rating} - Rank: #{game.game_rank} - Designer: #{game.designers.join(", ")} - Mechanics: #{game.mechanics.join(", ")} - " <<
22
+ "http://boardgamegeek.com/boardgame/#{game.id}"
23
+ end
24
+ end
25
+
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}"
29
+ end
30
+
31
+ #--------------------------------------------------------------------------------
32
+ # Protected
33
+ #--------------------------------------------------------------------------------
34
+ protected
35
+
36
+ def search_bgg(search_string)
37
+ search_results_xml = Nokogiri::XML(open("http://boardgamegeek.com/xmlapi2/search?query=#{search_string.gsub(" ", "%20")}&type=boardgame&exact=1").read)
38
+ if search_results_xml.css('items')[0]['total'] == "0"
39
+ search_results_xml = Nokogiri::XML(open("http://boardgamegeek.com/xmlapi2/search?query=#{search_string.gsub(" ", "%20")}&type=boardgame").read)
40
+ end
41
+ search_results = search_results_xml.css('item').map { |i| i['id'].to_i }
42
+
43
+ # this is dumb, find a better way
44
+ if search_results.empty?
45
+ response = "not found"
46
+ elsif search_results.size > 50
47
+ response = "too big"
48
+ else
49
+ response = search_results.map do |id|
50
+ Game.new(id, get_info_for_game(id))
51
+ end
52
+ end
53
+ response
54
+ end
55
+
56
+ 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|
59
+ open("http://boardgamegeek.com/xmlapi2/thing?id=#{game_id}&stats=1") do |uri|
60
+ file.write(uri.read)
61
+ end
62
+ end
63
+ end
64
+ Nokogiri::XML(File.open("data/games/#{game_id}.xml"))
65
+ end
66
+
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)
70
+ User.new(name, user_xml, collection_xml)
71
+ end
72
+
73
+ end
74
+
75
+ class Game
76
+ attr_accessor :id, :rating, :rank, :name, :year, :minplayers, :maxplayers, :playingtime, :categories, :mechanics, :designers, :publishers
77
+
78
+ NOT_RANKED_RANK = 10001
79
+
80
+ def initialize(id, xml)
81
+ self.id = id
82
+ self.rating = xml.css('statistics ratings average')[0]['value'].to_f
83
+ self.rank = xml.css('statistics ratings ranks rank')[0]["value"]
84
+ # if ranked, convert the value to integer; if not, set the value of the rank to the last possible
85
+ self.rank = self.rank == "Not Ranked" ? NOT_RANKED_RANK : self.rank.to_i
86
+ self.name = xml.css('name')[0]['value']
87
+ self.year = xml.css('yearpublished')[0]['value'].to_i
88
+ self.minplayers = xml.css('minplayers')[0]['value'].to_i
89
+ self.maxplayers = xml.css('maxplayers')[0]['value'].to_i
90
+ self.playingtime = xml.css('playingtime')[0]['value'].to_i
91
+ self.categories = xml.css('link[type=boardgamecategory]').map{ |l| l['value'] }
92
+ self.mechanics = xml.css('link[type=boardgamemechanic]').map{ |l| l['value'] }
93
+ self.designers = xml.css('link[type=boardgamedesigner]').map{ |l| l['value'] }
94
+ self.publishers = xml.css('link[type=boardgamepublisher]').map{ |l| l['value'] }
95
+ end
96
+
97
+ # Since we are resetting the not ranked values, let's make sure we return the correct values
98
+ #
99
+ def game_rank
100
+ (self.rank == NOT_RANKED_RANK) ? "Not Ranked" : self.rank
101
+ end
102
+ end
103
+
104
+ class User
105
+
106
+ attr_accessor :name, :top_games, :hot_games, :collection
107
+
108
+ def initialize(username, user_xml, collection_xml)
109
+ self.name = username
110
+ self.top_games = user_xml.css("top item").map{ |g| g["name"] }
111
+ self.hot_games = user_xml.css("hot item").map{ |g| g["name"] }
112
+ self.collection = {}
113
+ collection_xml.css("items item").each do |g|
114
+ self.collection[g["objectid"]] = g.css("name")[0].content
115
+ end
116
+ end
117
+
118
+ end
119
+ end
120
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cinch-bgg
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Caitlin Woodward
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-16 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: cinch
16
+ requirement: &70337759365740 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70337759365740
25
+ - !ruby/object:Gem::Dependency
26
+ name: nokogiri
27
+ requirement: &70337759365260 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.5.2
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70337759365260
36
+ description: Gives Cinch IRC bots access to BoardGameGeek data
37
+ email:
38
+ - caitlin@caitlinwoodward.me
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - Gemfile
44
+ - README.md
45
+ - cinch-bgg.gemspec
46
+ - lib/cinch/plugins/bgg.rb
47
+ homepage: https://github.com/caitlin/cinch-bgg
48
+ licenses: []
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubyforge_project: cinch-bgg
67
+ rubygems_version: 1.8.6
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: Gives Cinch IRC bots access to BoardGameGeek data
71
+ test_files: []