qticker 1.0.5
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 +7 -0
- data/bin/qticker +7 -0
- data/config/environment.rb +15 -0
- data/lib/cli.rb +51 -0
- data/lib/desc.rb +8 -0
- data/lib/dev_cli.rb +58 -0
- data/lib/fixtures/FBIOX.html +1120 -0
- data/lib/fixtures/IBM.html +1269 -0
- data/lib/fixtures/MSFT.html +1268 -0
- data/lib/fixtures/QQQ.html +1059 -0
- data/lib/main_cli.rb +39 -0
- data/lib/qticker.rb +1 -0
- data/lib/quote.rb +13 -0
- data/lib/scraper.rb +82 -0
- data/lib/stock.rb +17 -0
- data/lib/stock_attr.rb +10 -0
- data/lib/table.rb +22 -0
- metadata +171 -0
data/lib/main_cli.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
class MainCli < Cli
|
2
|
+
|
3
|
+
attr_accessor :scraper, :dev
|
4
|
+
|
5
|
+
def initialize(cli = nil)
|
6
|
+
super(cli)
|
7
|
+
self.dev = DevCli.new(self)
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def ticker_symbol_prompt
|
12
|
+
valid = false
|
13
|
+
while !valid do
|
14
|
+
print "\nPlease enter a ticker symbol: "
|
15
|
+
symbol = gets.strip.upcase
|
16
|
+
if symbol == "DEV"
|
17
|
+
self.welcome("Developer Mode", -> {self.dev.option_menu}) if symbol == "DEV"
|
18
|
+
else
|
19
|
+
valid = self.symbol_validation(symbol, valid)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def stock_option_menu(opt_1_string, opt_1_lambda)
|
25
|
+
input = super(opt_1_string, opt_1_lambda)
|
26
|
+
if input == "1"
|
27
|
+
opt_1_lambda.()
|
28
|
+
elsif input == "2"
|
29
|
+
self.ticker_symbol_prompt
|
30
|
+
else
|
31
|
+
return nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def symbol_validation(symbol, valid, fixture_url = nil)
|
36
|
+
super(symbol, valid)[0] # returns whether entered symbol was valid
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/lib/qticker.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative '../config/environment.rb'
|
data/lib/quote.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
class Quote < StockAttr
|
2
|
+
|
3
|
+
def display
|
4
|
+
puts "Current: #{price} #{change}(#{change_pct})"
|
5
|
+
puts "Open: #{open}"
|
6
|
+
puts "Volume: #{volume}"
|
7
|
+
puts "Avg Vol: #{volume_avg}"
|
8
|
+
puts "Mkt Cap: #{mkt_cap}"
|
9
|
+
puts "P/E(ttm): #{pe_ttm}"
|
10
|
+
puts "Yield: #{div_yld}%"
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
data/lib/scraper.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
class Scraper
|
2
|
+
|
3
|
+
attr_accessor :cli, :gfs_noko_html, :stock
|
4
|
+
|
5
|
+
def initialize(cli)
|
6
|
+
self.cli = cli
|
7
|
+
end
|
8
|
+
|
9
|
+
def gfs_url(symbol)
|
10
|
+
"https://www.google.com/finance?q=" + symbol
|
11
|
+
end
|
12
|
+
|
13
|
+
def load_gfs_noko_html(url)
|
14
|
+
self.gfs_noko_html = Nokogiri::HTML(open(url))
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns an array. Array[0] is a stock if one was succesfully created and nil otherwise.
|
18
|
+
# Array[1] indicates whether the symbol cooresponds to a mutual fund.
|
19
|
+
def load_gfs(symbol, fixture_url = nil)
|
20
|
+
fixture_url.nil? ? load_gfs_noko_html(self.gfs_url(symbol)) : load_gfs_noko_html(fixture_url)
|
21
|
+
return [nil, true] unless self.gfs_noko_html.text.match('\(MUTF:').nil?
|
22
|
+
return [nil, false] if self.gfs_noko_html.css("span.pr").text.strip == "" # checks whether the page lists a price
|
23
|
+
# return [nil, false] if self.gfs_noko_html.css("div.fjfe-content").text.include?("- produced no matches.")
|
24
|
+
[self.create_stock(symbol), false]
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_stock(symbol)
|
28
|
+
data = scrape_stock(symbol)
|
29
|
+
Stock.new(data)
|
30
|
+
end
|
31
|
+
|
32
|
+
def scrape_stock(symbol)
|
33
|
+
data = { stock: {} }
|
34
|
+
data[:stock][:symbol] = symbol
|
35
|
+
begin
|
36
|
+
data[:stock][:name] = self.gfs_noko_html.css("div.g-first a").text.match('(?<=All news for )[\w,.)() ]*(?= »)')[0]
|
37
|
+
rescue NoMethodError
|
38
|
+
data[:stock][:name] = ""
|
39
|
+
end
|
40
|
+
data[:stock][:exchange] = self.gfs_noko_html.css("span.dis-large").text.split("\n")[0]
|
41
|
+
data[:stock] = self.nil_to_empty_str(data[:stock])
|
42
|
+
data[:quote] = self.scrape_quote
|
43
|
+
data[:desc] = self.scrape_desc
|
44
|
+
data
|
45
|
+
end
|
46
|
+
|
47
|
+
def scrape_quote
|
48
|
+
data = {}
|
49
|
+
data[:price] = self.gfs_noko_html.css("span.pr").text.strip
|
50
|
+
data[:change] = self.gfs_noko_html.css("div.nwp span.bld").text.split("\n")[0]
|
51
|
+
begin
|
52
|
+
data[:change_pct] = self.gfs_noko_html.css("div.nwp span.bld").text.split("\n")[1].gsub(/[)(]/, '')
|
53
|
+
rescue NoMethodError
|
54
|
+
data[:change_pct] = ""
|
55
|
+
end
|
56
|
+
data[:range] = self.gfs_noko_html.css("td[data-snapfield='range']+td").text.strip
|
57
|
+
data[:range_yr] = self.gfs_noko_html.css("td[data-snapfield='range_52week']+td").text.strip
|
58
|
+
data[:open] = self.gfs_noko_html.css("td[data-snapfield='open']+td").text.strip
|
59
|
+
data[:volume] = self.gfs_noko_html.css("td[data-snapfield='vol_and_avg']+td").text.strip.split("/")[0]
|
60
|
+
data[:volume_avg] = self.gfs_noko_html.css("td[data-snapfield='vol_and_avg']+td").text.strip.split("/")[1]
|
61
|
+
data[:mkt_cap] = self.gfs_noko_html.css("td[data-snapfield='market_cap']+td").text.strip
|
62
|
+
data[:pe_ttm] = self.gfs_noko_html.css("td[data-snapfield='pe_ratio']+td").text.strip
|
63
|
+
data[:div_yld] = self.gfs_noko_html.css("td[data-snapfield='latest_dividend-dividend_yield']+td").text.strip.split("/")[1]
|
64
|
+
nil_to_empty_str(data)
|
65
|
+
end
|
66
|
+
|
67
|
+
def scrape_desc
|
68
|
+
data = {}
|
69
|
+
data[:sector] = self.gfs_noko_html.css("a#sector").text
|
70
|
+
data[:industry] = self.gfs_noko_html.css("a#sector+a").text
|
71
|
+
data[:summary] = self.gfs_noko_html.css("div.companySummary").text.gsub("More from Reuters »", "").strip
|
72
|
+
nil_to_empty_str(data)
|
73
|
+
end
|
74
|
+
|
75
|
+
# convert any nil values to empty strings to avoid exceptions
|
76
|
+
def nil_to_empty_str(data_hash)
|
77
|
+
data_hash.each do |key, value|
|
78
|
+
data_hash[key] = "" if data_hash[key].nil?
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
data/lib/stock.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class Stock < Table
|
2
|
+
|
3
|
+
attr_accessor :quote, :desc
|
4
|
+
|
5
|
+
def initialize(data)
|
6
|
+
|
7
|
+
super(data[:stock])
|
8
|
+
self.quote = Quote.new(data[:quote], self)
|
9
|
+
self.desc = Desc.new(data[:desc], self)
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
def display
|
14
|
+
print "\n#{name} (#{exchange}:#{symbol})\n\n"
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
data/lib/stock_attr.rb
ADDED
data/lib/table.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
class Table
|
2
|
+
|
3
|
+
def initialize(data_hash)
|
4
|
+
|
5
|
+
self.class.create_table_columns(data_hash)
|
6
|
+
self.populate_table_columns(data_hash)
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
def populate_table_columns(data_hash)
|
11
|
+
data_hash.each do |key, value|
|
12
|
+
self.send("#{key}=", value)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.create_table_columns(data_hash)
|
17
|
+
data_hash.each do |key, value|
|
18
|
+
attr_accessor key.to_sym
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: qticker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Samuel Lair
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: nokogiri
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.6.8
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.6'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.6.8
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: word_wrap
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: require_all
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.3'
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 1.3.3
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '1.3'
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 1.3.3
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: bundler
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '1.13'
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 1.13.1
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '1.13'
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 1.13.1
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: pry
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - "~>"
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0.10'
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.10.4
|
97
|
+
type: :development
|
98
|
+
prerelease: false
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.10'
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 0.10.4
|
107
|
+
- !ruby/object:Gem::Dependency
|
108
|
+
name: rspec
|
109
|
+
requirement: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - "~>"
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '3.5'
|
114
|
+
type: :development
|
115
|
+
prerelease: false
|
116
|
+
version_requirements: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - "~>"
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '3.5'
|
121
|
+
description: This gem allows the user to enter a ticker symbol and retrieve a quote
|
122
|
+
and company description.
|
123
|
+
email: lair002@gmail.com
|
124
|
+
executables:
|
125
|
+
- qticker
|
126
|
+
extensions: []
|
127
|
+
extra_rdoc_files: []
|
128
|
+
files:
|
129
|
+
- bin/qticker
|
130
|
+
- config/environment.rb
|
131
|
+
- lib/cli.rb
|
132
|
+
- lib/desc.rb
|
133
|
+
- lib/dev_cli.rb
|
134
|
+
- lib/fixtures/FBIOX.html
|
135
|
+
- lib/fixtures/IBM.html
|
136
|
+
- lib/fixtures/MSFT.html
|
137
|
+
- lib/fixtures/QQQ.html
|
138
|
+
- lib/main_cli.rb
|
139
|
+
- lib/qticker.rb
|
140
|
+
- lib/quote.rb
|
141
|
+
- lib/scraper.rb
|
142
|
+
- lib/stock.rb
|
143
|
+
- lib/stock_attr.rb
|
144
|
+
- lib/table.rb
|
145
|
+
homepage: https://github.com/lair001/stocks-cli-gem
|
146
|
+
licenses:
|
147
|
+
- MIT
|
148
|
+
metadata: {}
|
149
|
+
post_install_message:
|
150
|
+
rdoc_options: []
|
151
|
+
require_paths:
|
152
|
+
- config
|
153
|
+
- lib
|
154
|
+
- lib/fixtures
|
155
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 2.3.0
|
160
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - ">="
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
requirements: []
|
166
|
+
rubyforge_project:
|
167
|
+
rubygems_version: 2.5.1
|
168
|
+
signing_key:
|
169
|
+
specification_version: 4
|
170
|
+
summary: 'Quick Ticker: Enter a ticker symbol and get information.'
|
171
|
+
test_files: []
|