webtool.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,205 行 · 第 1/3 页
ERL
1,205 行
end.stop_tools_page(_Env,Input,State)-> case get_tools(Input) of {tools,Tools}-> {ok,NewState}=handle_apps(Tools,State,stop), {NewState,[?HEADER,?HTML_HEADER_RELOAD,reload_started_apps(), show_started_apps(NewState),?HTML_END]}; _ -> {State,[?HEADER,?HTML_HEADER,show_started_apps(State),?HTML_END]} end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Functions that start and config the webserver%% 1. Collect the config data%% 2. Start webserver%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%----------------------------------------------------------------------% Start the webserver%----------------------------------------------------------------------start_webserver(Data,Path,Config)-> case get_conf_data(Data,Path,Config) of {ok,Conf_data}-> %%io:format("Conf_data: ~p~n",[Conf_data]), start_server(Conf_data); {error,Error} -> {error,{error_server_conf_file,Error}} end.start_server(Conf_data)-> case httpd:start2(Conf_data) of {ok,Pid}-> {ok,Pid}; Error-> {error,{server_error,Error}} end.%----------------------------------------------------------------------% Create config data for the webserver %----------------------------------------------------------------------get_conf_data(Data,Path,Config)-> Aliases=get_aliases(Data), ServerRoot = filename:join([Path,"root"]), MimeTypesFile = filename:join([ServerRoot,"conf","mime.types"]), case httpd_conf:load_mime_types(MimeTypesFile) of {ok,MimeTypes} -> Config1 = Config ++ Aliases, Config2 = [{server_root,ServerRoot}, {document_root,filename:join([Path,"root/doc"])}, {mime_types,MimeTypes} | Config1], {ok,Config2}; Error -> Error end.%----------------------------------------------------------------------% Control the path for *.tools files %----------------------------------------------------------------------get_tool_files_data()-> Tools=get_tools1(code:get_path()), %%io:format("Data : ~p ~n",[Tools]), get_file_content(Tools).%----------------------------------------------------------------------%Control that the data in the file really is erlang terms%---------------------------------------------------------------------- get_file_content(Tools)-> Get_data=fun({tool,ToolData}) -> %%io:format("Data : ~p ~n",[ToolData]), case httpd_util:key1search(ToolData,config_func) of {M,F,A}-> case catch apply(M,F,A) of {'EXIT',_} -> bad_data; Data when is_tuple(Data) -> Data; _-> bad_data end; _ -> bad_data end end, insert_file_content([X ||X<-lists:map(Get_data,Tools),X/=bad_data]).%----------------------------------------------------------------------%Insert the data from the file in to the ets:table%----------------------------------------------------------------------insert_file_content(Content)-> Table=ets:new(app_data,[bag]), lists:foreach(fun(X)-> insert_app(X,Table) end,Content), {ok,Table}.%----------------------------------------------------------------------%Control that we got a a tuple of a atom and a list if so add the %elements in the list to the ets:table%----------------------------------------------------------------------insert_app({Name,Key_val_list},Table) when is_list(Key_val_list),is_atom(Name)-> %%io:format("ToolData: ~p: ~p~n",[Name,Key_val_list]), lists:foreach( fun({alias,{erl_alias,Alias,Mods}}) -> Key_val = {erl_script_alias,{Alias,[atom_to_list(M)||M<-Mods]}}, %%io:format("Insert: ~p~n",[Key_val]), ets:insert(Table,{Name,Key_val}); (Key_val_pair)-> %%io:format("Insert: ~p~n",[Key_val_pair]), ets:insert(Table,{Name,Key_val_pair}) end, Key_val_list);insert_app(_,_)-> ok. %----------------------------------------------------------------------% Select all the alias in the database%----------------------------------------------------------------------get_aliases(Data)-> MS = ets:fun2ms(fun({_,{erl_script_alias,Alias}}) -> {erl_script_alias,Alias}; ({_,{alias,Alias}}) -> {alias,Alias} end), ets:select(Data,MS).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% Helper functions %%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%get_standard_data(Port)-> [ {port,Port}, {bind_address,?DEFAULT_ADDR}, {server_name,"localhost"} ].get_standard_data()-> case get_free_port(?DEFAULT_PORT,?MAX_NUMBER_OF_WEBTOOLS) of {error,Reason} -> {error,Reason}; Port -> [ {port,Port}, {bind_address,?DEFAULT_ADDR}, {server_name,"localhost"} ] end.get_free_port(_Port,0) -> {error,no_free_port_found};get_free_port(Port,N) -> case gen_tcp:connect("localhost",Port,[]) of {error, _Reason} -> Port; {ok,Sock} -> gen_tcp:close(Sock), get_free_port(Port+1,N-1) end.rest_of_standard_data() -> [ %% Do not allow the server to be crashed by malformed http-request {max_header_siz,1024}, {max_header_action,reply414}, %% Go on a straight ip-socket {com_type,ip_comm}, %% Do not change the order of these module names!! {modules,[mod_alias, mod_auth, mod_esi, mod_actions, mod_cgi, mod_include, mod_dir, mod_get, mod_head, mod_log, mod_disk_log]}, {directory_index,["index.html"]}, {default_type,"text/plain"} ].get_path()-> code:priv_dir(webtool).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% These functions is used to shutdown the webserver%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%----------------------------------------------------------------------% Shut down the webbserver %----------------------------------------------------------------------shutdown_server(State)-> {Addr,Port} = get_addr_and_port(State#state.web_data), httpd:stop(Addr,Port).get_addr_and_port(Config) -> Addr = httpd_util:key1search(Config,bind_address,?DEFAULT_ADDR), Port = httpd_util:key1search(Config,port,?DEFAULT_PORT), {Addr,Port}.%----------------------------------------------------------------------% Select all apps in the table and close them%----------------------------------------------------------------------shutdown_apps(State)-> Data=State#state.app_data, MS = ets:fun2ms(fun({_,{start,HowToStart}}) -> HowToStart end), lists:foreach(fun(Start_app)-> stop_app(Start_app) end, ets:select(Data,MS)).%----------------------------------------------------------------------%Shuts down the supervisor that supervises tools that is not%Designed as applications%----------------------------------------------------------------------shutdown_supervisor(State)-> %io:format("~n==================~n"), webtool_sup:stop(State#state.supvis). %io:format("~n==================~n").%----------------------------------------------------------------------%close the individual apps.%---------------------------------------------------------------------- stop_app({child,_Real_name})-> ok;stop_app({app,Real_name})-> application:stop(Real_name);stop_app({func,_Start,Stop})-> case Stop of {M,F,A} -> catch apply(M,F,A); _NoStop -> ok end.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% These functions creates the webpage where the user can select if %% to start apps or to stop apps%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%toolbar_page()-> "<TABLE> <TR> <TD> <B>Select Action</B> </TD> </TR> <TR> <TD> <A HREF=\"./start_tools\" TARGET=right> Start Tools</A> </TD> </TR> <TR> <TD> <A HREF=\"./stop_tools\" TARGET=right> Stop Tools</A> </TD> </TR> </TABLE>".%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% These functions creates the webbpage that shows the started apps%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%----------------------------------------------------------------------% started_tools(State)->String (html table)% State is a record of type state%----------------------------------------------------------------------started_tools(State)-> Names=get_started_apps(State#state.app_data,State#state.started), "<TABLE BORDER=1 WIDTH=100%> "++ make_rows(Names,[],0) ++" </TABLE>".%----------------------------------------------------------------------%get_started_apps(Data,Started)-> [{web_name,link}]%selects the started apps from the ets table of apps.%---------------------------------------------------------------------- get_started_apps(Data,Started)-> SelectData=fun({Name,Link}) -> {Name,Link} end, MS = lists:map(fun(A) -> {{A,{web_data,'$1'}},[],['$1']} end,Started), [{"WebTool","/tool_management.html"} | [SelectData(X) || X <- ets:select(Data,MS)]].%----------------------------------------------------------------------% make_rows(List,Result,Fields)-> String (The rows of a htmltable% List a list of tupler discibed above% Result an accumulator for the result% Field, counter that counts the number of cols in each row.%----------------------------------------------------------------------make_rows([],Result,Fields)-> Result ++ fill_out(Fields);make_rows([Data|Paths],Result,Field)when Field==0-> make_rows(Paths,Result ++ "<TR>" ++ make_field(Data),Field+1);make_rows([Path|Paths],Result,Field)when Field==4-> make_rows(Paths,Result ++ make_field(Path) ++ "</TR>",0);make_rows([Path|Paths],Result,Field)-> make_rows(Paths,Result ++ make_field(Path),Field+1).%----------------------------------------------------------------------% make_fields(Path)-> String that is a field i a html table% Path is a name url tuple {Name,url}%----------------------------------------------------------------------make_field(Path)-> "<TD WIDTH=20%>" ++ get_name(Path) ++ "</TD>".%----------------------------------------------------------------------%get_name({Nae,Url})->String that represents a <A> tag in html. %----------------------------------------------------------------------get_name({Name,Url})-> "<A HREF=\"" ++ Url ++ "\" TARGET=app_frame>" ++ Name ++ "</A>".%----------------------------------------------------------------------% fill_out(Nr)-> String, that represent Nr fields in a html-table.%----------------------------------------------------------------------fill_out(Nr)when Nr==0-> [];fill_out(Nr)when Nr==4-> "<TD WIDTH=\"20%\" > </TD></TR>";fill_out(Nr)-> "<TD WIDTH=\"20%\"> </TD>" ++ fill_out(Nr+1).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%These functions starts applicatons and builds the page showing tools%%to start%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%---------------------------------------------------------------------- %Controls whether the user selected a tool to start%----------------------------------------------------------------------get_tools(Input)-> case httpd:parse_query(Input) of []-> no_tools; Tools-> FormatData=fun({_Name,Data}) -> list_to_atom(Data) end, SelectData= fun({Name,_Data}) -> string:equal(Name,"app") end, {tools,[FormatData(X)||X<-Tools,SelectData(X)]} end.%----------------------------------------------------------------------% Selects the data to start the applications the user has ordered % starting of %----------------------------------------------------------------------handle_apps([],State,_Cmd)-> {ok,State};handle_apps([Tool|Tools],State,Cmd)-> case ets:match_object(State#state.app_data,{Tool,{start,'_'}}) of []-> Started = case Cmd of start -> [Tool|State#state.started]; stop -> lists:delete(Tool,State#state.started) end, {ok,#state{priv_dir=State#state.priv_dir, app_data=State#state.app_data, supvis=State#state.supvis, web_data=State#state.web_data, started=Started}}; ToStart -> case handle_apps2(ToStart,State,Cmd) of {ok,NewState}-> handle_apps(Tools,NewState,Cmd); _-> handle_apps(Tools,State,Cmd) end end.%----------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?