cointools 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e2f4474de548a07499b33a25f0f60645b990ec1e
4
- data.tar.gz: c73eef132777ced15047f894fa38ad886758ed6f
3
+ metadata.gz: ae9c00c6df51d228fb5d401f849d963ff2c05dfb
4
+ data.tar.gz: cd3ed48eb9317db5d26085f8fc0059f9788a9759
5
5
  SHA512:
6
- metadata.gz: ac701c46dd60b43b2311fbf572a444ec4bbf9131681e7a0edeb53a5f8ad441329ccbe214f809ec05e16813fb030f75c610e3331500e5e344691a9030cbdfd767
7
- data.tar.gz: eec97b9cce9ae49995723a00cf1da3bfe65d0296e8015ac3df2703152687d38780e1a186544b813a996048313d6302306f3886cfa662b9fdeddc8e3c63e23bb6
6
+ metadata.gz: dcb355f0ce41f2d570425c974e91fc20510073d214c574ace8009b37a0d4fe2fc07f4fa6360e5081cfa9a96a56e76eac1ee9778e08bc24e6354bc5a31e716d38
7
+ data.tar.gz: 2ea61e0a5f07649ea6592b0a003058de5d4c2bedbf2f8d7d37f3aba4bc7ba040479f9747a18e52bc9f36c40c087b951c490b29d3d90af838bd97616416c58499
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ #### Version 0.2.0 (29.01.2018)
2
+
3
+ * added CoinMarketCap class & coinmcap binary
4
+
5
+ #### Version 0.1.2 (24.01.2018)
6
+
7
+ * fixed --help command
8
+
9
+ #### Version 0.1.1 (24.01.2018)
10
+
11
+ * first working release
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Cointools
2
2
 
3
- This is a collection of Ruby scripts and library classes that let you check cryptocurrency prices on various services (currently Cryptowatch).
3
+ This is a collection of Ruby scripts and library classes that let you check cryptocurrency prices on various services.
4
4
 
5
5
  ## Installation
6
6
 
@@ -16,9 +16,7 @@ To use the code as a library, add it to your Gemfile:
16
16
  gem 'cointools'
17
17
  ```
18
18
 
19
- ## Usage
20
-
21
- ### [Cryptowatch](https://cryptowat.ch)
19
+ ## [Cryptowatch](https://cryptowat.ch)
22
20
 
23
21
  To check past price of a given coin on a chosen exchange, pass the exchange and market name and a properly formatted timestamp:
24
22
 
@@ -42,7 +40,7 @@ cryptowatch --list-markets bithumb
42
40
  In code:
43
41
 
44
42
  ```ruby
45
- require 'cointools'
43
+ require 'cointools' # or 'cointools/cryptowatch'
46
44
  cryptowatch = CoinTools::Cryptowatch.new
47
45
 
48
46
  exchange = cryptowatch.exchanges.first
@@ -60,6 +58,55 @@ puts "#{market} today: #{result.price}"
60
58
  The result object contains the requested price and (for historical prices) the actual timestamp of the found price, which might slightly differ from the timestamp passed in the argument (the earlier the date, the less precise the result).
61
59
 
62
60
 
61
+ ## [CoinMarketCap](https://coinmarketcap.com)
62
+
63
+ CoinMarketCap's API only returns current coin prices. To look up a coin's price, you need to pass its name as used on CoinMarketCap:
64
+
65
+ ```
66
+ coinmcap power-ledger
67
+ ```
68
+
69
+ Alternatively, you can pass the cryptocurrency's symbol using the `-s` or `--symbol` parameter:
70
+
71
+ ```
72
+ coinmcap -s powr
73
+ ```
74
+
75
+ However, this operation needs to download a complete ticker for all currencies and scan through the list, so it's recommended to use the name as in the example above.
76
+
77
+ You can also use the `-b` or `--btc-price` flag to request a price in BTC instead of USD:
78
+
79
+ ```
80
+ coinmcap power-ledger -b
81
+ ```
82
+
83
+ Or you can request the price in one of the ~30 other supported fiat currencies with `-f` or `--fiat-currency`:
84
+
85
+ ```
86
+ coinmcap request-network -fEUR
87
+ ```
88
+
89
+ You can print a list of supported fiat currencies with `coinmcap --list-fiat-currencies`.
90
+
91
+ Same things in code:
92
+
93
+ ```ruby
94
+ require 'cointools' # or 'cointools/coinmarketcap'
95
+ cmc = CoinTools::CoinMarketCap.new
96
+
97
+ p CoinTools::CoinMarketCap::FIAT_CURRENCIES
98
+
99
+ ltc = cryptowatch.get_price('litecoin')
100
+ puts "LTC: #{ltc.usd_price} USD / #{ltc.btc_price} BTC"
101
+
102
+ xmr = cryptowatch.get_price_by_symbol('xmr')
103
+ puts "XMR: #{xmr.usd_price} USD / #{xmr.btc_price} BTC"
104
+
105
+ eth = cryptowatch.get_price('ethereum', convert_to: 'EUR')
106
+ puts "ETH: #{eth.converted_price} EUR"
107
+ ```
108
+
109
+
63
110
  ## Credits & contributing
64
111
 
65
112
  Copyright © 2018 [Kuba Suder](https://mackuba.eu). Licensed under [Very Simple Public License](https://github.com/mackuba/cointools/blob/master/VSPL-LICENSE.txt), my custom license that's basically a simplified version of the MIT license that fits in 3 lines.
data/bin/coinmcap ADDED
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'cointools'
5
+
6
+ require 'optparse'
7
+ require 'time'
8
+
9
+ def print_help
10
+ puts "Usage: #{$PROGRAM_NAME} <coin_name> [-b/--btc-price] [-fXXX/--fiat-currency XXX] [-v/--verbose]"
11
+ puts " e.g.: #{$PROGRAM_NAME} litecoin"
12
+ puts
13
+ puts "* To look up the currency by symbol instead of name (slower, downloads more data):"
14
+ puts " #{$PROGRAM_NAME} -s/--symbol <symbol> [-b/--btc-price] [-fXXX/--fiat-currency XXX] [-v/--verbose]"
15
+ puts " e.g.: #{$PROGRAM_NAME} -s LTC"
16
+ puts
17
+ puts "* To list supported fiat currencies:"
18
+ puts " #{$PROGRAM_NAME} --list-fiat-currences"
19
+ puts
20
+ puts "* -b / --btc-price: returns the coin's price in BTC instead of USD"
21
+ puts "* -fEUR / --fiat-currency EUR: returns the price in a given fiat currency instead of USD"
22
+ end
23
+
24
+ verbose = false
25
+ btc_price = false
26
+ fiat_currency = nil
27
+ symbol = nil
28
+
29
+ OptionParser.new do |opts|
30
+ opts.on('-v', '--verbose') { verbose = true }
31
+ opts.on('-b', '--btc-price') { btc_price = true }
32
+ opts.on('-fXXX', '--fiat-currency XXX') { |f| fiat_currency = f }
33
+
34
+ opts.on('--list-fiat-currencies') do
35
+ puts CoinTools::CoinMarketCap::FIAT_CURRENCIES
36
+ exit 0
37
+ end
38
+
39
+ opts.on('-h', '--help') do
40
+ print_help
41
+ exit 0
42
+ end
43
+
44
+ opts.on('-sSYMBOL', '--symbol SYMBOL') { |s| symbol = s }
45
+
46
+ opts.parse!
47
+ end
48
+
49
+ unless symbol
50
+ if ARGV.length != 1
51
+ print_help
52
+ exit 1
53
+ end
54
+
55
+ coin_name = ARGV[0].downcase
56
+ end
57
+
58
+ if fiat_currency && btc_price
59
+ puts "#{$PROGRAM_NAME}: --btc-price and --fiat-currency options cannot be used together"
60
+ exit 2
61
+ end
62
+
63
+ begin
64
+ if symbol
65
+ result = CoinTools::CoinMarketCap.new.get_price_by_symbol(symbol, convert_to: fiat_currency)
66
+ else
67
+ result = CoinTools::CoinMarketCap.new.get_price(coin_name, convert_to: fiat_currency)
68
+ end
69
+
70
+ if btc_price
71
+ price = result.btc_price
72
+ unit = 'BTC'
73
+ elsif fiat_currency
74
+ price = result.converted_price
75
+ unit = fiat_currency.upcase
76
+ else
77
+ price = result.usd_price
78
+ unit = 'USD'
79
+ end
80
+
81
+ if verbose
82
+ puts "#{symbol&.upcase || coin_name} @ #{result.time || Time.now} ==> #{price} #{unit}"
83
+ puts
84
+ else
85
+ puts price
86
+ end
87
+ rescue CoinTools::CoinMarketCap::InvalidResponseException => e
88
+ $stderr.puts "Error: Incorrect coin name: #{coin_name} (#{e})"
89
+ exit 3
90
+ rescue CoinTools::CoinMarketCap::NoDataException => e
91
+ $stderr.puts "Error: #{e}"
92
+ exit 4
93
+ rescue CoinTools::CoinMarketCap::InvalidFiatCurrencyException => e
94
+ $stderr.puts "Error: Unsupported fiat currency: #{fiat_currency}"
95
+ exit 5
96
+ end
data/bin/cryptowatch CHANGED
@@ -66,7 +66,7 @@ rescue CoinTools::Cryptowatch::InvalidDateException => e
66
66
  $stderr.puts "Error: #{e}"
67
67
  exit 2
68
68
  rescue CoinTools::Cryptowatch::BadRequestException => e
69
- $stderr.puts "Error: Incorrect exchange or market name: #{e}"
69
+ $stderr.puts "Error: Incorrect exchange or market name (#{e})"
70
70
  exit 3
71
71
  rescue CoinTools::Cryptowatch::NoDataException => e
72
72
  $stderr.puts "Error: #{e}: data not ready yet"
@@ -0,0 +1,135 @@
1
+ require_relative 'version'
2
+
3
+ require 'json'
4
+ require 'net/http'
5
+ require 'uri'
6
+
7
+ module CoinTools
8
+ class CoinMarketCap
9
+ BASE_URL = "https://api.coinmarketcap.com"
10
+ USER_AGENT = "cointools/#{CoinTools::VERSION}"
11
+
12
+ FIAT_CURRENCIES = [
13
+ 'AUD', 'BRL', 'CAD', 'CHF', 'CLP', 'CNY', 'CZK', 'DKK', 'EUR', 'GBP',
14
+ 'HKD', 'HUF', 'IDR', 'ILS', 'INR', 'JPY', 'KRW', 'MXN', 'MYR', 'NOK',
15
+ 'NZD', 'PHP', 'PKR', 'PLN', 'RUB', 'SEK', 'SGD', 'THB', 'TRY', 'TWD',
16
+ 'ZAR'
17
+ ]
18
+
19
+ class DataPoint
20
+ attr_reader :time, :usd_price, :btc_price, :converted_price
21
+
22
+ def initialize(time, usd_price, btc_price, converted_price = nil)
23
+ @time = time
24
+ @usd_price = usd_price
25
+ @btc_price = btc_price
26
+ @converted_price = converted_price
27
+ end
28
+ end
29
+
30
+ class InvalidResponseException < StandardError
31
+ attr_reader :response
32
+
33
+ def initialize(response)
34
+ super("#{response.code} #{response.message}")
35
+ @response = response
36
+ end
37
+ end
38
+
39
+ class BadRequestException < InvalidResponseException
40
+ end
41
+
42
+ class NoDataException < StandardError
43
+ end
44
+
45
+ class InvalidFiatCurrencyException < StandardError
46
+ end
47
+
48
+ class InvalidDateException < StandardError
49
+ end
50
+
51
+ def get_price(coin_name, convert_to: nil)
52
+ url = URI("#{BASE_URL}/v1/ticker/#{coin_name}/")
53
+
54
+ if convert_to
55
+ validate_fiat_currency(convert_to)
56
+ url += "?convert=#{convert_to}"
57
+ end
58
+
59
+ response = make_request(url)
60
+
61
+ case response
62
+ when Net::HTTPSuccess
63
+ json = JSON.load(response.body)
64
+ record = json[0]
65
+
66
+ usd_price = record['price_usd']&.to_f
67
+ btc_price = record['price_btc']&.to_f
68
+ timestamp = Time.at(record['last_updated'].to_i)
69
+
70
+ if convert_to
71
+ converted_price = record["price_#{convert_to.downcase}"]&.to_f
72
+ raise NoDataException.new('Conversion to chosen fiat currency failed') if converted_price.nil?
73
+ end
74
+
75
+ return DataPoint.new(timestamp, usd_price, btc_price, converted_price)
76
+ when Net::HTTPBadRequest
77
+ raise BadRequestException.new(response)
78
+ else
79
+ raise InvalidResponseException.new(response)
80
+ end
81
+ end
82
+
83
+ def get_price_by_symbol(coin_symbol, convert_to: nil)
84
+ url = URI("#{BASE_URL}/v1/ticker/?limit=0")
85
+ symbol = coin_symbol.downcase
86
+
87
+ if convert_to
88
+ validate_fiat_currency(convert_to)
89
+ url += "&convert=#{convert_to}"
90
+ end
91
+
92
+ response = make_request(url)
93
+
94
+ case response
95
+ when Net::HTTPSuccess
96
+ json = JSON.load(response.body)
97
+ record = json.detect { |r| r['symbol'].downcase == symbol }
98
+ raise NoDataException.new('No coin found with given symbol') if record.nil?
99
+
100
+ usd_price = record['price_usd']&.to_f
101
+ btc_price = record['price_btc']&.to_f
102
+ timestamp = Time.at(record['last_updated'].to_i)
103
+
104
+ if convert_to
105
+ converted_price = record["price_#{convert_to.downcase}"]&.to_f
106
+ raise NoDataException.new('Conversion to chosen fiat currency failed') if converted_price.nil?
107
+ end
108
+
109
+ return DataPoint.new(timestamp, usd_price, btc_price, converted_price)
110
+ when Net::HTTPBadRequest
111
+ raise BadRequestException.new(response)
112
+ else
113
+ raise Exception.new(response)
114
+ end
115
+ end
116
+
117
+
118
+ private
119
+
120
+ def validate_fiat_currency(fiat_currency)
121
+ unless FIAT_CURRENCIES.include?(fiat_currency.upcase)
122
+ raise InvalidFiatCurrencyException
123
+ end
124
+ end
125
+
126
+ def make_request(url)
127
+ Net::HTTP.start(url.host, url.port, use_ssl: true) do |http|
128
+ request = Net::HTTP::Get.new(url)
129
+ request['User-Agent'] = USER_AGENT
130
+
131
+ http.request(request)
132
+ end
133
+ end
134
+ end
135
+ end
@@ -45,7 +45,7 @@ module CoinTools
45
45
  when Net::HTTPBadRequest
46
46
  raise BadRequestException.new(response)
47
47
  else
48
- raise Exception.new(response)
48
+ raise InvalidResponseException.new(response)
49
49
  end
50
50
  end
51
51
 
@@ -1,3 +1,3 @@
1
1
  module CoinTools
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/cointools.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'cointools/coinmarketcap'
1
2
  require 'cointools/cryptowatch'
2
3
  require 'cointools/version'
3
4
 
metadata CHANGED
@@ -1,27 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cointools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kuba Suder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-24 00:00:00.000000000 Z
11
+ date: 2018-01-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
15
15
  - jakub.suder@gmail.com
16
16
  executables:
17
17
  - cryptowatch
18
+ - coinmcap
18
19
  extensions: []
19
20
  extra_rdoc_files: []
20
21
  files:
22
+ - CHANGELOG.md
21
23
  - README.md
22
24
  - VSPL-LICENSE.txt
25
+ - bin/coinmcap
23
26
  - bin/cryptowatch
24
27
  - lib/cointools.rb
28
+ - lib/cointools/coinmarketcap.rb
25
29
  - lib/cointools/cryptowatch.rb
26
30
  - lib/cointools/version.rb
27
31
  homepage: https://github.com/mackuba/cointools
@@ -44,7 +48,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
44
48
  version: '0'
45
49
  requirements: []
46
50
  rubyforge_project:
47
- rubygems_version: 2.5.1
51
+ rubygems_version: 2.5.2
48
52
  signing_key:
49
53
  specification_version: 4
50
54
  summary: A collection of scripts for checking cryptocurrency prices.