commit - 160c2c60efb53d06d2086cc8ab2baf548b87fab2
commit + 9e8448028c925b352290fd78bec02da092edcc82
blob - 32dc8a03c9eeee1534b5d6023c33820a6b162c50
blob + f3f2cbdeb281ebd0c684b5389bada54b6f087e61
--- Makefile
+++ Makefile
AUTH_TOKEN := demo
BASE_URL := http://localhost
PORT := 4000
-DB_PATH := shortener.db
+DB_PATH := shirts.db
export AUTH_TOKEN
export BASE_URL
blob - 76b1eda62e1420008576386407e4836ba2aceb0f
blob + 4c71fded6ba028239409f1abb6fd337c85dd2d66
--- config/config.exs
+++ config/config.exs
import Config
-config :shortener,
+config :shirts,
port: System.get_env("PORT", "4000") |> String.to_integer(),
host: System.get_env("HOST", "127.0.0.1"),
auth_token: System.get_env("AUTH_TOKEN", "changeme"),
blob - bc6cff4c1baef67c58d544d64561664a311e9fbd
blob + 38d357f7c440babbac320f31b5cab51bc8194f0b
--- config/runtime.exs
+++ config/runtime.exs
end
end
- config :shortener,
+ config :shirts,
port: get.("PORT", "4000") |> String.to_integer(),
host: get.("HOST", "127.0.0.1"),
auth_token:
blob - 4e5971a9bfa966d720359b2b4be6ac7ab3fd2ead
blob + b7b692ef95c8974eb0e19479274c393fbc44d791
--- flake.nix
+++ flake.nix
};
packages.x86_64-linux.default = beamPackages.mixRelease {
- pname = "shortener";
+ pname = "shirts";
inherit version;
src = ./.;
ELIXIR_MAKE_CACHE_DIR = "nix-elixir-make";
mixFodDeps = beamPackages.fetchMixDeps {
- pname = "shortener-deps";
+ pname = "shirts-deps";
inherit version;
src = ./.;
sha256 = "sha256-U/tNP3s7b4bBUrQx5l4VtDHpV9DsWj6zBYj8jsM4Acw=";
blob - 87d59f64389a6b86b3177a046b36a8ef2709ec49
blob + 3ee23c57ff7e3893e87caa78f254442781a1656d
--- lib/shortener/application.ex
+++ lib/shortener/application.ex
-defmodule Shortener.Application do
+defmodule Shirts.Application do
@moduledoc """
- Shortener application entry point.
+ Shirts application entry point.
Starts the database and the HTTP server (Bandit).
"""
use Application
@impl true
def start(_type, _args) do
- port = Application.fetch_env!(:shortener, :port)
- host = Application.fetch_env!(:shortener, :host)
- db_path = Application.fetch_env!(:shortener, :db_path)
+ port = Application.fetch_env!(:shirts, :port)
+ host = Application.fetch_env!(:shirts, :host)
+ db_path = Application.fetch_env!(:shirts, :db_path)
children = [
- {Shortener.DB, db_path},
- {Bandit, plug: Shortener.Router, port: port, ip: parse_ip(host)}
+ {Shirts.DB, db_path},
+ {Bandit, plug: Shirts.Router, port: port, ip: parse_ip(host)}
]
- Logger.info("Starting shortener on #{host}:#{port}")
+ Logger.info("Starting shirts on #{host}:#{port}")
- Supervisor.start_link(children, strategy: :one_for_one, name: Shortener.Supervisor)
+ Supervisor.start_link(children, strategy: :one_for_one, name: Shirts.Supervisor)
end
@impl true
def stop(_state) do
- Logger.info("Shortener application stopped")
+ Logger.info("Shirts application stopped")
:ok
end
blob - b97d1f28a4d6a733674ec2078b6e0eafabceb6ec
blob + adb477250409be8a3b1985e36c99c421eecbc76b
--- lib/shortener/db.ex
+++ lib/shortener/db.ex
-defmodule Shortener.DB do
+defmodule Shirts.DB do
@moduledoc """
SQLite database interface using Exqlite.
Stores and retrieves short links.
blob - 8eaad91102aa62b00e48cd8024faee3bdc187d13
blob + d698f2418635d4afd161d46dd441a3e975820a41
--- lib/shortener/router.ex
+++ lib/shortener/router.ex
-defmodule Shortener.Router do
+defmodule Shirts.Router do
@moduledoc """
Plug router:
POST /curtail — create a short link (requires Bearer token)
with :ok <- check_auth(conn),
{:ok, url} <- fetch_url(conn),
code <- Map.get(conn.body_params, "code") || random_code(),
- :ok <- Shortener.DB.insert(code, url) do
- base_url = Application.fetch_env!(:shortener, :base_url)
+ :ok <- Shirts.DB.insert(code, url) do
+ base_url = Application.fetch_env!(:shirts, :base_url)
short_url = "#{base_url}/s/#{code}"
conn
# GET /s/:code — redirect
# ---------------------------------------------------------------------------
get "/s/:code" do
- case Shortener.DB.lookup(code) do
+ case Shirts.DB.lookup(code) do
{:ok, url} ->
conn
|> put_resp_header("location", url)
# ---------------------------------------------------------------------------
defp check_auth(conn) do
- expected = "Bearer #{Application.fetch_env!(:shortener, :auth_token)}"
+ expected = "Bearer #{Application.fetch_env!(:shirts, :auth_token)}"
case get_req_header(conn, "authorization") do
[^expected] -> :ok
blob - 2a6f448fb2400bf5622fad451f0595a517025202
blob + 38a4c06e5ae4ecfdf40fb6dd3bfb2ac78e6b7638
--- mix.exs
+++ mix.exs
-defmodule Shortener.MixProject do
+defmodule Shirts.MixProject do
use Mix.Project
def project do
[
- app: :shortener,
+ app: :shirts,
version: "0.3.0",
elixir: "~> 1.18",
start_permanent: Mix.env() == :prod,
def application do
[
extra_applications: [:logger],
- mod: {Shortener.Application, []}
+ mod: {Shirts.Application, []}
]
end