localspot/lib/mix/tasks/localspot.import.ex
Kevin Sivic 70bca86c23 Add business import feature with Mix task and admin UI
- Add Import module for parsing JSON and creating businesses with associations
- Add `mix localspot.import` task for CLI-based imports
- Add admin import page with drag-and-drop file upload at /admin/import
- Include sample import JSON and Buffalo NY business data (40 businesses)
- Support for importing hours and photos with each business

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 00:57:46 -05:00

67 lines
1.7 KiB
Elixir

defmodule Mix.Tasks.Localspot.Import do
@moduledoc """
Imports businesses from a JSON file.
## Usage
mix localspot.import path/to/businesses.json
## JSON Format
See `Localspot.Businesses.Import` for the expected JSON format.
## Example
mix localspot.import priv/data/businesses.json
"""
use Mix.Task
@shortdoc "Imports businesses from a JSON file"
@impl Mix.Task
def run(args) do
case args do
[path] ->
Mix.Task.run("app.start")
import_file(path)
_ ->
Mix.shell().error("Usage: mix localspot.import <path_to_json_file>")
exit({:shutdown, 1})
end
end
defp import_file(path) do
Mix.shell().info("Importing businesses from #{path}...")
case Localspot.Businesses.Import.from_file(path) do
{:ok, %{imported: imported, errors: errors}} ->
Mix.shell().info("Successfully imported #{imported} business(es)")
if length(errors) > 0 do
Mix.shell().info("#{length(errors)} error(s) occurred:")
Enum.each(errors, fn {:error, index, reason} ->
Mix.shell().error(" - Row #{index}: #{inspect(reason)}")
end)
end
{:error, {:file_error, reason}} ->
Mix.shell().error("Could not read file: #{inspect(reason)}")
exit({:shutdown, 1})
{:error, {:json_error, reason}} ->
Mix.shell().error("Invalid JSON: #{inspect(reason)}")
exit({:shutdown, 1})
{:error, {:invalid_format, message}} ->
Mix.shell().error("Invalid format: #{message}")
exit({:shutdown, 1})
{:error, reason} ->
Mix.shell().error("Import failed: #{inspect(reason)}")
exit({:shutdown, 1})
end
end
end