qticker 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,10 @@
1
+ class StockAttr < Table
2
+
3
+ attr_accessor :stock
4
+
5
+ def initialize(data_hash, stock)
6
+ super(data_hash)
7
+ self.stock = stock
8
+ end
9
+
10
+ end
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: []