defmodule Mix.Tasks.GenerateMockups do @moduledoc """ Generates product mockups using the Printify API. This task automates the creation of product mockups for the SimpleshopTheme sample content. It downloads artwork from Unsplash, uploads it to Printify, creates products, and downloads the generated mockups. ## Requirements - A Printify account with API access - The PRINTIFY_API_TOKEN environment variable must be set ## Usage # Generate mockups (keeps products in Printify) mix generate_mockups # Generate mockups and delete products afterwards mix generate_mockups --cleanup # Search for available blueprints mix generate_mockups --search "poster" # List all blueprints mix generate_mockups --list-blueprints ## Output Mockup images are saved to: priv/static/mockups/ """ use Mix.Task alias SimpleshopTheme.Printify.MockupGenerator @shortdoc "Generates product mockups using Printify API" @impl Mix.Task def run(args) do # Start required applications Mix.Task.run("app.start") {opts, _, _} = OptionParser.parse(args, switches: [ cleanup: :boolean, search: :string, list_blueprints: :boolean, help: :boolean ], aliases: [ c: :cleanup, s: :search, l: :list_blueprints, h: :help ] ) cond do opts[:help] -> print_help() opts[:list_blueprints] -> list_blueprints() opts[:search] -> search_blueprints(opts[:search]) true -> generate_mockups(opts) end end defp print_help do Mix.shell().info(""" Printify Mockup Generator ========================= Generates product mockups using the Printify API. Usage: mix generate_mockups [options] Options: --cleanup, -c Delete created products from Printify after downloading mockups --search, -s TERM Search for blueprints by name --list-blueprints List all available blueprint IDs and names --help, -h Show this help message Environment: PRINTIFY_API_TOKEN Required. Your Printify API token. Examples: # Generate all mockups export PRINTIFY_API_TOKEN="your-token" mix generate_mockups # Generate and cleanup mix generate_mockups --cleanup # Find blueprint IDs mix generate_mockups --search "poster" """) end defp list_blueprints do Mix.shell().info("Fetching blueprints from Printify...") case MockupGenerator.list_blueprints() do blueprints when is_list(blueprints) -> Mix.shell().info("\nAvailable Blueprints:\n") blueprints |> Enum.each(fn {id, title} -> Mix.shell().info(" #{id}: #{title}") end) Mix.shell().info("\nTotal: #{length(blueprints)} blueprints") {:error, reason} -> Mix.shell().error("Error fetching blueprints: #{inspect(reason)}") end end defp search_blueprints(term) do Mix.shell().info("Searching for blueprints matching '#{term}'...") case MockupGenerator.search_blueprints(term) do results when is_list(results) -> if length(results) == 0 do Mix.shell().info("No blueprints found matching '#{term}'") else Mix.shell().info("\nMatching Blueprints:\n") results |> Enum.each(fn {id, title} -> Mix.shell().info(" #{id}: #{title}") end) Mix.shell().info("\nFound: #{length(results)} blueprints") end {:error, reason} -> Mix.shell().error("Error searching blueprints: #{inspect(reason)}") end end defp generate_mockups(opts) do cleanup = Keyword.get(opts, :cleanup, false) Mix.shell().info(""" ╔═══════════════════════════════════════════╗ ║ Printify Mockup Generator ║ ╠═══════════════════════════════════════════╣ ║ Cleanup mode: #{if cleanup, do: "ON ", else: "OFF"} ║ ╚═══════════════════════════════════════════╝ """) # Verify API token is set case System.get_env("PRINTIFY_API_TOKEN") do nil -> Mix.shell().error(""" Error: PRINTIFY_API_TOKEN environment variable is not set. To get your API token: 1. Log in to Printify 2. Go to Settings > API tokens 3. Create a new token with required permissions Then run: export PRINTIFY_API_TOKEN="your-token" mix generate_mockups """) _token -> results = MockupGenerator.generate_all(cleanup: cleanup) # Summary successful = Enum.count(results, &match?({:ok, _, _, _}, &1)) failed = Enum.count(results, &match?({:error, _, _}, &1)) Mix.shell().info(""" ═══════════════════════════════════════════ Summary ═══════════════════════════════════════════ Successful: #{successful} Failed: #{failed} ═══════════════════════════════════════════ """) if failed > 0 do Mix.shell().error("Some products failed to generate. Check the output above for details.") end end end end