coinquery 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/coinquery.rb +173 -0
- metadata +111 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0f23a051f568acaab4c738d29fac386542ccc59ed10446a2502c00ef8d4e2eef
|
4
|
+
data.tar.gz: c8c21260fecd79db5645057b4fcd68efb6e751cadf6bd99bcbf4ac9012ffee5e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4473291976036afd8912c54e14308ee605a9debbbd631fe2713ea60a91ad156f1559f1e19ffc88e81bc0f22c030a5f8158c573e9113a32f1a18e9d73fa946129
|
7
|
+
data.tar.gz: fb1d9fcc8256edf7a1d68a1048a2cb40d89d75b88fd13be45c63c955bdc77b5b5d792a90eb8d60ae891050302189d55e212dc137d61f762868ae182957f844bf
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
Binary file
|
data/lib/coinquery.rb
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# file: coinquery.rb
|
4
|
+
# description: Uses the Coingecko API. Inspired by the coingecko_client gem
|
5
|
+
|
6
|
+
require 'c32'
|
7
|
+
require 'json'
|
8
|
+
require 'excon'
|
9
|
+
require 'unichron'
|
10
|
+
require 'did_you_mean'
|
11
|
+
|
12
|
+
|
13
|
+
class CoinQueryException < Exception
|
14
|
+
end
|
15
|
+
|
16
|
+
class CoinQuery
|
17
|
+
using ColouredText
|
18
|
+
|
19
|
+
attr_reader :list
|
20
|
+
|
21
|
+
def initialize(autofind: true, dym: true, debug: false)
|
22
|
+
|
23
|
+
@autofind, @dym, @debug = autofind, dym, debug
|
24
|
+
|
25
|
+
@url_base = 'https://api.coingecko.com/api/v3/'
|
26
|
+
r = ping()
|
27
|
+
|
28
|
+
if r then
|
29
|
+
|
30
|
+
puts ('CoinQuery').highlight + ' (powered by CoinGecko)'
|
31
|
+
puts
|
32
|
+
puts ('ping response: ' + r.to_a.first.join(' ')).info
|
33
|
+
|
34
|
+
if autofind then
|
35
|
+
|
36
|
+
file = 'coinquery.dat'
|
37
|
+
|
38
|
+
if not File.exists? file then
|
39
|
+
|
40
|
+
puts ('fetching coins list ...').info
|
41
|
+
@list = api_call 'coins/list'
|
42
|
+
|
43
|
+
|
44
|
+
if @dym then
|
45
|
+
|
46
|
+
puts 'loading did_you_mean ...'.info if @debug
|
47
|
+
|
48
|
+
@dym = DidYouMean::SpellChecker.new(dictionary: @list.flat_map \
|
49
|
+
{|x| [x['symbol'], x['name']]})
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
if not File.exists? file then
|
56
|
+
|
57
|
+
File.open(file, 'w+') do |f|
|
58
|
+
Marshal.dump([@list, @dym], f)
|
59
|
+
end
|
60
|
+
|
61
|
+
else
|
62
|
+
|
63
|
+
puts ('loading coins list ...').info
|
64
|
+
File.open(file) do |f|
|
65
|
+
@list, @dym = Marshal.load(f)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
# lists the top coins (limited to 5 by default)
|
76
|
+
#
|
77
|
+
def coins(limit: 5)
|
78
|
+
currency = 'usd'
|
79
|
+
api_call "coins/markets?vs_currency=#{currency}&per_page=#{limit}"
|
80
|
+
end
|
81
|
+
|
82
|
+
# lists the names and identifiers of all coins
|
83
|
+
#
|
84
|
+
def coins_list
|
85
|
+
@list
|
86
|
+
end
|
87
|
+
|
88
|
+
# returns the price of a coin for a given historical date
|
89
|
+
# e.g. historical_price('Bitcoin', '01-05-2021')
|
90
|
+
#
|
91
|
+
def historical_price(coin, rawdate)
|
92
|
+
|
93
|
+
uc = Unichron.new(rawdate.to_s, :little_endian)
|
94
|
+
raise 'invalid date' unless uc.valid?
|
95
|
+
date = uc.to_date.strftime("%d-%m-%Y")
|
96
|
+
|
97
|
+
id = find_id coin
|
98
|
+
r = api_call "coins/%s/history?date=%s" % [id, date]
|
99
|
+
price = r['market_data']['current_price']['usd']
|
100
|
+
price < 1 ? price : price.round(2)
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
alias history historical_price
|
105
|
+
|
106
|
+
def ping
|
107
|
+
api_call 'ping'
|
108
|
+
end
|
109
|
+
|
110
|
+
# returns the price for a given a coin
|
111
|
+
# e.g. price('Litecoin')
|
112
|
+
#
|
113
|
+
def price(coin)
|
114
|
+
|
115
|
+
currency = 'usd'
|
116
|
+
id = find_id coin
|
117
|
+
r = api_call("simple/price?ids=#{id}&vs_currencies=#{currency}")
|
118
|
+
|
119
|
+
if r then
|
120
|
+
val = r[id][currency]
|
121
|
+
val < 1 ? val : val.round(2)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def api_call(api_request)
|
129
|
+
|
130
|
+
begin
|
131
|
+
Timeout::timeout(3){
|
132
|
+
response = Excon.get(@url_base + api_request)
|
133
|
+
JSON.parse(response.body)
|
134
|
+
}
|
135
|
+
rescue Timeout::Error => e
|
136
|
+
raise CoinQueryException, 'connection timed out'
|
137
|
+
rescue OpenURI::HTTPError => e
|
138
|
+
raise CoinQueryException, '400 bad request'
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
def find_id(coin_name)
|
144
|
+
|
145
|
+
return coin_name unless @autofind
|
146
|
+
|
147
|
+
s = coin_name.to_s.downcase
|
148
|
+
puts 's: ' + s.inspect if @debug
|
149
|
+
r = @list.find {|coin| coin['symbol'].downcase == s || coin['name'].downcase == s}
|
150
|
+
puts 'r: ' + r.inspect if @debug
|
151
|
+
|
152
|
+
if r.nil? then
|
153
|
+
|
154
|
+
if @dym then
|
155
|
+
|
156
|
+
suggestion = @dym.correct coin_name
|
157
|
+
raise CoinQueryException, "unknown coin or token name. \n" \
|
158
|
+
+ "Did you mean %s?" % [suggestion.first]
|
159
|
+
|
160
|
+
else
|
161
|
+
|
162
|
+
raise CoinQueryException, "unknown coin or token name."
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
r['id']
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: coinquery
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- James Robertson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIEXjCCAsagAwIBAgIBATANBgkqhkiG9w0BAQsFADAsMSowKAYDVQQDDCFnZW1t
|
14
|
+
YXN0ZXIvREM9amFtZXNyb2JlcnRzb24vREM9ZXUwHhcNMjEwNTAxMTc0MDQwWhcN
|
15
|
+
MjIwNTAxMTc0MDQwWjAsMSowKAYDVQQDDCFnZW1tYXN0ZXIvREM9amFtZXNyb2Jl
|
16
|
+
cnRzb24vREM9ZXUwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC6rjtU
|
17
|
+
mmToxQ17l/iglxID3NQELOPb0Og3PomskJjMMP3Z6DfR7HFG4oCf+AOqApu1MJlY
|
18
|
+
HtA9D+wBc3UDwXqx+tGb5jK8z5wiPc7bxZw8KWXlMr6xl39aOV6Mar+ba85YfXYy
|
19
|
+
A0AKLFZ0aGJlWFJDhaKY15A1BvCLIxzs8khQhU9SrswpMRvTMh4vbGMUTSLH6YfM
|
20
|
+
CePCq4oePv0hCt9mJRM07mvnZTluvC3luKCZX/epoXhz27SjfEfkIDLBp5CGBi/F
|
21
|
+
T1glfaiFeGMZXvEIOSSYD334FlpFssJm17ZkCZbyhEpJbADKf59tp3SopApkCp8a
|
22
|
+
jgOaxAwNAPx1x4O7b+QB6cc94UJ8dUBzGpO4k+WmjMfyD2uH5tRy31wgOYtEFdwK
|
23
|
+
PnP4nhcNlCarLW8mlhdTjuv/MF3LL+eTPeSNzYjLVB6llRTIOuMRbZMtRGqqxakO
|
24
|
+
xF7uFbx551al1xMp7a2j9/8ms1i/HOUC7HYIY3Sypbxo4vr+DS4exHFw/HkCAwEA
|
25
|
+
AaOBijCBhzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUj4/MG5Mc
|
26
|
+
hxuUT+ppdcmWq844BvswJgYDVR0RBB8wHYEbZ2VtbWFzdGVyQGphbWVzcm9iZXJ0
|
27
|
+
c29uLmV1MCYGA1UdEgQfMB2BG2dlbW1hc3RlckBqYW1lc3JvYmVydHNvbi5ldTAN
|
28
|
+
BgkqhkiG9w0BAQsFAAOCAYEAea5PKLTuEVWpVIPL9qnLJy8nLsIlK5pCo4jIvSUj
|
29
|
+
aAio8zozuuuF4xmL99fL25AR0azdGNdbTqir87Nw89UCIeWCaoVT+xoBzIDjOk+K
|
30
|
+
6/zU5ycp9R1MpkCUxyQVJkPzS5sv/GSobGt1+N+ezZX6PTQ0E15pYZw1EgTfoj+P
|
31
|
+
DpmmpF+2oQ7p3EkTw9Zq68frhVOr58eDq2c/UTB54ONFMNc2fAsG0pCjcbxiKb9/
|
32
|
+
aA/xcjAS/wQOj7E0SnMZ30VHq+/ZJ1Iuo4SOTUdIs0Q83U5NmSAenD1rS2GqE9Cq
|
33
|
+
jYE1eDshtl97Xr7PUmlWAEhdG0ftXhq2T2ihNnufpa4fzIKyGENSIMv77j6gbdkq
|
34
|
+
RxI8h/TvvVjmGBA48mE72dv2EOWUOB03ER5kNxLl/ewhn2Ya1sBSyttRAl/prDFr
|
35
|
+
KVqLf8YURgYwosAadSWCIhJ2efQFYT3GwOQXoeYsgAZtjSlrVzoyQ6UNkYulTmkH
|
36
|
+
A92PcSEe/WR5K1FfkBZK5q7Q
|
37
|
+
-----END CERTIFICATE-----
|
38
|
+
date: 2021-05-01 00:00:00.000000000 Z
|
39
|
+
dependencies:
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: excon
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.81.0
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0.81'
|
50
|
+
type: :runtime
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 0.81.0
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0.81'
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: uniqchron
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - "~>"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0.3'
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.3.4
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0.3'
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 0.3.4
|
80
|
+
description:
|
81
|
+
email: digital.robertson@gmail.com
|
82
|
+
executables: []
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- lib/coinquery.rb
|
87
|
+
homepage: https://github.com/jrobertson/coinquery
|
88
|
+
licenses:
|
89
|
+
- MIT
|
90
|
+
metadata: {}
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubyforge_project:
|
107
|
+
rubygems_version: 2.7.10
|
108
|
+
signing_key:
|
109
|
+
specification_version: 4
|
110
|
+
summary: Uses the Coingecko API. Inspired by the coingecko_client gem
|
111
|
+
test_files: []
|
metadata.gz.sig
ADDED
Binary file
|