예제 #1
0
        public async Task <bool> RunAlgorithmAsync(string inputFilePath, string scriptFilePath,
                                                   System.Threading.CancellationToken ctk)
        {
            bool bHasCalcs = false;

            try
            {
                meta.ErrorMessage = string.Empty;
                if (string.IsNullOrEmpty(inputFilePath) || (!inputFilePath.EndsWith(".csv")))
                {
                    meta.ErrorMessage = "The dataset file URL has not been added to the Data URL. The file must be stored in a Resource and use a csv file extension.";
                }
                if (string.IsNullOrEmpty(scriptFilePath) || (!scriptFilePath.EndsWith(".txt")))
                {
                    meta.ErrorMessage += "The script file URL has not been added to the Joint Data.The file must be stored in a Resource and use a txt file extension.";
                }
                //unblock after debug
                if (!string.IsNullOrEmpty(meta.ErrorMessage))
                {
                    return(bHasCalcs);
                }
                StringBuilder sb = new StringBuilder();
                //get the path to the script executable
                string sScriptExecutable = CalculatorHelpers.GetAppSettingString(
                    this._params.ExtensionDocToCalcURI, "RExecutable");
                if (_algorithm == Calculator1.MATH_TYPES.algorithm3.ToString())
                {
                    //python must be installed to automatically run
                    sScriptExecutable = CalculatorHelpers.GetAppSettingString(
                        this._params.ExtensionDocToCalcURI, "PyExecutable");
                    if (_subalgorithm == Calculator1.MATH_SUBTYPES.subalgorithm1.ToString())
                    {
                        //python scripts must be run by executable as '.pyw' files
                        //save the 'txt' file as a 'pyw' file in temp path
                        //has to be done each time because can't be sure when scriptfile changed last
                        if (!scriptFilePath.EndsWith(".pyw"))
                        {
                            //allow the console to generate error messages
                            string sFileName         = Path.GetFileName(scriptFilePath);
                            string sPyScriptFileName = sFileName.Replace(".txt", ".pyw");
                            bool   bIsLocalCache     = false;
                            string sFilePath         = CalculatorHelpers.GetTempDocsPath(
                                _params.ExtensionDocToCalcURI, bIsLocalCache, sPyScriptFileName);
                            bool bHasFile = await CalculatorHelpers.CopyFiles(
                                _params.ExtensionDocToCalcURI, scriptFilePath, sFilePath);

                            scriptFilePath = sFilePath;
                            //216: pythonw.exe stopped accepting urls as input file paths (https redirect?)
                            sFileName = Path.GetFileName(inputFilePath);
                            sFilePath = CalculatorHelpers.GetTempDocsPath(
                                _params.ExtensionDocToCalcURI, bIsLocalCache, sFileName);
                            bool bHasCopied = await CalculatorHelpers.CopyWebFileToFileSystemAsync(
                                inputFilePath, sFilePath);

                            if (!string.IsNullOrEmpty(sFilePath))
                            {
                                inputFilePath = sFilePath;
                            }

                            //pre 216
                            //210: deprecated bottom code in favor of moving it to temp docs path -overcomes localhost:5509 versus 5000 debugging
                            //string sFileName = Path.GetFileName(scriptFilePath);
                            //bool bIsLocalCache = false;
                            //string sTempPath = CalculatorHelpers.GetTempDocsPath(_params.ExtensionDocToCalcURI, bIsLocalCache, sFileName);
                            //pre 210:
                            //bool bHasFile = CalculatorHelpers.SaveTextInURI(_params.ExtensionDocToCalcURI, sPyScript, sPyPath, out sError);
                            //bool bHasFile = await CalculatorHelpers.CopyFiles(
                            //    _params.ExtensionDocToCalcURI, scriptFilePath, sTempPath);
                            //scriptFilePath = sTempPath;
                            //pre 210
                            //string sPyScript = CalculatorHelpers.ReadText(_params.ExtensionDocToCalcURI, scriptFilePath, out sError);
                            //if (!string.IsNullOrEmpty(sPyScript))
                            //{
                            //    string sFileName = Path.GetFileName(scriptFilePath);
                            //    string sPyScriptFileName = sFileName.Replace(".txt", ".pyw");
                            //    bool bIsLocalCache = false;
                            //    string sPyPath = CalculatorHelpers.GetTempDocsPath(_params.ExtensionDocToCalcURI, bIsLocalCache, sPyScriptFileName);
                            //    bool bHasFile = CalculatorHelpers.SaveTextInURI(_params.ExtensionDocToCalcURI, sPyScript, sPyPath, out sError);
                            //    scriptFilePath = sPyPath;
                            //}
                        }
                    }
                    sb.AppendLine("python results");
                }
                else
                {
                    if (_subalgorithm == Calculator1.MATH_SUBTYPES.subalgorithm1.ToString())
                    {
                        //check for 2.0.2 -R Open can run from a url
                        //rscript.exe can't run from a url
                        if (scriptFilePath.StartsWith("http"))
                        {
                            //210: started using temp docs path -overcomes localhost:5509 versus 5000 debugging
                            string sFileName     = Path.GetFileName(scriptFilePath);
                            bool   bIsLocalCache = false;
                            string sTempPath     = CalculatorHelpers.GetTempDocsPath(_params.ExtensionDocToCalcURI, bIsLocalCache, sFileName);
                            bool   bHasFile      = await CalculatorHelpers.CopyFiles(
                                _params.ExtensionDocToCalcURI, scriptFilePath, sTempPath);

                            scriptFilePath = sTempPath;
                        }
                    }
                    //r is default
                    sb.AppendLine("r results");
                }
                List <string> lastLines = new List <string>();
                string        sLastLine = string.Empty;
                //2.0.2: algo 2 subalgo2 is r or algo 3 subalgo2 Python; subalgo 2 is virtual machine
                if (_subalgorithm == Calculator1.MATH_SUBTYPES.subalgorithm2.ToString())
                {
                    //run on remote servers that have the DevTreksStatsApi WebApi app deployed
                    string sStatType = Data.Helpers.StatScript.STAT_TYPE.r.ToString();
                    if (_algorithm == Calculator1.MATH_TYPES.algorithm3.ToString())
                    {
                        //python is significantly slower than R
                        sStatType = Data.Helpers.StatScript.STAT_TYPE.py.ToString();
                    }
                    else if (_algorithm == Calculator1.MATH_TYPES.algorithm6.ToString())
                    {
                        //julia has not been tested in 2.0.2
                        sStatType = Data.Helpers.StatScript.STAT_TYPE.julia.ToString();
                    }

                    DevTreks.Data.Helpers.StatScript statScript
                        = DevTreks.Data.Helpers.StatScript.GetStatScript(
                              sStatType, scriptFilePath, inputFilePath);
                    string sPlatformType = CalculatorHelpers.GetAppSettingString(
                        this._params.ExtensionDocToCalcURI, "PlatformType");
                    if (sPlatformType.Contains("azure"))
                    {
                        //webapi web domain
                        if (inputFilePath.Contains("localhost"))
                        {
                            statScript.DefaultWebDomain = "https://localhost:5001/";
                        }
                        else
                        {
                            statScript.DefaultWebDomain = "http://devtreksapi1.southcentralus.cloudapp.azure.com/";
                        }
                    }
                    else
                    {
                        if (inputFilePath.Contains("localhost"))
                        {
                            statScript.DefaultWebDomain = "https://localhost:5001/";
                        }
                        else
                        {
                            //run tests on cloud webapi site too
                            statScript.DefaultWebDomain = "http://devtreksapi1.southcentralus.cloudapp.azure.com/";
                        }
                    }
                    //use a console app to post to a webapi CreateClient controller action
                    bool bIsSuccess = await CalculatorHelpers.ClientCreate(statScript);

                    if (bIsSuccess)
                    {
                        if ((!string.IsNullOrEmpty(statScript.StatisticalResult)))
                        {
                            List <string> lines = CalculatorHelpers
                                                  .GetLinesFromUTF8Encoding(statScript.StatisticalResult);
                            if (lines != null)
                            {
                                if (lines.Count > 0)
                                {
                                    //store the result in the MathResult (or in the MathResult.URL below)
                                    sb.Append(statScript.StatisticalResult);
                                    sLastLine = lines.Last();
                                    int iLastIndex = lines.Count - 1;
                                    //datasets sometime inadvertently include blank end rows
                                    if (string.IsNullOrEmpty(sLastLine) &&
                                        iLastIndex > 0)
                                    {
                                        iLastIndex = lines.Count - 2;
                                        if (iLastIndex >= 0)
                                        {
                                            sLastLine = lines[iLastIndex];
                                        }
                                    }
                                    if (iLastIndex >= 2)
                                    {
                                        lastLines.Add(lines[iLastIndex - 2]);
                                    }
                                    if (iLastIndex >= 1)
                                    {
                                        lastLines.Add(lines[iLastIndex - 1]);
                                    }
                                    lastLines.Add(sLastLine);
                                }
                            }
                        }
                    }
                    else
                    {
                        if ((!string.IsNullOrEmpty(statScript.StatisticalResult)))
                        {
                            meta.MathResult += statScript.ErrorMessage;
                        }
                        else
                        {
                            meta.MathResult += "The remote server returned a successful response header but failed to generate the statistical results.";
                        }
                    }
                }
                else
                {
                    //default subalgo1 runs statpackages on the same server
                    lastLines = RunScript(sb, sScriptExecutable, scriptFilePath, inputFilePath);
                }
                if (lastLines.Count > 0)
                {
                    Shared.META_TYPE mType = await Shared.GetMetaType(_params, scriptFilePath);

                    bHasCalcs = await Shared.FillMathResult(meta, mType,
                                                            _params, sb, lastLines);

                    if (!bHasCalcs)
                    {
                        meta.MathResult = "The script did not run successfully. Please check the dataset and script. Verify their urls.";
                    }
                }
                else
                {
                    meta.MathResult = "The script did not run successfully. Please check the dataset and script. Verify their urls.";
                }
            }
            catch (Exception ex)
            {
                meta.ErrorMessage += ex.Message;
            }
            return(bHasCalcs);
        }