Module: Gnomika
- Defined in:
- lib/gnomika.rb,
lib/gnomikologikon/ui.rb,
lib/gnomikologikon/quote.rb,
lib/gnomikologikon/version.rb,
lib/gnomikologikon/category.rb,
lib/gnomikologikon/arg_parser.rb,
lib/gnomikologikon/file_writer.rb,
lib/gnomikologikon/web_processing.rb
Overview
Module containing all classes and functions of the application
Defined Under Namespace
Modules: Ruby Classes: ArgParser, Category, FileWriter, Quote, Subcategory
Class Method Summary collapse
-
.fetch_category_info ⇒ Object
Gets information about all categories from the website.
-
.get_quotes_for_categories(subcategories) { ... } ⇒ Object
Get all quotes for the given subcategories.
-
.get_quotes_from_html(page_body) ⇒ Object
Fetch all quotes from given HTML page.
- .main ⇒ Object
-
.select_category(categories) ⇒ Object
Prompt the user to select a category.
-
.select_subcategories(category) ⇒ Object
Prompt user to select subcategories.
-
.write_files(options, quotes) ⇒ Object
Writes given quotes to files according to the given options.
Class Method Details
.fetch_category_info ⇒ Object
Gets information about all categories from the website
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/gnomikologikon/web_processing.rb', line 13 def self.fetch_category_info response = HTTParty.get('https://www.gnomikologikon.gr/categ.php', { headers: {"User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"}, }) doc = Nokogiri::HTML.parse(response.body) # Each "big" category is stored in a table with class "authrst" category_tables = doc.xpath("//table[@class='authrst']") categories = [] category_tables.each do |table| # Get category name. Category names are stored in td elements with class "authrsh" category_name = table.xpath("tr/td[@class='authrsh']").text # Get the subcategories of each category subcategories = [] # Subcategories of each category are a elements in a list subcategory_elements = table.xpath("tr//ul//li//a") subcategory_elements.each do |element| subcategory_name = element.content # Need to prefix category URLs with the website URL subcategory_url = "https://www.gnomikologikon.gr/#{element[:href]}" subcategories << Subcategory.new(subcategory_name,subcategory_url) end categories << Category.new(category_name,subcategories: subcategories) end categories end |
.get_quotes_for_categories(subcategories) { ... } ⇒ Object
Get all quotes for the given subcategories
47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/gnomikologikon/web_processing.rb', line 47 def self.get_quotes_for_categories(subcategories) quotes = {} subcategories.each do |subcategory| response = HTTParty.get(subcategory.url, { headers: {"User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"}, }) quotes[subcategory] = get_quotes_from_html(response.body) yield if block_given? # Throttle the connection because processing is fast sleep 1 end quotes end |
.get_quotes_from_html(page_body) ⇒ Object
Fetch all quotes from given HTML page
65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/gnomikologikon/web_processing.rb', line 65 def self.get_quotes_from_html(page_body) doc = Nokogiri::HTML.parse(page_body) quotes_tables = doc.xpath("//table[@class='quotes']//td[@class='quote']") quotes = [] quotes_tables.each do |quote| content = get_quote_contents(quote) # HTML p elements with class auth0-auth4 contain quote author and additional information (e.g. book) # Get the text of all auth p elements and combine them in a string = quote.xpath(".//p[contains(@class, 'auth')]") = .map{|el| el.text}.join(' ') quotes << Quote.new(content,) end quotes end |
.main ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/gnomika.rb', line 12 def self.main # Parse command line arguments = ArgParser.parse(ARGV) # Get available categories available_categories = Gnomika.fetch_category_info # Prompt user to select a category selected_category = select_category(available_categories) # Prompt user to select subcategories selected_subcategories = select_subcategories(selected_category) # Create a progress bar = ProgressBar.create(total: selected_subcategories.length, title: "Download Progress") # Get the quotes and display progress quotes = Gnomika.get_quotes_for_categories(selected_subcategories){ .increment } # Create quote files with the options given as parameters begin write_files(, quotes) rescue StandardError => e STDERR.puts e. end end |
.select_category(categories) ⇒ Object
Prompt the user to select a category
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/gnomikologikon/ui.rb', line 6 def self.select_category(categories) # Index starting from 1 categories.each_with_index { |category, index| puts "#{index+1}. #{category.name}" } ok = false num = -1 until ok print "Select a category: " STDOUT.flush input = STDIN.gets begin # Remove 1 because display indexes starting from 1. num = Integer(input) - 1 break unless num < 0 || num > categories.length-1 # Input was number but out of bounds puts "Invalid selection!" rescue ArgumentError # Input could not be converted to integer puts "Invalid selection!" end end # Return Category object chosen by the user categories[num] end |
.select_subcategories(category) ⇒ Object
Prompt user to select subcategories. Selection can be a range e.g. 1-2, single categories e.g. 1,2,3 or both e.g 1,2-4
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/gnomikologikon/ui.rb', line 35 def self.select_subcategories(category) subcategories = category.subcategories # Index starting from 1 subcategories.each_with_index { |subcategory, index| puts "#{index+1}. #{subcategory.name}" } puts "You can select multiple categories separated by ',' or a range of categories with '-'." # Contains indexes of all subcategories specified by the user selected_indexes = [] ok = false until ok print "Select subcategories: " # On each loop we assume input is ok until an error is encountered ok = true # Empty the indexes array, in case of leftovers from previous loop selected_indexes = [] input = STDIN.gets # Split the input input = input.split(",") # Check each selection input.each do |selection| begin # We need to remove 1 from each because during selection category numbers started from 1 selected_indexes += selection_to_array(selection, subcategories.length).map{|it| it - 1} rescue => error ok = false puts error. break end end end # Remove any duplicate indexes selected_indexes.uniq! # Create an array with the corresponding Subcategory objects and return it selected_indexes.map { |index| subcategories[index]} end |
.write_files(options, quotes) ⇒ Object
Writes given quotes to files according to the given options.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/gnomikologikon/file_writer.rb', line 7 def self.write_files(, quotes) # If no custom directory is specified, use the current directory output_directory = Dir.pwd if .custom_output_dir_set custom_dir = .custom_output_dir_value begin unless Dir.exist? custom_dir Dir.mkdir custom_dir end output_directory = custom_dir rescue StandardError => e raise e end end file_writer = FileWriter.new(output_directory, .single_file, single_file_name: .single_file_name) quotes.each_pair do |subcategory,subcategory_quotes| file_writer.write_quotes(subcategory.name,subcategory_quotes) end # Must generate strfiles for fortune command to work file_writer.generate_strfiles end |