coinquery 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.
- 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
|