metacritic_games 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.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +40 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/metacritic-games +7 -0
- data/bin/setup +8 -0
- data/lib/cli.rb +114 -0
- data/lib/concerns/findable.rb +18 -0
- data/lib/concerns/nameable.rb +10 -0
- data/lib/concerns/persistable.rb +14 -0
- data/lib/game.rb +147 -0
- data/lib/genre.rb +28 -0
- data/lib/metacritic_games.rb +20 -0
- data/lib/metacritic_games/version.rb +3 -0
- data/lib/platform.rb +36 -0
- data/lib/scraper.rb +68 -0
- data/metacritic_games.gemspec +41 -0
- data/spec.md +6 -0
- metadata +179 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2d08a86bcad550eb33cdceda0392cf603a787aa8
|
4
|
+
data.tar.gz: 41d1fc0da3c55c69973990b0b2c3e31b4e3c6951
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0f04771908e5284333a5ef576d15dacf504ea9bebe04b847dff26bf770c721a7517f0c917cbe587fd7ede0552248a1f80b29720aed0e1e2e62d7d4dcab2719ba
|
7
|
+
data.tar.gz: 603df8bf300cd2f9125e3c4a1e8ca1dbb1a48c58cf0605acdeb6263d5dfff4dfbab3dce6679406aa330adf1f548ce8843e52a33973ec15f25fee216f4debdf10
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 TODO: Write your name
|
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
|
13
|
+
all 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
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# MetacriticGames
|
2
|
+
|
3
|
+
This gem scrapes the new release page of metacritic games and returns the newest releases listed by console. Each
|
4
|
+
game can be selected to find out metacritic score, user score, game genre, and a link to the metacritic review page.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'metacritic_games'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install metacritic_games
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Run 'bin/metacritic-games', then allow the cli to scrape and create the data for use. Once the platform menu loads, you can choose a platform to
|
25
|
+
see new games, and then select a game for more information, or return to the platform menu.
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
+
|
31
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/dschlauderaff/metacritic_games.
|
36
|
+
|
37
|
+
|
38
|
+
## License
|
39
|
+
|
40
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "metacritic_games"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/cli.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
# CLI controller
|
2
|
+
class MetacriticGames::CLI
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
attr_accessor :cli, :platform, :url, :genre
|
7
|
+
|
8
|
+
def self.progressbar
|
9
|
+
@@progressbar
|
10
|
+
end
|
11
|
+
|
12
|
+
# call gets everything running. sets the url for scraping main page, initializes highline for menus and progressbar for loading animation, creates platforms and games, then calls the first menu list
|
13
|
+
def call
|
14
|
+
self.cli = HighLine.new
|
15
|
+
self.url = "http://www.metacritic.com/browse/games/release-date/new-releases/all/date"
|
16
|
+
@@progressbar = ProgressBar.create(:starting_at => 20, :total => nil)
|
17
|
+
MetacriticGames::Platform.create_platforms(build_platform_array)
|
18
|
+
MetacriticGames::Game.create_games(build_game_array)
|
19
|
+
@platform = MetacriticGames::Platform.all
|
20
|
+
@genre = MetacriticGames::Genre.all
|
21
|
+
list_platforms
|
22
|
+
end
|
23
|
+
|
24
|
+
# scrapes and returns the platforms listed on the new release page
|
25
|
+
def build_platform_array
|
26
|
+
MetacriticGames::Scraper.scrape_platform(self.url)
|
27
|
+
end
|
28
|
+
|
29
|
+
# scrapes the games listed on the new release page
|
30
|
+
def build_game_array
|
31
|
+
game_array = MetacriticGames::Scraper.scrape_new_releases
|
32
|
+
game_array.reject! {|game| game == nil}
|
33
|
+
game_array
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def list_platforms
|
38
|
+
puts "\nPlatforms".bold.underline
|
39
|
+
self.cli.choose do |menu|
|
40
|
+
menu.index = :number
|
41
|
+
menu.index_suffix = ")"
|
42
|
+
menu.prompt = "Please choose the platform you want new release info for:"
|
43
|
+
self.platform.each do |platform|
|
44
|
+
menu.choice :"#{platform.name}" do list_games(platform) end
|
45
|
+
end
|
46
|
+
menu.choice :"List Platforms" do list_platforms end
|
47
|
+
menu.choice :Exit do goodbye end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
#lists games based on the platform passed in and creates the menu option for further game details
|
53
|
+
def list_games(platform)
|
54
|
+
cli.say "Metacritic's newest releases for #{platform.name}:"
|
55
|
+
self.cli.choose do |menu|
|
56
|
+
menu.index = :number
|
57
|
+
menu.index_suffix = ")"
|
58
|
+
menu.prompt = "Please choose the game you want more information on:"
|
59
|
+
platform.games.each do |game|
|
60
|
+
menu.choice :"#{game.name}" do game_details(game, platform) end
|
61
|
+
end
|
62
|
+
menu.choice :"Return to platform list" do list_platforms end
|
63
|
+
menu.choice :Exit do goodbye end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
#gives greater detail on a particular game and a link to access more
|
68
|
+
def game_details(game, platform)
|
69
|
+
cli.say "#{game.name} has a metacritic score of #{game.metascore[platform.name.to_sym]} and a current user score of: #{game.user_score[platform.name.to_sym]}."
|
70
|
+
cli.say "It is classified to the following genres:"
|
71
|
+
game.genre.each {|genre| cli.say "#{genre.name}"}
|
72
|
+
sleep 1
|
73
|
+
starship_troopers
|
74
|
+
game_url(game, platform)
|
75
|
+
self.cli.choose do |menu|
|
76
|
+
menu.index = :number
|
77
|
+
menu.index_suffix = ")"
|
78
|
+
menu.prompt = "Which menu would you like to return to?"
|
79
|
+
menu.choice :"Return to games list" do list_games(platform) end
|
80
|
+
menu.choice :"Return to platform list" do list_platforms end
|
81
|
+
menu.choice :Exit do goodbye end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def goodbye
|
86
|
+
puts "See you next time!"
|
87
|
+
exit
|
88
|
+
end
|
89
|
+
|
90
|
+
def starship_troopers
|
91
|
+
msg = "Would you like to know more?".bold
|
92
|
+
|
93
|
+
5.times do
|
94
|
+
print "\r#{msg}"
|
95
|
+
sleep 0.3
|
96
|
+
print "\r#{ ' ' * msg.size}"
|
97
|
+
sleep 0.3
|
98
|
+
end
|
99
|
+
puts "\nClick the link for more details".bold
|
100
|
+
end
|
101
|
+
|
102
|
+
# since games can have multiple platforms, logic to select the correct link for the specific platform
|
103
|
+
def game_url(game, platform)
|
104
|
+
if platform.name == "Xbox One"
|
105
|
+
puts "#{game.url[:XONE]}".colorize(:blue)
|
106
|
+
elsif platform.name == "Wii U"
|
107
|
+
puts "#{game.url[:WIIU]}".colorize(:blue)
|
108
|
+
elsif platform.name == "PS Vita"
|
109
|
+
puts "#{game.url[:VITA]}".colorize(:blue)
|
110
|
+
else
|
111
|
+
puts "#{game.url[platform.name.to_sym]}".colorize(:blue)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module MetacriticGames::Concerns::Findable
|
2
|
+
|
3
|
+
module ClassMethods
|
4
|
+
# Search class @@all array for object name
|
5
|
+
def find_by_name(name)
|
6
|
+
self.all.detect {|item| item.name == name}
|
7
|
+
end
|
8
|
+
|
9
|
+
# If find_by_name returns nil, create a new instance of the class with name argument
|
10
|
+
def find_or_create_by_name(name)
|
11
|
+
if self.find_by_name(name) == nil
|
12
|
+
self.create(name)
|
13
|
+
else
|
14
|
+
self.find_by_name(name)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/game.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
class MetacriticGames::Game
|
2
|
+
|
3
|
+
extend MetacriticGames::Concerns::Nameable::ClassMethods
|
4
|
+
extend MetacriticGames::Concerns::Findable::ClassMethods
|
5
|
+
extend MetacriticGames::Concerns::Persistable::ClassMethods
|
6
|
+
include MetacriticGames::Concerns::Persistable::InstanceMethods
|
7
|
+
|
8
|
+
attr_accessor :name, :genre, :metascore, :user_score, :platform, :url
|
9
|
+
|
10
|
+
@@all = []
|
11
|
+
|
12
|
+
def self.all
|
13
|
+
@@all
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
self.platform = []
|
18
|
+
self.url = {}
|
19
|
+
self.genre = []
|
20
|
+
self.metascore = {}
|
21
|
+
self.user_score = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_platform(platform)
|
25
|
+
platform.add_game(self) unless platform.games.include?(self)
|
26
|
+
self.platform << platform unless self.platform.include?(platform)
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_genre(genre)
|
30
|
+
genre.add_game(self) unless genre.games.include?(self)
|
31
|
+
self.genre << genre unless self.genre.include?(genre)
|
32
|
+
end
|
33
|
+
|
34
|
+
# creates the game object based on the array passed in from the controller. once the game is created, it scrapes it calls the scraper to scrape it's platform-specific page, then assigns the values and creates genre objects based off scrape data
|
35
|
+
def self.create_games(game_array)
|
36
|
+
game_array.each do |game|
|
37
|
+
MetacriticGames::CLI.progressbar.increment
|
38
|
+
if game[:platform] == "XONE" #metacritic naming for the xboxone does not follow standard pattern
|
39
|
+
platform = MetacriticGames::Platform.all.find {|platform| platform.name == "Xbox One"}
|
40
|
+
|
41
|
+
game.tap do |new_game|
|
42
|
+
new_game = self.find_or_create_by_name(game[:name])
|
43
|
+
new_game.add_platform(platform)
|
44
|
+
new_game.url[:"#{game[:platform]}"] = game[:url]
|
45
|
+
MetacriticGames::Scraper.scrape_game(new_game.url[:XONE]).each do |key,value|
|
46
|
+
if value.is_a? Array
|
47
|
+
value.each do |genre|
|
48
|
+
new_genre = MetacriticGames::Genre.create_genre(genre)
|
49
|
+
new_game.add_genre(new_genre)
|
50
|
+
end
|
51
|
+
elsif value.fetch(:platform) == "tbd"
|
52
|
+
value[:platform] = "currently unavailable"
|
53
|
+
new_game.send(("#{key}="), value)
|
54
|
+
elsif value.fetch(:platform) == ""
|
55
|
+
value[:platform] = "currently unavailable"
|
56
|
+
new_game.send(("#{key}="), value)
|
57
|
+
else
|
58
|
+
new_game.send(("#{key}="), value)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
score_by_platform(new_game, platform)
|
62
|
+
end
|
63
|
+
elsif game[:platform] == "WIIU" #metacritic naming for the wii u does not follow standard pattern
|
64
|
+
platform = MetacriticGames::Platform.all.find {|platform| platform.name == "Wii U"}
|
65
|
+
|
66
|
+
game.tap do |new_game|
|
67
|
+
new_game = self.find_or_create_by_name(game[:name])
|
68
|
+
new_game.add_platform(platform)
|
69
|
+
new_game.url[:"#{game[:platform]}"] = game[:url]
|
70
|
+
MetacriticGames::Scraper.scrape_game(new_game.url[:WIIU]).each do |key,value|
|
71
|
+
if value.is_a? Array
|
72
|
+
value.each do |genre|
|
73
|
+
new_genre = MetacriticGames::Genre.create_genre(genre)
|
74
|
+
new_game.add_genre(new_genre)
|
75
|
+
end
|
76
|
+
elsif value.fetch(:platform) == "tbd"
|
77
|
+
value[:platform] = "currently unavailable"
|
78
|
+
new_game.send(("#{key}="), value)
|
79
|
+
elsif value.fetch(:platform) == ""
|
80
|
+
value[:platform] = "currently unavailable"
|
81
|
+
new_game.send(("#{key}="), value)
|
82
|
+
else
|
83
|
+
new_game.send(("#{key}="), value)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
score_by_platform(new_game, platform)
|
87
|
+
end
|
88
|
+
elsif game[:platform] == "VITA" #metacritic naming for the ps vita does not follow standard pattern
|
89
|
+
platform = MetacriticGames::Platform.all.find {|platform| platform.name == "PS Vita"}
|
90
|
+
|
91
|
+
game.tap do |new_game|
|
92
|
+
new_game = self.find_or_create_by_name(game[:name])
|
93
|
+
new_game.add_platform(platform)
|
94
|
+
new_game.url[:"#{game[:platform]}"] = game[:url]
|
95
|
+
MetacriticGames::Scraper.scrape_game(new_game.url[:VITA]).each do |key,value|
|
96
|
+
if value.is_a? Array
|
97
|
+
value.each do |genre|
|
98
|
+
new_genre = MetacriticGames::Genre.create_genre(genre)
|
99
|
+
new_game.add_genre(new_genre)
|
100
|
+
end
|
101
|
+
elsif value.fetch(:platform) == "tbd"
|
102
|
+
value[:platform] = "currently unavailable"
|
103
|
+
new_game.send(("#{key}="), value)
|
104
|
+
elsif value.fetch(:platform) == ""
|
105
|
+
value[:platform] = "currently unavailable"
|
106
|
+
new_game.send(("#{key}="), value)
|
107
|
+
else
|
108
|
+
new_game.send(("#{key}="), value)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
score_by_platform(new_game, platform)
|
112
|
+
end
|
113
|
+
else
|
114
|
+
platform = MetacriticGames::Platform.all.find {|platform| platform.name == game[:platform]}
|
115
|
+
|
116
|
+
game.tap do |new_game|
|
117
|
+
new_game = self.find_or_create_by_name(game[:name])
|
118
|
+
new_game.add_platform(platform)
|
119
|
+
new_game.url[:"#{game[:platform]}"] = game[:url]
|
120
|
+
MetacriticGames::Scraper.scrape_game(new_game.url[:"#{platform.name}"]).each do |key,value|
|
121
|
+
if value.is_a? Array
|
122
|
+
value.each do |genre|
|
123
|
+
new_genre = MetacriticGames::Genre.create_genre(genre)
|
124
|
+
new_game.add_genre(new_genre)
|
125
|
+
end
|
126
|
+
elsif value.fetch(:platform) == "tbd"
|
127
|
+
value[:platform] = "currently unavailable"
|
128
|
+
new_game.send(("#{key}="), value)
|
129
|
+
elsif value.fetch(:platform) == ""
|
130
|
+
value[:platform] = "currently unavailable"
|
131
|
+
new_game.send(("#{key}="), value)
|
132
|
+
else
|
133
|
+
new_game.send(("#{key}="), value)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
score_by_platform(new_game, platform)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# changes the key of the metacritic and user scores from the generic ":platform" to a unique platform.name key required for multiplatform releases
|
143
|
+
def self.score_by_platform(game, platform)
|
144
|
+
game.metascore[platform.name.to_sym] = game.metascore.delete(:platform)
|
145
|
+
game.user_score[platform.name.to_sym] = game.user_score.delete(:platform)
|
146
|
+
end
|
147
|
+
end
|
data/lib/genre.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
class MetacriticGames::Genre
|
2
|
+
|
3
|
+
extend MetacriticGames::Concerns::Nameable::ClassMethods
|
4
|
+
extend MetacriticGames::Concerns::Findable::ClassMethods
|
5
|
+
extend MetacriticGames::Concerns::Persistable::ClassMethods
|
6
|
+
include MetacriticGames::Concerns::Persistable::InstanceMethods
|
7
|
+
|
8
|
+
attr_accessor :name, :games
|
9
|
+
|
10
|
+
@@all = []
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
self.games = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.all
|
17
|
+
@@all
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.create_genre(genre)
|
21
|
+
self.find_or_create_by_name(genre)
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_game(game)
|
25
|
+
game.genre << self unless game.genre.include? self
|
26
|
+
self.games << game unless self.games.include?(game)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative "./metacritic_games/version"
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'open-uri'
|
4
|
+
require 'openssl'
|
5
|
+
require 'highline'
|
6
|
+
require 'pry'
|
7
|
+
require 'colorize'
|
8
|
+
require 'ruby-progressbar'
|
9
|
+
require_relative './cli'
|
10
|
+
|
11
|
+
module MetacriticGames::Concerns
|
12
|
+
end
|
13
|
+
|
14
|
+
require_relative './concerns/persistable'
|
15
|
+
require_relative './concerns/findable'
|
16
|
+
require_relative './concerns/nameable'
|
17
|
+
require_relative './platform'
|
18
|
+
require_relative './game'
|
19
|
+
require_relative './genre'
|
20
|
+
require_relative './scraper'
|
data/lib/platform.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
class MetacriticGames::Platform
|
2
|
+
|
3
|
+
extend MetacriticGames::Concerns::Nameable::ClassMethods
|
4
|
+
extend MetacriticGames::Concerns::Findable::ClassMethods
|
5
|
+
extend MetacriticGames::Concerns::Persistable::ClassMethods
|
6
|
+
include MetacriticGames::Concerns::Persistable::InstanceMethods
|
7
|
+
|
8
|
+
attr_accessor :name, :games
|
9
|
+
|
10
|
+
@@all = []
|
11
|
+
|
12
|
+
def self.all
|
13
|
+
@@all
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
self.games = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.create_platforms(platform_array)
|
21
|
+
platform_array.each do |platform|
|
22
|
+
MetacriticGames::CLI.progressbar.increment
|
23
|
+
self.find_or_create_by_name(platform)
|
24
|
+
end
|
25
|
+
self.all
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_game(game)
|
29
|
+
game.platform << self unless game.platform.include? self
|
30
|
+
self.games << game unless self.games.include?(game)
|
31
|
+
end
|
32
|
+
|
33
|
+
def genres
|
34
|
+
self.games.collect {|game| game.genre}.uniq
|
35
|
+
end
|
36
|
+
end
|
data/lib/scraper.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
class MetacriticGames::Scraper
|
2
|
+
|
3
|
+
def self.doc= (name)
|
4
|
+
@@doc = name
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.doc
|
8
|
+
@@doc
|
9
|
+
end
|
10
|
+
|
11
|
+
#scrapes page for platforms and sets the class url variable to avoid scraping the index page a second time, returns the platform array to CLI
|
12
|
+
def self.scrape_platform(url)
|
13
|
+
self.doc = Nokogiri::HTML(open(url, ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE, 'User-Agent' => 'safari'))
|
14
|
+
self.doc.css(".platform_item").collect do |platform|
|
15
|
+
MetacriticGames::CLI.progressbar.increment
|
16
|
+
platform.text
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
#returns the array of game information hashes from the index page
|
21
|
+
def self.scrape_new_releases
|
22
|
+
self.doc.css(".product_wrap .product_title").collect do |game|
|
23
|
+
MetacriticGames::CLI.progressbar.increment
|
24
|
+
if game.text.include? ?(
|
25
|
+
game_hash = {
|
26
|
+
:name => self.get_title_text(game),
|
27
|
+
:platform => self.get_title_platform(game),
|
28
|
+
:url => self.get_title_url(game)
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# method to clean up text scrape
|
35
|
+
def self.get_title_text(game)
|
36
|
+
game.text.gsub(/\(([^)]+)\)/, "").strip
|
37
|
+
end
|
38
|
+
|
39
|
+
# method to clean up text scrape for platform
|
40
|
+
def self.get_title_platform(game)
|
41
|
+
game.text.slice(/\(([^)]+)\)/).delete"()"
|
42
|
+
end
|
43
|
+
|
44
|
+
# method to convert relative url on index page to absolute url
|
45
|
+
def self.get_title_url(game)
|
46
|
+
absolute = "http://www.metacritic.com"
|
47
|
+
absolute + game.css("a").attribute("href").value
|
48
|
+
end
|
49
|
+
|
50
|
+
# scrape individual page and return scores and genre listings
|
51
|
+
def self.scrape_game(url)
|
52
|
+
doc = Nokogiri::HTML(open(url, ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE, 'User-Agent' => 'safari'))
|
53
|
+
genre_array = []
|
54
|
+
doc.css("li.summary_detail.product_genre").css("span.data").each do |genre|
|
55
|
+
MetacriticGames::CLI.progressbar.increment
|
56
|
+
genre_array << genre.text
|
57
|
+
end
|
58
|
+
details_hash = {
|
59
|
+
:metascore => {
|
60
|
+
:platform => doc.css("div.metascore_w.xlarge").text
|
61
|
+
},
|
62
|
+
:user_score => {
|
63
|
+
:platform => doc.css(".metascore_anchor .user").text
|
64
|
+
},
|
65
|
+
:genre => genre_array
|
66
|
+
}
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'metacritic_games/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "metacritic_games"
|
8
|
+
spec.version = MetacriticGames::VERSION
|
9
|
+
spec.authors = ["David Schlauderaff"]
|
10
|
+
spec.email = ["dschlaud@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Scrap new release page of Metacritic games, return consoles, games, and information.}
|
13
|
+
spec.homepage = "https://github.com/dschlauderaff/metacritic_games.git"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
|
+
if spec.respond_to?(:metadata)
|
19
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
20
|
+
else
|
21
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
22
|
+
"public gem pushes."
|
23
|
+
end
|
24
|
+
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
26
|
+
f.match(%r{^(test|spec|features)/})
|
27
|
+
end
|
28
|
+
spec.bindir = "exe"
|
29
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
|
+
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
33
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
34
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
35
|
+
spec.add_development_dependency "pry"
|
36
|
+
spec.add_dependency "highline"
|
37
|
+
spec.add_dependency "nokogiri"
|
38
|
+
spec.add_dependency "colorize"
|
39
|
+
spec.add_dependency "ruby-progressbar"
|
40
|
+
|
41
|
+
end
|
data/spec.md
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
# Specifications for the CLI Assessment
|
2
|
+
|
3
|
+
Specs:
|
4
|
+
- [x] Have a CLI for interfacing with the application - bin/metacritic-games has requirements and call to start the interface
|
5
|
+
- [x] Pull data from an external source - scraper.rb pulls new release info from metacritic.com/games and the individual game pages
|
6
|
+
- [x] Implement both list and detail views - games are listed by platform, and selectable to display more information and page link
|
metadata
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: metacritic_games
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Schlauderaff
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-05-18 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: '1.14'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.14'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: highline
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: nokogiri
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: colorize
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: ruby-progressbar
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description:
|
126
|
+
email:
|
127
|
+
- dschlaud@gmail.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".gitignore"
|
133
|
+
- ".rspec"
|
134
|
+
- ".travis.yml"
|
135
|
+
- Gemfile
|
136
|
+
- LICENSE.txt
|
137
|
+
- README.md
|
138
|
+
- Rakefile
|
139
|
+
- bin/console
|
140
|
+
- bin/metacritic-games
|
141
|
+
- bin/setup
|
142
|
+
- lib/cli.rb
|
143
|
+
- lib/concerns/findable.rb
|
144
|
+
- lib/concerns/nameable.rb
|
145
|
+
- lib/concerns/persistable.rb
|
146
|
+
- lib/game.rb
|
147
|
+
- lib/genre.rb
|
148
|
+
- lib/metacritic_games.rb
|
149
|
+
- lib/metacritic_games/version.rb
|
150
|
+
- lib/platform.rb
|
151
|
+
- lib/scraper.rb
|
152
|
+
- metacritic_games.gemspec
|
153
|
+
- spec.md
|
154
|
+
homepage: https://github.com/dschlauderaff/metacritic_games.git
|
155
|
+
licenses:
|
156
|
+
- MIT
|
157
|
+
metadata:
|
158
|
+
allowed_push_host: https://rubygems.org
|
159
|
+
post_install_message:
|
160
|
+
rdoc_options: []
|
161
|
+
require_paths:
|
162
|
+
- lib
|
163
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
173
|
+
requirements: []
|
174
|
+
rubyforge_project:
|
175
|
+
rubygems_version: 2.4.8
|
176
|
+
signing_key:
|
177
|
+
specification_version: 4
|
178
|
+
summary: Scrap new release page of Metacritic games, return consoles, games, and information.
|
179
|
+
test_files: []
|