ten_largest_cities 1.0.1

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: '04258b023e2281becc21eda5021ec2fdb3d630583305662453c2c3d6023cbd88'
4
+ data.tar.gz: 595b730a99055b1107d5511de2dfe2fc106633245ab315771c1aa1a5f879b405
5
+ SHA512:
6
+ metadata.gz: 0f87f5c63478f8d2d601af96bbc2569eb10edc100d012a30ac6f11021849cf8d1c0a64394bf8a7d969c9c92df361854a2282218d3235c2fb340d693b46016e74
7
+ data.tar.gz: 829fcd994c0eebc794ca36a660a815fe018076eefe0ea8682a4cb61e312ce17452013702f4d88b727256ef7f4eac39e2e2efc0da33d23831a5355a8748f11553
data/bin/run.rb ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../config/environment'
3
+
4
+ Cli.new.start
@@ -0,0 +1,10 @@
1
+ require 'bundler/setup'
2
+ Bundler.require
3
+
4
+ require 'nokogiri'
5
+ require 'require_all'
6
+ require 'open-uri'
7
+ require 'pry'
8
+ require 'colorize'
9
+
10
+ require_all 'lib'
data/lib/city.rb ADDED
@@ -0,0 +1,32 @@
1
+
2
+ class City
3
+ attr_accessor :city_name, :population, :location, :country
4
+
5
+ @@all = []
6
+
7
+ #This uses the scraped information to make new cities
8
+ def initialize(city_name, population, location, country)
9
+ @city_name = city_name
10
+ @population = population
11
+ @location = location
12
+ @country = country
13
+ @@all << self
14
+ end
15
+
16
+ #This displays all of the city objects
17
+ def self.all
18
+ @@all
19
+ end
20
+
21
+ #this allows the user to see the desired city data displayed
22
+ def self.info
23
+ i = 0
24
+ self.all.collect do |city|
25
+ puts "#{i+=1}. #{city.city_name}".light_blue
26
+ puts "Population: #{city.population}"
27
+ puts "Coordinates: #{city.location}"
28
+ end
29
+ puts "\n"
30
+ end
31
+
32
+ end
@@ -0,0 +1,53 @@
1
+
2
+ class CityScraper
3
+ attr_accessor :country, :city_table
4
+
5
+ #initialize runs the scraper through the required methods of opening, collecting, creating cities
6
+ def initialize(country)
7
+ @country = country
8
+ @city_table = open_page
9
+ chunked = collect_cities
10
+ create_cities(chunked)
11
+ end
12
+
13
+ #opens the webpage to initiate the scraping process
14
+ def open_page
15
+ html = open(self.country.largest_cities_link)
16
+ data = Nokogiri::HTML(html).css('table.restable.sortable').css('td')
17
+ city_table = data.css('td').collect {|l| l}
18
+ city_table
19
+ end
20
+
21
+ #uses the collected data to iterate through and print out the pertinent text
22
+ def collect_cities
23
+ result = []
24
+ chunked = []
25
+ city_table.each_with_index do |v, i|
26
+ if (i > 0 && v.children.text.length > 2 && v.children.first.text != v.children.last.text)
27
+ data = v.children.first.text.concat(v.children.last.text)
28
+ result << data
29
+ elsif (i > 0 && v.children.text.length > 2 && v.children.first.text == v.children.last.text)
30
+ data = v.children.text
31
+ result << data
32
+ end
33
+ end
34
+ result
35
+
36
+ #collects 3 data points and associates them together
37
+ while result.length > 2
38
+ chunked << result.slice!(0,3)
39
+ end
40
+ chunked
41
+ end
42
+
43
+ #creates new city objects based off of these collected datapoints
44
+ def create_cities(chunked)
45
+ chunked.collect do |city|
46
+ city_name = city[0]
47
+ population = city[1]
48
+ location = city[2]
49
+ country = self.country.name
50
+ new = City.new(city_name, population, location, country)
51
+ end
52
+ end
53
+ end
data/lib/cli.rb ADDED
@@ -0,0 +1,74 @@
1
+ class Cli
2
+ attr_accessor :country
3
+
4
+ #welcome message and first menu option - search or exit. posts country list if selected.
5
+ def start
6
+ puts "\nIt's time to learn about countries and their largest cities!".blue
7
+ puts "Browse the menu by typing the first letter of a country's name - or type 'exit'.".blue
8
+ letter = gets.strip.upcase
9
+ if letter == "EXIT"
10
+ finished
11
+ elsif (letter != "EXIT" && ("A".."Z").to_a.include?(letter))
12
+ Scraper.new
13
+ list = Country.search_all_names(letter)
14
+ puts list
15
+ puts "\n"
16
+ country_info
17
+ else
18
+ start
19
+ end
20
+ end
21
+
22
+ #second menu option - choose a country? posts country information if selected
23
+ def country_info
24
+ puts "\nPlease type the name of the desired country.".blue
25
+ name = gets.strip.downcase
26
+ if Country.find_by_name(name) != nil
27
+ self.country = Country.find_by_name(name)
28
+ puts "\nGreat! Let's take a look.\n".blue
29
+ list = self.country.info
30
+ puts list
31
+ city_info
32
+ else
33
+ country_info
34
+ end
35
+ end
36
+
37
+ #third menu option - continue to city data, or quit? posts city data if selected
38
+ def city_info
39
+ puts "\nDo you want to learn more about #{self.country.name}'s largest cities? (Y/N)".blue
40
+ continue = gets.strip.upcase
41
+ if continue == "Y"
42
+ CityScraper.new(self.country)
43
+ puts "\n"
44
+ list = City.info
45
+ puts list
46
+ puts "Additional City Information:"
47
+ puts "#{self.country.largest_cities_link}"
48
+ finished
49
+ elsif continue == "N"
50
+ finished
51
+ else
52
+ city_info
53
+ end
54
+ end
55
+
56
+ #finishes program
57
+ def finished
58
+ puts "\n"
59
+ puts "Do you want to learn about a new country? (Y/N)"
60
+ continue = gets.strip.upcase
61
+ if continue == "Y"
62
+ Country.all.clear
63
+ City.all.clear
64
+ Cli.new.start
65
+ elsif continue == "N"
66
+ puts "That's all I got! Please check out the links provided for additional info.".blue
67
+ puts "\n"
68
+ else
69
+ finished
70
+ end
71
+ end
72
+
73
+
74
+ end
data/lib/country.rb ADDED
@@ -0,0 +1,50 @@
1
+
2
+ class Country
3
+ attr_accessor :country_link, :name, :abbreviation, :largest_cities_link
4
+ @@all = []
5
+
6
+ #This uses the scraped information to make new countries
7
+ def initialize(name, abbreviation, country_link)
8
+ @name = name
9
+ @abbreviation = abbreviation
10
+ @country_link = country_link
11
+ l_name = name.downcase.gsub(" ", "-")
12
+ @largest_cities_link = "https://www.geonames.org/#{self.abbreviation}/largest-cities-in-#{l_name}.html"
13
+ @@all << self
14
+ end
15
+
16
+ #This displays all of the country objects
17
+ def self.all
18
+ @@all.sort! {|a,b| a.name <=> b.name}
19
+ end
20
+
21
+ def self.search_all_names(input)
22
+ input = input.to_s
23
+ result = []
24
+ self.all.each do |v|
25
+ if input == v.name[0]
26
+ result << "#{v.name}"
27
+ end
28
+ end
29
+ result
30
+ end
31
+
32
+ #this allows you to look up a country object by country name
33
+ def self.find_by_name(input)
34
+ self.all.detect { |x| x.name.downcase == input }
35
+ end
36
+
37
+ #looking up cities via using country object to initiate the city scraper
38
+ def self.lookup_cities(name)
39
+ country = self.find_by_name(name)
40
+ country = CityScraper.new(country)
41
+ end
42
+
43
+ #this allows the user to see the data displayed
44
+ def info
45
+ puts "Country Name: #{self.name}".light_blue
46
+ puts "Country Abbreviation: #{self.abbreviation}"
47
+ puts "Country Info link: #{self.country_link}"
48
+ end
49
+
50
+ end
@@ -0,0 +1,49 @@
1
+ class Scraper
2
+ #Scraper.new pulls methods together: open the page, scrape, and instantiate new countries
3
+ def initialize
4
+ country_table = open_page
5
+ country_table = collect_countries(country_table)
6
+ create_countries(country_table)
7
+ end
8
+
9
+ #this opens our website url and stores it as a zoomed-in array
10
+ def open_page
11
+ html = open("https://www.geonames.org/countries/")
12
+ country_table = Nokogiri::HTML(html).css('#countries')
13
+ country_table = country_table.css('td').css('a').collect {|l| l}
14
+ end
15
+
16
+ #this iterates over the country table data to chunk together data
17
+ def collect_countries(country_table)
18
+ result = []
19
+ chunked = []
20
+
21
+ country_table.each_with_index do |v, i|
22
+ if i.even?
23
+ country_abbreviation = v.attributes['name'].value
24
+ result << country_abbreviation
25
+ else
26
+ country_name = v.children.text
27
+ country_link = v.attributes['href'].value
28
+ result << country_name
29
+ result << "https://www.geonames.org#{country_link}"
30
+ end
31
+ end
32
+ #taking each set of three data points and associating them together
33
+ while result.length > 3
34
+ chunked << result.slice!(0,3)
35
+ end
36
+ chunked
37
+ end
38
+
39
+ #this creates new countries based on the data chunks
40
+ def create_countries(country_table)
41
+ country_table.each do |country|
42
+ abbreviation = country[0]
43
+ name = country[1]
44
+ info_link = country[2]
45
+ name = Country.new(name, abbreviation, info_link)
46
+ end
47
+ end
48
+
49
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ten_largest_cities
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Mackenzie Moore
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-03-25 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ executables:
16
+ - run.rb
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - bin/run.rb
21
+ - config/environment.rb
22
+ - lib/city.rb
23
+ - lib/city_scraper.rb
24
+ - lib/cli.rb
25
+ - lib/country.rb
26
+ - lib/country_scraper.rb
27
+ homepage: https://github.com/mackenzie-km/ten_largest_cities
28
+ licenses:
29
+ - MIT
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - bin
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubygems_version: 3.0.3
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: learn about countries and their largest cities
50
+ test_files: []