mcoin 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []