Current section

Files

Jump to
gliberapay src gliberapay.erl
Raw

src/gliberapay.erl

-module(gliberapay).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-define(FILEPATH, "src/gliberapay.gleam").
-export([download_patrons_csv_request/1, parse_patrons_csv/1]).
-export_type([patron/0, error/0, date/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type patron() :: {patron,
date(),
integer(),
binary(),
gleam@option:option(binary()),
binary(),
gleam@option:option(float()),
binary()}.
-type error() :: {invalid_csv_syntax, gsv:parse_error()} |
missing_csv_header_row |
{missing_csv_headers, list(binary())} |
{invalid_value, binary()}.
-type date() :: {date, integer(), integer(), integer()}.
-file("src/gliberapay.gleam", 55).
?DOC(
" Construct a HTTP request to download the public Liberapay patrons CSV for\n"
" the given recipient.\n"
"\n"
" Once you have a response for the request you can parse the body with the\n"
" `parse_patrons_csv` function.\n"
).
-spec download_patrons_csv_request(binary()) -> gleam@http@request:request(binary()).
download_patrons_csv_request(Recipient) ->
_pipe = gleam@http@request:new(),
_pipe@1 = gleam@http@request:set_host(_pipe, <<"liberapay.com"/utf8>>),
gleam@http@request:set_path(
_pipe@1,
<<<<"/"/utf8, Recipient/binary>>/binary, "/patrons/public.csv"/utf8>>
).
-file("src/gliberapay.gleam", 112).
-spec optional_string(binary()) -> gleam@option:option(binary()).
optional_string(S) ->
case S of
<<""/utf8>> ->
none;
_ ->
{some, S}
end.
-file("src/gliberapay.gleam", 119).
-spec parse_int(binary()) -> {ok, integer()} | {error, error()}.
parse_int(Int) ->
case gleam_stdlib:parse_int(Int) of
{ok, I} ->
{ok, I};
_ ->
{error, {invalid_value, <<"invalid int: "/utf8, Int/binary>>}}
end.
-file("src/gliberapay.gleam", 126).
-spec parse_amount(binary()) -> {ok, gleam@option:option(float())} |
{error, error()}.
parse_amount(Amount) ->
case Amount of
<<""/utf8>> ->
{ok, none};
<<"private"/utf8>> ->
{ok, none};
_ ->
case gleam_stdlib:parse_float(Amount) of
{ok, F} ->
{ok, {some, F}};
_ ->
case gleam_stdlib:parse_int(Amount) of
{ok, I} ->
{ok, {some, erlang:float(I)}};
_ ->
{error,
{invalid_value,
<<"invalid float: "/utf8, Amount/binary>>}}
end
end
end.
-file("src/gliberapay.gleam", 141).
-spec parse_date(binary()) -> {ok, date()} | {error, error()}.
parse_date(Date) ->
gleam@result:'try'(
begin
_pipe = gleam@string:split(Date, <<"-"/utf8>>),
_pipe@1 = gleam@list:try_map(_pipe, fun gleam_stdlib:parse_int/1),
gleam@result:map_error(
_pipe@1,
fun(_) ->
{invalid_value, <<"invalid date: "/utf8, Date/binary>>}
end
)
end,
fun(Numbers) -> case Numbers of
[Year, Month, Day] ->
{ok, {date, Year, Month, Day}};
_ ->
{error,
{invalid_value, <<"invalid date: "/utf8, Date/binary>>}}
end end
).
-file("src/gliberapay.gleam", 153).
-spec pop_headers(list(list(binary()))) -> {ok,
{list(binary()), list(list(binary()))}} |
{error, error()}.
pop_headers(Csv) ->
gleam@result:'try'(case Csv of
[First | Rest] ->
{ok, {First, Rest}};
[] ->
{error, missing_csv_header_row}
end, fun(_use0) ->
{Headers, Rest@1} = _use0,
Headers_set = gleam@set:from_list(Headers),
Missing = gleam@list:filter(
[<<"pledge_date"/utf8>>,
<<"patron_id"/utf8>>,
<<"patron_username"/utf8>>,
<<"patron_public_name"/utf8>>,
<<"donation_currency"/utf8>>,
<<"weekly_amount"/utf8>>,
<<"patron_avatar_url"/utf8>>],
fun(H) -> not gleam@set:contains(Headers_set, H) end
),
case Missing of
[] ->
{ok, {Headers, Rest@1}};
_ ->
{error, {missing_csv_headers, Missing}}
end
end).
-file("src/gliberapay.gleam", 75).
-spec extract_csv_patrons(list(list(binary()))) -> {ok, list(patron())} |
{error, error()}.
extract_csv_patrons(Csv) ->
gleam@result:'try'(
pop_headers(Csv),
fun(_use0) ->
{Headers, Rows} = _use0,
Rows@1 = gleam@list:map(
Rows,
fun(Row) -> _pipe = gleam@list:zip(Headers, Row),
maps:from_list(_pipe) end
),
gleam@list:try_map(
Rows@1,
fun(Row@1) ->
Get = fun(K) -> case gleam_stdlib:map_get(Row@1, K) of
{ok, V} ->
{ok, V};
_ ->
{error,
{invalid_value,
<<"missing value for "/utf8, K/binary>>}}
end end,
gleam@result:'try'(
Get(<<"pledge_date"/utf8>>),
fun(Date) ->
gleam@result:'try'(
Get(<<"patron_id"/utf8>>),
fun(Id) ->
gleam@result:'try'(
Get(<<"patron_username"/utf8>>),
fun(Username) ->
gleam@result:'try'(
Get(
<<"patron_public_name"/utf8>>
),
fun(Name) ->
gleam@result:'try'(
Get(
<<"donation_currency"/utf8>>
),
fun(Currency) ->
gleam@result:'try'(
Get(
<<"weekly_amount"/utf8>>
),
fun(Amount) ->
gleam@result:'try'(
Get(
<<"patron_avatar_url"/utf8>>
),
fun(
Avatar
) ->
gleam@result:'try'(
parse_date(
Date
),
fun(
Date@1
) ->
gleam@result:'try'(
parse_int(
Id
),
fun(
Id@1
) ->
gleam@result:'try'(
parse_amount(
Amount
),
fun(
Amount@1
) ->
{ok,
{patron,
Date@1,
Id@1,
Username,
optional_string(
Name
),
Currency,
Amount@1,
Avatar}}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/gliberapay.gleam", 68).
?DOC(
" Parse a Liberapay patrons CSV, as can be downloaded from the Liberapay, e.g.\n"
" <https://liberapay.com/gleam/patrons/public.csv>\n"
"\n"
" If you want to download this in Gleam see the `download_patrons_csv` function.\n"
).
-spec parse_patrons_csv(binary()) -> {ok, list(patron())} | {error, error()}.
parse_patrons_csv(Csv) ->
_pipe = Csv,
_pipe@1 = gsv:to_lists(_pipe),
_pipe@2 = gleam@result:map_error(
_pipe@1,
fun(Field@0) -> {invalid_csv_syntax, Field@0} end
),
gleam@result:'try'(_pipe@2, fun extract_csv_patrons/1).