------------------------------------------------------------------------------ -- -- -- DEMO EMBEDDED WEB INTERFACE TO THE R LANGUAGE -- -- -- -- WEBD -- -- (http://ecardio.uhosp.ro) -- -- -- -- Copyright (C) 2001-2003 Alexandru Dan Corlan MD PhD -- -- -- -- WEBD is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 2, or (at your option) any later ver- -- -- sion. It is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- -- for more details. You should have received a copy of the GNU General -- -- Public License distributed with GNAT; see file COPYING. If not, write -- -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, -- -- MA 02111-1307, USA. -- -- -- ------------------------------------------------------------------------------ with Ada.Interrupts; use Ada.Interrupts; with Ada.Interrupts.Names; use Ada.Interrupts.Names; package Unisig is protected Termination_Flag is procedure Termi; pragma Interrupt_Handler(Termi); pragma Attach_Handler(Termi,SIGQUIT); function Istermi return Boolean; private Stopit: Boolean:= False; end Termination_Flag; end Unisig; package body Unisig is protected body Termination_Flag is procedure Termi is begin Stopit := True; end Termi; function Istermi return Boolean is begin return Stopit; end Istermi; end Termination_Flag; end Unisig; with Ada.Text_IO; use Ada.Text_Io; with Gnat.Os_Lib; use Gnat.Os_Lib; with AWS.Response; with AWS.Server; with AWS.Status; with AWS.Default; with Aws.Parameters; with Aws.Mime; with Unisig; use Unisig; with Ada.Strings.Fixed; use Ada.Strings.Fixed; with Interfaces.C; use Interfaces.C; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; procedure Webd is WS : AWS.Server.HTTP; Root_Dir: String:= "/home/dcorlan/.www"; function Log_Frag(Request: Aws.Status.Data) return String is begin return Aws.Status.Http_Version(Request) & " FROM=" & Aws.Status.Peername(Request) & " URI=" & Aws.Status.Uri(Request) & " AGENT=" & Aws.Status.User_Agent(Request); end Log_Frag; protected Logfile is procedure Log(S: String); private Fi: File_Type; end Logfile; protected body Logfile is procedure Log(S: String) is begin Open(Fi,Append_File,Root_Dir & "/log/webd"); Put_Line(Fi,S); Close(Fi); end Log; end Logfile; type struct_sched_param is record sched_priority : Integer; -- scheduling priority end record; pragma Convention (C, struct_sched_param); -- the following are useful to control the scheduling method -- of the processes (scripts) which might be run from this task function Getpri(What: Integer; Who: Process_Id) return Integer; pragma Import(C, Getpri, "getpriority"); function Setpri(What: Integer; Who: Process_Id; Prio: Integer) return Integer; pragma Import(C, Setpri, "setpriority"); function Getsched(Pid: Process_Id) return Integer; pragma Import(C, Getsched, "sched_getscheduler"); function J_Getsched(Pid: Integer) return Integer; pragma Import(C, J_Getsched, "sched_getscheduler"); function Setsched (Pid: Process_Id; policy : Integer; param : access struct_sched_param) return Integer; pragma Import (C, Setsched, "sched_setscheduler"); protected Rjob is procedure Rrun(S: String; P:Aws.Parameters.List; Op: out Unbounded_String); private Crtj: Integer; Ng: Integer:= 0; Arg_List_Buff: Argument_List(1..10) := (others => null); Sccs: Boolean; Pid: Process_Id; X: Integer; Ssp: aliased Struct_Sched_Param; end Rjob; protected body Rjob is procedure Rrun(S: String; P: Aws.Parameters.List; Op: out Unbounded_String) is Job_Dir: String := Root_Dir & "/bin"; R_Filename: String:= Job_Dir & "/x.R"; Out_Filename: String:= Root_Dir & "/www/x.out"; Fi: File_Type; Ss: String(1..4096); Lst: Integer; function Par(Vname: String) return String is begin return Aws.Parameters.Get(P,Vname); end Par; begin Create(Fi,Out_File,R_Filename); Put_Line(Fi,"sink(""" & Out_Filename & """)"); if S="/RSCRIPT/chisq" then Put_Line(Fi,"cat(""
\n"")");
Put_Line(Fi,"cht <- chisq.test(matrix(c(" & Par("V1") &
", " & Par("V2") & ", " & Par("V3") & ", " & Par("V4") &
"),nrow=2))");
Put_Line(Fi, "cat(""Testul chi patrat
"")");
Put_Line(Fi, "cat(""Valori observate
"")");
Put_Line(Fi, "cat(""\n"")");
Put_Line(Fi, "print.default(cht$observed)");
Put_Line(Fi, "cat(""\n\n"")");
Put_Line(Fi, "cat(""Valori calculate
\n"")");
Put_Line(Fi, "print.default(cht$expected)");
Put_Line(Fi, "cat(""p ="", cht$p.value, ""
\n"")");
Put_Line(Fi,"cat(""\n
\n"")");
elsif S="/RSCRIPT/binom.conf" then
Put_Line(Fi,"cat(""\n"")");
Put_Line(Fi,"bt <- binom.test(" & Par("PL") & ", " & Par("NN") & ")");
Put_Line(Fi, "cat(""Date
\n"")");
Put_Line(Fi, "cat(""Esantionul are " & par("NN") & " cazuri din care "
& Par("PL") & " sunt pozitive.
\n"")");
Put_Line(Fi, "cat(""
Rezultate
\n"")");
Put_Line(Fi, "cat(""Cu probabilitate de 95% proportia pozitivilor "
& "in populatie este cuprinsa intre "", bt$conf.int[1] , "" si """
& ", bt$conf.int[2], ""
\n"")");
Put_Line(Fi,"cat(""\n\n"")");
elsif S="/RSCRIPT/specif" then
Put_Line(Fi,"cat(""
\n"")");
Put_Line(Fi,"realp <- " & Par("REALP"));
Put_Line(Fi,"realn <- " & Par("REALN"));
Put_Line(Fi,"falsp <- " & Par("FALSP"));
Put_Line(Fi,"falsn <- " & Par("FALSN"));
Put_Line(Fi,"tp <- " & Par("REALP") & "+" & Par("FALSN") );
Put_Line(Fi,"tn <- " & Par("REALN") & "+" & Par("FALSP"));
Put_Line(Fi,"sens <- " & Par("REALP") & "/ tp");
Put_Line(Fi,"spec <- " & Par("REALN") & "/ tn");
Put_Line(Fi,"ppv <- " & Par("REALP") & "/(" & Par("FALSP") & "+" & Par("REALP")
& ")");
Put_Line(Fi,"npv <- " & Par("REALN") & "/(" & Par("FALSN") & "+" & Par("REALN")
& ")");
Put_Line(Fi, "cat(""Date
\n"")");
Put_Line(Fi, "cat(""Real pozitivi="", realp, ""
\n"")");
Put_Line(Fi, "cat(""Real negativi="", realn, ""
\n"")");
Put_Line(Fi, "cat(""Fals pozitivi="", falsp, ""
\n"")");
Put_Line(Fi, "cat(""Fals negativi="", falsn, ""
\n"")");
Put_Line(Fi, "cat(""
Rezultate
\n"")");
Put_Line(Fi, "cat(""Sensibilitate = "", sens, ""
\n"")");
Put_Line(Fi, "cat(""Specificitate = "", spec, ""
\n"")");
Put_Line(Fi, "cat(""Valoare predictiva pozitiva = "", ppv, ""
\n"")");
Put_Line(Fi, "cat(""Valoare predictiva negativa = "", npv, ""
\n"")");
Put_Line(Fi,"cat(""\n\n"")");
end if;
Put_Line(Fi,"sink()");
Close(Fi);
Arg_List_Buff(1) := new String'("BATCH");
Arg_List_Buff(2) := new String'("--slave");
Arg_List_Buff(3) := new String'("--no-save");
Arg_List_Buff(4) := new String'("--no-restore");
Arg_List_Buff(5) := new String'(R_Filename);
-- Spawn("/usr/bin/R",Arg_List_Buff(1..5), Sccs);
-- Arg_List_Buff(1) := new String'("bajo");
Pid := Non_Blocking_Spawn("/usr/bin/R", Arg_List_Buff(1..5));
Ssp.Sched_Priority:=0;
X := Setsched(Pid,0,Ssp'Access); -- make the script have normal scheduling
Wait_Process(Pid,Sccs);
Open(Fi,In_File,Out_Filename);
loop
Get_Line(Fi,Ss,Lst);
Append(Op,Ss(1..Lst) & Ascii.Lf);
if End_Of_File(Fi) then
exit;
end if;
end loop;
Close(Fi);
end Rrun;
end Rjob;
function Page_Server (Request : in AWS.Status.Data)
return AWS.Response.Data is
P: Aws.Parameters.List:= Aws.Status.Parameters(Request);
In_Dir: String:= Root_Dir & "/www";
Uri: String:= Aws.Status.Uri(Request);
Urr: Unbounded_String:= To_Unbounded_String("");
begin
Logfile.Log(Log_Frag(Request));
if Uri="/" or else Index(Uri,"..")>0 then
return AWS.Response.File
(Content_Type => "text/html",
Filename => In_Dir & "/index.html");
elsif Uri(1..9)="/RSCRIPT/" then
Rjob.Rrun(Uri,P,Urr);
return Aws.Response.Build ("text/html", Urr);
elsif Is_Regular_File(Root_Dir & Uri) then
return AWS.Response.File
(Content_Type => AWS.MIME.Content_Type (Root_Dir & Uri),
Filename => Root_Dir & Aws.Status.Uri(Request));
else
return Aws.Response.Build ("text/html",
"
Sorry, """ & Uri & """ could not be found." & Ascii.Lf); end if; end Page_Server; begin AWS.Server.Start (WS, "webd", Max_Connection => 10, Port => 80, Callback => Page_Server'Unrestricted_Access); loop delay 1.0; if Termination_Flag.Istermi then exit; end if; end loop; Put_Line("OK, webd leaving gracefully."); AWS.Server.Shutdown (WS); end Webd;