coinpare 0.0.0 → 0.1.0

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.
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pastel'
4
+ require 'tty-pager'
5
+ require 'tty-spinner'
6
+ require 'tty-table'
7
+ require 'timers'
8
+
9
+ require_relative '../command'
10
+ require_relative '../fetcher'
11
+
12
+ module Coinpare
13
+ module Commands
14
+ class Markets < Coinpare::Command
15
+ def initialize(name, options)
16
+ @name = name
17
+ @options = options
18
+ @pastel = Pastel.new
19
+ @timers = Timers::Group.new
20
+ @spinner = TTY::Spinner.new(':spinner Fetching data...',
21
+ format: :dots, clear: true)
22
+ end
23
+
24
+ def execute(input: $stdin, output: $stdout)
25
+ pager = TTY::Pager::BasicPager.new(output: output)
26
+ @spinner.auto_spin
27
+
28
+ if @options['watch']
29
+ output.print cursor.hide
30
+ interval = @options['watch'].to_f > 0 ? @options['watch'].to_f : DEFAULT_INTERVAL
31
+ @timers.now_and_every(interval) { display_markets(output, pager) }
32
+ loop { @timers.wait }
33
+ else
34
+ display_markets(output, pager)
35
+ end
36
+ ensure
37
+ @spinner.stop
38
+ if @options['watch']
39
+ @timers.cancel
40
+ output.print cursor.clear_screen_down
41
+ output.print cursor.show
42
+ end
43
+ end
44
+
45
+ def display_markets(output, pager)
46
+ to_symbol = fetch_symbol
47
+ response = Fetcher.fetch_top_exchanges_by_pair(
48
+ @name.upcase, @options['base'].upcase, @options)
49
+ return unless response
50
+ table = setup_table(response["Data"]["Exchanges"], to_symbol)
51
+
52
+ lines = banner.lines.size + 1 + table.rows_size + 3
53
+ @spinner.stop
54
+ clear_output(output, lines) { print_results(table, output, pager) }
55
+ end
56
+
57
+ def clear_output(output, lines)
58
+ output.print cursor.clear_screen_down if @options['watch']
59
+ yield if block_given?
60
+ output.print cursor.up(lines) if @options['watch']
61
+ end
62
+
63
+ def print_results(table, output, pager)
64
+ output.puts banner
65
+ pager.page(table.render(:unicode, padding: [0, 1], alignment: :right))
66
+ output.puts
67
+ end
68
+
69
+ def fetch_symbol
70
+ prices = Fetcher.fetch_prices(
71
+ @name.upcase, @options['base'].upcase, @options)
72
+ return unless prices
73
+ prices['DISPLAY'][@name.upcase][@options['base'].upcase]['TOSYMBOL']
74
+ end
75
+
76
+ def banner
77
+ "\n#{add_color('Coin', :yellow)} #{@name.upcase} " \
78
+ "#{add_color('Base Currency', :yellow)} #{@options['base'].upcase} " \
79
+ "#{add_color('Time', :yellow)} #{timestamp}\n\n"
80
+ end
81
+
82
+ def setup_table(data, to_symbol)
83
+ table = TTY::Table.new(header: [
84
+ { value: 'Market', alignment: :left },
85
+ 'Price',
86
+ 'Chg. 24H',
87
+ 'Chg.% 24H',
88
+ 'Open 24H',
89
+ 'High 24H',
90
+ 'Low 24H',
91
+ 'Direct Vol. 24H',
92
+ ])
93
+
94
+ data.each do |market|
95
+ change24h = market['CHANGE24HOUR']
96
+ market_details = [
97
+ { value: add_color(market['MARKET'], :yellow), alignment: :left },
98
+ add_color("#{to_symbol} #{number_to_currency(round_to(market['PRICE']))}", pick_color(change24h)),
99
+ add_color("#{pick_arrow(change24h)} #{to_symbol} #{number_to_currency(round_to(change24h))}", pick_color(change24h)),
100
+ add_color("#{pick_arrow(change24h)} #{round_to(market['CHANGEPCT24HOUR'] * 100)}%", pick_color(change24h)),
101
+ "#{to_symbol} #{number_to_currency(round_to(market['OPEN24HOUR']))}",
102
+ "#{to_symbol} #{number_to_currency(round_to(market['HIGH24HOUR']))}",
103
+ "#{to_symbol} #{number_to_currency(round_to(market['LOW24HOUR']))}",
104
+ "#{to_symbol} #{number_to_currency(round_to(market['VOLUME24HOURTO']))}"
105
+ ]
106
+ table << market_details
107
+ end
108
+
109
+ table
110
+ end
111
+ end # Markets
112
+ end # Commands
113
+ end # Coinpare
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'json'
5
+
6
+ module Coinpare
7
+ # Handle all data fetching from remote api
8
+ module Fetcher
9
+ API_URL = "https://min-api.cryptocompare.com/data/"
10
+
11
+ def handle_response(response)
12
+ status = response["Response"]
13
+ if status == "Error"
14
+ puts response["Message"]
15
+ exit
16
+ end
17
+ response
18
+ end
19
+ module_function :handle_response
20
+
21
+ def fetch_json(url)
22
+ uri = URI.parse(url)
23
+ http = Net::HTTP.new(uri.host, uri.port)
24
+ http.read_timeout = 5
25
+ http.use_ssl = uri.scheme == 'https'
26
+ response = http.start { |req| req.get(uri.request_uri) }
27
+ case response
28
+ when Net::HTTPSuccess
29
+ handle_response(JSON.parse(response.body))
30
+ else
31
+ response.value
32
+ end
33
+ rescue Net::ReadTimeout
34
+ end
35
+ module_function :fetch_json
36
+
37
+ def fetch_daily_hist(from_symbol, to_symbol, options)
38
+ url = ["#{API_URL}histoday"]
39
+ url << "?fsym=BTC&tsym=USD&limit=7&aggregate=7"
40
+
41
+ fetch_json(url.join)
42
+ end
43
+
44
+ def fetch_top_coins_by_volume(to_symbol, options)
45
+ url = ["#{API_URL}top/totalvol"]
46
+ url << "?tsym=#{to_symbol}"
47
+ url << "&limit=#{options['top']}&page=0" if options['top']
48
+
49
+ fetch_json(url.join)
50
+ end
51
+ module_function :fetch_top_coins_by_volume
52
+
53
+ def fetch_prices(from_symbols, to_symbols, options)
54
+ url = ["#{API_URL}pricemultifull"]
55
+ url << "?fsyms=#{from_symbols}&tsyms=#{to_symbols}"
56
+ url << "&e=#{options['exchange']}" if options['exchange']
57
+ url << "&tryConversion=true"
58
+
59
+ fetch_json(url.join)
60
+ end
61
+ module_function :fetch_prices
62
+
63
+ def fetch_top_exchanges_by_pair(from_symbol, to_symbol, options)
64
+ url = ["#{API_URL}top/exchanges/full"]
65
+ url << "?fsym=#{from_symbol}&tsym=#{to_symbol}"
66
+ url << "&limit=#{options['top']}&page=0" if options['top']
67
+
68
+ fetch_json(url.join)
69
+ end
70
+ module_function :fetch_top_exchanges_by_pair
71
+ end
72
+ end
@@ -1,3 +1,3 @@
1
1
  module Coinpare
2
- VERSION = "0.0.0"
2
+ VERSION = "0.1.0"
3
3
  end
metadata CHANGED
@@ -1,15 +1,197 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coinpare
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-03 00:00:00.000000000 Z
11
+ date: 2018-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tty-color
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.4.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.4.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: tty-config
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: tty-cursor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.5.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.5.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: tty-editor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.4.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.4.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: tty-font
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.2.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.2.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: tty-pager
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.11.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.11.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: tty-prompt
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.16.1
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.16.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: tty-spinner
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.8.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.8.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: tty-table
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 0.10.0
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 0.10.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: pastel
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.7.2
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.7.2
153
+ - !ruby/object:Gem::Dependency
154
+ name: thor
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 0.20.0
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 0.20.0
167
+ - !ruby/object:Gem::Dependency
168
+ name: toml
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: 0.2.0
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: 0.2.0
181
+ - !ruby/object:Gem::Dependency
182
+ name: timers
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: 4.1.2
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: 4.1.2
13
195
  - !ruby/object:Gem::Dependency
14
196
  name: bundler
15
197
  requirement: !ruby/object:Gem::Requirement
@@ -52,15 +234,46 @@ dependencies:
52
234
  - - "~>"
53
235
  - !ruby/object:Gem::Version
54
236
  version: '3.0'
55
- description: Write a longer description or delete this line.
56
- email: []
57
- executables: []
237
+ - !ruby/object:Gem::Dependency
238
+ name: webmock
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - "~>"
242
+ - !ruby/object:Gem::Version
243
+ version: '3.3'
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - "~>"
249
+ - !ruby/object:Gem::Version
250
+ version: '3.3'
251
+ - !ruby/object:Gem::Dependency
252
+ name: timecop
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - "~>"
256
+ - !ruby/object:Gem::Version
257
+ version: 0.9.1
258
+ type: :development
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - "~>"
263
+ - !ruby/object:Gem::Version
264
+ version: 0.9.1
265
+ description: Compare cryptocurrency trading data across multiple exchanges and blockchains.
266
+ email:
267
+ - ''
268
+ executables:
269
+ - coinpare
58
270
  extensions: []
59
271
  extra_rdoc_files: []
60
272
  files:
61
273
  - ".gitignore"
62
274
  - ".rspec"
63
275
  - ".travis.yml"
276
+ - CHANGELOG.md
64
277
  - CODE_OF_CONDUCT.md
65
278
  - Gemfile
66
279
  - LICENSE.txt
@@ -69,11 +282,19 @@ files:
69
282
  - bin/console
70
283
  - bin/setup
71
284
  - coinpare.gemspec
285
+ - exe/coinpare
72
286
  - lib/coinpare.rb
287
+ - lib/coinpare/cli.rb
288
+ - lib/coinpare/command.rb
289
+ - lib/coinpare/commands/.gitkeep
290
+ - lib/coinpare/commands/coins.rb
291
+ - lib/coinpare/commands/holdings.rb
292
+ - lib/coinpare/commands/markets.rb
293
+ - lib/coinpare/fetcher.rb
73
294
  - lib/coinpare/version.rb
74
- homepage:
295
+ homepage: https://github.com/piotrmurach/coinpare
75
296
  licenses:
76
- - MIT
297
+ - AGPL-3.0
77
298
  metadata: {}
78
299
  post_install_message:
79
300
  rdoc_options: []
@@ -91,8 +312,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
312
  version: '0'
92
313
  requirements: []
93
314
  rubyforge_project:
94
- rubygems_version: 2.5.1
315
+ rubygems_version: 2.7.3
95
316
  signing_key:
96
317
  specification_version: 4
97
- summary: Write a short summary, because RubyGems requires one.
318
+ summary: Compare cryptocurrency trading data across multiple exchanges and blockchains.
98
319
  test_files: []