- 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
183 lines
4.3 KiB
Elixir
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
|