Class: RateBeer::Review
- Inherits:
-
Object
- Object
- RateBeer::Review
- Extended by:
- URLs
- Defined in:
- lib/ratebeer/review.rb
Overview
The Review class contains reviews of Beers posted to RateBeer.com. It also provides some scraping functionality for obtaining reviews.
Constant Summary
Constants included from URLs
URLs::BASE_URL, URLs::SEARCH_URL
Class Attribute Summary collapse
-
.review_limit ⇒ Object
readonly
Returns the value of attribute review_limit.
-
.review_order ⇒ Object
readonly
Returns the value of attribute review_order.
Instance Attribute Summary collapse
-
#beer ⇒ Object
readonly
Returns the value of attribute beer.
-
#comment ⇒ Object
readonly
Returns the value of attribute comment.
-
#date ⇒ Object
readonly
Returns the value of attribute date.
-
#location ⇒ Object
readonly
Returns the value of attribute location.
-
#rating ⇒ Object
readonly
Returns the value of attribute rating.
-
#rating_breakdown ⇒ Object
readonly
Returns the value of attribute rating_breakdown.
-
#reviewer ⇒ Object
readonly
Returns the value of attribute reviewer.
-
#reviewer_rank ⇒ Object
readonly
Returns the value of attribute reviewer_rank.
Class Method Summary collapse
-
.num_pages(limit) ⇒ Integer
Calculate the number of pages of reviews to retrieve.
-
.retrieve(beer, order: :most_recent, limit: 10) ⇒ Array<RateBeer::Review>
Retrieve all reviews for a given beer.
-
.url_suffix(order) ⇒ String
Determine the URL suffix required for a particular sort order.
Instance Method Summary collapse
- #==(other_review) ⇒ Object
-
#initialize(**options) ⇒ Review
constructor
A new instance of Review.
- #inspect ⇒ Object
- #to_s ⇒ Object
Methods included from URLs
beer_url, brewery_beers_url, brewery_url, country_url, region_url, review_url, style_beers_url, style_url
Constructor Details
#initialize(**options) ⇒ Review
Returns a new instance of Review.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/ratebeer/review.rb', line 125 def initialize(**) @beer = if [:beer].is_a?(RateBeer::Beer) [:beer] elsif [:beer].is_a?(Integer) RateBeer::Beer::Beer.new([:beer]) else raise ArgumentError.new("incorrect beer parameter: #{[:beer]}") end [:reviewer, :reviewer_rank, :location, :date, :rating, :rating_breakdown, :comment].each do |param| if [param].nil? raise ArgumentError.new("#{param.to_s} parameter required") end instance_variable_set("@#{param.to_s}", [param]) end end |
Class Attribute Details
.review_limit ⇒ Object (readonly)
Returns the value of attribute review_limit.
13 14 15 |
# File 'lib/ratebeer/review.rb', line 13 def review_limit @review_limit end |
.review_order ⇒ Object (readonly)
Returns the value of attribute review_order.
14 15 16 |
# File 'lib/ratebeer/review.rb', line 14 def review_order @review_order end |
Instance Attribute Details
#beer ⇒ Object (readonly)
Returns the value of attribute beer.
116 117 118 |
# File 'lib/ratebeer/review.rb', line 116 def beer @beer end |
#comment ⇒ Object (readonly)
Returns the value of attribute comment.
123 124 125 |
# File 'lib/ratebeer/review.rb', line 123 def comment @comment end |
#date ⇒ Object (readonly)
Returns the value of attribute date.
120 121 122 |
# File 'lib/ratebeer/review.rb', line 120 def date @date end |
#location ⇒ Object (readonly)
Returns the value of attribute location.
119 120 121 |
# File 'lib/ratebeer/review.rb', line 119 def location @location end |
#rating ⇒ Object (readonly)
Returns the value of attribute rating.
121 122 123 |
# File 'lib/ratebeer/review.rb', line 121 def @rating end |
#rating_breakdown ⇒ Object (readonly)
Returns the value of attribute rating_breakdown.
122 123 124 |
# File 'lib/ratebeer/review.rb', line 122 def @rating_breakdown end |
#reviewer ⇒ Object (readonly)
Returns the value of attribute reviewer.
117 118 119 |
# File 'lib/ratebeer/review.rb', line 117 def reviewer @reviewer end |
#reviewer_rank ⇒ Object (readonly)
Returns the value of attribute reviewer_rank.
118 119 120 |
# File 'lib/ratebeer/review.rb', line 118 def reviewer_rank @reviewer_rank end |
Class Method Details
.num_pages(limit) ⇒ Integer
Calculate the number of pages of reviews to retrieve.
Ten reviews appear on a page, so this method calculates the number of pages on this basis.
24 25 26 |
# File 'lib/ratebeer/review.rb', line 24 def num_pages(limit) (limit / 10.0).ceil end |
.retrieve(beer, order: :most_recent, limit: 10) ⇒ Array<RateBeer::Review>
Retrieve all reviews for a given beer.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/ratebeer/review.rb', line 59 def retrieve(beer, order: :most_recent, limit: 10) if beer.is_a?(RateBeer::Beer::Beer) beer_id = beer.id elsif beer.is_a?(Integer) beer_id = beer beer = RateBeer::Beer::Beer.new(beer) else raise "unknown beer value: #{beer}" end reviews = num_pages(limit).times.flat_map do |page_number| url = URI.join(BASE_URL, review_url(beer_id, url_suffix(order), page_number)) doc = RateBeer::Scraping.noko_doc(url) root = doc.at_css('.reviews-container') # All reviews are contained within the sole cell in the sole row of # the selected table. Each review consists of rating information, # details of the reviewer, and the text of the review itself. # # The components are contained within div, small, div tags # respectively. We need to scrape these specifically. root.at_css('div div') .children .select { |x| x.name == 'div' || x.name == 'small' } .map(&:text) .reject { |x| x.empty? || x.include?("googleFillSlot") } .each_slice(3).map do |(, reviewer_data, review)| = /^(?<total>\d+(\.\d+)?).+ AROMA\s(?<aroma>\d+\/10).+ APPEARANCE\s(?<appearance>\d+\/5).+ TASTE\s(?<taste>\d+\/10).+ PALATE\s(?<palate>\d+\/5).+ OVERALL\s(?<overall>\d+\/20)$/x reviewer_pattern = /^(?<name>.+)\s\((?<rank>\d+\))\s-\s? (?<location>.+)?\s?-\s (?<date>.+)$/x = .match() = {} reviewer = reviewer_data.gsub(RateBeer::Scraping.nbsp, ' ').match(reviewer_pattern) [:overall, :aroma, :appearance, :taste, :palate].each { |k| [k] = Rational([k]) } = [:total].to_f self.new({ beer: beer, reviewer: reviewer[:name], reviewer_rank: reviewer[:rank], location: reviewer[:location].strip, date: Date.parse(reviewer[:date]), rating: , rating_breakdown: , comment: review }) end end reviews.take(limit) end |
.url_suffix(order) ⇒ String
Determine the URL suffix required for a particular sort order.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/ratebeer/review.rb', line 34 def url_suffix(order) = [:most_recent, :top_raters, :highest_score] unless .include?(order) raise ArgumentError.new("unknown ordering: #{order}") end case order when :most_recent "1" when :top_raters "2" when :highest_score "3" end end |
Instance Method Details
#==(other_review) ⇒ Object
150 151 152 153 154 155 |
# File 'lib/ratebeer/review.rb', line 150 def ==(other_review) self.reviewer == other_review.reviewer && self.date == other_review.date && self.beer == other_review.beer && self.comment == other_review.comment end |
#inspect ⇒ Object
142 143 144 |
# File 'lib/ratebeer/review.rb', line 142 def inspect var = "#<Review of #{self.beer} - #{@reviewer} on #{@date}>" end |
#to_s ⇒ Object
146 147 148 |
# File 'lib/ratebeer/review.rb', line 146 def to_s inspect end |