bgg-hotness-cli 0.1.2

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 662aca314b21e8095dd8a513497a4c79305534b92fb1003adca478ca086201bf
4
+ data.tar.gz: 8308e6f342ed1e4184bad23626275504d596a05ed304bbe3aa9bcd9f50eae5ab
5
+ SHA512:
6
+ metadata.gz: 95faa1444bdf4c6b7f512d7b13cf35c17b37a08f062da188bc5a23c006e1af59842938723bfe4b24b6a57cb38d56adfb987aae135777e9670ef9bc99ce59d899
7
+ data.tar.gz: 56d71273c8951887223c85f8b1c406f99b574a89eee392c6d0a08621017010bc819bd18ab94de47184520be42e8625d6e8664dd7cb12247483567e498b582639
@@ -0,0 +1,2 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ Gemfile.lock
data/.replit ADDED
@@ -0,0 +1,2 @@
1
+ language = "ruby"
2
+ run = "bin/console"
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ - Using welcoming and inclusive language
18
+ - Being respectful of differing viewpoints and experiences
19
+ - Gracefully accepting constructive criticism
20
+ - Focusing on what is best for the community
21
+ - Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ - The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ - Trolling, insulting/derogatory comments, and personal or political attacks
28
+ - Public or private harassment
29
+ - Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ - Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at 'joshe523@gmail.com'. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem 'bundler'
6
+ gem 'pry'
7
+ gem 'nokogiri'
8
+ gem 'launchy'
9
+ gem 'tty-prompt'
10
+ gem "rake", "~> 12.0"
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Josh Ellis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,58 @@
1
+ # BGG Hotness CLI
2
+
3
+ ## Description
4
+
5
+ BGG Hotness CLI is a fast command line interface for checking the top 50 hot boardgames of BoardGameGeek.com's API.
6
+
7
+ It was built by [@imjoshellis](https://github.com/imjoshellis) as a part of Flatiron School's Software Engineering program.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```bash
14
+ gem "bgg-hotness-cli"
15
+
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ ```bash
21
+ bundle
22
+ ```
23
+
24
+ Or if you prefer:
25
+
26
+ ```bash
27
+ gem install bgg-hotness-cli
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ Run `bin/bgg-hotness-cli` in your terminal for a quickstart.
33
+
34
+ Or `require 'bgg-hotness-cli` and create a `BggHotnessCLI` object with `.new.run` methods wherever you want it.
35
+
36
+ For example:
37
+
38
+ ```ruby
39
+ irb
40
+ require 'bgg-hotness-cli'
41
+ BggHotnessCLI.new.run
42
+ ```
43
+
44
+ Once you're in the interface, use ↑/↓ arrows to navigate between options and press Enter to select your choice.
45
+
46
+ ![screenshot of start page](https://github.com/imjoshellis/BGG-Hotness-CLI/blob/master/img/start-page.jpg 'BGG Hotness CLI Start Page')
47
+
48
+ ## Contributing
49
+
50
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/imjoshellis/bgg-hotness-cli> This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
51
+
52
+ ## License
53
+
54
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
55
+
56
+ ## Code of Conduct
57
+
58
+ Everyone interacting in the Bgg Hotness CLI project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/imjoshellis/BGG-Hotness-CLI/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,26 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "bgg-hotness-cli"
3
+ spec.version = "0.1.2"
4
+ spec.authors = ["'Josh Ellis'"]
5
+ spec.email = ['joshe523@gmail.com']
6
+
7
+ spec.summary = "Quickly browse the hottest games on BoardGameGeek"
8
+ spec.description = "Command Line Interface that utilizes the API of BoardGameGeek.com to list hot boardgames."
9
+ spec.homepage = "https://github.com/imjoshellis/bgg-hotness-cli"
10
+ spec.license = "MIT"
11
+
12
+ # Specify which files should be added to the gem when it is released.
13
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
14
+ spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
15
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ end
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 2.0"
22
+ spec.add_development_dependency "rake", "~> 12.3.3"
23
+ spec.add_development_dependency "nokogiri", "~> 1.10.4"
24
+ spec.add_development_dependency "launchy", "~> 2.5.0"
25
+ spec.add_development_dependency "tty-prompt", "~> 0.20.0"
26
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "bgg-hotness-cli"
5
+
6
+ # Everything happens in a single instance of CommandLineInterface
7
+ BggHotnessCLI.new.run
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
Binary file
@@ -0,0 +1,38 @@
1
+ require_relative './bgg-hotness-cli/scraper.rb'
2
+ require_relative './bgg-hotness-cli/game.rb'
3
+ require_relative './bgg-hotness-cli/wrap.rb'
4
+ require_relative './bgg-hotness-cli/page.rb'
5
+ require 'launchy'
6
+ require 'tty-prompt'
7
+
8
+ class BggHotnessCLI
9
+ # Displays goodbye and ends program
10
+ def self.goodbye
11
+ puts
12
+ puts "Goodbye!"
13
+ puts
14
+ return
15
+ end
16
+
17
+ def self.header
18
+ puts "\e[H\e[2J"
19
+ puts
20
+ puts "BGG Hotness CLI"
21
+ end
22
+
23
+ # Runs program by creating empty pages,
24
+ # doing a scrape of the hot list, adding games to pages,
25
+ # and printing the first 10 items on the list.
26
+ def run
27
+ # Create empty pages
28
+ Page.make_pages
29
+
30
+ # Scrape list, which creates game instances
31
+ # and adds them to their pages in order.
32
+ Scraper.new("https://www.boardgamegeek.com/xmlapi2/hot?boardgame").game_list
33
+
34
+ Page.all[0].display_page
35
+ end
36
+
37
+ # NOTE: #run must be last so other methods can load.
38
+ end
@@ -0,0 +1,183 @@
1
+ class Game
2
+ attr_accessor :page, :description, :minplayers, :maxplayers, :minplaytime, :maxplaytime, :minage, :category, :mechanic, :publisher, :designer, :url
3
+ attr_reader :name, :id, :year, :rank
4
+
5
+ # Initialize with as much data as the list API gives for each game
6
+ def initialize(name, id, year, rank)
7
+ @name = name
8
+ @id = id
9
+ @year = year
10
+ @rank = rank
11
+
12
+ # Calculate page index of Page.all[]
13
+ page_index = ((@rank.to_i - 1) / 10).floor
14
+ # Put page into its game
15
+ @page = Page.all[page_index]
16
+ # Put game into its page
17
+ Page.all[page_index].games << self
18
+ end
19
+
20
+ def header
21
+ # Print header
22
+ BggHotnessCLI.header
23
+ puts
24
+ puts "#{@rank}. #{@name} (#{@year})"
25
+ end
26
+
27
+ # Get the details from the game's details page via API
28
+ def get_details
29
+
30
+ # If the description is nil, it needs to be scraped.
31
+ # Otherwise, all data should be in memory, so skip this.
32
+ if @description.nil?
33
+ Scraper.new("https://boardgamegeek.com/xmlapi2/thing?id=#{@id}").get_details(self)
34
+ end
35
+ end
36
+
37
+ def display_details
38
+
39
+ # Variable for indentation string to make it easy to change
40
+ @indent = "· "
41
+
42
+ # Print loading message.
43
+ # This is cleared by separator after load finishes,
44
+ # and generally won't be on the screen for long.
45
+ puts
46
+ puts "Loading details..."
47
+ puts
48
+
49
+ # Check to see if details exist, and scrapes if needed
50
+ get_details
51
+ @back_to_details = false
52
+
53
+ header
54
+
55
+ # 2-4 players • 60-90 minutes • ages 12+
56
+ puts "#{@minplayers}–#{@maxplayers} players • #{@minplaytime}–#{@maxplaytime} minutes • ages #{@minage}+"
57
+
58
+ # https://boardgamegeek.com/boardgame/ID
59
+ puts "#{@url}"
60
+ puts
61
+
62
+ # Use wrap method to add indentation & word wrap
63
+ puts "DESCRIPTION:"
64
+ puts wrap("#{@description[0..140]}...",@indent)
65
+ puts
66
+
67
+ # Use print_array method to print arrays (with wrap method)
68
+ print_array("categories", "category", @category)
69
+ print_array("mechanics", "mechanic", @mechanic)
70
+
71
+ # See what user wants to do next
72
+ details_input
73
+ end
74
+
75
+ # Prints array with commas as needed
76
+ def print_array(plural, single, array)
77
+ # Sometimes new games have empty fields.
78
+ # Don't do anything if array is empty.
79
+ if array.size != 0
80
+ puts array.size > 1 ? "#{plural.upcase}: " : "#{single.upcase}: "
81
+
82
+ # Initialize variable for holding output string
83
+ output = ""
84
+ array.each_with_index do |item,idx|
85
+ output += item
86
+
87
+ # if there's more than one item and this isn't the last item, add commas
88
+ if item != array.last && array.size > 1
89
+
90
+ # print an & before last item
91
+ if idx == array.size - 2
92
+ output += ", & "
93
+
94
+ # otherwise, just print a comma and space
95
+ else
96
+ output += ", "
97
+ end
98
+ end
99
+ end
100
+
101
+ # print the output with word-wrapping
102
+ puts wrap(output, @indent)
103
+ puts
104
+ end
105
+ end
106
+
107
+ def details_input
108
+
109
+ choices = [
110
+ "Return to the list",
111
+ "See full description",
112
+ "See publisher(s) & designer(s)",
113
+ "Open BGG page in your default browser"
114
+ ]
115
+ choices << "Return to game details" if @back_to_details
116
+ choices << "Quit"
117
+
118
+ # Set up prompt
119
+ prompt = TTY::Prompt.new(active_color: :blue)
120
+
121
+ # Set up greeting
122
+ greeting = "Select an option:"
123
+
124
+ # Capture input & display prompt
125
+ @input = prompt.select(greeting, choices, cycle: true)
126
+
127
+ # Parse user input
128
+ if @input == choices[0]
129
+ # If they chose 1st option, return to the list
130
+ @page.display_page
131
+ elsif @input == choices[1]
132
+ # If they choose 2nd option, print full description
133
+ @back_to_details = true
134
+ full_description
135
+ elsif @input == choices[2]
136
+ # If they choose 3rd option, print publisher and designer
137
+ @back_to_details = true
138
+ publisher_designer
139
+ elsif @input == choices[3]
140
+ # If they choose 4th option, open URL with launchy and reset details page
141
+ puts
142
+ puts "Attempting to open URL..."
143
+ puts
144
+ Launchy.open(@url)
145
+ @input = @rank # Set input to rank so correct game is chosen
146
+ display_details
147
+ elsif @input == choices[4] && @back_to_details
148
+ # If they choose back to game details, go back to game details
149
+ @back_to_details = false
150
+ display_details
151
+ elsif @input == choices.last
152
+ # If they quit, run "goodbye" method
153
+ BggHotnessCLI.goodbye
154
+ end
155
+ end
156
+
157
+ # Displays full description
158
+ def full_description
159
+ header
160
+
161
+ # Use wrap method to add indentation & word wrap
162
+ puts "DESCRIPTION:"
163
+ puts wrap("#{@description}",@indent)
164
+ puts
165
+
166
+ # See what user wants to do next
167
+ details_input
168
+ end
169
+
170
+ # Displays publisher(s) and designer(s)
171
+ def publisher_designer
172
+ header
173
+
174
+ # Use print_array method to print arrays (with wrap method)
175
+ print_array("publishers", "publisher", @publisher)
176
+ print_array("designers", "designer", @designer)
177
+ puts
178
+
179
+ # See what user wants to do next
180
+ details_input
181
+ end
182
+
183
+ end
@@ -0,0 +1,105 @@
1
+ # Each page is a list of 10 games.
2
+ # In total, the app has 5 pages (50 games).
3
+ class Page
4
+ attr_accessor :start_rank, :end_rank, :games, :page_number
5
+
6
+ @@all = []
7
+
8
+ def self.all
9
+ @@all
10
+ end
11
+
12
+ def initialize(start_rank, end_rank)
13
+ @start_rank = start_rank
14
+ @end_rank = end_rank
15
+ @page_number = end_rank / 10
16
+ @games = []
17
+ self.class.all << self
18
+ end
19
+
20
+ ## Instance Methods ##
21
+ def display_page
22
+ # Displays list of games between @start_rank and @end_rank
23
+
24
+ # Print header
25
+ BggHotnessCLI.header
26
+ puts "The top #{@start_rank}–#{@end_rank} hot games on BGG."
27
+ puts
28
+
29
+ choices = []
30
+
31
+ # First option in array is to see next 10 games
32
+ if @end_rank != 50
33
+ choices << {name: "See the next 10 games on the list", value: "next"}
34
+ else
35
+ choices << {name: "(end of list) Start over", value: "next"}
36
+ end
37
+
38
+ # Put each game into choices
39
+ @games.each do |game|
40
+ # If the rank is less than 10, add an extra space to make numbers line up
41
+ choices << {name: " #{game.rank}. #{game.name} (#{game.year})", value: game} if game.rank.to_i < 10
42
+ choices << {name: "#{game.rank}. #{game.name} (#{game.year})", value: game} if game.rank.to_i >= 10
43
+ end
44
+
45
+ # Last option is always to quit
46
+ choices << {name: "Quit", value: "quit"}
47
+
48
+ # Set up prompt
49
+ prompt = TTY::Prompt.new(active_color: :blue)
50
+
51
+ # Set up greeting
52
+ greeting = "Select a game to view its details:"
53
+
54
+ # Capture input (input takes :value from choice[x]) & display prompt
55
+ @input = prompt.select(greeting, choices, per_page: 12, cycle: true)
56
+
57
+ # Parse user input
58
+ if @input == "next"
59
+ # If user selects next part of the list...
60
+ if @end_rank == 50
61
+ # ...if at the end of the list (50), display the first page
62
+ Page.all[0].display_page
63
+ else
64
+ # ...otherwise, display the next page
65
+ # this works because the first page is [0] index,
66
+ # but it's page # is 1, meaning this will show
67
+ # the second page (which is at all[1]).
68
+ # TODO: make this less confusing?
69
+ Page.all[@page_number].display_page
70
+ end
71
+ elsif @input == 'quit'
72
+ # If they quit, run "goodbye" method
73
+ BggHotnessCLI.goodbye
74
+ else
75
+ # Otherwise, navigate to selected game
76
+ @input.display_details
77
+ end
78
+
79
+ end
80
+
81
+ ## Class Methods ##
82
+
83
+ # Made obsolete by Game.new
84
+ # def self.add_game(game)
85
+ # # when a game is added, put it into the right page.
86
+ # self.all.each do |page|
87
+ # if game.rank.to_i >= page.start_rank && game.rank.to_i <= page.end_rank
88
+ # page.games[(game.rank.to_i - 1) % 10] = game
89
+ # game.page = page
90
+ # end
91
+ # end
92
+ # end
93
+
94
+ # Create 5 pages of 10 games
95
+ def self.make_pages
96
+ _start_rank = 1 # temp local variable
97
+ _end_rank = 10 # temp local variable
98
+ 5.times do
99
+ Page.new(_start_rank, _end_rank)
100
+ _start_rank += 10
101
+ _end_rank += 10
102
+ end
103
+ end
104
+
105
+ end
@@ -0,0 +1,52 @@
1
+ require 'nokogiri'
2
+ require 'open-uri'
3
+
4
+ class Scraper
5
+
6
+ # Initialize with an API path to open
7
+ def initialize(path)
8
+ @doc = Nokogiri::HTML(URI.open(path))
9
+ end
10
+
11
+ # Get the initial list of games from the hotness list.
12
+ def game_list
13
+
14
+ # Get the data and create a new instance of
15
+ # Game for each item in the main list
16
+ @doc.css('item').each do |item|
17
+ name = item.css('name')[0]['value']
18
+ rank = item['rank']
19
+ id = item['id']
20
+ year = item.css('yearpublished')[0]['value']
21
+
22
+ # Create a new instance of Game with item data
23
+ game = Game.new(name, id, year, rank)
24
+ end
25
+
26
+ end
27
+
28
+ # Get the details from the game's details page via API.
29
+ # This could be done during the initial loop, but it's
30
+ # done per game request to save inital load time.
31
+ def get_details(game)
32
+
33
+ # HTML.parse is used here to clean up HTML codes like &nbsp; and line breaks
34
+ game.description = Nokogiri::HTML.parse(@doc.css('description').text).text
35
+
36
+ # These items are pretty easy to grab
37
+ game.minplayers = @doc.css('minplayers')[0]['value']
38
+ game.maxplayers = @doc.css('maxplayers')[0]['value']
39
+ game.minplaytime = @doc.css('minplaytime')[0]['value']
40
+ game.maxplaytime = @doc.css('maxplaytime')[0]['value']
41
+ game.minage = @doc.css('minage')[0]['value']
42
+
43
+ # Pull the various types of item out of <link> into respective arrays
44
+ game.category = @doc.css('link').select{|link| link['type']=="boardgamecategory"}.collect{|link| link['value']}
45
+ game.mechanic = @doc.css('link').select{|link| link['type']=="boardgamemechanic"}.collect{|link| link['value']}
46
+ game.publisher = @doc.css('link').select{|link| link['type']=="boardgamepublisher"}.collect{|link| link['value']}
47
+ game.designer = @doc.css('link').select{|link| link['type']=="boardgamedesigner"}.collect{|link| link['value']}
48
+
49
+ # The URL formula isn't via API. It's just boardgamegeek's URL scheme.
50
+ game.url = "https://boardgamegeek.com/boardgame/#{game.id}"
51
+ end
52
+ end
@@ -0,0 +1,5 @@
1
+ # via http://www.java2s.com/Code/Ruby/String/WordwrappingLinesofText.htm
2
+
3
+ def wrap(s, indent, width=78)
4
+ s.gsub(/(.{1,#{width}})(\s+|\Z)/, "#{indent}\\1\n")
5
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bgg-hotness-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - "'Josh Ellis'"
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-03-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 12.3.3
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 12.3.3
41
+ - !ruby/object:Gem::Dependency
42
+ name: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.10.4
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.10.4
55
+ - !ruby/object:Gem::Dependency
56
+ name: launchy
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 2.5.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 2.5.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: tty-prompt
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.20.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.20.0
83
+ description: Command Line Interface that utilizes the API of BoardGameGeek.com to
84
+ list hot boardgames.
85
+ email:
86
+ - joshe523@gmail.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitattributes"
92
+ - ".gitignore"
93
+ - ".replit"
94
+ - CODE_OF_CONDUCT.md
95
+ - Gemfile
96
+ - LICENSE
97
+ - README.md
98
+ - Rakefile
99
+ - bgg-hotness-cli.gemspec
100
+ - bin/bgg-hotness-cli
101
+ - bin/setup
102
+ - img/start-page.jpg
103
+ - lib/bgg-hotness-cli.rb
104
+ - lib/bgg-hotness-cli/game.rb
105
+ - lib/bgg-hotness-cli/page.rb
106
+ - lib/bgg-hotness-cli/scraper.rb
107
+ - lib/bgg-hotness-cli/wrap.rb
108
+ homepage: https://github.com/imjoshellis/bgg-hotness-cli
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubygems_version: 3.1.2
128
+ signing_key:
129
+ specification_version: 4
130
+ summary: Quickly browse the hottest games on BoardGameGeek
131
+ test_files: []