diff --git a/lib/mave_metrics_web/channels/session_channel.ex b/lib/mave_metrics_web/channels/session_channel.ex index de9cf61..7dbba21 100644 --- a/lib/mave_metrics_web/channels/session_channel.ex +++ b/lib/mave_metrics_web/channels/session_channel.ex @@ -10,29 +10,24 @@ defmodule MaveMetricsWeb.SessionChannel do %{"identifier" => identifier, "key" => key} = params, %{id: _session_id, assigns: %{ua: ua}} = socket ) do - with %UAInspector.Result.Bot{name: _name} <- UAInspector.parse(ua) do - {:error, %{reason: "bot"}} - else - parsed_ua -> - case Keys.valid_key?(key) do - {:ok, key} -> - source_url = params["source_url"] || socket.assigns.source_url - - # we're not storing the complete user-agent string to make it impossible to make a fingerprint - session_attrs = - %{ - metadata: params["session_data"] - } - |> Map.merge(parsed_ua |> session_info()) - - {:ok, video} = Stats.find_or_create_video(source_url, identifier, params["metadata"]) - - {:ok, session} = Stats.create_session(video, key, session_attrs) - {:ok, socket |> assign(:session_id, session.id) |> monitor(self())} - - {:error, _reason} -> - {:error, %{reason: "invalid key"}} - end + case Keys.valid_key?(key) do + {:ok, key} -> + source_url = params["source_url"] || socket.assigns.source_url + + # we're not storing the complete user-agent string to make it impossible to make a fingerprint + session_attrs = + %{ + metadata: params["session_data"] + } + |> Map.merge(ua) + + {:ok, video} = Stats.find_or_create_video(source_url, identifier, params["metadata"]) + + {:ok, session} = Stats.create_session(video, key, session_attrs) + {:ok, socket |> assign(:ua, nil) |> assign(:session_id, session.id) |> monitor(self())} + + {:error, _reason} -> + {:error, %{reason: "invalid key"}} end end @@ -160,21 +155,21 @@ defmodule MaveMetricsWeb.SessionChannel do end # https://github.com/phoenixframework/phoenix/issues/3844 - defp monitor(socket, pid) do + defp monitor(%{assigns: %{session_id: session_id}} = socket, pid) do Task.Supervisor.start_child(MaveMetrics.TaskSupervisor, fn -> Process.flag(:trap_exit, true) ref = Process.monitor(pid) receive do {:DOWN, ^ref, :process, _pid, _reason} -> - on_disconnect(socket) + on_disconnect(session_id) end end) socket end - defp on_disconnect(%{assigns: %{session_id: session_id}} = _socket) do + defp on_disconnect(session_id) do with true <- Stats.duration_not_closed?(:play, session_id), %{timestamp: timestamp, from: from} = duration <- Stats.get_last_duration(session_id) do now = DateTime.utc_now() @@ -208,47 +203,4 @@ defmodule MaveMetricsWeb.SessionChannel do _ -> nil end end - - defp on_disconnect(_socket), do: nil - - defp session_info(%{os_family: platform, device: device, client: browser}) do - %{ - browser_type: browser |> get_browser_type, - platform: platform |> get_platform, - device_type: device |> get_device - } - end - - defp get_browser_type(%{name: browser}) - when browser in ["Chrome Mobile", "Chrome Mobile iOS", "Chrome"], - do: :chrome - - defp get_browser_type(%{name: browser}) - when browser in ["Firefox Mobile", "Firefox Mobile iOS", "Firefox"], - do: :firefox - - defp get_browser_type(%{name: browser}) - when browser in ["Mobile Safari", "Safari Technology Preview", "Safari"], - do: :safari - - defp get_browser_type(%{name: browser}) when browser in ["Opera Mobile", "Opera"], do: :opera - defp get_browser_type(%{name: browser}) when browser in ["Edge Mobile", "Edge"], do: :edge - - defp get_browser_type(%{name: browser}) when browser in ["IE Mobile", "Internet Explorer"], - do: :ie - - defp get_browser_type(%{name: browser}) when browser in ["Brave"], do: :brave - defp get_browser_type(_browser), do: :other - - defp get_platform(platform) when platform in ["Windows", "Mac", "Linux", "iOS", "Android"], - do: platform |> String.downcase() |> String.to_atom() - - defp get_platform(_platform), do: :other - - defp get_device(%{type: device}) when device == "smartphone", do: :mobile - - defp get_device(%{type: device}) when device in ["tablet", "desktop"], - do: device |> String.to_atom() - - defp get_device(_device), do: :other end diff --git a/lib/mave_metrics_web/channels/video_socket.ex b/lib/mave_metrics_web/channels/video_socket.ex index 5dd24fd..64de482 100644 --- a/lib/mave_metrics_web/channels/video_socket.ex +++ b/lib/mave_metrics_web/channels/video_socket.ex @@ -6,7 +6,11 @@ defmodule MaveMetricsWeb.VideoSocket do @impl true def connect(%{"source_url" => source_url} = _params, socket, connect_info) do ua = connect_info[:user_agent] - {:ok, socket |> assign(:ua, ua) |> assign(:source_url, source_url)} + + {:ok, + socket + |> assign(:ua, UAInspector.parse(ua) |> session_info()) + |> assign(:source_url, source_url)} end @impl true @@ -16,4 +20,45 @@ defmodule MaveMetricsWeb.VideoSocket do @impl true def id(_socket), do: nil + + defp session_info(%{os_family: platform, device: device, client: browser}) do + %{ + browser_type: browser |> get_browser_type, + platform: platform |> get_platform, + device_type: device |> get_device + } + end + + defp get_browser_type(%{name: browser}) + when browser in ["Chrome Mobile", "Chrome Mobile iOS", "Chrome"], + do: :chrome + + defp get_browser_type(%{name: browser}) + when browser in ["Firefox Mobile", "Firefox Mobile iOS", "Firefox"], + do: :firefox + + defp get_browser_type(%{name: browser}) + when browser in ["Mobile Safari", "Safari Technology Preview", "Safari"], + do: :safari + + defp get_browser_type(%{name: browser}) when browser in ["Opera Mobile", "Opera"], do: :opera + defp get_browser_type(%{name: browser}) when browser in ["Edge Mobile", "Edge"], do: :edge + + defp get_browser_type(%{name: browser}) when browser in ["IE Mobile", "Internet Explorer"], + do: :ie + + defp get_browser_type(%{name: browser}) when browser in ["Brave"], do: :brave + defp get_browser_type(_browser), do: :other + + defp get_platform(platform) when platform in ["Windows", "Mac", "Linux", "iOS", "Android"], + do: platform |> String.downcase() |> String.to_atom() + + defp get_platform(_platform), do: :other + + defp get_device(%{type: device}) when device == "smartphone", do: :mobile + + defp get_device(%{type: device}) when device in ["tablet", "desktop"], + do: device |> String.to_atom() + + defp get_device(_device), do: :other end