123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- %% Feel free to use, reuse and abuse the code in this file.
- %% @doc Pastebin handler.
- -module(toppage_handler).
- %% REST Callbacks
- -export([init/3]).
- -export([allowed_methods/2]).
- -export([content_types_provided/2]).
- -export([content_types_accepted/2]).
- -export([resource_exists/2]).
- -export([post_is_create/2]).
- -export([create_path/2]).
- %% Callback Callbacks
- -export([create_paste/2]).
- -export([paste_html/2]).
- -export([paste_text/2]).
- init(_Transport, _Req, []) ->
- % For the random number generator:
- {X, Y, Z} = now(),
- random:seed(X, Y, Z),
- {upgrade, protocol, cowboy_rest}.
- allowed_methods(Req, State) ->
- {[<<"GET">>, <<"POST">>], Req, State}.
- content_types_provided(Req, State) ->
- {[
- {{<<"text">>, <<"plain">>, []}, paste_text},
- {{<<"text">>, <<"html">>, []}, paste_html}
- ], Req, State}.
- content_types_accepted(Req, State) ->
- {[{{<<"application">>, <<"x-www-form-urlencoded">>, []}, create_paste}],
- Req, State}.
- resource_exists(Req, _State) ->
- case cowboy_req:binding(paste_id, Req) of
- {undefined, Req2} ->
- {true, Req2, index};
- {PasteID, Req2} ->
- case valid_path(PasteID) and file_exists(PasteID) of
- true -> {true, Req2, PasteID};
- false -> {false, Req2, PasteID}
- end
- end.
- post_is_create(Req, State) ->
- {true, Req, State}.
- create_path(Req, State) ->
- {<<$/, (new_paste_id())/binary>>, Req, State}.
- create_paste(Req, State) ->
- {<<$/, PasteID/binary>>, Req2} = cowboy_req:meta(put_path, Req),
- {ok, [{<<"paste">>, Paste}], Req3} = cowboy_req:body_qs(Req2),
- ok = file:write_file(full_path(PasteID), Paste),
- {true, Req3, State}.
- paste_html(Req, index) ->
- {read_file("index.html"), Req, index};
- paste_html(Req, Paste) ->
- {Style, Req2} = cowboy_req:qs_val(<<"lang">>, Req, plain),
- {format_html(Paste, Style), Req2, Paste}.
- paste_text(Req, index) ->
- {read_file("index.txt"), Req, index};
- paste_text(Req, Paste) ->
- {Style, Req2} = cowboy_req:qs_val(<<"lang">>, Req, plain),
- {format_text(Paste, Style), Req2, Paste}.
- % Private
- read_file(Name) ->
- {ok, Binary} = file:read_file(full_path(Name)),
- Binary.
- full_path(Name) ->
- {ok, Cwd} = file:get_cwd(),
- filename:join([Cwd, "priv", Name]).
- file_exists(Name) ->
- case file:read_file_info(full_path(Name)) of
- {ok, _Info} -> true;
- {error, _Reason} -> false
- end.
- valid_path(<<>>) -> true;
- valid_path(<<$., _T/binary>>) -> false;
- valid_path(<<$/, _T/binary>>) -> false;
- valid_path(<<_Char, T/binary>>) -> valid_path(T).
- new_paste_id() ->
- Initial = random:uniform(62) - 1,
- new_paste_id(<<Initial>>, 7).
- new_paste_id(Bin, 0) ->
- Chars = <<"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890">>,
- << <<(binary_part(Chars, B, 1))/binary>> || <<B>> <= Bin >>;
- new_paste_id(Bin, Rem) ->
- Next = random:uniform(62) - 1,
- new_paste_id(<<Bin/binary, Next>>, Rem - 1).
- format_html(Paste, plain) ->
- Text = escape_html_chars(read_file(Paste)),
- <<"<!DOCTYPE html><html>",
- "<head><title>paste</title></head>",
- "<body><pre><code>", Text/binary, "</code></pre></body></html>\n">>;
- format_html(Paste, Lang) ->
- highlight(full_path(Paste), Lang, "html").
- format_text(Paste, plain) ->
- read_file(Paste);
- format_text(Paste, Lang) ->
- highlight(full_path(Paste), Lang, "ansi").
- highlight(Path, Lang, Type) ->
- Path1 = binary_to_list(Path),
- Lang1 = binary_to_list(Lang),
- os:cmd(["highlight --syntax=", Lang1,
- " --doc-title=paste ",
- " --out-format=", Type,
- " --include-style ", Path1]).
- % Escape some HTML characters that might make a fuss
- escape_html_chars(Bin) ->
- << <<(escape_html_char(B))/binary>> || <<B>> <= Bin >>.
- escape_html_char($<) -> <<"<">>;
- escape_html_char($>) -> <<">">>;
- escape_html_char($&) -> <<"&">>;
- escape_html_char(C) -> <<C>>.
|