Packages

An open source two way communication platform for the social sector

Current section

Files

Jump to
glific lib glific.ex
Raw

lib/glific.ex

defmodule Glific do
import Ecto.Changeset
@moduledoc """
Glific keeps the contexts that define your domain
and business logic.
Contexts are also responsible for managing your data, regardless
if it comes from the database, an external API or others.
For now we'll keep some commonly used functions here, until we need
a new file
"""
@doc """
Wrapper to return :ok/:error when parsing strings to potential integers
"""
@spec parse_maybe_integer(String.t() | integer) :: {:ok, integer} | :error
def parse_maybe_integer(value) when is_integer(value),
do: {:ok, value}
def parse_maybe_integer(value) do
case Integer.parse(value) do
{n, ""} -> {:ok, n}
{_num, _rest} -> :error
:error -> :error
end
end
@doc """
Validates inputed shortcode, if shortcode is invalid it returns message that the shortcode is invalid
along with the valid shortcode.
"""
@spec(
validate_shortcode(Ecto.Changeset.t()) :: Ecto.Changeset.t() | Ecto.Changeset.t(),
atom(),
String.t()
)
def validate_shortcode(%Ecto.Changeset{} = changeset) do
shortcode = Map.get(changeset.changes, :shortcode)
valid_shortcode = string_clean(shortcode)
if valid_shortcode == shortcode,
do: changeset,
else:
add_error(
changeset,
:shortcode,
"Invalid shortcode, valid shortcode will be #{valid_shortcode}"
)
end
@doc """
Lets get rid of all non valid characters. We are assuming any language and hence using unicode syntax
and not restricting ourselves to alphanumeric
"""
@spec string_clean(String.t() | nil) :: String.t() | nil
def string_clean(str) when is_nil(str) or str == "", do: str
def string_clean(str),
do:
str
|> String.replace(~r/[\p{P}\p{S}\p{Z}\p{C}]+/u, "")
|> String.downcase()
|> String.trim()
@doc """
See if the current time is within the past time units
"""
@spec in_past_time(DateTime.t(), atom(), integer) :: boolean
def in_past_time(time, units \\ :hours, back \\ 24),
do: Timex.diff(DateTime.utc_now(), time, units) < back
@doc """
Return a time object where you go back x units. We introduce the notion
of hour and minute
"""
@spec go_back_time(integer, DateTime.t(), atom()) :: DateTime.t()
def go_back_time(go_back, time \\ DateTime.utc_now(), unit \\ :hour) do
# convert hours to second
{unit, go_back} =
case unit do
:hour -> {:second, go_back * 60 * 60}
:minute -> {:second, go_back * 60}
_ -> {unit, go_back}
end
DateTime.add(time, -1 * go_back, unit)
end
end