diff --git a/lib/mse25/directus.ex b/lib/mse25/directus.ex index 8d0ac70..292e039 100644 --- a/lib/mse25/directus.ex +++ b/lib/mse25/directus.ex @@ -20,6 +20,7 @@ defmodule Mse25.Directus do "," ) ] + |> annual?(:articles, options) |> query_params_string(options, :articles) get("/articles?" <> params) @@ -105,12 +106,15 @@ defmodule Mse25.Directus do "slug", "poster", "category", + "started_at", + "ended_at", "bands.artists_id.name", "mia.artists_id.name" ], "," ) ] + |> annual?(:events, options) |> query_params_string(options, :events) get("/events?" <> params) @@ -138,6 +142,7 @@ defmodule Mse25.Directus do "," ) ] + |> annual?(:links, options) |> query_params_string(options, :links) get("/links?" <> params) @@ -215,4 +220,42 @@ defmodule Mse25.Directus do pg -> ["filter[title][_icontains]=" <> String.replace(to_string(pg), " ", "%20") | params] end end + + defp annual?(params, type, opts) do + case opts[:year] do + nil -> + params + + year -> + year_filter(type, year, params) + end + end + + defp year_filter(:albums, year, params), + do: [ + "filter[purchased_at][_gte]=" <> to_string(year) <> "-01-01", + "filter[purchased_at][_lte]=" <> to_string(year) <> "-12-31" + | params + ] + + defp year_filter(:articles, year, params), + do: [ + "filter[pubDate][_gte]=" <> to_string(year) <> "-01-01", + "filter[pubDate][_lte]=" <> to_string(year) <> "-12-31" + | params + ] + + defp year_filter(:events, year, params), + do: [ + "filter[started_at][_gte]=" <> to_string(year) <> "-01-01", + "filter[ended_at][_lte]=" <> to_string(year) <> "-12-31" + | params + ] + + defp year_filter(:links, year, params), + do: [ + "filter[pubDate][_gte]=" <> to_string(year) <> "-01-01", + "filter[pubDate][_lte]=" <> to_string(year) <> "-12-31" + | params + ] end diff --git a/lib/mse25/timeline.ex b/lib/mse25/timeline.ex new file mode 100644 index 0000000..7c8da09 --- /dev/null +++ b/lib/mse25/timeline.ex @@ -0,0 +1,61 @@ +defmodule Mse25.Timeline do + alias Mse25.Directus + + def archive() do + items = + Task.await_many([ + Task.async(fn -> Directus.get_albums!() end), + Task.async(fn -> Directus.get_articles!(limit: 9999) end), + Task.async(fn -> Directus.get_links!(limit: 9999) end), + Task.async(fn -> Directus.get_events!(limit: 9999) end) + ]) + end + + def annual(year) do + items = + Task.await_many([ + Task.async(fn -> Directus.get_albums!(limit: 9999, year: year) end), + Task.async(fn -> Directus.get_articles!(limit: 9999, year: year) end), + Task.async(fn -> Directus.get_links!(limit: 9999, year: year) end), + Task.async(fn -> Directus.get_events!(limit: 9999, year: year) end) + ]) + + counts = + items + |> Enum.reject(&Enum.empty?/1) + |> Enum.map(fn [item | l] -> {item_key(item), Enum.count(l) + 1} end) + |> Map.new() + + timeline = + items + |> List.flatten() + |> Enum.sort_by(&sort_key/1) + |> Enum.map(&categorize/1) + |> Enum.group_by(fn item -> sort_key(item) |> String.slice(5..6) end) + |> Enum.reverse() + + {:ok, %{year: year, timeline: timeline, counts: counts}} + end + + def search(query) do + items = + Task.await_many([ + Task.async(fn -> Directus.get_articles!(limit: 9999, query: query) end), + Task.async(fn -> Directus.get_links!(limit: 9999, query: query) end), + Task.async(fn -> Directus.get_events!(limit: 9999, query: query) end) + ]) + end + + defp sort_key(%{"pubDate" => date}), do: date + defp sort_key(%{"started_at" => date}), do: date + defp sort_key(%{"purchased_at" => date}), do: date + + defp item_key(%{"source" => _s, "pubDate" => _}), do: :links + defp item_key(%{"pubDate" => _}), do: :articles + defp item_key(%{"started_at" => _}), do: :events + defp item_key(%{"purchased_at" => _}), do: :albums + + defp categorize(item) do + Map.put(item, :t, item_key(item)) + end +end diff --git a/lib/mse25_web/controllers/item_controller.ex b/lib/mse25_web/controllers/item_controller.ex index 4e48c0c..7d27978 100644 --- a/lib/mse25_web/controllers/item_controller.ex +++ b/lib/mse25_web/controllers/item_controller.ex @@ -1,6 +1,7 @@ defmodule Mse25Web.ItemController do use Mse25Web, :controller alias Mse25.Directus + alias Mse25.Timeline def index(conn, _params) do case conn.path_info |> fetch do @@ -38,12 +39,36 @@ defmodule Mse25Web.ItemController do end defp fetch([slug]) do - case Directus.get_page(slug) do - {:ok, response} -> {:ok, :page, response} - not_found -> not_found + case Integer.parse(slug) do + {:error} -> + case Directus.get_page(slug) do + {:ok, response} -> {:ok, :page, response} + error -> error + end + + {year, _} -> + case Timeline.annual(year) do + {:ok, response} -> {:ok, :annual, response} + error -> error + end end end + defp assigns(:annual, %{ + timeline: timeline, + year: year, + counts: counts + }), + do: [ + year: year, + page_title: "Innehåll från " <> to_string(year), + timeline: timeline, + brutal_legends_count: Map.get(counts, :albums, 0), + article_count: Map.get(counts, :articles, 0), + event_count: Map.get(counts, :events, 0), + link_count: Map.get(counts, :links, 0) + ] + defp assigns(:article, %{ "title" => heading, "contents" => contents, diff --git a/lib/mse25_web/controllers/item_html.ex b/lib/mse25_web/controllers/item_html.ex index 9a103f0..6df1958 100644 --- a/lib/mse25_web/controllers/item_html.ex +++ b/lib/mse25_web/controllers/item_html.ex @@ -3,4 +3,23 @@ defmodule Mse25Web.ItemHTML do import Mse25.EventHelpers embed_templates "item_html/*" + + def month_name("01"), do: "Januari" + def month_name("02"), do: "Februari" + def month_name("03"), do: "Mars" + def month_name("04"), do: "April" + def month_name("05"), do: "Maj" + def month_name("06"), do: "Juni" + def month_name("07"), do: "Juli" + def month_name("08"), do: "Augusti" + def month_name("09"), do: "September" + def month_name("10"), do: "Oktober" + def month_name("11"), do: "November" + def month_name("12"), do: "December" + + def csl(items) do + items + |> Enum.join(", ") + |> String.replace(~r/, ([^,]+?)$/, " och \\1") + end end diff --git a/lib/mse25_web/controllers/item_html/annual.html.heex b/lib/mse25_web/controllers/item_html/annual.html.heex new file mode 100644 index 0000000..27e9ed4 --- /dev/null +++ b/lib/mse25_web/controllers/item_html/annual.html.heex @@ -0,0 +1,104 @@ +
+ +

<%= @page_title %>

+ + + <%= for {month, items} <- @timeline do %> +
month}> +

<%= month_name(month) <> ", " <> to_string(@year) %>

+ <%= for item = %{t: t} <- items do %> +
+ <%= if t == :articles do %> +

+ item["slug"]}> + <%= item["title"] %> + +

+ <% end %> + <%= if t == :events do %> +

+ item["slug"]}> + <%= item["title"] %> + +

+

<%= item["lead"] %>

+ item["poster"] <> "?key=poster"} + loading="lazy" + alt="Affisch" + width="200" + /> + <% end %> + <%= if t == :links do %> +

+ <%= item["title"] %> +

+

<%= raw(Earmark.as_html!(item["contents"])) %>

+ Källa: + item["source"]}> + <%= item["h1"] %> + + <% end %> + <%= if t == :albums do %> +

+ <%= item["artist"] <> + " - " <> item["album"] <> " (" <> to_string(item["year"]) <> ")" %> + +

+ <%= if item["contents"] do %> +

<%= raw(Earmark.as_html!(item["contents"])) %>

+ <% end %> +
    + <%= for song <- item["songs"] do %> +
  • <%= song["artist"]["name"] <> " - " <> song["title"] %>
  • + <% end %> +
+ item["cover"] <> "?key=rectangular"} + alt="Skivomslag" + loading="lazy" + height="75" + width="75" + /> + <% end %> +
+ <% end %> +
+ <% end %> +
diff --git a/lib/mse25_web/router.ex b/lib/mse25_web/router.ex index b7d83ff..a80d74c 100644 --- a/lib/mse25_web/router.ex +++ b/lib/mse25_web/router.ex @@ -25,7 +25,6 @@ defmodule Mse25Web.Router do # get "/kommande-evenemang.ics", EventController, :calendar # get "/event-map.js", EventController, :interactive_map - # get "/:year", TimelineController, :annual # get "/prenumerera.xml", TimelineController, :feed get "/*path", ItemController, :index