top_100 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7c57a07c3ddc393b6799747e92fe571f5652880d
4
- data.tar.gz: cba9ff3caa5bbe22fbc22af7d98c58701968afa7
3
+ metadata.gz: f6a3918efad8b3cacb60d1516ebbc5d4d487d074
4
+ data.tar.gz: 0483d33e3c8a6c5ff042e560ddda3d9028c3101d
5
5
  SHA512:
6
- metadata.gz: f3ca2a290d65245c7073ff958285ca47100617c94b3ab36ff3aef221cdbb5a5169cdd9db08f99ee6e6692126ff4b5383101cd613cedf5d80fada6b9d73bf387f
7
- data.tar.gz: f9b5b464f6de09435880a261f404a883e958c9f1321a0552da0b658101db7fcad8a70f7fd0a2b7c29bcd69c9dae35ad01255d52402a118bbe7df74dd0b544c87
6
+ metadata.gz: 00ae5dcf8c0e9b1dde4de7962efe77a0880b17fee76f77056a4267113a4002cc50e86b704b78629f3491824360868f10c0b075a5cff2c7a88a37157c079770d3
7
+ data.tar.gz: 44b7acb6b3cdb7d4dbfe0bb81e3b3d667936d13cc121ff2a118619235a4d5b356020dcdef160fd7cc83a87007617268987f145d43baa3f4e3d7b20779424a2c8
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Top100
2
2
 
3
- This gem allows the user to interact with the Billboard's Top 100 via the command line interface. Users can acquire a real time list of trending songs and acquire more information about the artists responsible for the works. Information is acquired through the use of the Nokogiri gem and OpenUri in order to data scrape information from the Billboard website.
3
+ This gem allows the user to interact with the Billboard's Top 100 via the command line interface. Users can acquire a real time list of trending songs and acquire more information about the artists responsible for the works. Users can also open up Spotify links in their default browser of any songs they wish to hear. Information is acquired through the use of the Nokogiri gem and OpenUri in order to scrape data and information from the Billboard website.
4
4
 
5
5
  ## Installation
6
6
 
@@ -30,4 +30,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
30
30
 
31
31
  ## Contributing
32
32
 
33
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/top_100.
33
+ Bug reports and pull requests are welcome on GitHub at https://github.com/viparthasarathy/top_100.
data/bin/top_100 CHANGED
@@ -3,4 +3,4 @@
3
3
  require "bundler/setup"
4
4
  require "top_100"
5
5
 
6
- Top100::CLI.new.call
6
+ CLI.new.call
data/exe/top_100 CHANGED
@@ -3,4 +3,4 @@
3
3
  require "bundler/setup"
4
4
  require "top_100"
5
5
 
6
- Top100::CLI.new.call
6
+ CLI.new.call
@@ -1,32 +1,35 @@
1
- class Top100::Artist
1
+ class Artist
2
2
  attr_accessor :songs, :name, :location, :date, :bio
3
- CURRENT_HITS = Top100::BillboardScraper.new.scrape_from_chart_page
3
+ @@artists = []
4
4
 
5
- def initialize(artist_hash)
6
- artist_hash.each {|key, value| self.send("#{key}=", value)}
7
- @songs = []
8
- self.add_current_hits
9
- end
10
-
11
- def add_current_hits
12
- CURRENT_HITS.each { |hit| self.songs << hit[:song_name] if hit[:song_artist].include?(self.name) }
5
+ #Songs already initialized, search for matching songs using name.
6
+ def initialize(artist_name)
7
+ @songs = Song.all.select {|song| song.artist_name == artist_name}
8
+ if @songs.empty?
9
+ self.name = nil
10
+ else
11
+ BillboardScraper.scrape_from_artist_bio_page(@songs[0].artist_bio_url).each {|key, value| self.send("#{key}=", value)}
12
+ @@artists << self
13
+ end
13
14
  end
14
15
 
15
16
  def display_details
16
17
  puts "Name: #{self.name}"
17
18
  puts "From: #{self.location}"
18
19
  puts "Formed: #{self.date} "
19
- puts "Currently Trending Songs: #{self.songs.join(", ")}"
20
+ song_names = self.songs.map {|s| s.name}
21
+ puts "Currently Trending Songs: #{song_names.join(", ")}"
20
22
  puts "Bio: #{self.bio}"
21
23
  end
22
24
 
23
- def self.create_artist(rank)
24
- info_hash = CURRENT_HITS.find { |hit| hit[:current_rank] == rank }
25
- unless info_hash == nil
26
- artist_hash = Top100::BillboardScraper.new.scrape_from_artist_bio_page(info_hash[:artist_bio_link])
27
- artist = self.new(artist_hash)
28
- artist
29
- end
25
+ def self.all
26
+ @@artists
27
+ end
28
+
29
+ #Artists have unique names, search for a match using the name or create a new Artist object.
30
+ def self.find_or_create(artist_name)
31
+ Artist.all.each {|a| return a if a.name == artist_name}
32
+ Artist.new(artist_name)
30
33
  end
31
34
 
32
35
  end
@@ -1,32 +1,35 @@
1
- class Top100::BillboardScraper
1
+ class BillboardScraper
2
2
 
3
- def scrape_from_chart_page
4
- html = open('http://www.billboard.com/charts/hot-100')
5
- nokogiri_object = Nokogiri::HTML(html)
6
- charts_array = Array.new
3
+ def self.scrape_from_chart_page
4
+ nokogiri_object = Nokogiri::HTML(open('http://www.billboard.com/charts/hot-100'))
7
5
  nokogiri_object.css('div.chart-row__primary').each do |song|
8
- charts_array << {
9
- current_rank: song.css('span.chart-row__current-week').text,
10
- song_name: song.css('h2.chart-row__song').text,
11
- song_artist: song.css('a.chart-row__link').text.strip,
12
- artist_bio_link: song.css('a.chart-row__link').attribute('href').value + '/biography'
6
+ url = song.css('a.chart-row__player-link')
7
+ name = song.css('h3.chart-row__artist').text.strip.split(//)
8
+ song_hash = {
9
+ rank: song.css('span.chart-row__current-week').text,
10
+ name: song.css('h2.chart-row__song').text,
11
+ artist_bio_url: song.css('a.chart-row__link').attribute('href').value + '/biography',
12
+ artist_name: song.css('h3.chart-row__artist').text.strip,
13
+ # missing url for some songs due to copyright issues, save url as nil for such songs
14
+ url: url.empty? ? nil : url.attribute('href').value
13
15
  }
16
+ Song.new(song_hash)
14
17
  end
15
- charts_array
16
18
  end
17
19
 
18
-
19
- def scrape_from_artist_bio_page(url)
20
- html = open(url)
21
- bio = Nokogiri::HTML(html)
20
+ def self.scrape_from_artist_bio_page(url)
21
+ bio = Nokogiri::HTML(open(url))
22
+ location_date = bio.css('dl.facts > dd').text
23
+ info = bio.css('article.bio_content').text
22
24
  artist = {
23
25
  name: bio.css('h1.title').text,
24
- location: bio.css('dl.facts > dd').text.split(" ")[0].strip,
25
- date: bio.css('dl.facts > dd').text.match(/\d+/)[0],
26
+ # missing information for some artists, need to catch that by checking if nokogiri returned empty strings.
27
+ location: location_date.empty? ? "Not Specified" : location_date.split(" ")[0].strip,
28
+ date: location_date.empty? ? "Not Specified" : location_date.match(/\d+/)[0],
29
+ #issues with .empty? for bio due to return values of long whitespace strings, so using regex to filter those out instead.
30
+ # calling split on info to separate bio aside and main text which does not have a different grouping outside 'article.bio_content'
31
+ bio: info.match(/\A\s*\z/) ? "Not Specified" : info.split(" ")[-1].strip
26
32
  }
27
- bio.css('aside.bio_sidebar').remove
28
- artist[:bio] = bio.css('article.bio_content').text.strip
29
- artist
30
33
  end
31
34
 
32
35
  end
data/lib/top_100/cli.rb CHANGED
@@ -1,14 +1,12 @@
1
- class Top100::CLI
2
- attr_accessor :tracker, :current_hits, :scraper
1
+ class CLI
2
+ attr_accessor :tracker
3
3
 
4
4
 
5
5
  def initialize
6
6
  @tracker = 0
7
- @scraper = Top100::BillboardScraper.new
8
- @current_hits = self.scraper.scrape_from_chart_page
7
+ BillboardScraper.scrape_from_chart_page
9
8
  end
10
9
 
11
-
12
10
  def call
13
11
  puts "Welcome to the Billboard Hot 100. Now outputting the top twenty songs..."
14
12
  display_chart
@@ -20,40 +18,41 @@ class Top100::CLI
20
18
  puts "There are no more songs to display."
21
19
  else
22
20
  20.times do
23
- hit = self.current_hits[self.tracker]
24
- puts "##{hit[:current_rank]}: #{hit[:song_name]} by #{hit[:song_artist]}."
25
- puts "--------------------------------"
21
+ Song.all[self.tracker].display
26
22
  self.tracker += 1
27
23
  end
28
24
  end
29
25
  end
30
26
 
31
- def display_artist(rank)
32
- artist = Top100::Artist.create_artist(rank)
33
- if artist == nil
34
- puts "Invalid input"
35
- else
36
- artist.display_details
37
- end
27
+ def display_artist(name)
28
+ artist = Artist.find_or_create(name)
29
+ artist.name == nil ? puts("Artist not found.") : artist.display_details
38
30
  puts "--------------------------------"
39
31
  end
40
32
 
41
33
  def present_options
42
- puts "Options: 1. type in 'exit' to exit. 2. type in 'next' for the next twenty songs. 3. type in the number of a song for an artist you would like to learn more about."
34
+ puts "Options: 1. type in 'exit' to exit. 2. type in 'next' for the next twenty songs. 3. type 'song' to choose a song to play. 4. type in the full artist title of a song to learn more about the main artist."
43
35
  choice = gets.chomp
44
- if choice == 'exit'
36
+ case choice
37
+ when 'exit'
45
38
  puts "Now exiting..."
46
- elsif choice == 'next'
39
+ when 'next'
47
40
  display_chart
48
41
  present_options
49
- elsif choice.match(/\d+/)
50
- display_artist(choice.match(/\d+/)[0])
42
+ when 'song'
43
+ puts "Enter the chart number of the song you would like to play."
44
+ rank = gets.chomp
45
+ Song.play(rank)
51
46
  present_options
52
47
  else
53
- puts "Unknown command. Try again."
48
+ begin
49
+ display_artist(choice)
50
+ # catches issues using OpenURI to access certain artist pages or issues with making frequent requests
51
+ rescue OpenURI::HTTPError => error
52
+ puts "Sorry, we're having trouble displaying this artist's details."
53
+ end
54
54
  present_options
55
55
  end
56
56
  end
57
57
 
58
-
59
58
  end
@@ -0,0 +1,33 @@
1
+ class Song
2
+ attr_accessor :rank, :name, :artist_name, :artist_bio_url, :url
3
+ @@songs = []
4
+
5
+ def initialize(song_hash)
6
+ song_hash.each {|key, value| self.send("#{key}=", value)}
7
+ @@songs << self
8
+ end
9
+
10
+ def self.all
11
+ @@songs
12
+ end
13
+
14
+ def display
15
+ puts "##{self.rank}: #{self.name} by #{self.artist_name}."
16
+ puts "--------------------------------"
17
+ end
18
+
19
+ def self.play(rank)
20
+ song = Song.all.find {|s| s.rank == rank }
21
+
22
+ if song.nil?
23
+ puts "You've entered an invalid chart name."
24
+ #check if song has a valid url, copyright issues with certain songs
25
+ elsif !!song.url
26
+ puts "Playing song..."
27
+ `open #{song.url}`
28
+ else
29
+ puts "Sorry, that artist does not have their song on Spotify."
30
+ end
31
+ end
32
+
33
+ end
@@ -1,3 +1,3 @@
1
1
  module Top100
2
- VERSION = "1.1.0"
2
+ VERSION = "2.0.0"
3
3
  end
data/lib/top_100.rb CHANGED
@@ -5,3 +5,4 @@ require_relative "./top_100/version.rb"
5
5
  require_relative "./top_100/billboard_scraper.rb"
6
6
  require_relative "./top_100/artist.rb"
7
7
  require_relative "./top_100/cli.rb"
8
+ require_relative "./top_100/song.rb"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: top_100
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - viparthasarathy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-03-26 00:00:00.000000000 Z
11
+ date: 2016-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -88,6 +88,7 @@ files:
88
88
  - lib/top_100/artist.rb
89
89
  - lib/top_100/billboard_scraper.rb
90
90
  - lib/top_100/cli.rb
91
+ - lib/top_100/song.rb
91
92
  - lib/top_100/version.rb
92
93
  - top_100.gemspec
93
94
  homepage: https://github.com/viparthasarathy/top-100