Skip to content
This repository has been archived by the owner on Oct 19, 2022. It is now read-only.

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
foxweb committed Apr 27, 2020
0 parents commit d51e5cf
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
TINKOFF_OPENAPI_URL=https://api-invest.tinkoff.ru/openapi
TINKOFF_OPENAPI_TOKEN=
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.env.local
.env.*.local
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.7.1
11 changes: 11 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
source 'https://rubygems.org'

gem 'dotenv'

gem 'faraday'
gem 'faraday_middleware'
gem 'faraday_middleware-parse_oj'

gem 'awesome_pry'

gem 'tty-table'
59 changes: 59 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
GEM
remote: https://rubygems.org/
specs:
awesome_print (1.8.0)
awesome_pry (0.0.1)
awesome_print
pry-rails
coderay (1.1.2)
dotenv (2.7.5)
equatable (0.6.1)
faraday (0.17.3)
multipart-post (>= 1.2, < 3)
faraday_middleware (0.14.0)
faraday (>= 0.7.4, < 1.0)
faraday_middleware-parse_oj (0.3.2)
faraday (~> 0.9)
faraday_middleware (>= 0.9.1, < 1.0)
oj (>= 2.0, < 4.0)
method_source (1.0.0)
multipart-post (2.1.1)
necromancer (0.6.0)
oj (3.10.6)
pastel (0.7.3)
equatable (~> 0.6)
tty-color (~> 0.5)
pry (0.13.1)
coderay (~> 1.1)
method_source (~> 1.0)
pry-rails (0.3.9)
pry (>= 0.10.4)
strings (0.1.8)
strings-ansi (~> 0.1)
unicode-display_width (~> 1.5)
unicode_utils (~> 1.4)
strings-ansi (0.2.0)
tty-color (0.5.1)
tty-screen (0.7.1)
tty-table (0.11.0)
equatable (~> 0.6)
necromancer (~> 0.5)
pastel (~> 0.7.2)
strings (~> 0.1.5)
tty-screen (~> 0.7)
unicode-display_width (1.7.0)
unicode_utils (1.4.0)

PLATFORMS
ruby

DEPENDENCIES
awesome_pry
dotenv
faraday
faraday_middleware
faraday_middleware-parse_oj
tty-table

BUNDLED WITH
2.1.4
10 changes: 10 additions & 0 deletions bin/console
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env ruby

require 'bundler/setup'
require 'pry'
require 'awesome_print'
AwesomePrint.pry!

require_relative '../lib/tinky_client'

Pry.start(TinkyClient)
3 changes: 3 additions & 0 deletions bin/portfolio
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env ruby
require_relative '../lib/tinky_client'
TinkyClient.portfolio
7 changes: 7 additions & 0 deletions config/dotenv.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require 'dotenv'
Dotenv.load(
".env.#{ENV['APP_ENV']}.local",
'.env.local',
".env.#{ENV['APP_ENV']}",
'.env'
)
6 changes: 6 additions & 0 deletions config/oj.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require 'oj'

Oj.default_options = {
mode: :compat,
symbol_keys: true
}
124 changes: 124 additions & 0 deletions lib/tinky_client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
require './config/dotenv'
require './config/oj'

require 'faraday'
require 'faraday_middleware'
require 'faraday_middleware/parse_oj'

require 'tty/table'

require 'pry'
require 'awesome_print'

module TinkyClient
CURRENCIES = { RUB: '₽', USD: '$', EUR: '€' }.freeze

class Client
attr_reader :connection

def initialize
@connection = Client.make_connection(ENV['TINKOFF_OPENAPI_URL'])
end

def get_portfolio
get_data('portfolio')
end

private
def get_data(url)
request(:get, url)
end

def request(method, url, params = {})
response = connection.public_send(method, url, params)

if response.success?
response.body
else
handle_error(response)
end
end

def handle_error(response)
raise ClientError, "Tinkoff responded with HTTP #{response.status}: #{response.body.ai}"
end

class << self
def make_connection(url)
Faraday.new(url: url) do |builder|
builder.request :json
builder.authorization :Bearer, ENV['TINKOFF_OPENAPI_TOKEN']
builder.response :oj, content_type: 'application/json'
builder.adapter Faraday.default_adapter
end
end
end
end

class ClientError < StandardError; end

class << self
def portfolio
puts

summary = client.get_portfolio

table = TTY::Table.new(header: ['Type', 'Name', 'Amount', 'Yield'])

summary.dig(:payload, :positions).each do |p|
currency = CURRENCIES[p[:expectedYield][:currency].to_sym]
decorated_yield = decorate_value(p[:expectedYield][:value], currency)

table << [
p[:instrumentType].upcase,
decorate_name(p[:name]),
{ value: decorate_amount(p[:balance]), alignment: :right },
{ value: decorated_yield, alignment: :right }
]
end

puts table.render(:ascii, padding: [0,1,0,1])
puts
end

private
def client
@client ||= Client.new
end

def pastel
@pastel ||= Pastel.new
end

def decorate_value(value, currency)
color = if value.positive?
:green
elsif value.negative?
:red
else
:clear
end

formatted_value = sprintf("%+d #{currency}", value)
pastel.decorate(formatted_value, color)
end

def decorate_amount(amount)
if amount == amount.to_i
amount.round
else
amount
end
end

def decorate_name(name)
stripped_name = if name.length > 29
name[0..28] + '…'
else
name
end

pastel.bold(stripped_name)
end
end
end

0 comments on commit d51e5cf

Please sign in to comment.