Instantly share code, notes, and snippets.

@mrfoto /quotes.rb
Last active Sep 20, 2018

Embed
What would you like to do?
Stoic quotes from Goodreads
require 'rubygems'
require 'bundler'
Bundler.require(:default)
require 'concurrent'
require 'open-uri'
require 'json'
class QuoteDownloader
attr_reader :author
BASE_URL = 'https://www.goodreads.com/author/quotes/'
def initialize(author)
@quotes = Concurrent::Array.new
@author = author
end
def quotes
download_quotes if @quotes.empty?
@quotes
end
private
def download_quotes
1.upto(number_of_pages).map do |page|
Concurrent::Future.execute { load_quotes_from("#{BASE_URL}#{author}?page=#{page}") }
end.map(&:value)
end
def load_quotes_from(url)
Nokogiri::XML(open(url)).css('.quoteText').each do |quote_text|
text = quote_text.children.select { |c| c.is_a? Nokogiri::XML::Text }.map(&:text).join(' ').strip
@quotes << {text: text, author: author_name}
end
end
def number_of_pages
main_doc.css('a').select{ |a| a[:href] =~ /page=/ }.map{ |a| a['href'][/page=(\d+)/, 1].to_i }.max || 1
end
def author_name
@author_name ||= main_doc.css('h1 a').children.last.text
end
def main_doc
@main_doc ||= Nokogiri::XML(open("#{BASE_URL}#{author}"))
end
end
all_quotes = []
['13852.Epictetus', '4918776.Seneca', '17212.Marcus_Aurelius', '833825.Zeno_of_Citium'].each do |author|
all_quotes << QuoteDownloader.new(author).quotes
end
File.write('quotes.json', {quotes: all_quotes.flatten}.to_json)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment