Commit 38a8add9 authored by Jyrki's avatar Jyrki 🐾

Add Bad Dragon API client

parent 0da8a50c
version: 1.0
shards:
crest:
github: mamantoha/crest
version: 0.14.0
telegram_bot:
github: hangyas/telegram_bot
commit: 722bab24876d13a661f513b09c4569916f7a81c1
......
......@@ -9,6 +9,8 @@ targets:
main: src/main.cr
dependencies:
crest:
github: mamantoha/crest
telegram_bot:
github: hangyas/telegram_bot
......
require "crest"
require "../../../application"
require "../../../errors"
require "../entities/product"
require "../entities/toy"
require "./paginated_response"
module BadDragon
module API
class Client
API_BASE = "https://bad-dragon.com/api"
def initialize(@api_base = API_BASE)
@api = Crest::Resource.new(@api_base)
end
# performs a GET /products request
# @return (BadDragon::Entity::Product)
def products
response = @api["/products"].get
Array(BadDragon::Entities::Product).from_json(response.body)
rescue Crest::RequestFailed
raise Errors::HTTPError.new("HTTP request failed")
end
def inventory_toys
fetch_inventory_toys
end
private def fetch_inventory_toys(page = 1)
Application.logger.debug("fetching inventory toys - page #{page}")
response = @api["/inventory-toys"].get(
params: {
:limit => 60,
:page => page,
"sort[field]" => "created",
"sort[direction]" => "desc",
"price[min]" => 0,
"price[max]" => 300,
}
)
paginated_response = PaginatedResponse::Toys.from_json(response.body)
return [] of BadDragon::Entities::Toy if paginated_response.toys.empty?
paginated_response.toys + fetch_inventory_toys(page + 1)
rescue e : Crest::RequestFailed
raise Errors::HTTPError.new("HTTP request failed", cause: e)
end
end
end
end
require "json"
require "../entities/toy"
module BadDragon
module API
module PaginatedResponse
private macro paginated_response_class(array_name, array_type)
class {{ array_name.capitalize.id }}
JSON.mapping(
page: Int32,
limit: Int32,
size: Int32,
total: Int32,
totalPages: Int32,
{{ array_name }}: Array({{ array_type }})
)
end
end
paginated_response_class "toys", BadDragon::Entities::Toy
end
end
end
require "json"
module BadDragon
module Entities
# A Product represents... a product. Who would have thought?
class Product
JSON.mapping(
sku: String,
name: String,
type: String,
title: String,
furry_title: {type: String?, key: "furryTitle"}
)
end
end
end
require "json"
require "../size"
module BadDragon
module Entities
# A toy is a ready-made toy.
class Toy
JSON.mapping(
id: Int32,
sku: String,
price: Int32,
flop_reason: String,
type: String,
size: BadDragon::Size,
firmness: String,
cumtube: Int32,
suction_cup: Int32,
color: String,
color_type: String,
color1: String,
color2: String,
color3: String,
original_text: String,
original_toy_id: Int32,
original_order_id: Int32,
created: {type: Time, converter: Time::Format.new("%FT%T")},
updated: {type: Time?, converter: Time::Format.new("%FT%T")},
images: Array(Toy::Image)
)
class Image
JSON.mapping(
id: Int32,
inventory_toy_id: {type: Int32, key: "inventoryToyId"},
full_filename: {type: String, key: "fullFilename"},
thumb_filename: {type: String, key: "thumbFilename"},
created: {type: Time, converter: Time::Format.new("%FT%T")}
)
end
end
end
end
module BadDragon
enum Size
Onesize
Mini
Small
Medium
Large
Extralarge
end
end
......@@ -8,4 +8,6 @@ module Errors
class GenericError < Base; end
class ConfigurationError < Base; end
class HTTPError < Base; end
end
require "./cli_commands/start_bot"
require "./cli_commands/help"
{% unless flag?(:release) %}
require "./cli_commands/debug"
{% end %}
module UseCase
module CliCommands
COMMANDS = {{UseCase::CliCommands::Base.subclasses}}.map do |subclass|
......
require "./base"
require "../../../bad_dragon/api/client"
module UseCase
module CliCommands
class Debug < CliCommands::Base
def self.command_name
"debug"
end
def self.description
"Whatever I'm currently debugging/testing. (non-release builds only)"
end
def call(_argv)
client = BadDragon::API::Client.new
toys = client.inventory_toys
pp toys.map(&.type).uniq
pp toys.map(&.size).uniq
products = client.products
pp products.map(&.type).uniq
rescue e
puts e.cause
puts e.cause.as(Crest::RequestFailed).response.body
puts e.cause.as(Crest::RequestFailed).response.request.url
raise e
end
end
end
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