webtool.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,205 行 · 第 1/3 页

ERL
1,205
字号
%execute every start or stop data about a tool.%----------------------------------------------------------------------handle_apps2([{Name,Start_data}],State,Cmd)->    case handle_app({Name,Start_data},State#state.app_data,State#state.supvis,Cmd) of	ok->	    Started = case Cmd of			  start ->			      [Name|State#state.started];			  stop ->			      			      lists:delete(Name,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}};	_->	    error    end;handle_apps2([{Name,Start_data}|Rest],State,Cmd)->    case handle_app({Name,Start_data},State#state.app_data,State#state.supvis,Cmd)of	ok->	    handle_apps2(Rest,State,Cmd);	_->	    error    end.%----------------------------------------------------------------------% Handle start and stop of applications%---------------------------------------------------------------------- handle_app({Name,{start,{func,Start,Stop}}},Data,_Pid,Cmd)->    Action = case Cmd of		 start ->		     Start;		 _ ->		     Stop	     end,        case Action of	{M,F,A} ->	    case catch apply(M,F,A) of		{'EXIT',_} = Exit->		    %%! Here the tool disappears from the webtool interface!!		    io:format("\n=======ERROR (webtool, line ~w) =======\n"			      "Could not start application \'~p\'\n\n"			      "~w:~w(~s) ->\n"			      "~p\n\n",			      [?LINE,Name,M,F,format_args(A),Exit]),		    ets:delete(Data,Name);		_OK->		    ok	    end;	_NoStart ->	    ok    end;	    handle_app({Name,{start,{child,ChildSpec}}},Data,Pid,Cmd)->    case Cmd of	start ->	    case catch supervisor:start_child(Pid,ChildSpec) of		{ok,_}->		    ok;		{ok,_,_}->		    ok;		{error,Reason}->		    %%! Here the tool disappears from the webtool interface!!		    io:format("\n=======ERROR (webtool, line ~w) =======\n"			      "Could not start application \'~p\'\n\n"			      "supervisor:start_child(~p,~p) ->\n"			      "~p\n\n",			      [?LINE,Name,Pid,ChildSpec,{error,Reason}]),		    ets:delete(Data,Name);		Error ->		    %%! Here the tool disappears from the webtool interface!!		    io:format("\n=======ERROR (webtool, line ~w) =======\n"			      "Could not start application \'~p\'\n\n"			      "supervisor:start_child(~p,~p) ->\n"			      "~p\n\n",			      [?LINE,Name,Pid,ChildSpec,Error]),		    ets:delete(Data,Name)	    end;	stop ->	    case catch supervisor:terminate_child(websup,element(1,ChildSpec)) of		ok ->		    supervisor:delete_child(websup,element(1,ChildSpec));		_ ->		    error	    end    end;handle_app({Name,{start,{app,Real_name}}},Data,_Pid,Cmd)->    case Cmd of	start ->	    case application:start(Real_name,temporary) of		ok->		    io:write(Name),		    ok;		{error,{already_started,_}}->		    %% Remove it from the database so we dont start		    %% anything already started		    ets:match_delete(Data,{Name,{start,{app,Real_name}}}),		    ok;		{error,_Reason}=Error->		    %%! Here the tool disappears from the webtool interface!!		    io:format("\n=======ERROR (webtool, line ~w) =======\n"			      "Could not start application \'~p\'\n\n"			      "application:start(~p,~p) ->\n"			      "~p\n\n",			      [?LINE,Name,Real_name,temporary,Error]),		    ets:delete(Data,Name)	    end;		stop ->	    application:stop(Real_name)    end;%----------------------------------------------------------------------% If the data is incorrect delete the app%----------------------------------------------------------------------handle_app({Name,Incorrect},Data,_Pid,Cmd)->    %%! Here the tool disappears from the webtool interface!!    io:format("\n=======ERROR (webtool, line ~w) =======\n"	      "Could not ~w application \'~p\'\n\n"	      "Incorrect data: ~p\n\n",	      [?LINE,Cmd,Name,Incorrect]),    ets:delete(Data,Name).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                                                                  %%%% this functions creates the page that shows the unstarted tools   %%%%                                                                  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%reload_started_apps()->    "<script>        function reloadCompiledList()        {          parent.parent.top1.document.location.href=\"/webtool/webtool/started_tools\";        }     </script>".show_unstarted_apps(State)->  "<TABLE HEIGHT=100%  WIDTH=100% BORDER=0>     <TR HEIGHT=80%><TD ALIGN=\"center\" VALIGN=\"middle\">       <FORM NAME=\"stop_apps\" ACTION=\"/webtool/webtool/start_tools\" >       <TABLE BORDER=1 WIDTH=60%>	 <TR BGCOLOR=\"#8899AA\">	   <TD ALIGN=CENTER COLSPAN=2><FONT SIZE=4>Available Tools<FONT></TD>	 </TR> 	<TR>	   <TD WIDTH=50%>	       <TABLE BORDER=0>	           "++ list_available_apps(State)++"                   <TR><TD COLSPAN=2>&nbsp;</TD></TR>                   <TR>                      <TD COLSPAN=2 ALIGN=\"center\">                         <INPUT TYPE=submit VALUE=\"Start\">                      </TD>                   </TR>                </TABLE>            </TD>           <TD>                To Start a Tool:             <UL>             <LI>Select the             checkbox for each tool to             start.</LI>             <LI>Click on the              button marked <EM>Start</EM>.</LI></UL>            </TD>                  </TR>      </TABLE>     </FORM>   </TD></TR>   <TR><TD>&nbsp;</TD></TR>   </TABLE>".list_available_apps(State)->    MS = ets:fun2ms(fun({Tool,{web_data,{Name,_}}}) -> {Tool,Name} end),    Unstarted_apps=	lists:filter(	  fun({Tool,_})->		  false==lists:member(Tool,State#state.started)	  end,	  ets:select(State#state.app_data,MS)),    case Unstarted_apps of	[]->	    "<TR><TD>All tools are started</TD></TR>";	_->	    list_apps(Unstarted_apps)    end.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                                                                  %%%% these functions creates the page that shows the started apps     %%%% the user can select to shutdown                                  %%%%                                                                  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%show_started_apps(State)->  "<TABLE HEIGHT=100%  WIDTH=100% BORDER=0>     <TR HEIGHT=80%><TD ALIGN=\"center\" VALIGN=\"middle\">       <FORM NAME=\"stop_apps\" ACTION=\"/webtool/webtool/stop_tools\" >       <TABLE BORDER=1 WIDTH=60%>	 <TR BGCOLOR=\"#8899AA\">	   <TD ALIGN=CENTER COLSPAN=2><FONT SIZE=4>Started Tools<FONT></TD>	 </TR> 	<TR>	   <TD WIDTH=50%>	       <TABLE BORDER=0>	           "++ list_started_apps(State)++"                   <TR><TD COLSPAN=2>&nbsp;</TD></TR>                   <TR>                      <TD COLSPAN=2 ALIGN=\"center\">                         <INPUT TYPE=submit VALUE=\"Stop\">                      </TD>                   </TR>                </TABLE>            </TD>           <TD>                Stop a Tool:             <UL>             <LI>Select the             checkbox for each tool to             stop.</LI>             <LI>Click on the              button marked <EM>Stop</EM>.</LI></UL>            </TD>                  </TR>      </TABLE>     </FORM>   </TD></TR>   <TR><TD>&nbsp;</TD></TR>   </TABLE>".list_started_apps(State)->    MS = lists:map(fun(A) -> {{A,{web_data,{'$1','_'}}},[],[{{A,'$1'}}]} end,		   State#state.started),    Started_apps= ets:select(State#state.app_data,MS),    case Started_apps of	[]->	    "<TR><TD>No tool is started yet.</TD></TR>";	_->	    list_apps(Started_apps)    end.list_apps(Apps) ->      lists:map(fun({Tool,Name})->			"<TR><TD>                            <INPUT TYPE=\"checkbox\" NAME=\"app\" VALUE=\""  			    ++ atom_to_list(Tool) ++ "\">                               " ++ Name ++ "                                 </TD></TR>"		end,		Apps).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                                                                   %%%% Collecting the data from the  *.tool files                        %%%%                                                                   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%----------------------------------------% get_tools(Dirs) => [{M,F,A},{M,F,A}...{M,F,A}]%   Dirs - [string()] Directory names% Calls get_tools2/2 recursively for a number of directories% to retireve the configuration data for the web based tools.%----------------------------------------get_tools1(Dirs)->    get_tools1(Dirs,[]).get_tools1([Dir|Rest],Data) when is_list(Dir) ->    Tools=case filename:basename(Dir) of	      %% Dir is an 'ebin' directory, check in '../priv' as well	      "ebin" ->		  [get_tools2(filename:join(filename:dirname(Dir),"priv")) |		   get_tools2(Dir)];	      _ ->		  get_tools2(Dir)	  end,    get_tools1(Rest,[Tools|Data]);get_tools1([],Data) ->  lists:flatten(Data).%----------------------------------------% get_tools2(Directory) => DataList%   DataList : [WebTuple]|[]%   WebTuple: {tool,[{web,M,F,A}]}%%----------------------------------------get_tools2(Dir)->    get_tools2(tool_files(Dir),[]).get_tools2([ToolFile|Rest],Data) ->    case get_tools3(ToolFile) of	{tool,WebData} ->	    get_tools2(Rest,[{tool,WebData}|Data]);	{error,_Reason} ->	    get_tools2(Rest,Data);	nodata ->	    get_tools2(Rest,Data)    end;get_tools2([],Data) ->    Data.%----------------------------------------% get_tools3(ToolFile) => {ok,Tool}|{error,Reason}|nodata %   Tool: {tool,[KeyValTuple]}%   ToolFile - string() A .tool file%   Now we have the file get the data and sort it out%----------------------------------------get_tools3(ToolFile) ->    case file:consult(ToolFile) of	{error,open} ->	    {error,nofile};	{error,read} ->	    {error,format};	{ok,[{version,"1.2"},ToolInfo]} when is_list(ToolInfo)->	    webdata(ToolInfo);	{ok,[{version,_Vsn},_Info]} ->	    {error,old_version};	{ok,_Other} ->	    {error,format}    end.%----------------------------------------------------------------------% webdata(TupleList)-> ToolTuple| nodata% ToolTuple: {tool,[{config_func,{M,F,A}}]}%% There are a little unneccesary work in this format but it is extendable%----------------------------------------------------------------------webdata(TupleList)->     case httpd_util:key1search(TupleList,config_func,nodata) of	{M,F,A} ->	    {tool,[{config_func,{M,F,A}}]};	_ ->	   nodata    end.%=============================================================================% Functions for getting *.tool configuration files%=============================================================================%----------------------------------------% tool_files(Dir) => ToolFiles%   Dir - string() Directory name%   ToolFiles - [string()]% Return the list of all files in Dir ending with .tool (appended to Dir)%----------------------------------------tool_files(Dir) ->    case file:list_dir(Dir) of	{ok,Files} ->	    filter_tool_files(Dir,Files);	{error,_Reason} ->	    []    end.%----------------------------------------% filter_tool_files(Dir,Files) => ToolFiles%   Dir - string() Directory name%   Files, ToolFiles - [string()] File names% Filters out the files in Files ending with .tool and append them to Dir%----------------------------------------filter_tool_files(_Dir,[]) ->    [];filter_tool_files(Dir,[File|Rest]) ->    case filename:extension(File) of	".tool" ->	    [filename:join(Dir,File)|filter_tool_files(Dir,Rest)];	_ ->	    filter_tool_files(Dir,Rest)    end.%%%-----------------------------------------------------------------%%% format functionsffunc({M,F,A}) when is_list(A) ->    io_lib:format("~w:~w(~s)\n",[M,F,format_args(A)]);ffunc({M,F,A}) when is_integer(A) ->    io_lib:format("~w:~w/~w\n",[M,F,A]).format_args([]) ->    "";format_args(Args) ->    Str = lists:append(["~p"|lists:duplicate(length(Args)-1,",~p")]),    io_lib:format(Str,Args).

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?