simpleshop_theme/lib/simpleshop_theme/printify/client.ex
Jamey Greenwood d4dbd8998f fix: resolve compilation warnings and update tests to match implementation
- Remove unused generate_mood/1, generate_typography/1, generate_shape/1,
  generate_density/1 functions from CSSGenerator (now handled via CSS
  data attributes)
- Prefix unused _opts parameters in Printify.Client
- Remove unused created_products variable from MockupGenerator
- Update CSSGeneratorTest to test actual generated CSS (accent colors,
  font size scale, layout width, etc.)
- Update PresetsTest to match 8 presets (not 9)
- Fix PreviewDataTest to accept local image paths
- Update ThemeLiveTest to use correct selectors and match actual UI
2026-01-15 22:36:15 +00:00

183 lines
4.3 KiB
Elixir

defmodule SimpleshopTheme.Printify.Client do
@moduledoc """
HTTP client for the Printify API.
Handles authentication and provides low-level API access.
Requires PRINTIFY_API_TOKEN environment variable to be set.
"""
@base_url "https://api.printify.com/v1"
@doc """
Get the API token from environment.
"""
def api_token do
System.get_env("PRINTIFY_API_TOKEN") ||
raise "PRINTIFY_API_TOKEN environment variable is not set"
end
@doc """
Make a GET request to the Printify API.
"""
def get(path, _opts \\ []) do
url = @base_url <> path
case Req.get(url, headers: auth_headers(), receive_timeout: 30_000) do
{:ok, %Req.Response{status: status, body: body}} when status in 200..299 ->
{:ok, body}
{:ok, %Req.Response{status: status, body: body}} ->
{:error, {status, body}}
{:error, reason} ->
{:error, reason}
end
end
@doc """
Make a POST request to the Printify API.
"""
def post(path, body, _opts \\ []) do
url = @base_url <> path
case Req.post(url, json: body, headers: auth_headers(), receive_timeout: 60_000) do
{:ok, %Req.Response{status: status, body: body}} when status in 200..299 ->
{:ok, body}
{:ok, %Req.Response{status: status, body: body}} ->
{:error, {status, body}}
{:error, reason} ->
{:error, reason}
end
end
@doc """
Make a DELETE request to the Printify API.
"""
def delete(path, _opts \\ []) do
url = @base_url <> path
case Req.delete(url, headers: auth_headers(), receive_timeout: 30_000) do
{:ok, %Req.Response{status: status, body: body}} when status in 200..299 ->
{:ok, body}
{:ok, %Req.Response{status: status}} when status == 204 ->
{:ok, nil}
{:ok, %Req.Response{status: status, body: body}} ->
{:error, {status, body}}
{:error, reason} ->
{:error, reason}
end
end
@doc """
Get all shops for the authenticated account.
"""
def get_shops do
get("/shops.json")
end
@doc """
Get the first shop ID for the account.
"""
def get_shop_id do
case get_shops() do
{:ok, shops} when is_list(shops) and length(shops) > 0 ->
{:ok, hd(shops)["id"]}
{:ok, []} ->
{:error, :no_shops}
error ->
error
end
end
@doc """
Get all blueprints (product types) from the catalog.
"""
def get_blueprints do
get("/catalog/blueprints.json")
end
@doc """
Get print providers for a specific blueprint.
"""
def get_print_providers(blueprint_id) do
get("/catalog/blueprints/#{blueprint_id}/print_providers.json")
end
@doc """
Get variants for a specific blueprint and print provider.
"""
def get_variants(blueprint_id, print_provider_id) do
get("/catalog/blueprints/#{blueprint_id}/print_providers/#{print_provider_id}/variants.json")
end
@doc """
Get shipping information for a blueprint/provider combination.
"""
def get_shipping(blueprint_id, print_provider_id) do
get("/catalog/blueprints/#{blueprint_id}/print_providers/#{print_provider_id}/shipping.json")
end
@doc """
Upload an image to Printify via URL.
"""
def upload_image(file_name, url) do
post("/uploads/images.json", %{
file_name: file_name,
url: url
})
end
@doc """
Create a product in a shop.
"""
def create_product(shop_id, product_data) do
post("/shops/#{shop_id}/products.json", product_data)
end
@doc """
Get a product by ID.
"""
def get_product(shop_id, product_id) do
get("/shops/#{shop_id}/products/#{product_id}.json")
end
@doc """
Delete a product from a shop.
"""
def delete_product(shop_id, product_id) do
delete("/shops/#{shop_id}/products/#{product_id}.json")
end
@doc """
Download a file from a URL to a local path.
"""
def download_file(url, output_path) do
case Req.get(url, into: File.stream!(output_path), receive_timeout: 60_000) do
{:ok, %Req.Response{status: status}} when status in 200..299 ->
{:ok, output_path}
{:ok, %Req.Response{status: status}} ->
File.rm(output_path)
{:error, {:http_error, status}}
{:error, reason} ->
File.rm(output_path)
{:error, reason}
end
end
defp auth_headers do
[
{"Authorization", "Bearer #{api_token()}"},
{"Content-Type", "application/json"}
]
end
end