From 2658040f3a2b23d90d7fe37c059300894be17e0c Mon Sep 17 00:00:00 2001 From: Kevin Lynx Date: Sat, 20 Jul 2013 10:56:41 +0800 Subject: [PATCH] add simple `get' json api, fix http search space decode --- src/http_front/api.erl | 77 +++++++++++++++++++++++++++++++++ src/http_front/crawler_http.erl | 12 ++++- src/http_front/http_handler.erl | 10 +---- 3 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 src/http_front/api.erl diff --git a/src/http_front/api.erl b/src/http_front/api.erl new file mode 100644 index 0000000..85f52d7 --- /dev/null +++ b/src/http_front/api.erl @@ -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). diff --git a/src/http_front/crawler_http.erl b/src/http_front/crawler_http.erl index 8a11cce..8d15fa5 100644 --- a/src/http_front/crawler_http.erl +++ b/src/http_front/crawler_http.erl @@ -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. diff --git a/src/http_front/http_handler.erl b/src/http_front/http_handler.erl index 7285feb..e5e0f43 100644 --- a/src/http_front/http_handler.erl +++ b/src/http_front/http_handler.erl @@ -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 ->