-module(ftpasta). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([describe_error/1, new/1, connect/1, auth/3, port/2, encryption/2, append_bytes/3, change_working_dir/2, close/1, create_dir/2, delete_dir/2, delete_file/2, download_bytes/2, get_working_dir/1, rename/3, upload_bytes/3, list/2, delete_recursive/2, append_file/3, download_file/3, download_recursive/3, upload_file/3, upload_recursive/3]). -export_type([connection/0, listing/0, config/0]). -opaque connection() :: {connection, gleam@erlang@process:pid_()}. -type listing() :: {directory, binary()} | {file, binary(), integer()} | {link, binary(), binary()}. -type config() :: {config, binary(), integer(), ftpasta@tls_config:tls_config(), binary(), binary()}. -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 29). -spec describe_error(ftpasta@ftp_error:ftp_error()) -> binary(). describe_error(Error) -> case Error of dir_parse_error -> <<"Parsing directory contents failed."/utf8>>; {local_file_error, E} -> <<"Local file error: "/utf8, (simplifile:describe_error(E))/binary>>; _ -> ftpasta_ffi:formaterror(Error) end. -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 51). -spec new(binary()) -> config(). new(Host) -> {config, Host, 21, plaintext, <<"anonymous"/utf8>>, <<""/utf8>>}. -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 62). -spec connect(config()) -> {ok, connection()} | {error, ftpasta@ftp_error:ftp_error()}. connect(Config) -> gleam@result:'try'( ftpasta_ffi:open( erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config) ), fun(Pid) -> gleam@result:map( ftpasta_ffi:user( Pid, erlang:element(5, Config), erlang:element(6, Config) ), fun(_) -> {connection, Pid} end ) end ). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 69). -spec auth(config(), binary(), binary()) -> config(). auth(Config, Username, Password) -> erlang:setelement(6, erlang:setelement(5, Config, Username), Password). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 74). -spec port(config(), integer()) -> config(). port(Config, Port) -> erlang:setelement(3, Config, Port). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 79). -spec encryption(config(), ftpasta@tls_config:tls_config()) -> config(). encryption(Config, Tls) -> erlang:setelement(4, Config, Tls). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 86). -spec append_bytes(connection(), bitstring(), binary()) -> {ok, nil} | {error, ftpasta@ftp_error:ftp_error()}. append_bytes(Connection, Data, Remote_file) -> ftpasta_ffi:append_bin(erlang:element(2, Connection), Data, Remote_file). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 97). -spec change_working_dir(connection(), binary()) -> {ok, nil} | {error, ftpasta@ftp_error:ftp_error()}. change_working_dir(Connection, Remote_dir) -> ftpasta_ffi:cd(erlang:element(2, Connection), Remote_dir). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 102). -spec close(connection()) -> nil. close(Connection) -> ftpasta_ffi:close(erlang:element(2, Connection)). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 107). -spec create_dir(connection(), binary()) -> {ok, nil} | {error, ftpasta@ftp_error:ftp_error()}. create_dir(Connection, Remote_dir) -> ftpasta_ffi:mkdir(erlang:element(2, Connection), Remote_dir). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 112). -spec delete_dir(connection(), binary()) -> {ok, nil} | {error, ftpasta@ftp_error:ftp_error()}. delete_dir(Connection, Remote_dir) -> ftpasta_ffi:rmdir(erlang:element(2, Connection), Remote_dir). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 117). -spec delete_file(connection(), binary()) -> {ok, nil} | {error, ftpasta@ftp_error:ftp_error()}. delete_file(Connection, Remote_file) -> ftpasta_ffi:delete(erlang:element(2, Connection), Remote_file). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 139). -spec download_bytes(connection(), binary()) -> {ok, bitstring()} | {error, ftpasta@ftp_error:ftp_error()}. download_bytes(Connection, Remote_file) -> ftpasta_ffi:recv_bin(erlang:element(2, Connection), Remote_file). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 168). -spec get_working_dir(connection()) -> {ok, binary()} | {error, ftpasta@ftp_error:ftp_error()}. get_working_dir(Connection) -> ftpasta_ffi:pwd(erlang:element(2, Connection)). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 189). -spec rename(connection(), binary(), binary()) -> {ok, nil} | {error, ftpasta@ftp_error:ftp_error()}. rename(Connection, Old_path, New_path) -> ftpasta_ffi:rename(erlang:element(2, Connection), Old_path, New_path). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 194). -spec upload_bytes(connection(), bitstring(), binary()) -> {ok, nil} | {error, ftpasta@ftp_error:ftp_error()}. upload_bytes(Connection, Data, Remote_file) -> ftpasta_ffi:send_bin(erlang:element(2, Connection), Data, Remote_file). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 227). -spec parse_ls_line(binary()) -> {ok, listing()} | {error, ftpasta@ftp_error:ftp_error()}. parse_ls_line(Text) -> _assert_subject = gleam@regex:from_string(<<" +"/utf8>>), {ok, Whitespace} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"ftpasta"/utf8>>, function => <<"parse_ls_line"/utf8>>, line => 228}) end, _assert_subject@1 = gleam@regex:from_string(<<"(?:\\S+ +){8}(.+)"/utf8>>), {ok, Filename} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail@1, module => <<"ftpasta"/utf8>>, function => <<"parse_ls_line"/utf8>>, line => 229}) end, gleam@result:'try'(case gleam@regex:scan(Filename, Text) of [{match, _, [{some, X}]}] -> {ok, X}; _ -> {error, dir_parse_error} end, fun(Name) -> case gleam@regex:split(Whitespace, Text) of [<<"d"/utf8, _/binary>> | _] -> {ok, {directory, Name}}; [<<"-"/utf8, _/binary>>, _, _, _, Size_text | _] -> case gleam@int:parse(Size_text) of {ok, Size} -> {ok, {file, Name, Size}}; {error, _} -> {error, dir_parse_error} end; [<<"l"/utf8, _/binary>> | _] -> case gleam@string:split_once(Name, <<" -> "/utf8>>) of {ok, {Name@1, Target}} -> {ok, {link, Name@1, Target}}; {error, _} -> {error, dir_parse_error} end; _ -> {error, dir_parse_error} end end). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 173). -spec list(connection(), binary()) -> {ok, list(listing())} | {error, ftpasta@ftp_error:ftp_error()}. list(Connection, Remote_dir) -> _assert_subject = gleam@regex:from_string(<<"[\\r\\n]+"/utf8>>), {ok, Re} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"ftpasta"/utf8>>, function => <<"list"/utf8>>, line => 177}) end, Arg = case Remote_dir of <<""/utf8>> -> <<"-Al"/utf8>>; Dir -> <<"-Al "/utf8, Dir/binary>> end, gleam@result:'try'( ftpasta_ffi:ls(erlang:element(2, Connection), Arg), fun(Text) -> _pipe = gleam@regex:split(Re, Text), _pipe@1 = gleam@list:filter( _pipe, fun(S) -> not gleam@string:is_empty(S) end ), gleam@list:try_map(_pipe@1, fun parse_ls_line/1) end ). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 122). -spec delete_recursive(connection(), binary()) -> {ok, nil} | {error, ftpasta@ftp_error:ftp_error()}. delete_recursive(Connection, Remote_dir) -> gleam@result:'try'( get_working_dir(Connection), fun(Current_dir) -> gleam@result:'try'( change_working_dir(Connection, Remote_dir), fun(_) -> gleam@result:'try'( list(Connection, <<""/utf8>>), fun(Items) -> gleam@result:'try'( gleam@list:try_map( Items, fun(Item) -> case Item of {file, Name, _} -> delete_file(Connection, Name); {link, Name, _} -> delete_file(Connection, Name); {directory, Name@1} -> delete_recursive( Connection, Name@1 ) end end ), fun(_) -> gleam@result:'try'( change_working_dir( Connection, Current_dir ), fun(_) -> delete_dir(Connection, Remote_dir) end ) end ) end ) end ) end ). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 258). -spec reset_local_dir(connection()) -> {ok, nil} | {error, ftpasta@ftp_error:ftp_error()}. reset_local_dir(Connection) -> case simplifile:current_directory() of {ok, Path} -> ftpasta_ffi:lcd(erlang:element(2, Connection), Path); {error, E} -> {error, {local_file_error, E}} end. -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 91). -spec append_file(connection(), binary(), binary()) -> {ok, nil} | {error, ftpasta@ftp_error:ftp_error()}. append_file(Connection, Local_file, Remote_file) -> gleam@result:'try'( reset_local_dir(Connection), fun(_) -> ftpasta_ffi:append( erlang:element(2, Connection), Local_file, Remote_file ) end ). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 144). -spec download_file(connection(), binary(), binary()) -> {ok, nil} | {error, ftpasta@ftp_error:ftp_error()}. download_file(Connection, Remote_file, Local_file) -> gleam@result:'try'( reset_local_dir(Connection), fun(_) -> ftpasta_ffi:recv( erlang:element(2, Connection), Remote_file, Local_file ) end ). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 150). -spec download_recursive(connection(), binary(), binary()) -> {ok, nil} | {error, ftpasta@ftp_error:ftp_error()}. download_recursive(Connection, Remote_dir, Local_dir) -> gleam@result:'try'( begin _pipe = simplifile_erl:create_directory(Local_dir), gleam@result:map_error( _pipe, fun(Field@0) -> {local_file_error, Field@0} end ) end, fun(_) -> gleam@result:'try'( list(Connection, Remote_dir), fun(Items) -> _pipe@1 = gleam@list:try_map( Items, fun(Item) -> Local_path = filepath:join( Local_dir, erlang:element(2, Item) ), Remote_path = <<<>/binary, (erlang:element(2, Item))/binary>>, case Item of {file, _, _} -> download_file( Connection, Remote_path, Local_path ); {link, _, _} -> download_file( Connection, Remote_path, Local_path ); {directory, _} -> download_recursive( Connection, Remote_path, Local_path ) end end ), gleam@result:replace(_pipe@1, nil) end ) end ). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 199). -spec upload_file(connection(), binary(), binary()) -> {ok, nil} | {error, ftpasta@ftp_error:ftp_error()}. upload_file(Connection, Local_file, Remote_file) -> gleam@result:'try'( reset_local_dir(Connection), fun(_) -> ftpasta_ffi:send( erlang:element(2, Connection), Local_file, Remote_file ) end ). -file("/home/richy/Projects/ftpasta/src/ftpasta.gleam", 205). -spec upload_recursive(connection(), binary(), binary()) -> {ok, nil} | {error, ftpasta@ftp_error:ftp_error()}. upload_recursive(Connection, Local_dir, Remote_dir) -> gleam@result:'try'( create_dir(Connection, Remote_dir), fun(_) -> gleam@result:'try'( begin _pipe = simplifile_erl:read_directory(Local_dir), gleam@result:map_error( _pipe, fun(Field@0) -> {local_file_error, Field@0} end ) end, fun(Items) -> _pipe@1 = gleam@list:try_map( Items, fun(Name) -> Local_path = filepath:join(Local_dir, Name), Remote_path = <<<>/binary, Name/binary>>, case simplifile_erl:is_file(Local_path) of {ok, true} -> upload_file( Connection, Local_path, Remote_path ); {ok, false} -> upload_recursive( Connection, Local_path, Remote_path ); {error, E} -> {error, {local_file_error, E}} end end ), gleam@result:replace(_pipe@1, nil) end ) end ).