npr_cli_news_reader 0.2.0 → 0.2.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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +1 -0
- data/bin/npr_cli_news_reader +1 -0
- data/lib/npr_cli_news_reader.rb +6 -5
- data/lib/npr_cli_news_reader/article.rb +5 -15
- data/lib/npr_cli_news_reader/cli.rb +81 -51
- data/lib/npr_cli_news_reader/scraper.rb +23 -25
- data/lib/npr_cli_news_reader/version.rb +1 -1
- data/to_do_notes.md +21 -0
- metadata +3 -3
- data/lib/npr_cli_news_reader/run.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6bc48b3aa6d5410a0a6bd8ceab34c05615646322a0e7d3e63b2871d9ba44d9f
|
4
|
+
data.tar.gz: caa3b3ca9ae015d245156380ae3eb7c01086b08eedb2fae0808590db80e1299e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24e3a943d90ad23e31097b7764b73b20731db83bc987871ac4711788b65458d4d16b54dc177f73cbcbcd57321b7f8873a906dbcb9ced69e05e06b6fa23a9e1cf
|
7
|
+
data.tar.gz: 57fa73b4db9f2990b6ae13d2cd204e15af1b94799f0b52e602f7bde9c34a1790bfacf12f64225290a3aeb8145796795e16aad48d9f05156ef3b4b069e5132976
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
data/bin/npr_cli_news_reader
CHANGED
data/lib/npr_cli_news_reader.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
require_relative './npr_cli_news_reader/version'
|
2
|
-
require_relative './npr_cli_news_reader/article'
|
3
|
-
require_relative './npr_cli_news_reader/cli'
|
4
|
-
require_relative './npr_cli_news_reader/run'
|
5
|
-
require_relative'./npr_cli_news_reader/scraper'
|
6
1
|
require 'open-uri'
|
7
2
|
require 'nokogiri'
|
8
3
|
require 'rainbow'
|
4
|
+
require 'pry'
|
5
|
+
require_relative './npr_cli_news_reader/version'
|
6
|
+
require_relative './npr_cli_news_reader/article'
|
7
|
+
require_relative'./npr_cli_news_reader/scraper'
|
8
|
+
require_relative './npr_cli_news_reader/cli'
|
9
|
+
|
9
10
|
|
10
11
|
|
11
12
|
module NprCliNewsReader
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class NprCliNewsReader::Article
|
2
2
|
|
3
|
-
attr_accessor :category, :title, :
|
3
|
+
attr_accessor :category, :title, :teaser, :full_article, :article_url, :author, :date
|
4
4
|
|
5
5
|
@@all = []
|
6
6
|
|
@@ -13,22 +13,12 @@ class NprCliNewsReader::Article
|
|
13
13
|
@@all
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
self.
|
16
|
+
def add_full_article(full_article)
|
17
|
+
self.full_article = full_article
|
18
18
|
end
|
19
19
|
|
20
|
-
def self.
|
21
|
-
|
22
|
-
NprCliNewsReader::Scraper.get_articles("/sections/#{filter}")
|
23
|
-
else
|
24
|
-
self.sort_articles(filter)
|
25
|
-
end
|
20
|
+
def self.sort_articles_by_category(filter)
|
21
|
+
self.all.select {|article| article.category == filter.downcase}
|
26
22
|
end
|
27
23
|
|
28
|
-
def self.sort_articles(filter)
|
29
|
-
self.all.select {|article| article.category == filter}
|
30
|
-
end
|
31
|
-
|
32
|
-
|
33
|
-
|
34
24
|
end
|
@@ -1,25 +1,35 @@
|
|
1
1
|
class NprCliNewsReader::CLI
|
2
2
|
|
3
|
-
attr_accessor :
|
4
|
-
|
5
|
-
@sorted_articles = []
|
3
|
+
attr_accessor :selected_category
|
6
4
|
|
7
5
|
def initialize
|
8
6
|
@categories = ["National", "World", "Politics", "Business", "Health", "Science", "Technology", "Race & Culture"]
|
9
|
-
@done = false
|
10
7
|
end
|
11
8
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
def call
|
10
|
+
greet_user
|
11
|
+
present_categories
|
12
|
+
handle_category_input
|
13
|
+
handle_article_selection
|
14
|
+
end
|
15
|
+
|
16
|
+
def greet_user
|
17
|
+
puts Rainbow("Hello fellow fact finder...").bright
|
18
|
+
puts Rainbow("Welcome to the Npr Cli News Reader.").bright.fg(:green)
|
19
|
+
puts "--------------------"
|
20
|
+
sleep(1.5)
|
18
21
|
end
|
19
22
|
|
20
|
-
def
|
21
|
-
puts "
|
22
|
-
|
23
|
+
def present_categories
|
24
|
+
puts Rainbow("Categories").bright
|
25
|
+
puts "--------------------"
|
26
|
+
@categories.each_with_index do |category, i|
|
27
|
+
if i.even?
|
28
|
+
puts Rainbow("#{i + 1}). #{category}").bright
|
29
|
+
else
|
30
|
+
puts Rainbow("#{i + 1}). #{category}").bright.fg(:green)
|
31
|
+
end
|
32
|
+
end
|
23
33
|
end
|
24
34
|
|
25
35
|
def valid_input?(user_input, collection)
|
@@ -30,55 +40,75 @@ class NprCliNewsReader::CLI
|
|
30
40
|
end
|
31
41
|
end
|
32
42
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
@selected_category = @categories[categories_index].downcase
|
37
|
-
NprCliNewsReader::Article.find_or_create_articles(@selected_category)
|
38
|
-
@sorted_articles = NprCliNewsReader::Article.sort_articles(@selected_category)
|
39
|
-
display_articles
|
40
|
-
end
|
43
|
+
def format_teaser(teaser_string)
|
44
|
+
formatted_teaser = teaser_string.split(/\A.+[\u0095]\s/)[1]
|
45
|
+
formatted_teaser
|
41
46
|
end
|
42
47
|
|
43
|
-
def
|
44
|
-
puts
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
puts "
|
49
|
-
puts "
|
48
|
+
def handle_category_input
|
49
|
+
puts Rainbow("Which Category would you like to see articles for?").bright
|
50
|
+
puts "Use the numbers associated with the categories."
|
51
|
+
category_input = gets.strip
|
52
|
+
while !valid_input?(category_input, @categories)
|
53
|
+
puts "Sorry, the input received is not valid to select a category"
|
54
|
+
puts "Please enter a number 1-#{@categories.size}:"
|
55
|
+
category_input = gets.strip
|
50
56
|
end
|
57
|
+
@selected_category = @categories[category_input.to_i - 1].downcase
|
58
|
+
puts Rainbow("#{@selected_category.capitalize} Category").bright
|
59
|
+
puts "--------------------"
|
60
|
+
NprCliNewsReader::Scraper.scrape_articles_for_category(@selected_category)
|
61
|
+
display_category_articles
|
51
62
|
end
|
52
63
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
64
|
+
def display_category_articles
|
65
|
+
NprCliNewsReader::Article.sort_articles_by_category(@selected_category).each_with_index do |article, i|
|
66
|
+
formatted_teaser = format_teaser(article.teaser)
|
67
|
+
if i % 2 == 0
|
68
|
+
puts Rainbow("#{i + 1}").bright + ")." + Rainbow(" #{article.title}").bright
|
69
|
+
puts
|
70
|
+
puts Rainbow("#{formatted_teaser}")
|
71
|
+
puts
|
72
|
+
puts "--------------------"
|
73
|
+
puts
|
74
|
+
else
|
75
|
+
puts Rainbow("#{i + 1}). #{article.title}").bright.fg(:green)
|
76
|
+
puts
|
77
|
+
puts Rainbow("#{formatted_teaser}").fg(:green)
|
78
|
+
puts
|
79
|
+
puts "--------------------"
|
80
|
+
puts
|
81
|
+
end
|
62
82
|
end
|
63
83
|
end
|
64
84
|
|
65
|
-
def
|
66
|
-
|
67
|
-
puts Rainbow(article
|
68
|
-
|
69
|
-
|
85
|
+
def handle_article_selection
|
86
|
+
sorted_articles = NprCliNewsReader::Article.sort_articles_by_category(@selected_category)
|
87
|
+
puts Rainbow("Which article would you like to see the full article for?").bright
|
88
|
+
puts "Use the numbers associated with the articles."
|
89
|
+
article_input = gets.strip
|
90
|
+
while !valid_input?(article_input, sorted_articles)
|
91
|
+
puts "Sorry, the input received is not valid to select an article"
|
92
|
+
puts "Please enter a number 1-#{sorted_articles.size}:"
|
93
|
+
article_input = gets.strip
|
94
|
+
end
|
95
|
+
article = sorted_articles[article_input.to_i - 1]
|
96
|
+
NprCliNewsReader::Scraper.scrape_full_article(article)
|
97
|
+
display_full_article(article)
|
70
98
|
end
|
71
99
|
|
72
|
-
def
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
puts "
|
78
|
-
|
79
|
-
|
100
|
+
def display_full_article(article)
|
101
|
+
puts Rainbow("#{article.title}").bright
|
102
|
+
puts "--------------------"
|
103
|
+
article.full_article.each do |paragraph_node|
|
104
|
+
puts "\t#{paragraph_node.text}"
|
105
|
+
puts "--------------------"
|
106
|
+
end
|
107
|
+
puts Rainbow("Would you like to see the article on your default web browse? (y/n):").bright
|
108
|
+
user_input = gets.strip
|
109
|
+
if ["yes, y"].include?(user_input.downcase)
|
110
|
+
system("open #{article.article_url}")
|
80
111
|
end
|
81
112
|
end
|
82
113
|
|
83
|
-
|
84
114
|
end
|
@@ -1,35 +1,33 @@
|
|
1
1
|
class NprCliNewsReader::Scraper
|
2
2
|
|
3
|
-
|
4
|
-
def self.get_articles(category_url)
|
5
|
-
html = open("https://www.npr.org#{category_url}")
|
6
|
-
doc = Nokogiri::HTML(html)
|
7
|
-
category = category_url.split("/")[2]
|
8
|
-
articles = doc.css("article.item")
|
9
|
-
self.get_and_set_article_attributes(articles, category)
|
10
|
-
end
|
3
|
+
@@base_url = "https://www.npr.org"
|
11
4
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
5
|
+
def self.scrape_articles_for_category(selected_category)
|
6
|
+
if NprCliNewsReader::Article.all.detect {|article| article.category == selected_category}
|
7
|
+
return
|
8
|
+
else
|
9
|
+
html = open("#{@@base_url}/sections/#{selected_category}")
|
10
|
+
doc = Nokogiri::HTML(html)
|
11
|
+
articles = doc.css('article.item')
|
12
|
+
articles.each do |article|
|
13
|
+
article_attributes = {
|
14
|
+
category: selected_category.downcase,
|
15
|
+
title: article.css('h2.title a').text.strip,
|
16
|
+
teaser: article.css('p.teaser a').text.strip,
|
17
|
+
article_url: article.css('h2.title a').attr('href').to_s.strip
|
18
|
+
}
|
19
|
+
NprCliNewsReader::Article.new(article_attributes)
|
20
|
+
end
|
23
21
|
end
|
22
|
+
|
24
23
|
end
|
25
24
|
|
26
|
-
def self.
|
27
|
-
html = open(article_url)
|
25
|
+
def self.scrape_full_article(article)
|
26
|
+
html = open (article.article_url)
|
28
27
|
doc = Nokogiri::HTML(html)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
text_array
|
28
|
+
# discard the first p tag
|
29
|
+
paragraphs = doc.css('#storytext > p')
|
30
|
+
article.full_article = paragraphs
|
33
31
|
end
|
34
32
|
|
35
33
|
end
|
data/to_do_notes.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
TO DO NOTES
|
2
|
+
|
3
|
+
- Once the article is read, give the user options
|
4
|
+
- exit the program
|
5
|
+
- go back to article selection
|
6
|
+
- go back to category selection
|
7
|
+
|
8
|
+
- Another feature could be to add a clickable link at the bottom of
|
9
|
+
the article that states if clicked it will take them to the article
|
10
|
+
on the NPR website.
|
11
|
+
|
12
|
+
- Complete documentation for github
|
13
|
+
- description
|
14
|
+
- collaboration guidelines
|
15
|
+
|
16
|
+
- Complete documentation and setup as Ruby gem on rubygems.org
|
17
|
+
- possibly use a tool for documentation
|
18
|
+
- description
|
19
|
+
- usage
|
20
|
+
- installation process
|
21
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: npr_cli_news_reader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "'Jake Garcia'"
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-03-
|
11
|
+
date: 2020-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -104,10 +104,10 @@ files:
|
|
104
104
|
- lib/npr_cli_news_reader.rb
|
105
105
|
- lib/npr_cli_news_reader/article.rb
|
106
106
|
- lib/npr_cli_news_reader/cli.rb
|
107
|
-
- lib/npr_cli_news_reader/run.rb
|
108
107
|
- lib/npr_cli_news_reader/scraper.rb
|
109
108
|
- lib/npr_cli_news_reader/version.rb
|
110
109
|
- npr_cli_news_reader.gemspec
|
110
|
+
- to_do_notes.md
|
111
111
|
homepage: https://github.com/jgarcia4444/npr_cli_news_reader.git
|
112
112
|
licenses:
|
113
113
|
- MIT
|
@@ -1,21 +0,0 @@
|
|
1
|
-
class NprCliNewsReader::Run
|
2
|
-
def self.start
|
3
|
-
cli = NprCliNewsReader::CLI.new
|
4
|
-
while !cli.done
|
5
|
-
cli.greeting
|
6
|
-
cli.display_article_categories
|
7
|
-
puts "Which category would you like to see news articles for?"
|
8
|
-
puts "(Enter the # associated with the category)"
|
9
|
-
category_input = gets.strip
|
10
|
-
cli.handle_category_input(category_input)
|
11
|
-
puts "Which article would you like to read?"
|
12
|
-
puts "(Enter the number associated with the article):"
|
13
|
-
selected_article = gets.strip
|
14
|
-
cli.handle_article_input(selected_article)
|
15
|
-
puts "Would you like to go back to the category selection or exit the program?"
|
16
|
-
puts "(enter home or exit)"
|
17
|
-
end_of_program_input = gets.strip.downcase
|
18
|
-
cli.restart_or_exit(end_of_program_input)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|