Skip to content

Commit

Permalink
Merge 1a4b1da into 5f29fbd
Browse files Browse the repository at this point in the history
  • Loading branch information
kurt-smith committed Jan 8, 2018
2 parents 5f29fbd + 1a4b1da commit d10b57c
Show file tree
Hide file tree
Showing 23 changed files with 4,553 additions and 7,133 deletions.
12 changes: 12 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,14 @@
AllCops:
TargetRubyVersion: 2.3
Exclude:
- 'Gemfile'
Documentation:
Enabled: false
LineLength:
Max: 140
Style/RaiseArgs:
EnforcedStyle: compact
Metrics/AbcSize:
Enabled: false
Metrics/MethodLength:
Max: 30
56 changes: 46 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
[![Gem Version](https://badge.fury.io/rb/coinmarketcap.svg)](https://badge.fury.io/rb/coinmarketcap) [![Build Status](https://travis-ci.org/ankitsamarthya/coinmarketcap.svg?branch=master)](https://travis-ci.org/ankitsamarthya/coinmarketcap) [![Code Climate](https://codeclimate.com/github/ankitsamarthya/coinmarketcap/badges/gpa.svg)](https://codeclimate.com/github/ankitsamarthya/coinmarketcap) [![Coverage Status](https://coveralls.io/repos/github/ankitsamarthya/coinmarketcap/badge.svg?branch=master)](https://coveralls.io/github/ankitsamarthya/coinmarketcap?branch=master) [![Issue Count](https://codeclimate.com/github/ankitsamarthya/coinmarketcap/badges/issue_count.svg)](https://codeclimate.com/github/ankitsamarthya/coinmarketcap)
[![Gem Version](https://badge.fury.io/rb/coinmarketcap.svg)](https://badge.fury.io/rb/coinmarketcap) [![Build Status](https://travis-ci.org/kurt-smith/coinmarketcap.svg?branch=master)](https://travis-ci.org/kurt-smith/coinmarketcap) [![Code Climate](https://codeclimate.com/github/kurt-smith/coinmarketcap/badges/gpa.svg)](https://codeclimate.com/github/kurt-smith/coinmarketcap) [![Coverage Status](https://coveralls.io/repos/github/kurt-smith/coinmarketcap/badge.svg?branch=master)](https://coveralls.io/github/kurt-smith/coinmarketcap?branch=master) [![Issue Count](https://codeclimate.com/github/kurt-smith/coinmarketcap/badges/issue_count.svg)](https://codeclimate.com/github/kurt-smith/coinmarketcap)

# Coinmarketcap
# coinmarketcapper

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/coinmarketcap`. To experiment with that code, run `bin/console` for an interactive prompt.

TODO: Delete this and the text above, and describe your gem
This project has been forked from the `coinmarketcap` gem to provide a wrapper to the public coinmarketcap.com V1 API.

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'coinmarketcap'
gem 'coinmarketcapper'
```

And then execute:
Expand All @@ -20,11 +18,49 @@ And then execute:

Or install it yourself as:

$ gem install coinmarketcap
$ gem install coinmarketcapper

## Usage

TODO: Write usage instructions here
### Coinmarketcap.com API responses

#### All Coins

```ruby
CoinMarketCap.coins(limit: 0, rank: nil, currency: nil)
```

#### Coin by Coin Market Cap ID

```ruby
CoinMarketCap.coin('litecoin', currency: nil)
```

#### Global

```ruby
CoinMarketCap.global(currency: nil)
```

### Additional Functionality

#### Coin by symbol

```ruby
CoinMarketCap.coin_by_symbol('LTC')
```

#### Retrieve markets by coin

```ruby
CoinMarketCap.coin_markets(id: 'iota')
```

#### Retrieve Coin historical price

```ruby
CoinMarketCap.historical_price('request-network', '2018-01-01', '2018-01-08')
```

## Development

Expand All @@ -34,12 +70,12 @@ To install this gem onto your local machine, run `bundle exec rake install`. To

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/ankitsamarthya/coinmarketcap. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
Bug reports and pull requests are welcome on GitHub at https://github.com/kurt-smith/coinmarketcap. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.

## License

The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).

## Code of Conduct

Everyone interacting in the Coinmarketcap project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/ankitsamarthya/coinmarketcap/blob/master/CODE_OF_CONDUCT.md).
Everyone interacting in the CoinMarketCap project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/kurt-smith/coinmarketcap/blob/master/CODE_OF_CONDUCT.md).
62 changes: 32 additions & 30 deletions coinmarketcap.gemspec
Original file line number Diff line number Diff line change
@@ -1,43 +1,45 @@
# coding: utf-8
lib = File.expand_path("../lib", __FILE__)
# frozen_string_literal: true

lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "coinmarketcap/version"
require 'coinmarketcap/version'

Gem::Specification.new do |spec|
spec.name = "coinmarketcap"
spec.version = Coinmarketcap::VERSION
spec.authors = ["Ankit Samarthya"]
spec.email = ["ankitsamar@outlook.com"]
spec.name = 'coinmarketcapper'
spec.version = CoinMarketCap::VERSION
spec.authors = ['Kurt Smith']
spec.email = ['zippydev@protonmail.com']

spec.summary = %q{Coinmarketcap.com API ruby wrapper}
spec.description = %q{Get all the coins listed on coinmarketcap.com}
spec.homepage = "https://github.com/ankitsamarthya/coinmarketcap"
spec.license = "MIT"
spec.summary = 'CoinMarketCap V1 API wrapper'
spec.description = 'coinmarketcap.com V1 API wrapper including additional historical prices and coin market pairs.'
spec.homepage = 'https://github.com/kurt-smith/coinmarketcap'
spec.license = 'MIT'

# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
# to allow pushing to a single host or delete this section to allow pushing to any host.
if spec.respond_to?(:metadata)
spec.metadata["allowed_push_host"] = "https://rubygems.org"
else
raise "RubyGems 2.0 or newer is required to protect against " \
"public gem pushes."
end
# if spec.respond_to?(:metadata)
# spec.metadata['allowed_push_host'] = 'https://rubygems.org'
# else
# raise 'RubyGems 2.0 or newer is required to protect against ' \
# 'public gem pushes.'
# end

spec.files = `git ls-files -z`.split("\x0").reject do |f|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
f.match(%r{^(test|spec|features)/})
end
spec.bindir = "exe"
spec.bindir = 'exe'
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.require_paths = ['lib']

spec.add_dependency 'activesupport', '~> 5.1'
spec.add_dependency 'http', '~> 3.0'
spec.add_dependency 'nokogiri', '~> 1.8'

spec.add_runtime_dependency 'httparty'
spec.add_runtime_dependency 'nokogiri'
spec.add_development_dependency 'bundler', '~> 1.14'
spec.add_development_dependency 'rake', '~> 10.0'
spec.add_development_dependency 'rspec', '~> 3.0'
spec.add_development_dependency 'coveralls'
spec.add_development_dependency 'vcr'
spec.add_development_dependency 'webmock'
spec.add_development_dependency 'pry'
spec.add_development_dependency 'pry-coolline'
spec.add_development_dependency 'bundler', '~> 1.14'
spec.add_development_dependency 'coveralls', '~> 0.8'
spec.add_development_dependency 'pry', '~> 0.11'
spec.add_development_dependency 'rake', '~> 10.0'
spec.add_development_dependency 'rspec', '~> 3.7'
spec.add_development_dependency 'vcr', '~> 4.0'
spec.add_development_dependency 'webmock', '~> 3.2'
end
148 changes: 111 additions & 37 deletions lib/coinmarketcap.rb
Original file line number Diff line number Diff line change
@@ -1,51 +1,125 @@
# frozen_string_literal: false

require 'active_support'
require 'active_support/core_ext'
require 'coinmarketcap/version'
require 'open-uri'
require 'httparty'
require 'http'
require 'nokogiri'

module Coinmarketcap
def self.coins(limit = nil)
if limit.nil?
HTTParty.get('https://api.coinmarketcap.com/v1/ticker/')
else
HTTParty.get("https://api.coinmarketcap.com/v1/ticker/?limit=#{limit}")
end
module CoinMarketCap
API_URL = 'https://api.coinmarketcap.com/v1'.freeze
BASE_URL = 'https://coinmarketcap.com'.freeze

# @param rank [Integer] Coins market cap rank greater than or equal
# @param limit [Integer] Maximum limit set. Defaults to 0 to return all results
# @param currency [String] Country currency code to convert price
# @return [Array<Hash>]
# @see https://coinmarketcap.com/api/
def self.coins(limit: 0, rank: nil, currency: nil)
params = {
limit: limit,
start: rank,
convert: currency
}.compact.to_param

url = "#{API_URL}/ticker/"
url << "?#{params}" if params.present?

response = HTTP.get(url)
JSON.parse(response.body.to_s, symbolize_names: true)
end

def self.coin(id, currency = 'USD')
HTTParty.get("https://api.coinmarketcap.com/v1/ticker/#{id}/?convert=#{currency}")
# @param id [Integer] CoinMarketCap coin id
# @param currency [String] Country currency code to convert price
# @return [Hash]
def self.coin(id, currency: nil)
params = {
convert: currency
}.compact.to_param

url = "#{API_URL}/ticker/#{id}/"
url << "?#{params}" if params.present?

response = HTTP.get(url)
json = JSON.parse(response.body.to_s, symbolize_names: true)
json.is_a?(Array) ? json.first : json
end

def self.global(currency = 'USD')
HTTParty.get("https://api.coinmarketcap.com/v1/global/?convert=#{currency}")
# @param symbol [String] Coin symbol
# @return [Hash]
def self.coin_by_symbol(symbol)
response = HTTP.get("#{API_URL}/ticker/?limit=0")
json = JSON.parse(response.body.to_s, symbolize_names: true)
json.find { |x| x[:symbol].strip.casecmp(symbol.strip.upcase).zero? }
end

def self.get_historical_price(id, start_date, end_date) # 20170908
prices = []
doc = Nokogiri::HTML(open("https://coinmarketcap.com/currencies/#{id}/historical-data/?start=#{start_date}&end=#{end_date}"))
rows = doc.css('tr')
if rows.count == 31
doc = Nokogiri::HTML(open("https://coinmarketcap.com/assets/#{id}/historical-data/?start=#{start_date}&end=#{end_date}"))
rows = doc.css('tr')
# @param id [String] Coin market cap id
# @param symbol [String] Coin symbol
# @return [Array<Hash>]
def self.coin_markets(id: nil, symbol: nil)
raise ArgumentError.new('id or symbol is required') if id.blank? && symbol.blank?

coin_id = symbol.present? ? coin_by_symbol(symbol)[:id] : id
response = HTTP.get("#{BASE_URL}/currencies/#{coin_id}/\#markets")
html = Nokogiri::HTML(response.body.to_s)
rows = html.css('table#markets-table tbody tr')

markets = rows.each_with_object([]) do |row, arr|
td = row.css('td')
arr << {
source: td[1].text.strip,
pair: td[2].text.strip,
volume_usd: td[3].text.strip[/\$(.+)/, 1].delete(',').to_f,
price_usd: td[4].text.strip[/\$(.+)/, 1].delete(',').to_f,
volume_percentage: td[5].text.to_f,
last_updated: td[6].text.strip
}
end
rows.shift
rows.each do |row|
begin
each_row = Nokogiri::HTML(row.to_s).css('td')
if each_row.count > 1
price_bundle = {}
price_bundle[:date] = Date.parse(each_row[0].text)
price_bundle[:open] = each_row[1].text.to_f
price_bundle[:high] = each_row[2].text.to_f
price_bundle[:low] = each_row[3].text.to_f
price_bundle[:close] = each_row[4].text.to_f
price_bundle[:avg] = (price_bundle[:high] + price_bundle[:low]) / 2.0
prices << price_bundle
end
rescue
next
end

markets
end

# @param currency [String] Country currency code to convert price
# @return [Hash]
def self.global(currency: nil)
params = {
convert: currency
}.compact.to_param

url = "#{API_URL}/global/"
url << "?#{params}" if params.present?

response = HTTP.get(url)
JSON.parse(response.body.to_s, symbolize_names: true)
end

# @param id [String] CoinMarketCap coin id
# @param start_date [String] Start date (YYYY-MM-DD)
# @param end_date [String] End date (YYYY-MM-DD)
# @return [Array<Hash>]
def self.historical_price(id, start_date, end_date)
sd = start_date.to_date.to_s.delete('-')
ed = end_date.to_date.to_s.delete('-')

url = "#{BASE_URL}/currencies/#{id}/historical-data/?start=#{sd}&end=#{ed}"
response = HTTP.get(url)
html = Nokogiri::HTML(response.body.to_s)
rows = html.css('#historical-data table tbody tr')

prices = rows.each_with_object([]) do |row, arr|
td = row.css('td')
daily = {
date: Date.parse(td[0].text).to_s,
open: td[1].text.to_f,
high: td[2].text.to_f,
low: td[3].text.to_f,
close: td[4].text.to_f
}

daily[:average] = ((daily[:high] + daily[:low]).to_d / 2).to_f
arr << daily
end

prices
end
end
6 changes: 4 additions & 2 deletions lib/coinmarketcap/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module Coinmarketcap
VERSION = "0.2.4"
# frozen_string_literal: true

module CoinMarketCap
VERSION = '0.1.20180108'
end

0 comments on commit d10b57c

Please sign in to comment.