Packages

Process a set of IP clicks based on constraint

Current section

Files

Jump to
click lib click.ex
Raw

lib/click.ex

defmodule Click do
@type click :: %{ip: String.t(), timestamp: Calendar.datetime(), amount: float()}
@moduledoc """
A click ​is the composite of an IP address, a timestamp, and a click amount
"""
@doc """
Create a new Click with value as the given 'data'
"""
@spec new(any) :: click
def new(data) do
timestamp = data.timestamp |> Processor.convert_timestamp_to_datetime()
%{ip: data.ip, timestamp: timestamp, amount: data.amount}
end
@doc """
It will process click json and returns the resultset
We will filter if an IP has more than 10 clicks in a day
"""
def process(data) do
data
|> Stream.map(fn x -> new(x) end)
|> Enum.group_by(fn x -> x.ip end)
|> Enum.reject(fn {_, v} -> Enum.count(v) >= 10 end)
|> Enum.map_every(1, fn {_, v} ->
result = v |> Enum.group_by(&by_period(&1))
result
|> Enum.map_every(1, fn {_, val} ->
Enum.max_by(Enum.sort(val, &(Timex.diff(&1.timestamp, &2.timestamp) < 0)), & &1.amount)
end)
end)
|> Enum.flat_map(fn
x when is_list(x) -> x
x -> [x]
end)
end
@doc """
This method used to distribute record based on hour time in the period
"""
def by_period(%{timestamp: timestamp}) do
hour_time = timestamp.hour
cond do
hour_time >= 0 and hour_time < 1 -> "P1"
hour_time >= 1 and hour_time < 2 -> "P2"
hour_time >= 2 and hour_time < 3 -> "P3"
hour_time >= 3 and hour_time < 4 -> "P4"
hour_time >= 4 and hour_time < 5 -> "P5"
hour_time >= 5 and hour_time < 6 -> "P6"
hour_time >= 6 and hour_time < 7 -> "P7"
hour_time >= 7 and hour_time < 8 -> "P8"
hour_time >= 8 and hour_time < 9 -> "P9"
hour_time >= 9 and hour_time < 10 -> "P10"
hour_time >= 10 and hour_time < 11 -> "P11"
hour_time >= 11 and hour_time < 12 -> "P12"
hour_time >= 12 and hour_time < 13 -> "P13"
hour_time >= 13 and hour_time < 14 -> "P14"
hour_time >= 14 and hour_time < 15 -> "P15"
hour_time >= 15 and hour_time < 16 -> "P16"
hour_time >= 16 and hour_time < 17 -> "P17"
hour_time >= 17 and hour_time < 18 -> "P18"
hour_time >= 18 and hour_time < 19 -> "P19"
hour_time >= 19 and hour_time < 20 -> "P20"
hour_time >= 20 and hour_time < 21 -> "P21"
hour_time >= 21 and hour_time < 22 -> "P22"
hour_time >= 22 and hour_time < 23 -> "P23"
hour_time >= 23 and hour_time < 24 -> "P24"
true -> nil
end
end
end