Generate UPC Barcode with Number with rails - ruby-on-rails

I'm able to generate barcode by using "Barby" gem with "EAN13 & UPCA" But I need to show numbers with the barcode and I have no idea, what I'm missing in code.
Current Generated Barcode
Read out the barby gem documentation but no luck.
#barcode_value = "123456789123"
full_path = "public/Barcodes/"+#barcode_value+".png"
barcode = Barby::EAN13.new(#barcode_value)
File.open(full_path, 'wb') { |f| f.write barcode.to_png(:margin => 3, :xdim => 2, :height => 50) }
Generate Barcode with Number.
Required Barcode

The code you generated is a Code 39. The barcode you marked as required is a Code EAN 13, not UPC (those are not identical). One way to create such a code with Ruby would be using an API, e.g. https://mcapi.io/barcode/barcode-api-ruby.php
The API is hosted on RapidAPI; sample call to create your barcode:
# Ruby
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://mcapi-barcode.p.rapidapi.com/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["x-rapidapi-key"] = 'YOUR_API_KEY'
request["x-rapidapi-host"] = 'mcapi-barcode.p.rapidapi.com'
request.body = "{
\"data\": \"9501101530003\",
\"type\": 1,
\"size\": 2,
\"format\": \"pdf\"
}"
response = http.request(request)
The returned code will be in response.read_body as a base64 encoded PDF (posted as a screenshot since SO doesn't display PDFs):
EAN13 created with Ruby
(Disclaimer: We are the developers.)

Related

FTX.com REST API POST Authentication FAILS with Ruby on Rails and net/https

Hoping for some help as this one has me baffled...
I created a user account and API credentials at FTX.com.
They have an interesting Auth setup which is detailed here: https://docs.ftx.com/?python#authentication
They only provide code examples for python, javascript and c#, but I need to implement the integration on a RoR app.
Here's a link which also provides an example for both GET and POST calls: https://blog.ftx.com/blog/api-authentication/
I'm using:
ruby '3.0.1'
gem 'rails', '~> 6.1.4', '>= 6.1.4.1'
also,
require 'uri'
require 'net/https'
require 'net/http'
require 'json'
I got the authentication working for GET calls as follows:
def get_market
get_market_url = 'https://ftx.com/api/markets/BTC-PERP/orderbook?depth=20'
api_get_call(get_market_url)
end
def api_get_call(url)
ts = (Time.now.to_f * 1000).to_i
signature_payload = "#{ts}GET/api/markets"
key = ENV['FTX_API_SECRET']
data = signature_payload
digest = OpenSSL::Digest.new('sha256')
signature = OpenSSL::HMAC.hexdigest(digest, key, data)
headers = {
'FTX-KEY': ENV['FTX_API_KEY'],
'FTX-SIGN': signature,
'FTX-TS': ts.to_s
}
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.read_timeout = 1200
http.use_ssl = true
rsp = http.get(uri, headers)
JSON.parse(rsp.body)
end
This works great and I get the correct response:
=>
{"success"=>true,
"result"=>
{"bids"=>
[[64326.0, 2.0309],
...
[64303.0, 3.1067]],
"asks"=>
[[64327.0, 4.647],
...
[64352.0, 0.01]]}}
However, I can't seem to authenticate correctly for POST calls (even though as far as I can tell I am following the instructions correctly). I use the following:
def create_subaccount
create_subaccount_url = 'https://ftx.com/api/subaccounts'
call_body =
{
"nickname": "sub2",
}.to_json
api_post_call(create_subaccount_url, call_body)
end
def api_post_call(url, body)
ts = (Time.now.to_f * 1000).to_i
signature_payload = "#{ts}POST/api/subaccounts#{body}"
key = ENV['FTX_API_SECRET']
data = signature_payload
digest = OpenSSL::Digest.new('sha256')
signature = OpenSSL::HMAC.hexdigest(digest, key, data)
headers = {
'FTX-KEY': ENV['FTX_API_KEY'],
'FTX-SIGN': signature,
'FTX-TS': ts.to_s
}
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.read_timeout = 1200
http.use_ssl = true
request = Net::HTTP::Post.new(uri, headers)
request.body = body
response = http.request(request)
JSON.parse(response.body)
end
Also tried passing headers via request[] directly:
def api_post_call(url, body)
ts = (Time.now.to_f * 1000).to_i
signature_payload = "#{ts}POST/api/subaccounts#{body}"
key = ENV['FTX_API_SECRET']
data = signature_payload
digest = OpenSSL::Digest.new('sha256')
signature = OpenSSL::HMAC.hexdigest(digest, key, data)
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.read_timeout = 1200
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['FTX-KEY'] = ENV['FTX_API_KEY']
request['FTX-SIGN'] = signature
request['FTX-TS'] = ts.to_s
request.body = body
response = http.request(request)
JSON.parse(response.body)
end
This is the error response:
=> {"success"=>false, "error"=>"Not logged in: Invalid signature"}
My feeling is the issue is somewhere in adding the body to signature_payload before generating the signature via HMAC here..?:
signature_payload = "#{ts}POST/api/subaccounts#{body}"
Thinking this because, if I leave out #{body} here, like so:
signature_payload = "#{ts}POST/api/subaccounts"
the response is:
=> {"success"=>false, "error"=>"Missing parameter nickname"}
I have tried several iterations of setting up the POST call method using various different net/https examples but have had no luck...
I have also contacted FTX support but have had no response.
Would truly appreciate if anyone has some insight on what I am doing wrong here?
try this headers
headers = {
'FTX-KEY': ENV['FTX_API_KEY'],
'FTX-SIGN': signature,
'FTX-TS': ts.to_s,
'Content-Type' => 'application/json',
'Accepts' => 'application/json',
}
Here's a working example of a class to retrieve FTX subaccounts. Modify for your own purposes. I use HTTParty.
class Balancer
require 'uri'
require "openssl"
include HTTParty
def get_ftx_subaccounts
method = 'GET'
path = '/subaccounts'
url = "#{ENV['FTX_BASE_URL']}#{path}"
return HTTParty.get(url, headers: headers(method, path, ''))
end
def headers(*args)
{
'FTX-KEY' => ENV['FTX_API_KEY'],
'FTX-SIGN' => signature(*args),
'FTX-TS' => ts.to_s,
'Content-Type' => 'application/json',
'Accepts' => 'application/json',
}
end
def signature(*args)
OpenSSL::HMAC.hexdigest(digest, ENV['FTX_API_SECRET'], signature_payload(*args))
end
def signature_payload(method, path, query)
payload = [ts, method.to_s.upcase, "/api", path].compact
if method==:post
payload << query.to_json
elsif method==:get
payload << ("?" + URI.encode_www_form(query))
end unless query.empty?
payload.join.encode("UTF-8")
end
def ts
#ts ||= (Time.now.to_f * 1000).to_i
end
def digest
#digest ||= OpenSSL::Digest.new('sha256')
end
end

JSON parse javascript string

Trying to parse the json string with JSON.parse I get unexpected token error
require "net/http"
require "uri"
url = URI.parse("https://url-goes-here")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
req = Net::HTTP::Get.new(url.request_uri)
req['Accept'] = 'application/json'
res = Net::HTTP.new(url.host, url.port).start do |http|
http.request(req)
end
json = JSON.parse(res)
puts json
Data in response looks like JSONP, rather old method of doing rpc. Instead of returning plain JSON it outputs some_js_callback_function_name({here_goes: the_json}), usually there's also a parameter that controls the function name.
To get json from it - trim the function call before parsing:
json_data = res.body.gsub(/\A[^(]+\(/, '').gsub(/\)\s*\z/, '')
json = JSON.parse(json_data)

Making Ruby Net::HTTP::Get request with cookie

I'd like to open my stackoverflow.com page via ruby.
And I'd like to see it as if I am authenticated.
I took usr cookie from Google Chrome and created the following snippet:
require 'net/http'
require 'cgi'
url = "http://stackoverflow.com/users/1650525/alex-smolov"
uri = URI(url)
http = Net::HTTP.new(uri.host, 80)
request = Net::HTTP::Get.new(uri.request_uri)
cookie = CGI::Cookie.new("usr", "[my cookie is here]")
request['Cookie'] = cookie
r = http.request(request)
puts r.body
It does output a page, but I'm not authenticated there.
Is it possible to make a Net::HTTP::Get request in Ruby with cookie?
You need to call CGI::Cookie.to_s method.
request['Cookie'] = cookie.to_s
Try following code with / without .to_s.
require 'net/http'
require 'cgi'
uri = URI("http://httpbin.org/cookies")
http = Net::HTTP.new(uri.host, 80)
request = Net::HTTP::Get.new(uri.request_uri)
cookie1 = CGI::Cookie.new('usr', 'blah')
request['Cookie'] = cookie1.to_s # <---
r = http.request(request)
puts r.body
UPDATE
As the other answer mentioned, the resulted string is for server output. You need to strip out ; path= part.
CGI::Cookie.new('usr', 'value').to_s.sub(/; path=$/, '')
The accepted answer is imho incorrect. CGI::Cookie#to_s generates
string which should SERVER send to client, not something Net::HTTP should
use. It can be easily demonstrated:
[1] pry(main)> require 'cgi'
=> true
[2] pry(main)> CGI::Cookie.new('usr', 'value').to_s
=> "usr=value; path="
Code like this should work better.
require 'net/http'
require 'cgi'
uri = URI("http://httpbin.org/cookies")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
request['Cookie'] = "usr=#{CGI.encode cookie_value}"
r = http.request(request)
puts r.body
Or in case you have multiple cookies in a hash:
h = {'cookie1' => 'val1', 'cookie2' => 'val2'}
req['Cookie'] = h.map { |k,v| "#{k}=#{CGI.encode v}" } .join('; ')

Pretty print webservice response on ruby

I have to call a webservice but I don't know the format of the response. In any case (xml, json or html) I have to pretty print the response.
For example, if it is a xml I have to indent and show it properly. Same thing if it is a json. I have two problems here:
Detecting the format
Apply a format depending on the type.
I think that (1) is the most challenging problem.
Any help?
As several of the comments have suggested, the http header will contain the content type.
net/http has methods for this: http://ruby-doc.org/stdlib-2.0.0/libdoc/net/http/rdoc/Net/HTTP.html#method-i-head
require 'net/http'
require 'json'
require 'rexml/document'
response = nil
Net::HTTP.start('www.google.com', 80) {|http|
response = http.get('/index.html')
}
header = response['content-type'].split(';').first # => "text/html"
body = response.read_body
then you can conditionally operate:
if header == "text/html"
puts response.read_body
elsif header == "application/json"
puts JSON.pretty_generate(JSON.parse(body))
elsif header == "text/xml"
xml = REXML::Document.new body
out = ""
xml.write(out, 1)
puts out
end
Most of this was pulled form other SO posts:
pretty JSON: How can I "pretty" format my JSON output in Ruby on Rails?
pretty XML: How to beautify xml code in rails application
This is the code that I finally used:
raw_response = response.body
response_html = ''
if response.header['Content-Type'].include? 'application/json'
tokens = CodeRay.scan(raw_response, :json)
response_html = tokens.div
elsif response.header['Content-Type'].include? 'application/xml'
tokens = CodeRay.scan(raw_response, :xml)
response_html = tokens.div
elsif response.header['Content-Type'].include? 'text/html'
tokens = CodeRay.scan(raw_response, :html)
response_html = tokens.div
else
response_html = '<div>' + raw_response + '</div>'
end
It's using the coderay gem.

get ebay time in rails

I've been looking around a bit for how to get the time off of ebay..
I don't want to use SAVON because... well it didn't work..
So I'm trying to use net/http, just to get the time. (for now)
Here's what I got so far.
def get_ebay_time
require "net/http"
require "uri"
devName = 000000000
appName = 000000000
certName = 000000000
authToken = 0000000000
url = URI.parse("https://api.ebay.com/ws/api.dll")
req = Net::HTTP::Post.new(url.path)
req.add_field("X-EBAY-API-COMPATIBILITY-LEVEL", "759")
req.add_field("X-EBAY-API-DEV-NAME", devName)
req.add_field("X-EBAY-API-APP-NAME", appName)
req.add_field("X-EBAY-API-CERT-NAME", certName)
req.add_field("X-EBAY-API-SITEID", "0")
req.add_field("X-EBAY-API-CALL-NAME", "GeteBayOfficialTime")
req.body = '<?xml version="1.0" encoding="utf-8"?>'+
'<GeteBayOfficialTimeRequest xmlns="urn:ebay:apis:eBLBaseComponents">'+
'<RequesterCredentials>'+
"<eBayAuthToken>#{authToken}</eBayAuthToken>"+
'</RequesterCredentials>'+
'</GeteBayOfficialTimeRequest>?'
http = Net::HTTP.new(url.host, url.port)
res = http.start do |http_runner|
http_runner.request(req)
end
return res.body
end
APIs wrappers are developed to help :)
Please use eBay4r and same on github: up_the_irons/ebay4r
require 'rubygems'
gem 'ebay'
# Put your credentials in this file
load('myCredentials.rb')
# Create new eBay caller object. Omit last argument to use live platform.
eBay = EBay::API.new($authToken, $devId, $appId, $certId, :sandbox => true)
resp = eBay.GeteBayOfficialTime
puts "Hello, World!"
puts "The eBay time is now: #{resp.timestamp}"
it didn't take me as long to find this as I thought.
in the bottom bit, I added SSL handling
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = 0
res = http.start do |http_runner|
http_runner.request(req)
end
return res.body

Resources