Commit fb3c9fb4 authored by Jose Ernesto Suarez's avatar Jose Ernesto Suarez

Primera version todavia no pasa los tests de configuracion

parent ccacf591
.DS_Store
TO-DO
\ No newline at end of file
* @jernestosuarez
\ No newline at end of file
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at ernesto@wedoops.io. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
FROM ruby:2.7
WORKDIR /app
ADD Gemfile /app/Gemfile
#ADD Gemfile.lock /app/Gemfile.lock
ADD . /app
RUN bundle install --system
RUN rake spec
RUN gem build zoholib.gemspec
#TO-DO: Get automatically the version number
RUN gem install zoholib-$(cat /app/lib/zoholib/version.rb|grep VERSION|cut -d '=' -f 2|sed "s/'//g" | sed "s/ //g").gem
CMD ["ruby", "main.rb"]
\ No newline at end of file
# frozen_string_literal: true
source 'https://rubygems.org'
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
## Specify your gem's dependencies in zoholib.gemspec
gemspec
gem 'httparty','~> 0.18.0'
gem 'http','~> 4.4.0'
gem 'logger','~> 1.4.2'
gem 'savon','~> 2.12.0'
gem 'sib-api-v3-sdk','~> 5.3.0'
gem 'launchy','~> 2.5.0'
\ No newline at end of file
PATH
remote: .
specs:
zoholib (0.0.1b)
GEM
remote: https://rubygems.org/
specs:
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
akami (1.3.1)
gyoku (>= 0.4.0)
nokogiri
builder (3.2.4)
diff-lcs (1.3)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
ethon (0.12.0)
ffi (>= 1.3.0)
ffi (1.12.2)
ffi-compiler (1.0.1)
ffi (>= 1.0.0)
rake
gyoku (1.3.1)
builder (>= 2.1.2)
http (4.4.1)
addressable (~> 2.3)
http-cookie (~> 1.0)
http-form_data (~> 2.2)
http-parser (~> 1.2.0)
http-cookie (1.0.3)
domain_name (~> 0.5)
http-form_data (2.3.0)
http-parser (1.2.1)
ffi-compiler (>= 1.0, < 2.0)
httparty (0.18.0)
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
httpi (2.4.4)
rack
socksify
json (2.3.0)
launchy (2.5.0)
addressable (~> 2.7)
logger (1.4.2)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2019.1009)
mini_portile2 (2.4.0)
multi_xml (0.6.0)
nokogiri (1.10.9)
mini_portile2 (~> 2.4.0)
nori (2.6.0)
public_suffix (4.0.4)
rack (2.2.2)
rake (13.0.1)
rspec (3.9.0)
rspec-core (~> 3.9.0)
rspec-expectations (~> 3.9.0)
rspec-mocks (~> 3.9.0)
rspec-core (3.9.1)
rspec-support (~> 3.9.1)
rspec-expectations (3.9.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-mocks (3.9.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-support (3.9.2)
savon (2.12.0)
akami (~> 1.2)
builder (>= 2.1.2)
gyoku (~> 1.2)
httpi (~> 2.3)
nokogiri (>= 1.8.1)
nori (~> 2.4)
wasabi (~> 3.4)
sib-api-v3-sdk (5.3.0)
json (~> 2.1, >= 2.1.0)
typhoeus (~> 1.0, >= 1.0.1)
socksify (1.7.1)
typhoeus (1.3.1)
ethon (>= 0.9.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
wasabi (3.5.0)
httpi (~> 2.0)
nokogiri (>= 1.4.2)
PLATFORMS
ruby
DEPENDENCIES
bundler (~> 1.15)
http (~> 4.4.0)
httparty (~> 0.18.0)
launchy (~> 2.5.0)
logger (~> 1.4.2)
rake (~> 13.0.1)
rspec (~> 3.0)
savon (~> 2.12.0)
sib-api-v3-sdk (~> 5.3.0)
zoholib!
BUNDLED WITH
1.16.4
The MIT License (MIT)
Copyright (c) 2019 ChaingoTech SL
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# zoholib # Zoho Library
\ No newline at end of file
# frozen_string_literal: true
require 'bundler/gem_tasks'
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)
task default: :spec
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'bundler/setup'
require 'zoholib'
# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.
# (If you use this, don't forget to add pry to your Gemfile!)
# require "pry"
# Pry.start
require 'irb'
IRB.start(__FILE__)
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
set -vx
bundle install
# Do any other automated setup that you need to do here
# frozen_string_literal: true
require 'zoholib/configuration'
require 'zoholib/version'
require 'zoholib/zoho_request'
require 'zoholib/response'
require 'zoholib/grant_request'
require 'zoholib/refresh_request'
require 'zoholib/authorization_request'
require 'zoholib/adamo_client'
require 'zoholib/b12_client'
require 'zoholib/zoho_basic_client'
require 'zoholib/zoho_client'
##
# This library is used for access Zoho
module Zoholib
class << self
attr_accessor :configuration
end
def self.configuration
puts "Init connfig"
@configuration ||= Configuration.new
end
def self.reset
@configuration = Configuration.new
end
def self.configure
puts "configuring"
yield(configuration)
end
end
require 'http'
require 'pp'
require 'json'
require 'logger'
require 'date'
module Zoholib
class AdamoClient
def initialize(options={})
@logger = Logger.new(STDOUT)
@http = HTTP
.use(logging: {logger: @logger})
.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache",
"accept" => "application/json",
"postman-token" => "8b126eb1-0de6-4a10-d78d-1fb417fb23b0",
"x-apikey" => "Af8cbSpgkAReYqBs66DHJUkf2MJW3d9JDFVJhWe4U5haD")
end
def cobertura_project
count=2
url = "https://coverage-dump.adamo.es/v1/cobertura-project/#{count}?limit=500"
return HTTP.use(logging: {logger: @logger})
.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache",
"accept" => "application/json",
"postman-token" => "8b126eb1-0de6-4a10-d78d-1fb417fb23b0",
"x-apikey" => "Af8cbSpgkAReYqBs66DHJUkf2MJW3d9JDFVJhWe4U5haD").get(url)
end
def cobertura
page=1
limit=50000
#date=Date.parse("06-04-2020").strftime("%Y%m%d")
date=Date.today.prev_day.strftime("%Y%m%d")
resultado_final=Array.new
r=Array.new
loop do
print "#{page} "
url= "https://coverage-dump.adamo.es/v1/cobertura/#{page}?limit=#{limit}&date=#{date}"
#.use(logging: {logger: @logger})
resultado= HTTP.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache",
"accept" => "application/json",
"postman-token" => "8b126eb1-0de6-4a10-d78d-1fb417fb23b0",
"x-apikey" => "zYkWN38SYH6hr2Ixq75xvDENl6hrYOvxx0FxLvPD7BUe6").get(url)
r= JSON.parse(resultado, symbolize_names: true)
resultado_final.concat(r)
page+=1
print "(#{r.size}/#{resultado_final.size}),"
break if r.size < limit || page >2
end
puts resultado_final.size
return resultado_final
end
def projects
page=1
limit=50000
#date=Date.today.prev_day.strftime("%Y%m%d")
date=Date.parse("01-01-2011").strftime("%Y%m%d")
resultado_final=Array.new
r=Array.new
loop do
print "#{page} "
url= "https://coverage-dump.adamo.es/v1/cobertura-project/#{page}?limit=#{limit}&date=#{date}"
#.use(logging: {logger: @logger})
resultado= HTTP.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache",
"accept" => "application/json",
"postman-token" => "8b126eb1-0de6-4a10-d78d-1fb417fb23b0",
"x-apikey" => "zYkWN38SYH6hr2Ixq75xvDENl6hrYOvxx0FxLvPD7BUe6").get(url)
r= JSON.parse(resultado, symbolize_names: true)
resultado_final.concat(r)
page+=1
print "(#{r.size}/#{resultado_final.size}),"
break if r.size < limit || page >2
end
puts resultado_final.size
return resultado_final
end
private
def get_params(url,payload)
@http.get(url, :params => payload)
end
def get(url)
@http.get(url)
end
end
end
\ No newline at end of file
#require 'zoho_request'
#require './lib/grant_request'
#En algun momento tenemos que abrir un navegador
require 'launchy'
require 'socket'
module Zoholib
class AuthorizationRequest < Zoholib::ZohoRequest
# Sin en algun momento se quiere evitar el encode de URL
# he aqui un truco
# En esta ocasion lo gastamos porque los scopes vienen separados por una coma que hace que falle
query_string_normalizer proc { |query|
query.map do |key, value|
[value].flatten.map {|v| "#{key}=#{v}"}.join('&')
end.join('&')
}
def initialize(options={})
#build_url(options)
@logger = ::Logger.new(STDOUT)
@options = Hash.new
options.merge!({response_type: 'code',access_type: 'offline',redirect_uri: 'http://localhost:8000/auth/callback'})
@grant_token = options[:grant_token]
#@options.merge!(grant_token: options[:grant_token] )
options.delete(:grant_token)
#Al iniciar este objeto estas opciones solo tienen sentido en query
@options.merge!(query: options)
@logged_in = false
end
def authorize(options={})
unless @options[:refresh_token].nil?
@logger.warn "Refresh token already exists! Ignoring call"
return @options
end
#El prompt consent obliga a mostrar la pantalla de consent
# de esta manera se consigue que devuelva siempre el
# refresh token que es valido para siempre
if options.has_key?(:force_prompt)
#Si esta opcion la establecemos a true entonces se forzara el consent
@options[:query].merge!(prompt:"consent") if options[:force_prompt]
end
#pp @options
get_grant_token if @grant_token.nil?
tokens = get_grant_request
#pp tokens
raise "Unknown error! I cannot find the refresh_token! try to force prompt" if tokens[:refresh_token].nil?
@options.merge!(tokens)
# Decido devolver tokens unicamente, dejo aqui los comentarios antiguos
# #Ya no necesitamos estas opciones dentro de query, las sacamos fuera
# # Para devolverselas a nuestro padre
# @options.merge!(@options[:query])
# @options.delete(:query)
# # El code solo tiene un uso y caducal al minuto, asi que
# # Lo eliminamos tambien
# @options.delete(:code)
@options.delete(:follow_redirects)
return tokens
end
def read_socket(port=8000)
@logger.info "Reading socket response"
server = TCPServer.new port
while session = server.accept
request = session.gets
match = /code=\d{4}\.\w{32}\.\w{32}/.match(request)
if match
code = match.to_s.split("=").last
end
session.print "HTTP/1.1 200\r\n" # 1
session.print "Content-Type: text/html\r\n" # 2
session.print "\r\n" # 3
session.print "Thank you! The time is #{Time.now}" #4
session.close
break
end
server.close
return code
end
def get_grant_token
# Ejecuta lo descrito en el paso 2 del ZOHO OAUTH https://www.zoho.com/crm/developer/docs/api/auth-request.html
# Para recibir el codigo que nos permitira generar los tokens
# Atencion, este metodo abre un navegador para autorizar y un socket en el puerto 8000 para recibir el codigo tras
# la aceptacion de permisos
@options.merge!(follow_redirects: false)
response=self.class.get('/auth', @options)
# puts "RESPONSE CODE:#{response.code}"
if response.code >= 300 && response.code < 400
redirect_url = response.headers['location']
Launchy.open(redirect_url)
grant_token=read_socket
@logger.info "GRANT TOKEN: #{grant_token}"
@grant_token = grant_token
return true
end
raise "Unable to get the grant token!"
end
def get_grant_request
# Prepara la llamada descrita en el paso 3 del ZOHO OAUTH https://www.zoho.com/crm/developer/docs/api/access-refresh.html
# Para recibir access_token y refresh_token
raise "Unable to get a grant request without grant token!" if @grant_token.nil?
options_grant_request = @options.dup
options_grant_request.delete(:grant_token)
options_grant_request.delete(:follow_redirects)
options_grant_request[:query].delete(:response_type)
options_grant_request[:query].delete(:scope)
options_grant_request[:query].delete(:access_type)
options_grant_request[:query].merge!(code: @grant_token)
grant_request=Zoholib::GrantRequest.new(options_grant_request)
result=grant_request.token
# pp result
raise "Error #{result[:error]}" unless result[:error].nil?
return result
end
end
end
\ No newline at end of file
require 'http'
require 'pp'
require 'json'
require 'logger'
require 'date'
require 'savon'
module Zoholib
class B12Client
def initialize(options={})
@logger = Logger.new(STDOUT)
initialize_client
@client.call(:lead)
end
def send_lead(lead)
@logger.info("Sending lead: #{lead[:idvar]} tlf:#{lead[:Telefono]}")
#pp lead
#puts ":.................:"
begin
response = @client.call(:lead) do
message(lead)
end
rescue Exception => e
@logger.error("Error sending the lead: #{e.message}")
return nil
end
begin
b12_id = response.body[:lead_response][:return]
unless b12_id.match(/^\d*$/)
raise "Error de B12, envio #{lead[:idvar]} tlf:#{lead[:Telefono]} duplicado (#{b12_id})" if b12_id == "-1"
raise "Error interno de B12, error #{b12_id} recibido"
end
rescue Exception => e
@logger.error("Error getting the LEAD ID: #{e.message}")
return nil
end
return b12_id
end
private
def initialize_client
@client = Savon.client do
wsdl 'http://panel.digitalion.com/wss/cobalt.lead.php?wsdl'
pretty_print_xml true
#convert_request_keys_to :camelcase
log false
log_level :info
end
end
end
end
\ No newline at end of file
# frozen_string_literal: true
module Zoholib
##
# This class permits the configuration of the Zoholib
class Configuration
attr_accessor :client_id, :client_secret, :scope, :refresh_token
def initialize
@client_id = nil
@client_secret = nil
@scope = nil
@refresh_token = nil
end
end
end
#require './lib/zoho_request'
module Zoholib
class GrantRequest < Zoholib::ZohoRequest
#base_uri "https://accounts.zoho.com/oauth/v2/token"
#headers: {"Authorization" => "Token token=\"111\""}
def initialize(options={})
@logger = ::Logger.new(STDOUT)
@logged_in = false
@options = options
end
def token(options={})
# Esta funcion se llama desde Zoholib::AuthorizationRequest
# Ejecuta lo descrito en https://www.zoho.com/crm/developer/docs/api/access-refresh.html
@options[:query].merge!(grant_type: "authorization_code")
@options.merge!(:logger => @logger)
response=self.class.post('/token',@options)
JSON.parse(response.body,symbolize_names: true)
end
end
end
\ No newline at end of file
#require './lib/zoho_request'
module Zoholib
class RefreshRequest < Zoholib::ZohoRequest
# Sin en algun momento se quiere evitar el encode de URL
# he aqui un truco
#query_string_normalizer proc { |query|
# query.map do |key, value|
# [value].flatten.map {|v| "#{key}=#{v}"}.join('&')
# end.join('&')
# }
def initialize(options={})
options.merge!(grant_type: "refresh_token")
@options={:query => options}
end
def get_token
self.class.post("/token",@options)
end
end
end
\ No newline at end of file
module Zoholib
module Zoho
class Response
attr_accessor :body, :status
def initialize(output = nil)
# puts "Response initialized"
@body=nil
@status=nil
@output=nil
begin
# No parseo con symbolize porque se queda al a partir de la tercera capa
raw=parse(output)
rescue Exception => e
puts "_______ ERROR PARSE_____"
puts e.backtrace
raise "#{__method__} Error parsing JSON: #{e.message}"
end
return @body
end
def success?
@status[:execution_code] == "success"
end
def id
@status[:id]
end
private
def valid_json?(string)
!!JSON.parse(string)
rescue JSON::ParserError
false
end
def standarize_collection(cadena)
# Aqui deberia controlar cuando es array y cuando elemento o devolver siempre un array de elementos
#puts "Standarizing this"
# puts "_------------------- INIT"
# puts cadena
#puts "_------------------- END"
if valid_json?("[#{cadena}]")
@output = Array
"[#{cadena}]"
else
@output = String
cadena
end
end
def parse(string,options = nil)
# For parsing JSON
begin
raw = JSON.parse(string,options)
rescue Exception => e
puts "#{__method__} Error del parser #{e.message} "
end
begin
generate_metadata(raw)
resultado = raw
rescue Exception => e
puts "_______ ERROR METADATAAA"
puts e.backtrace
puts "#{__method__} Error generando metadata: #{e.message} "
end
#raise "El parseo de JSON ha generado un resultado invalido!" unless valid_json?(resultado)
serializar_output(raw)
return @body
end
def generate_metadata(raw)
puts "Generating metadata!"
# Informacion de la llamada
@execution_code="#{raw["code"]}"
puts "Execution code #{@execution_code}"
@output_type="#{raw["details"]["output_type"]}"
puts "OutputType #{@output_type}"
@id="#{raw["details"]["id"]}"
puts "ID #{@id}"
@message="#{raw["message"]}"
puts "Message #{@message}"
@status = {
:execution_code => @execution_code,
:id => @id,
:output_type => @output_type,
:message => @message
}
puts "Initialized with:"
return @status
end
def serializar_output(raw)
resultado=standarize_collection(raw["details"]["output"])
begin
if @output == Array
output_serializado=JSON.parse(resultado,:symbolize_names => true)
else
output_serializado = {body: resultado}
end
rescue Exception => e
raise "#{__method__} Error serilizando la respuesta!: #{e.message}"
end
####
#Compruebo que a la salida doy un Hash valido pasandolo a JSON y validandolo
raise "El parseo de JSON ha generado un resultado invalido!" unless valid_json?(output_serializado.to_json)
@body = output_serializado
end
end
end
end
\ No newline at end of file
# frozen_string_literal: true
module Zoholib
VERSION = '0.0.1b'
end
require 'pp'
require 'json'
require 'logger'
#require 'date'
require 'httparty'
#require './lib/refresh_request'
#require './lib/authorization_request'
module Zoholib
class ZohoBasicClient
include HTTParty
base_uri 'https://www.zohoapis.com/crm/v2/'
def initialize(options={})
#Es un cliennte basico que trabaja a partir de refresh_tokens
@logger = ::Logger.new(STDOUT)
@logged_in = false
@options = options
@token = nil
end
def login
unless @options.has_key?(:refresh_token)
#En estos casos necesito mi refresh_token primero
auth_request=Zoholib::AuthorizationRequest.new(@options)
# Ojo esta opcion fuerza que siempre salga la pantalla
# de credenciales
result=auth_request.authorize({force_prompt: true})
@options.merge!(result)
#El refresh token habria que persisitirlo para
#evitar tener que cogerlo de nuevo
end
request= Zoholib::RefreshRequest.new(@options)
response=request.get_token
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
unless response[:access_token].nil?
@logged_in = true
@token = response[:access_token]
else
@logged_in = false
@token = nil
end
return @logged_in
end
def read_all(url,params={})
# ojo, maxrecords no tiene en cuenta cuantos registros se descaargan
# en cada ocasion por lo que puede devolver registros de mas
# como resto de la llamada anterior
page=1
maxrecords=-1
result = Hash.new
result[:data] = Array.new
params.delete(:page) if params.has_key?(:page)
if params.has_key?(:max_records)
maxrecords = params[:max_records]
params.delete(:max_records)
end
loop do
params.merge!(page: page)
response=read(url,params)
if response[:info][:more_records] == true
page+=1
result[:data].concat(response[:data])
break if maxrecords > 0 && result[:data].size >= maxrecords
else
break
end
end
return result
end
def read(url,params=nil)
self.login unless @logged_in
options = {}
options[:query] = params unless params.nil?
options.merge!(build_header)
response=self.class.get("/#{url}",options)
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
return response
end
def write(url,data)
raise "Invalid JSON!" unless valid_json?(data)
self.login unless @logged_in
options = {}
#Ojo, aqui tal vez deberiamos coprobar que viene con la forma :data => [:coleccion]
options[:body]=data
options.merge!(build_header)
response=self.class.post("/#{url}",options)
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
end
def update(url,data)
raise "Invalid JSON!" unless valid_json?(data)
self.login unless @logged_in
options = {}
#Ojo, aqui tal vez deberiamos coprobar que viene con la forma :data => [:coleccion]
options[:body]=data
options.merge!(build_header)
response=self.class.put("/#{url}",options)
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
end
def query(coql)
self.login unless @logged_in
options = {}
#Ojo, aqui tal vez deberiamos coprobar que viene con la forma :data => [:coleccion]
options[:body] = {:select_query => coql}.to_json
# options[:query]={scope:"ZohoCRM.coql.READ,ZohoCRM.modules.all"}
options[:logger]=@logger
options.merge!(build_header)
response=self.class.post("/coql",options)
#response=self.class.post("/coql?scope=ZohoCRM.modules.ALL,ZohoCRM.coql.read",options)
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
end
def query_all(coql,params={})
# ojo, maxrecords no tiene en cuenta cuantos registros se descaargan
# en cada ocasion por lo que puede devolver registros de mas
# como resto de la llamada anterior
page=1
maxrecords=-1
result = Hash.new
result[:data] = Array.new
params.delete(:page) if params.has_key?(:page)
if params.has_key?(:max_records)
maxrecords = params[:max_records]
params.delete(:max_records)
end
loop do
params.merge!(page: page)
response=self.query(coql)
return response if response[:status] == "error"
if response[:info][:more_records] == true
page+=1
result[:data].concat(response[:data])
break if maxrecords > 0 && result[:data].size >= maxrecords
else
break
end
@logger.debug("#{result[:data].size} records")
@logger.debug("#{result[:data].last} ")
end
return result
end
private
def build_header
{:headers => { "Authorization" => "Zoho-oauthtoken #{@token}"}}
end
def valid_json?(json)
JSON.parse(json)
return true
rescue JSON::ParserError => e
return false
end
end
end
This diff is collapsed.
require 'httparty'
require 'json'
module Zoholib
class ZohoRequest
include HTTParty
#debug_output $stdout
base_uri "https://accounts.zoho.com/oauth/v2/"
#https://accounts.zoho.com/oauth/v2/auth?
#https://accounts.zoho.com/oauth/v2/token?
headers 'Content-Type' => 'application/json'
attr_reader :subdomain, :uri
end
end
\ No newline at end of file
# frozen_string_literal: true
require 'bundler/setup'
require 'zoholib'
RSpec.configure do |conf|
conf.before(:all) do
Zoholib.configure do |config|
config.client_id = "client_id"
config.client_secret = "client_secret"
config.scope = "scope"
config.refresh_token = "refresh_token"
end
end
conf.add_formatter(:documentation)
# Enable flags like --only-failures and --next-failure
conf.example_status_persistence_file_path = '.rspec_status'
# Disable RSpec exposing methods globally on `Module` and `main`
conf.disable_monkey_patching!
conf.expect_with :rspec do |c|
c.syntax = :expect
end
end
require './lib/zoholib'
RSpec.describe Zoholib do
it 'has a version number' do
expect(Zoholib::VERSION).not_to be nil
end
it 'does something useful' do
expect(true).to eq(true)
end
describe 'Configuration' do
it 'The configuration shuld be a Zoholib::Configuration' do
expect(Zoholib.configuration).to be_a_kind_of(Zoholib::Configuration)
end
it 'The client_id is a string' do
expect(Zoholib.configuration.client_id).to be_an(String)
end
it 'The client_secret is a string' do
expect(Zoholib.configuration.client_secret).to be_an(String)
end
it 'The scopes is a string' do
expect(Zoholib.configuration.scopes).to be_an(String)
end
it 'The refresh_token is a string' do
expect(Zoholib.configuration.refresh_token).to be_an(String)
end
end
end
\ No newline at end of file
# frozen_string_literal: true
lib = File.expand_path('lib', __dir__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'zoholib/version'
Gem::Specification.new do |spec|
spec.name = 'zoholib'
spec.version = Zoholib::VERSION
spec.date = '2020-04-25'
spec.authors = ['Wedoops.io']
spec.email = 'wedoops@wedoops.io'
spec.summary = 'Zoho Library'
spec.description = 'A library for interact with ZOHO REST API'
spec.homepage = 'http://www.wedoops.io'
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'] = "TODO: Set to 'http://mygemserver.com'"
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|
f.match(%r{^(test|spec|features)/})
end
spec.bindir = 'exe'
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ['lib']
spec.add_development_dependency 'bundler', '~> 1.15'
spec.add_development_dependency 'rake', '~> 13.0.1'
spec.add_development_dependency 'rspec', '~> 3.0'
#spec.add_development_dependency 'httparty','~> 0.18.0'
#spec.add_development_dependency 'http','~> 4.4.0'
#spec.add_development_dependency 'logger','~> 1.4.2'
#spec.add_development_dependency 'savon','~> 2.12.0'
#spec.add_development_dependency 'sib-api-v3-sdk','~> 5.3.0'
#spec.add_development_dependency 'launchy','~> 2.5.0'
#
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment