FormerMember

WEB BOI

Posted By FormerMember

The ScriptBasic distribution comes with a web server version of the language. It runs as a Windows process and is multi-threaded. The best part is you can run your BOI external scripts on the web server with no modification to your BOI specific code. The ScriptBasic application web server can run standalone or as a proxy to Apache.

Windows Service

I'm putting a couple examples together that reads the AR_Customer table with BOI and ODBC and displays the results in a web browser. My plan is to create a separate Windows install for the ScriptBasic web server.

If you're running Sage 100c, you can run your ScriptBasic web application in the 100 launcher's web browser.

This will be offered as open source and FREE.

  • FormerMember
    0 FormerMember

    This is an example of the ScriptBasic web server as a proxy to Apache running my echo example. I'm getting the ScriptBasic web server environment setup on my Windows 10 Pro laptop that has Sage 100 2020 running on it. The BOI  and ODBC examples will be posted soon.

    ' CGI Echo
    
    GLOBAL CONST nl = "\n"
    CONST NumberOfCookies = 3
    
    INCLUDE cgi.sbi
    
    OPTION cgi$Method cgi::Get OR cgi::Post
    
    cgi::Header 200,"text/html"
    
    FOR i = 1 TO NumberOfCookies
      ' cookie(i) is i, no domain is defined, path is /, expires after 10 seconds, not secure
      cgi::SetCookie "cookie" & i, i, undef, "/", gmtime() + 10, false
    NEXT
    
    cgi::FinishHeader
    
    '-------------------------------------------------------
    PRINT """
    <HTML>
    <HEAD>
    <title>CGI Echo</title>
    </HEAD>
    <BODY><font face="VERDANA" size="2">
    <H1>View CGI Parameters</H1>
    This page shows the CGI parameters the way it was uploaded.
    <!-- here is the result of the previous HTTP request -->
    <FONT SIZE="3">
    <PRE>
    CGI system variables
    --------------------
    
    """
    
    PRINT "ServerSoftware  = ", cgi::ServerSoftware(), nl
    PRINT "ServerName      = ", cgi::ServerName(), nl
    PRINT "GatewayInterface= ", cgi::GatewayInterface(),nl
    PRINT "ServerProtocol  = ", cgi::ServerProtocol(), nl
    PRINT "ServerPort      = ", cgi::ServerPort(), nl
    PRINT "RequestMethod   = ", cgi::RequestMethod(), nl
    PRINT "PathInfo        = ", cgi::PathInfo(), nl
    PRINT "PathTranslated  = ", cgi::PathTranslated(), nl
    PRINT "ScriptName      = ", cgi::ScriptName(), nl
    PRINT "QueryString     = ", cgi::QueryString(), nl
    PRINT "RemoteHost      = ", cgi::RemoteHost(), nl
    PRINT "RemoteAddress   = ", cgi::RemoteAddress(), nl
    PRINT "AuthType        = ", cgi::AuthType(), nl
    PRINT "RemoteUser      = ", cgi::RemoteUser(), nl
    PRINT "RemoteIdent     = ", cgi::RemoteIdent(), nl
    PRINT "ContentType     = ", cgi::ContentType(), nl
    PRINT "ContentLength   = ", cgi::ContentLength(), nl
    PRINT "UserAgent       = ", cgi::UserAgent(), nl
    PRINT "Cookie          = ", cgi::RawCookie(), nl
    
    PRINT "Referer         = ", cgi::Referer(), nl
    PRINT "Password        = ", Environ("HTTP_PASSWORD"), nl
    PRINT "Full auth string= ", Environ("HTTP_AUTHORIZATION"), nl
    PRINT "\nCookies:\n"
    FOR i = 1 TO NumberOfCookies
      PRINT "cookie" & i, " ", cgi::Cookie("cookie" & i), "\n"
    NEXT
    
    IF cgi::RequestMethod() = "GET" THEN
      PRINT "GET text field using GetParam(\"TEXT-GET\") is ", cgi::GetParam("TEXT-GET"), nl
    END IF
    
    IF cgi::RequestMethod() = "POST" THEN
      PRINT "POST text field using PostParam(\"TEXT-POST\") is ", cgi::PostParam("TEXT-POST"), nl
    END IF
    
    PRINT """
    </PRE>
    <TABLE>
      <TR>
        <TD BORDER=0 BGCOLOR="EEEEEE">
          <PRE>
          A simple form to POST parameters:<BR>
          <FORM METHOD="POST" ACTION="/home/echo">
            <INPUT TYPE="TEXT" VALUE="Default POST Field Text" NAME="TEXT-POST">
            <INPUT TYPE="SUBMIT" NAME="SUBMIT-BUTTON" VALUE=" POST ">
          </FORM>
          </PRE>
        </TD>
        <TD BORDER=1 width="20"> </TD>
        <TD BORDER=0 BGCOLOR="EEEEEE">
        <PRE>
        A simple form to GET parameters:<BR>
        <FORM METHOD="GET" ACTION="/home/echo">
          <INPUT TYPE="TEXT" VALUE="Default GET Field Text" NAME="TEXT-GET">
          <INPUT TYPE="SUBMIT" NAME="SUBMIT-BUTTON" VALUE=" GET ">
        </FORM>
      
        </TD>
      </TR>
    </TABLE>
    </BODY>
    </HTML>
    """

  • FormerMember
    0 FormerMember in reply to FormerMember

    One advantage of using the ScriptBasic web server is you are only using one seat. This means that user access (a login system) has to be built into your web application.  This type of extension to 100 could be used to allow your customers to check status of orders, place (purchase) orders, ... with real time access to data.

    The ScriptBasic web server is not a web service like Sage's eCommerce Web Services. It allows you to create web pages using Sage 100 data live. You can configure the ScriptBasic web server to only accept requests from defined IPs (like your Apache server) and a port of your choosing when running as a proxy server. Web sessions are are handled in the server's memory using cookies.

    Your Apache server could be running on Linux remotely on AWS if you wish. The SciptBasic proxy is just a directory on Apache.

  • FormerMember
    0 FormerMember in reply to FormerMember

    This is an example of a customer list using BOI and as a standalone web server. This environment would work great for a local area network based application,

    This is the ScriptBasic web server code.

    ' BOI Customer Contact - Web Page
    
    IMPORT cgi.sbi
    IMPORT com.sbi
    
    oscript = COM::CREATE(:SET, "ProvideX.Script")
    COM::CBN oScript, "Init", :CALL, "C:\\Sage\\Sage 100 Standard\\MAS90\\Home"
    osession = COM::CBN(oscript, "NewObject", :SET, "SY_Session")
    COM::CBN osession, "nSetUser", :CALL, "UserID", "Password"
    COM::CBN osession, "nsetcompany", :CALL, "ABC"
    COM::CBN osession, "nSetDate", :CALL, "A/R", "20210606"
    COM::CBN osession, "nSetModule", :CALL, "A/R"
    ocust = COM::CBN(oscript, "NewObject", :SET, "AR_Customer_svc", osession)
    
    cgi::Header 200,"text/html"
    cgi::FinishHeader
    
    PRINT """
    <html>
    <body>
    <table>
    <center><h1>ABC - Customer Contacts</h1></center>
    <table style="width:100%">
      <tr>
        <th>Customer Number</th>
        <th>Company Name</th>
        <th>Phone Number</th>
      </tr>
    """
    
    COM::CBN ocust,"nMoveFirst"
    DO UNTIL COM::CBN(ocust, "nEOF", :GET)
      PRINT "  <tr>\n"
      PRINT "    <td>",COM::CBN(ocust, "sCUSTOMERNO", :GET),"</td>\n"
      PRINT "    <td>",COM::CBN(ocust, "sCUSTOMERNAME", :GET),"</td>\n"
      PRINT "    <td>",COM::CBN(ocust, "sTELEPHONENO", :GET),"</td>\n"
      PRINT "  </tr>\n"
      COM::CBN ocust, "nMoveNext"
    LOOP
    PRINT """
    </table>
    </body>
    </html>
    """
    
    COM::CBN ocust, "DropObject"
    COM::RELEASE ocust
    COM::CBN osession, "DropObject"
    COM::RELEASE osession
    COM::RELEASE oscript
    

  • FormerMember
    0 FormerMember in reply to FormerMember

    This is an example of using the ScriptBasic web server standalone with ODBC.

    webodbc ScriptBasic web server code.

    ' ODBC Customer Contact - Web Page
    
    IMPORT cgi.sbi
    IMPORT odbc.sbi
    
    dbh = odbc::RealConnect("SAGE100","","")
    odbc::query(dbh,"SELECT * FROM AR_Customer")
    
    cgi::Header 200,"text/html"
    cgi::FinishHeader
    
    PRINT """
    <html>
    <header>
    <title>ScriptBasic 100 ODBC</title>
    </header>
    <body>
    <table>
    <center><h1>ABC - Customer Contacts</h1></center>
    <table style="width:100%">
      <tr>
        <th>Customer Number</th>
        <th>Company Name</th>
        <th>Phone Number</th>
      </tr>
    """
    
    WHILE odbc::FetchHash(dbh, column)
      PRINT "  <tr>\n"
      PRINT "    <td>", column{"CustomerNo"}, "</td>\n"
      PRINT "    <td>", column{"CustomerName"}, "</td>\n"
      PRINT "    <td>", column{"TelephoneNo"}, "</td>\n"
      PRINT "  </tr>\n"
    WEND
    
    PRINT """
    </table>
    </body>
    </html>
    """
    
    odbc::Close(dbh)

  • FormerMember
    0 FormerMember in reply to FormerMember

    This is the echo example running under XAMPP Apache and the ScriptBasic web server as a proxy. The Apache server doesn't need to run local on the 100 server and can run under Linux in the cloud.

  • FormerMember
    0 FormerMember in reply to FormerMember

    The ScriptBasic web server standalone is lightening fast on my laptop with a Sage 100 connection. ODBC reads of Sage 100 data has to be 10X faster than doing the same with BOI. The ScriptBasic web server currently doesn't serve up media built-in and you would have to be build the headers for them manually with SB code, Fearful This is good reason to run as a proxy as Apache handles the media, load leveling and security.

  • FormerMember
    0 FormerMember in reply to FormerMember

    I figured out how to embed images using ScriptBasic web server standalone.

    <center>
    <a href="#"><img src="https://opensage.org/picture_library/forum_logo.png"></a>
    <br>
    <h1>ABC - Customer Contacts</h1>
    </center>
    

  • FormerMember
    0 FormerMember in reply to FormerMember

    To get some community involvement going with the ScriptBasic web server I would like to create a sales order entry web version using this enviornment. I would be happy to do the ScriptBasic coding if someone(s) would chip in and do the html / css / Javascript side. I have asked David if he could help out with BOI part. I can do the pop-up lookups but anything more becomes a challenge.

    I'll include the project as an example with the ScriptBasic web server install I'm putting together.

  • FormerMember
    0 FormerMember in reply to FormerMember

    It seems JavaScript and CSS works with the ScriptBasic sbhttpd standalone web server. I might be abe to use a JavaScript framework for the UI design.

    ScriptBasic has built-in socket support so I might try getting a web socket interface going to make page updating more seamless.

    IMPORT cgi.sbi
    
    cgi::Header 200,"text/html"
    cgi::FinishHeader
    
    PRINT """
    <html>
    <head>
    <script>
    function startTime() {
      var today = new Date();
      var h = today.getHours();
      var m = today.getMinutes();
      var s = today.getSeconds();
      m = checkTime(m);
      s = checkTime(s);
      document.getElementById('txt').innerHTML =
      h + ":" + m + ":" + s;
      var t = setTimeout(startTime, 1000);
    }
    function checkTime(i) {
      if (i < 10) {i = "0" + i};  // add zero in front of numbers < 10
      return i;
    }
    </script>
    </head>
    
    <body onload="startTime()">
    <p style="font-family:Courier; color:Blue; font-weight:bold; font-size:24px;">Web Clock</p>
    
    <div id="txt"></div>
    
    </body>
    </html>
    """
    

  • FormerMember
    0 FormerMember in reply to FormerMember

    If anyone would like to give the ScriptBasic web server a try, send me an e-mai (see my profile) for copy and instructions how to install it. You should already have ScriptBasic core installed.