mcoin 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4d8259c823f92b80f9e0124b3443c5e1b74d6120
4
+ data.tar.gz: 6de15f6269ef50557c690f414bee21dfef1d63fe
5
+ SHA512:
6
+ metadata.gz: 47b20bb1bed806bfcd73fe8a5d42c6709f80872cb088e3a23d126dc2dc339d9198fb1b9ff3990ec1b10ad407fb0c54e65037c68eb4bedb0678c591d22deabafd
7
+ data.tar.gz: eb57c25b083e53e67bb9d1a888e53f47ef56f1bc35038b265ae695d890ef1f767760eb9cb7a6abd41f0f154e8a0702ad543a9a08275d45d8067f0b07740c50d3
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.1
5
+ before_install: gem install bundler -v 1.16.0
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in mcoin.gemspec
6
+ gemspec
7
+
8
+ gem 'pry'
data/Gemfile.lock ADDED
@@ -0,0 +1,26 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ mcoin (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ coderay (1.1.2)
10
+ method_source (0.9.0)
11
+ pry (0.11.3)
12
+ coderay (~> 1.1.0)
13
+ method_source (~> 0.9.0)
14
+ rake (10.5.0)
15
+
16
+ PLATFORMS
17
+ ruby
18
+
19
+ DEPENDENCIES
20
+ bundler (~> 1.16)
21
+ mcoin!
22
+ pry
23
+ rake (~> 10.0)
24
+
25
+ BUNDLED WITH
26
+ 1.16.0
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # Mcoin
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/mcoin`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'mcoin'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install mcoin
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake ` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/mcoin.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler/gem_tasks'
2
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'mcoin'
5
+
6
+ require 'pry'
7
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/mcoin ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'mcoin'
5
+
6
+ Mcoin::Command.execute
data/lib/mcoin.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'mcoin/version'
2
+
3
+ # :nodoc:
4
+ module Mcoin
5
+ TYPES = %i[BTC ETH].freeze
6
+ CURRENCY = %i[USD].freeze
7
+
8
+ autoload :Command, 'mcoin/command'
9
+ autoload :Market, 'mcoin/market'
10
+ autoload :Data, 'mcoin/data'
11
+ autoload :Printer, 'mcoin/printer'
12
+ autoload :InfluxDB, 'mcoin/influx_db'
13
+ end
@@ -0,0 +1,94 @@
1
+ require 'optparse'
2
+ require 'optparse/uri'
3
+ require 'ostruct'
4
+
5
+ module Mcoin
6
+ # The command line interface
7
+ class Command < OptionParser
8
+ class << self
9
+ def execute
10
+ new
11
+ end
12
+ end
13
+
14
+ attr_reader :option
15
+
16
+ def initialize(&block)
17
+ super
18
+ prepare_options
19
+
20
+ self.banner = '=== Mcoin : Bitcoin Monitor Tools ==='
21
+ options_for_coin
22
+ options_for_influxdb
23
+ common_options
24
+
25
+ parse!
26
+ execute
27
+ end
28
+
29
+ def execute
30
+ raise OptionParser::MissingArgument, :market if option.market.nil?
31
+ market.print
32
+ # TODO: Provide general interface
33
+ market.save(option) if influxdb?
34
+ end
35
+
36
+ def market
37
+ @market ||= Market
38
+ .pick(option.market)
39
+ .new(option.type, option.currency)
40
+ end
41
+
42
+ def influxdb?
43
+ option.endpoint && option.database
44
+ end
45
+
46
+ def on(name, *args)
47
+ super(*args, ->(value) { option[name] = value })
48
+ end
49
+
50
+ def separator(content = nil)
51
+ super ''
52
+ super content unless content.nil?
53
+ end
54
+
55
+ private
56
+
57
+ def prepare_options
58
+ @option = OpenStruct.new
59
+ @option.type = :BTC
60
+ @option.currency = :USD
61
+ end
62
+
63
+ def common_options
64
+ separator 'Common Options: '
65
+ on_tail('-h', '--help', 'Show this message') do
66
+ puts self
67
+ exit
68
+ end
69
+
70
+ on_tail('-v', '--version', 'Show version') do
71
+ puts "Mcoin #{VERSION}"
72
+ exit
73
+ end
74
+ end
75
+
76
+ def options_for_influxdb
77
+ separator 'InfluxDB:'
78
+ on(:endpoint, '-e', '--endpoint ENDPOINT', URI, 'Database Endpoint')
79
+ on(:database, '-d', '--database NAME', String, 'Database Name')
80
+ on(:username, '-u', '--username USERNAME', String, 'Database Username')
81
+ on(:password, '-p', '--password PASSWORD', String, 'Database Password')
82
+ end
83
+
84
+ def options_for_coin
85
+ on(:type, '-t', '--type TYPE',
86
+ Mcoin::TYPES, "Available: #{Mcoin::TYPES.join(', ')}")
87
+ on(:currency, '-c', '--currency CURRENCY',
88
+ Mcoin::CURRENCY, "Available: #{Mcoin::CURRENCY.join(', ')}")
89
+ on(:market, '-m', '--market MARKET',
90
+ Mcoin::Market.available,
91
+ "Available: #{Mcoin::Market.available.join(', ')}")
92
+ end
93
+ end
94
+ end
data/lib/mcoin/data.rb ADDED
@@ -0,0 +1,6 @@
1
+ module Mcoin
2
+ # :nodoc:
3
+ module Data
4
+ autoload :Ticker, 'mcoin/data/ticker'
5
+ end
6
+ end
@@ -0,0 +1,29 @@
1
+ module Mcoin
2
+ module Data
3
+ # :nodoc:
4
+ class Ticker
5
+ attr_reader :type, :currency
6
+ attr_accessor :last, :ask, :bid, :low, :high, :volume
7
+
8
+ def initialize(type, currency, data = {})
9
+ @type = type
10
+ @currency = currency
11
+ data.each do |key, value|
12
+ send("#{key}=", value)
13
+ end
14
+ end
15
+
16
+ def to_influx(tags = {}, values = {})
17
+ tags = { type: @type, currency: @currency }.merge(tags)
18
+ values = {
19
+ last: @last,
20
+ ask: @ask, bid: @bid,
21
+ low: @low, high: @high,
22
+ volume: @volume
23
+ }.merge(values)
24
+ "prices,#{tags.map { |t| t.join('=') }.join(',')} " \
25
+ "#{values.map { |v| v.join('=') }.join(',')}"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,36 @@
1
+ require 'net/http'
2
+
3
+ module Mcoin
4
+ # :nodoc:
5
+ class InfluxDB
6
+ def initialize(endpoint, db, user = nil, pass = '')
7
+ @endpoint = endpoint
8
+ @db = db
9
+ @user = user
10
+ @pass = pass
11
+ end
12
+
13
+ def save(data)
14
+ req = request(data)
15
+ res = Net::HTTP.start(uri.hostname, uri.port) do |http|
16
+ http.request(req)
17
+ end
18
+
19
+ pp JSON.parse(res.body) unless res.body.nil?
20
+ end
21
+
22
+ protected
23
+
24
+ def request(data)
25
+ req = Net::HTTP::Post.new(uri)
26
+ req.basic_auth @user, @pass if @user
27
+ req.content_type = 'multipart/form-data'
28
+ req.body = data.join("\n")
29
+ req
30
+ end
31
+
32
+ def uri
33
+ URI("#{@endpoint}/write?db=#{@db}")
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ module Mcoin
2
+ # :nodoc:
3
+ module Market
4
+ autoload :Base, 'mcoin/market/base'
5
+ autoload :Bitfinex, 'mcoin/market/bitfinex'
6
+ autoload :Bitstamp, 'mcoin/market/Bitstamp'
7
+ autoload :Kraken, 'mcoin/market/kraken'
8
+
9
+ def self.pick(name)
10
+ const_get(name)
11
+ end
12
+
13
+ def self.available
14
+ constants - [:Base]
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,53 @@
1
+ require 'pp'
2
+ require 'json'
3
+ require 'net/http'
4
+
5
+ module Mcoin
6
+ module Market
7
+ # :nodoc:
8
+ class Base
9
+ def initialize(type, currency)
10
+ @type = type
11
+ @currency = currency
12
+ end
13
+
14
+ def print
15
+ fetch
16
+ puts '=== Result ==='
17
+ Printer.new(to_ticker).print
18
+ self
19
+ end
20
+
21
+ def save(option)
22
+ puts '=== InfluxDB ==='
23
+ InfluxDB.new(
24
+ option.endpoint,
25
+ option.database,
26
+ option.username,
27
+ option.password
28
+ ).save([to_ticker.to_influx(market: name)])
29
+ puts 'Saved'
30
+ self
31
+ end
32
+
33
+ def name
34
+ self.class.name.split('::').last
35
+ end
36
+
37
+ def fetch
38
+ @data ||= JSON.parse(Net::HTTP.get(uri))
39
+ self
40
+ end
41
+
42
+ def to_ticker
43
+ raise NotImplementedError
44
+ end
45
+
46
+ def uri
47
+ options = { type: @type.upcase, currency: @currency.upcase }
48
+ uri = format(self.class.const_get(:ENDPOINT), options)
49
+ URI(uri)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,20 @@
1
+ module Mcoin
2
+ module Market
3
+ # :nodoc:
4
+ class Bitfinex < Base
5
+ # rubocop:disable Metrics/LineLength
6
+ ENDPOINT = 'https://api.bitfinex.com/v1/pubticker/%<type>s%<currency>s'.freeze
7
+
8
+ def to_ticker
9
+ fetch
10
+ Data::Ticker.new(
11
+ @type, @currency,
12
+ last: @data['last_price'],
13
+ ask: @data['ask'], bid: @data['bid'],
14
+ low: @data['low'], high: @data['high'],
15
+ volume: @data['volume']
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Mcoin
2
+ module Market
3
+ # :nodoc:
4
+ class Bitstamp < Base
5
+ # rubocop:disable Metrics/LineLength
6
+ ENDPOINT = 'https://www.bitstamp.net/api/v2/ticker/%<type>s%<currency>s/'.freeze
7
+
8
+ def to_ticker
9
+ fetch
10
+ Data::Ticker.new(
11
+ @type, @currency,
12
+ last: @data['last'],
13
+ ask: @data['ask'], bid: @data['bid'],
14
+ low: @data['low'], high: @data['high'],
15
+ volume: @data['volume']
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ module Mcoin
2
+ module Market
3
+ # :nodoc:
4
+ class Kraken < Base
5
+ # rubocop:disable Metrics/LineLength
6
+ ENDPOINT = 'https://api.kraken.com/0/public/Ticker?pair=%<type>s%<currency>s'.freeze
7
+
8
+ def initialize(type, currency)
9
+ type = swap_btc(type)
10
+ super
11
+ end
12
+
13
+ def to_ticker
14
+ fetch
15
+ Data::Ticker.new(
16
+ swap_btc(@type), @currency,
17
+ last: @data['c'][0],
18
+ ask: @data['a'][0], bid: @data['b'][0],
19
+ low: @data['l'][1], high: @data['h'][1],
20
+ volume: @data['v'][1]
21
+ )
22
+ end
23
+
24
+ def fetch
25
+ super
26
+ return self if @data['result'].nil?
27
+ @data = @data.dig('result', "X#{@type}Z#{@currency}")
28
+ end
29
+
30
+ def swap_btc(type)
31
+ return :BTC if type == :XBT
32
+ return :XBT if type == :BTC
33
+ type
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,33 @@
1
+ module Mcoin
2
+ # :nodoc:
3
+ class Printer
4
+ def initialize(*rows)
5
+ @rows = rows.flatten
6
+ end
7
+
8
+ def print
9
+ puts row(columns.map(&:capitalize))
10
+ puts column_widths.map { |width| '-' * width }.join(' | ')
11
+ @rows.each do |row|
12
+ puts row(columns.map { |column| row.send(column) })
13
+ end
14
+ end
15
+
16
+ def row(row)
17
+ row.map(&:to_s)
18
+ .zip(column_widths)
19
+ .map { |item| item.reduce(:ljust) }
20
+ .join(' | ')
21
+ end
22
+
23
+ def column_widths
24
+ @widths ||= columns.map do |column|
25
+ [@rows.map(&column).map(&:size).max, column.size].max
26
+ end
27
+ end
28
+
29
+ def columns
30
+ %i[currency type last ask bid]
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module Mcoin
2
+ VERSION = '0.1.0'.freeze
3
+ end
data/mcoin.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'mcoin/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'mcoin'
9
+ spec.version = Mcoin::VERSION
10
+ spec.authors = ['蒼時弦也']
11
+ spec.email = ['contact@frost.tw']
12
+
13
+ spec.summary = 'The BTC market monitor tool'
14
+ spec.description = 'The BTC market monitor tool'
15
+ spec.homepage = 'https://github.com/elct9620/mcoin'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = 'exe'
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.16'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mcoin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - 蒼時弦也
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-12-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: The BTC market monitor tool
42
+ email:
43
+ - contact@frost.tw
44
+ executables:
45
+ - mcoin
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - ".travis.yml"
51
+ - Gemfile
52
+ - Gemfile.lock
53
+ - README.md
54
+ - Rakefile
55
+ - bin/console
56
+ - bin/setup
57
+ - exe/mcoin
58
+ - lib/mcoin.rb
59
+ - lib/mcoin/command.rb
60
+ - lib/mcoin/data.rb
61
+ - lib/mcoin/data/ticker.rb
62
+ - lib/mcoin/influx_db.rb
63
+ - lib/mcoin/market.rb
64
+ - lib/mcoin/market/base.rb
65
+ - lib/mcoin/market/bitfinex.rb
66
+ - lib/mcoin/market/bitstamp.rb
67
+ - lib/mcoin/market/kraken.rb
68
+ - lib/mcoin/printer.rb
69
+ - lib/mcoin/version.rb
70
+ - mcoin.gemspec
71
+ homepage: https://github.com/elct9620/mcoin
72
+ licenses: []
73
+ metadata: {}
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 2.6.11
91
+ signing_key:
92
+ specification_version: 4
93
+ summary: The BTC market monitor tool
94
+ test_files: []