add simple `get' json api, fix http search space decode

This commit is contained in:
Kevin Lynx 2013-07-20 10:56:41 +08:00
parent 54a30122fa
commit 2658040f3a
3 changed files with 89 additions and 10 deletions

77
src/http_front/api.erl Normal file
View File

@ -0,0 +1,77 @@
%%
%% api.erl
%% Kevin Lynx
%% 07.19.2013
%% HTTP API
%%
-module(api).
-export([search/3]).
-compile(export_all).
-define(TEXT(Fmt, Args), lists:flatten(io_lib:format(Fmt, Args))).
-define(MAX_FILE, 10).
search(SessionID, _Env, Input) ->
Res = case crawler_http:get_search_keyword(Input) of
[] ->
"{\"error\":\"null input\", \"suggest\":\"api/search?q=keyword\"}";
Keyword ->
do_search(Keyword)
end,
mod_esi:deliver(SessionID, ["Content-Type: application/json\r\n\r\n", Res]).
do_search(Keyword) ->
{Rets, Stats} = http_cache:search(Keyword),
{_Found, Cost, Scanned} = Stats,
Tip = ?TEXT("{\"keyword\":\"~s\", \"found\":~p, \"cost\":~p,", [Keyword, Scanned, Cost div 1000]),
BodyList = format_search_result(Rets),
Body = ?TEXT("\"results\":[~s]}", [BodyList]),
Tip ++ Body.
format_search_result([]) ->
"";
format_search_result([First|Rest]) ->
S = [format_one_result(First, false)] ++ ["," ++ format_one_result(Ret, false) || Ret <- Rest],
lists:flatten(S).
format_one_result({single, Hash, {Name, Length}, Announce, CTime}, ShowAll) ->
format_one_result(Hash, Name, [{Name, Length}], Announce, CTime, ShowAll);
format_one_result({multi, Hash, {Name, Files}, Announce, CTime}, ShowAll) ->
format_one_result(Hash, Name, Files, Announce, CTime, ShowAll).
format_one_result(Hash, Name, Files, Announce, CTime, ShowAll) ->
?TEXT("{\"hash\":\"~s\", \"name\":\"~s\", \"created_at\":~p, \"req\":~p,",
[Hash, Name, CTime, Announce]) ++
"\"files\":[" ++ format_files(Files, ShowAll) ++ "]}".
format_files([], _) ->
"";
format_files(Files, false) ->
Max = ?MAX_FILE,
Sub = case length(Files) >= Max of
true ->
lists:sublist(Files, Max) ++ [{more, length(Files) - Max}];
false ->
Files
end,
do_format_files(Sub);
format_files(Files, true) ->
do_format_files(Files).
do_format_files([First|Rest]) ->
S = [format_file(First)] ++ ["," ++ format_file(File) || File <- Rest],
lists:flatten(S).
format_file({more, Len}) ->
?TEXT("{\"name\":\"__more__\",\"size\":~b}", [Len]);
format_file({Name, Length}) ->
?TEXT("{\"name\":\"~s\",\"size\":~b}", [Name, Length]).
%%
test_search(Keyword) ->
Filename = ?TEXT("search_~s.html", [Keyword]),
Body = do_search(Keyword),
file:write_file(Filename, Body).

View File

@ -15,6 +15,7 @@
start/4,
start/1,
page_temp/0,
get_search_keyword/1,
stop/0]).
-record(state, {html_temp, httpid}).
@ -58,7 +59,7 @@ init([DBHost, DBPort, Port, PoolSize]) ->
{document_root, "www"},
{server_root, "."},
{directory_index, ["index.html"]},
{erl_script_alias, {"/e", [http_handler]}},
{erl_script_alias, {"/e", [http_handler, api]}},
{mime_types, [{"html","text/html"},
{"css","text/css"}, {"js","application/x-javascript"}]}]),
{ok, B} = file:read_file("www/page.temp"),
@ -90,3 +91,12 @@ code_change(_, _, State) ->
handle_info(_, State) ->
{noreply, State}.
get_search_keyword(Input) ->
D = urldecode:decode(Input),
ReqList = httpd:parse_query(D),
case proplists:get_value("q", ReqList) of
undefined ->
"";
Keyword ->
Keyword
end.

View File

@ -17,7 +17,7 @@
-define(CONTENT_TYPE, "Content-Type: text/html\r\n\r\n").
search(SessionID, _Env, Input) ->
{K, Body} = case get_search_keyword(Input) of
{K, Body} = case crawler_http:get_search_keyword(Input) of
[] ->
{"", "invalid input"};
Key ->
@ -73,14 +73,6 @@ index(SessionID, _Env, Input) ->
Response = simple_html("", Body),
mod_esi:deliver(SessionID, [?CONTENT_TYPE, Response]).
get_search_keyword(Input) ->
case string:equal(string:substr(Input, 1, 2), "q=") of
true ->
urldecode:decode(string:substr(Input, 3));
false ->
[]
end.
get_index_hash(Input) ->
case string:equal(string:substr(Input, 1, 2), "q=") of
true ->