From 15c50f011438983261f6a40446e8432761ad6f72 Mon Sep 17 00:00:00 2001
From: Adam Piontek <adam@73k.us>
Date: Tue, 23 Mar 2021 15:12:24 -0400
Subject: [PATCH] ics output seems to be working

---
 .../controllers/user_shifts_csv_controller.ex |  3 --
 .../controllers/user_shifts_ics_controller.ex | 40 +++++++++++++++++--
 .../live/user/settings/calendar_url.html.leex |  2 +-
 .../views/user_shifts_ics_view.ex             |  3 --
 mix.exs                                       |  3 +-
 mix.lock                                      |  1 +
 6 files changed, 40 insertions(+), 12 deletions(-)
 delete mode 100644 lib/shift73k_web/views/user_shifts_ics_view.ex

diff --git a/lib/shift73k_web/controllers/user_shifts_csv_controller.ex b/lib/shift73k_web/controllers/user_shifts_csv_controller.ex
index 38a93651..7c1099e2 100644
--- a/lib/shift73k_web/controllers/user_shifts_csv_controller.ex
+++ b/lib/shift73k_web/controllers/user_shifts_csv_controller.ex
@@ -9,8 +9,6 @@ defmodule Shift73kWeb.UserShiftsCsvController do
   end
 
   def export(conn, %{"csv_export" => request_params}) do
-    IO.inspect(request_params, label: "csv request params :")
-
     case Map.get(request_params, "user_id") == conn.assigns.current_user.id do
       true ->
         export_csv(conn, request_params)
@@ -39,7 +37,6 @@ defmodule Shift73kWeb.UserShiftsCsvController do
     [csv_headers() | csv_data(user_id, date_range)]
     |> NimbleCSV.RFC4180.dump_to_iodata()
     |> to_string()
-    |> IO.inspect()
   end
 
   def csv_data(user_id, date_range) do
diff --git a/lib/shift73k_web/controllers/user_shifts_ics_controller.ex b/lib/shift73k_web/controllers/user_shifts_ics_controller.ex
index 888a5230..570452ce 100644
--- a/lib/shift73k_web/controllers/user_shifts_ics_controller.ex
+++ b/lib/shift73k_web/controllers/user_shifts_ics_controller.ex
@@ -3,14 +3,46 @@ defmodule Shift73kWeb.UserShiftsIcsController do
 
   alias Shift73k.Accounts
   alias Shift73k.Accounts.User
+  alias Shift73k.Shifts
+  alias Shift73k.Shifts.Shift
 
   def index(conn, %{"slug" => slug}) do
     case Accounts.get_user_by_calendar_slug(slug) do
-      %User{} = user ->
-        render(conn, "index.html", slug: slug, user: user)
+      %User{} = user -> render_ics(conn, user.id)
+
+      _ -> send_not_found(conn)
 
-      _ ->
-        send_resp(conn, 404, "Not found")
     end
   end
+
+  defp send_not_found(conn), do: send_resp(conn, 404, "Not found")
+
+  defp render_ics(conn, user_id) do
+    user_id
+    |> Shifts.list_shifts_by_user()
+    |> Enum.map(&event_from_shift/1)
+    |> render_ics(conn, user_id)
+  end
+
+  defp render_ics([], conn, _user_id), do: send_not_found(conn)
+
+  defp render_ics(events, conn, user_id) do
+    conn
+    |> put_resp_content_type("text/calendar")
+    |> put_resp_header("content-disposition", "attachment; filename=\"#{user_id}.ics\"")
+    |> send_resp(200, ICalendar.to_ics(%ICalendar{events: events}))
+  end
+
+  defp event_from_shift(%Shift{} = s) do
+    dt_start = DateTime.new!(s.date, s.time_start, s.time_zone)
+    shift_length_s = Shifts.shift_length(s) * 60
+
+    %ICalendar.Event{
+      summary: s.subject,
+      dtstart: dt_start,
+      dtend: DateTime.add(dt_start, shift_length_s),
+      description: s.description,
+      location: s.location
+    }
+  end
 end
diff --git a/lib/shift73k_web/live/user/settings/calendar_url.html.leex b/lib/shift73k_web/live/user/settings/calendar_url.html.leex
index a1f8b10f..701f61be 100644
--- a/lib/shift73k_web/live/user/settings/calendar_url.html.leex
+++ b/lib/shift73k_web/live/user/settings/calendar_url.html.leex
@@ -4,7 +4,7 @@
 
   <p><%= @current_user.calendar_slug %></p>
 
-  <%= form_for :calendar_slug, "#", [phx_submit: :save, phx_target: @myself], fn csf -> %>
+  <%= form_for :calendar_slug, "#", [phx_submit: :save, phx_target: @myself], fn _csf -> %>
   <%= submit "Generate new", class: "btn btn-primary" %>
   <% end %>
 
diff --git a/lib/shift73k_web/views/user_shifts_ics_view.ex b/lib/shift73k_web/views/user_shifts_ics_view.ex
deleted file mode 100644
index d1f8b774..00000000
--- a/lib/shift73k_web/views/user_shifts_ics_view.ex
+++ /dev/null
@@ -1,3 +0,0 @@
-defmodule Shift73kWeb.UserShiftsIcsView do
-  use Shift73kWeb, :view
-end
diff --git a/mix.exs b/mix.exs
index b30a49b4..9d064ea5 100644
--- a/mix.exs
+++ b/mix.exs
@@ -52,7 +52,8 @@ defmodule Shift73k.MixProject do
       {:bamboo_smtp, "~> 4.0"},
       {:scrivener_ecto, "~> 2.0"},
       {:tzdata, "~> 1.1"},
-      {:nimble_csv, "~> 1.0"}
+      {:nimble_csv, "~> 1.0"},
+      {:icalendar, "~> 1.1"}
     ]
   end
 
diff --git a/mix.lock b/mix.lock
index a97b0243..578aa5fe 100644
--- a/mix.lock
+++ b/mix.lock
@@ -22,6 +22,7 @@
   "hackney": {:hex, :hackney, "1.17.4", "99da4674592504d3fb0cfef0db84c3ba02b4508bae2dff8c0108baa0d6e0977c", [:rebar3], [{:certifi, "~>2.6.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "de16ff4996556c8548d512f4dbe22dd58a587bf3332e7fd362430a7ef3986b16"},
   "html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
   "hut": {:hex, :hut, "1.3.0", "71f2f054e657c03f959cf1acc43f436ea87580696528ca2a55c8afb1b06c85e7", [:"erlang.mk", :rebar, :rebar3], [], "hexpm", "7e15d28555d8a1f2b5a3a931ec120af0753e4853a4c66053db354f35bf9ab563"},
+  "icalendar": {:hex, :icalendar, "1.1.0", "898a8640abb32d161d990e419999004718a7a4b48be31f48db248f90ca33fa6e", [:mix], [{:timex, "~> 3.4", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "a131f45fbabd2ee5a22e6bc49ea91e81131158394e7169274cee866263640dca"},
   "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
   "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
   "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},