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 +4 -4
- data/README.md +2 -2
- data/bin/top_100 +1 -1
- data/exe/top_100 +1 -1
- data/lib/top_100/artist.rb +21 -18
- data/lib/top_100/billboard_scraper.rb +23 -20
- data/lib/top_100/cli.rb +21 -22
- data/lib/top_100/song.rb +33 -0
- data/lib/top_100/version.rb +1 -1
- data/lib/top_100.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6a3918efad8b3cacb60d1516ebbc5d4d487d074
|
4
|
+
data.tar.gz: 0483d33e3c8a6c5ff042e560ddda3d9028c3101d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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/
|
33
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/viparthasarathy/top_100.
|
data/bin/top_100
CHANGED
data/exe/top_100
CHANGED
data/lib/top_100/artist.rb
CHANGED
@@ -1,32 +1,35 @@
|
|
1
|
-
class
|
1
|
+
class Artist
|
2
2
|
attr_accessor :songs, :name, :location, :date, :bio
|
3
|
-
|
3
|
+
@@artists = []
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
@songs =
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
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.
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
1
|
+
class BillboardScraper
|
2
2
|
|
3
|
-
def scrape_from_chart_page
|
4
|
-
|
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
25
|
-
|
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
|
2
|
-
attr_accessor :tracker
|
1
|
+
class CLI
|
2
|
+
attr_accessor :tracker
|
3
3
|
|
4
4
|
|
5
5
|
def initialize
|
6
6
|
@tracker = 0
|
7
|
-
|
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
|
-
|
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(
|
32
|
-
artist =
|
33
|
-
|
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
|
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
|
-
|
36
|
+
case choice
|
37
|
+
when 'exit'
|
45
38
|
puts "Now exiting..."
|
46
|
-
|
39
|
+
when 'next'
|
47
40
|
display_chart
|
48
41
|
present_options
|
49
|
-
|
50
|
-
|
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
|
-
|
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
|
data/lib/top_100/song.rb
ADDED
@@ -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
|
data/lib/top_100/version.rb
CHANGED
data/lib/top_100.rb
CHANGED
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:
|
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-
|
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
|