goodreads-books 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0e1b1a9e5fb954dad3a7677af78b522a95f6fcbddf4b9d762273361400f7d0b0
4
+ data.tar.gz: d8c0304c8b443208b591e9abdb2ad906bcb2afecf2b12a8a409561421e1a0eea
5
+ SHA512:
6
+ metadata.gz: 78d5ec945a11ba692ed363281243d73cb6918269619e9a8b8b2d80c338e7e21f9875cce15d12bc45ae02a217596c6633fe20125df05f99860c78e7eb2f8c0afb
7
+ data.tar.gz: b3ca162e6398e94bbba4000fb32cfca6b2080e0efe77adb10427edfb0e099b5cc89ead21f4eddc7cb31ac748af07c6b990a0c24adcaa1d0f0e338f3a01bcdf7d
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+
5
+ require_relative '../lib/goodreads_books'
6
+
7
+ GoodreadsBooks::CLI.new.call
@@ -0,0 +1,9 @@
1
+ require 'nokogiri'
2
+ require 'open-uri'
3
+ require 'colorize'
4
+ require 'pry'
5
+
6
+ require_relative '../lib/goodreads_books/version'
7
+ require_relative '../lib/goodreads_books/cli'
8
+ require_relative '../lib/goodreads_books/scraper'
9
+ require_relative '../lib/goodreads_books/book'
@@ -0,0 +1,5 @@
1
+ require_relative '../config/environment'
2
+
3
+ module GoodreadsBooks
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,70 @@
1
+ class GoodreadsBooks::Book
2
+ attr_accessor :awards_year, :category, :title, :author, :vote, :description, :cate_url, :url
3
+
4
+ BASE_URL = "https://www.goodreads.com"
5
+
6
+ @@all = []
7
+
8
+ def initialize(attributes)
9
+ attributes.each do |attr_name, attr_value|
10
+ self.send("#{attr_name}=", attr_value)
11
+ end
12
+ end #-- initialize --
13
+
14
+ def self.new_from_web_page(book_hash)
15
+ book = new(book_hash)
16
+ book.save
17
+ end #-- self.new_from_web_page --
18
+
19
+ def self.all
20
+ @@all
21
+ end #-- self.all --
22
+
23
+ def save
24
+ self.class.all << self
25
+ end #-- save --
26
+
27
+ def self.all_by_year(awards_year)
28
+ all.select { |book| book.awards_year == awards_year }
29
+ end #-- find_by_year --
30
+
31
+ def author
32
+ get_book_details if !@author
33
+ @author
34
+ end #-- author --
35
+
36
+ def vote
37
+ get_book_details if !@vote
38
+ @vote
39
+ end #-- vote --
40
+
41
+ def description
42
+ get_book_details if !@description
43
+ @description
44
+ end #-- description --
45
+
46
+ def url
47
+ get_book_details if !@url
48
+ @url
49
+ end #-- url --
50
+
51
+ def get_book_details
52
+ # Next level of scraping (get details of winner book within each category_url)
53
+ book_doc = Nokogiri::HTML(open(self.cate_url))
54
+
55
+ self.vote = book_doc.css(".gcaRightContainer .gcaWinnerHeader").text.split(" ")[1]
56
+ self.author = book_doc.css(".gcaRightContainer h3 .gcaAuthor a.authorName").text
57
+ self.url = "#{BASE_URL}#{book_doc.css(".gcaRightContainer h3 a.winningTitle").attr("href").text}"
58
+ self.description = book_doc.css(".gcaRightContainer .readable.stacked").text.strip
59
+
60
+ #binding.pry
61
+ end #-- get_book_details --
62
+
63
+ def self.populate_book_details(award_year)
64
+ all_by_year(awards_year).each do |book|
65
+ book.get_book_details
66
+ end
67
+ #binding.pry
68
+ end #-- self.populate_book_details --
69
+
70
+ end
@@ -0,0 +1,95 @@
1
+ class GoodreadsBooks::CLI
2
+
3
+ # This application only works for year 2010 to current year - 1.
4
+ # Goodreads Choice Awards Winner 2009 page setup differs from 2010 onwards.
5
+ BASE_YEAR = 2010
6
+ END_YEAR = Time.now.year - 1
7
+
8
+ def initialize
9
+ @@choice_awards = nil
10
+ end
11
+
12
+ def call
13
+ system "clear"
14
+ puts ""
15
+ puts "---------- Welcome to Goodreads Choice Awards Books ----------"
16
+ puts " ----------------------------------------"
17
+ puts ""
18
+
19
+ load_choice_awards
20
+
21
+ main_menu
22
+ end #-- call --
23
+
24
+ def load_choice_awards(awards_year = nil)
25
+ if awards_year == nil
26
+ puts "Loading The Latest Winners of Goodreads Choice Awards Books..."
27
+ else
28
+ puts "Loading The Winners of #{awards_year} Goodreads Choice Awards Books..."
29
+ end
30
+
31
+ @choice_awards = GoodreadsBooks::Scraper.find_or_create_by_year(awards_year)
32
+
33
+ @book_count = GoodreadsBooks::Book.all_by_year(@choice_awards.awards_year).count
34
+ end #-- load_choice_awards --
35
+
36
+ def main_menu
37
+ system "clear"
38
+
39
+ input = nil
40
+ while input != "exit"
41
+ list_books
42
+
43
+ puts ""
44
+ puts "Enter a number to view details of the book, or select another Choice Awards year (2010 onwards)."
45
+ puts "Type 'exit' to end the application."
46
+ input = gets.strip
47
+
48
+ if input.downcase == "exit"
49
+ break
50
+ elsif input.to_i.between?(1, @book_count)
51
+ book = GoodreadsBooks::Book.all_by_year(@choice_awards.awards_year)[input.to_i - 1]
52
+ view_book(book)
53
+ elsif input.to_i.between?(BASE_YEAR, END_YEAR)
54
+
55
+ load_choice_awards(input.to_i)
56
+ else
57
+ puts ""
58
+ puts "Please enter a number between 1 and #{@book_count} or a valid Choice Awards year".colorize(:red)
59
+ end
60
+ end
61
+
62
+ puts ""
63
+ puts "Thank you for using Goodreads Choice Awards Books."
64
+ end #-- main_menu --
65
+
66
+ def list_books
67
+ puts ""
68
+ puts "---------- #{@choice_awards.awards_year} Goodreads Choice Awards Books ----------"
69
+ puts ""
70
+
71
+ GoodreadsBooks::Book.all_by_year(@choice_awards.awards_year).each.with_index(1) do |book, index|
72
+ puts "#{index}. #{book.category} - #{book.title}"
73
+ end
74
+ end #-- display_books --
75
+
76
+ def view_book(book)
77
+ puts ""
78
+ puts "---------- #{@choice_awards.awards_year} BEST #{book.category.upcase} Winner ----------"
79
+ puts ""
80
+ puts "Title: #{book.title}"
81
+ puts "Author: #{book.author}"
82
+ puts "Votes: #{book.vote}"
83
+ puts ""
84
+ puts " --- Overview ---"
85
+ puts "#{book.description}"
86
+
87
+ puts ""
88
+ puts "Would you like to visit Goodreads website to view this book? Enter Y or N".colorize(:green)
89
+ input = gets.strip.downcase
90
+
91
+ if input.downcase == "y"
92
+ system("open #{book.url}")
93
+ end
94
+ end #-- view_book --
95
+ end
@@ -0,0 +1,77 @@
1
+ class GoodreadsBooks::Scraper
2
+ attr_accessor :awards_year, :main_url
3
+
4
+ BASE_URL = "https://www.goodreads.com"
5
+ PAGE_URL = "/choiceawards"
6
+
7
+ @@all = []
8
+
9
+ def initialize(awards_year = nil)
10
+ @awards_year = awards_year
11
+ end #-- initialize --
12
+
13
+ def self.all
14
+ @@all
15
+ end #-- self.all --
16
+
17
+ def save
18
+ self.class.all << self
19
+ end #-- save --
20
+
21
+ def self.find_or_create_by_year(awards_year = nil)
22
+ if !(choice_awards = find_by_year(awards_year))
23
+ choice_awards = create(awards_year)
24
+ choice_awards.scrape_books
25
+ end
26
+ find_by_year(choice_awards.awards_year)
27
+ end #-- self.find_or_create_by_year --
28
+
29
+ def self.find_by_year(awards_year = nil)
30
+ all.detect { |r| r.awards_year == awards_year }
31
+ end #-- self.find_by_year --
32
+
33
+ def self.create(awards_year = nil)
34
+ #choice_awards = new(awards_year)
35
+ #choice_awards.save
36
+ choice_awards = new(awards_year).tap { |s| s.save }
37
+
38
+ # if awards_year is missing from the url,
39
+ # goodreads.com defaults to latest choice awards
40
+ # /best-books-#{latest awards year}"
41
+ if awards_year == nil
42
+ choice_awards.main_url = "#{BASE_URL}#{PAGE_URL}"
43
+ doc = Nokogiri::HTML(open(choice_awards.main_url))
44
+ choice_awards.awards_year = doc.css("head title").text.split(" ")[2].to_i
45
+ else
46
+ choice_awards.main_url = "#{BASE_URL}#{PAGE_URL}/best-books-#{awards_year}"
47
+ choice_awards.awards_year = awards_year
48
+ end
49
+
50
+ choice_awards # return instance of scraper
51
+ end #-- self.create --
52
+
53
+ def scrape_books
54
+ doc = Nokogiri::HTML(open(@main_url))
55
+
56
+ # Category winners page
57
+ doc.css(".category.clearFix").each do |category|
58
+ cate_name = category.css("h4").text
59
+ cate_url = category.css("a").attr("href").text
60
+ cate_title = category.css("img").attr("alt").text
61
+ # cate_book_id = category.css("input")[2].attr("value") # don't need to keep book_id
62
+
63
+ # for each winner element, assemble the book_details hash
64
+ book_details = {
65
+ :awards_year => @awards_year,
66
+ :category => cate_name,
67
+ :title => cate_title,
68
+ :cate_url => "#{BASE_URL}#{cate_url}"
69
+ }
70
+
71
+ GoodreadsBooks::Book.new_from_web_page(book_details)
72
+ end
73
+
74
+ #binding.pry
75
+ end #-- scrape_books --
76
+
77
+ end
@@ -0,0 +1,3 @@
1
+ module GoodreadsBooks
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: goodreads-books
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ni Chia
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-09-04 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.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
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: nokogiri
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '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'
83
+ - !ruby/object:Gem::Dependency
84
+ name: colorize
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Goodreads CLI gem is a command line application that lists the yearly
98
+ Goodreads Choice Awards Winning Books.
99
+ email:
100
+ - nichia@gmail.com
101
+ executables:
102
+ - goodreads-books
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - bin/goodreads-books
107
+ - config/environment.rb
108
+ - lib/goodreads_books.rb
109
+ - lib/goodreads_books/book.rb
110
+ - lib/goodreads_books/cli.rb
111
+ - lib/goodreads_books/scraper.rb
112
+ - lib/goodreads_books/version.rb
113
+ homepage: https://github.com/nichia/goodreads_books.git
114
+ licenses:
115
+ - MIT
116
+ metadata: {}
117
+ post_install_message:
118
+ rdoc_options: []
119
+ require_paths:
120
+ - lib
121
+ - lib/goodreads_books
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 2.7.6
135
+ signing_key:
136
+ specification_version: 4
137
+ summary: Goodreads Choice Awards Books
138
+ test_files: []