public IActionResult GetPreview(string projectId, [FromQuery] string sourcePath, [FromQuery] string dataset, [FromQuery] string userEmail)
        {
            try
            {
                if (string.IsNullOrEmpty(projectId) || string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(dataset) || string.IsNullOrEmpty(userEmail))
                {
                    return(BadRequest("Invalid request parameters"));
                }

                var projectDetailsRequestModel = new GetProjectDetailsRequestModel
                {
                    ProjectId        = projectId,
                    ExcludeResources = false,
                    UserEmail        = userEmail
                };
                var projectDetails = MongoConnector.GetProjectDetails(projectDetailsRequestModel);
                var requestModel   = new GetResourceDetailsRequestModel
                {
                    ProjectId  = projectId,
                    SourcePath = sourcePath,
                    UserEmail  = userEmail
                };

                var resourceDetails = MongoConnector.GetResourceDetails(requestModel);
                var userId          = MongoConnector.GetUserIdFromUserEmail(new GetUserIdRequestModel {
                    UserEmail = userEmail
                });

                var languageEntity = MongoConnector.GetLanguageEntity(new GetLanguageEntityRequestModel
                {
                    EntityId = projectDetails.SchemaId,
                });
                var partialModel = new GetPartialPagesDetailsRequestModel
                {
                    ProjectId = projectId,
                    UserEmail = userEmail
                };

                GetPartialPagesDetailsResponseModel partialPages = MongoConnector.GetPartialPagesDetails(partialModel);

                languageEntity = new KLanguageBase().GetKitsuneLanguage(userEmail, projectId, projectDetails, languageEntity, userId.Id);

                //Compile and get the call the single page preview api
                var result = _service.GetPreviewAsync(userEmail, projectId, resourceDetails, projectDetails, languageEntity, partialPages, dataset, userId.Id);

                if (result != null)
                {
                    return(Ok(result));
                }
                return(BadRequest("Unable to get the preview"));
            }
            catch (Exception ex)
            {
                return(BadRequest(ex.Message));
            }
        }
Example #2
0
        private static void UpdateForPublish(ref HtmlDocument document,
                                             CompileResourceRequest request,
                                             KEntity kentity,
                                             List <CompilerError> compileErrors,
                                             Dictionary <string, int> customVariables,
                                             GetProjectDetailsResponseModel projectDetails,
                                             GetPartialPagesDetailsResponseModel partialPages = null,
                                             List <KLanguageModel> componentEntities          = null,
                                             bool isCSRFPresent = false
                                             )
        {
            var htmlString = document.DocumentNode.OuterHtml.ToString();

            htmlString = htmlString.Replace("itemscope=\"\"", "itemscope");
            if (!string.IsNullOrEmpty(htmlString))
            {
                if (isCSRFPresent)
                {
                    htmlString = Constants.CSRFRegularExpression.Replace(htmlString, Constants.CSRFReplacementToken);
                }

                var lines = htmlString.Split('\n');

                var descendants = document.DocumentNode.Descendants();
                var kdlOb       = descendants.Where(s => s.Attributes[LanguageAttributes.KDL.GetDescription()] != null);
                //store temporary original KDL value before replacement of _system object
                var tempKDL = string.Empty;
                if (kdlOb != null && kdlOb.Any())
                {
                    tempKDL = kdlOb.FirstOrDefault().GetAttributeValue(LanguageAttributes.KDL.GetDescription(), null);
                }

                for (int i = 0; i < lines.Length; i++)
                {
                    ReplaceCustomVariables(customVariables, lines, i);
                    InjectPartialView(request, kentity, projectDetails, partialPages, lines, i);
                    ReplaceComponentEntities(projectDetails, componentEntities, lines, i);
                    SetObject(compileErrors, kentity, projectDetails, lines, i, request.ClassName);
                }
                htmlString = string.Join("\n", lines);
                document   = GetDocumentObject();
                document.LoadHtml(htmlString);

                //restore back the original k-dl attribute
                if (!string.IsNullOrEmpty(tempKDL))
                {
                    document.DocumentNode.Descendants().First(x => x.Attributes["k-dl"] != null).Attributes["k-dl"].Value = tempKDL;
                }
                htmlString = document.DocumentNode.OuterHtml;
            }
        }
Example #3
0
        public static ResourceCompilationResult CompileProjectResource(CompileResourceRequest req,
                                                                       GetPartialPagesDetailsResponseModel partialPages = null)
        {
            //Source path should always start with / (to make sure its from root folder)
            if (!string.IsNullOrEmpty(req.SourcePath))
            {
                req.SourcePath = string.Format("/{0}", req.SourcePath.Trim('/'));
            }
            else
            {
                return new ResourceCompilationResult {
                           Success = false, ErrorMessages = new List <CompilerError> {
                               new CompilerError {
                                   LineNumber = 1, LinePosition = 1, Message = "Source path can not be empty."
                               }
                           }
                }
            };

            if (!string.IsNullOrEmpty(req.FileContent))
            {
                var document = new HtmlDocument();

                CompileResult compileResult = null;
                try
                {
                    //If the file is html extension then only compile
                    if (Kitsune.Helper.Constants.DynamicFileExtensionRegularExpression.IsMatch(req.SourcePath.ToLower()))
                    {
                        try
                        {
                            var byteStream = Convert.FromBase64String(req.FileContent);
                            req.FileContent = System.Text.Encoding.UTF8.GetString(byteStream);
                        }
                        catch
                        {
                            return(new ResourceCompilationResult {
                                Success = false, ErrorMessages = new List <CompilerError> {
                                    new CompilerError {
                                        Message = "Input string is not valid base64 string"
                                    }
                                }
                            });
                        }

                        var projectDetailsRequestModel = new GetProjectDetailsRequestModel
                        {
                            ProjectId        = req.ProjectId,
                            ExcludeResources = false,
                            UserEmail        = req.UserEmail
                        };
                        var projectDetails = MongoConnector.GetProjectDetails(projectDetailsRequestModel);
                        if (projectDetails == null)
                        {
                            return new ResourceCompilationResult
                                   {
                                       Success       = false,
                                       ErrorMessages = new List <CompilerError> {
                                           new CompilerError {
                                               Message = "Project not found."
                                           }
                                       }
                                   }
                        }
                        ;



                        var user = MongoConnector.GetUserIdFromUserEmail(new GetUserIdRequestModel
                        {
                            UserEmail = req.UserEmail
                        });
                        var languageEntity = MongoConnector.GetLanguageEntity(new GetLanguageEntityRequestModel
                        {
                            EntityId = projectDetails.SchemaId,
                        });
                        languageEntity = new KLanguageBase().GetKitsuneLanguage(req.UserEmail, req.ProjectId, projectDetails, languageEntity, user.Id);

                        #region Handle Project Components
                        var componentEntities = GetComponentReference(projectDetails.Components);
                        #endregion

                        //Compile only if the file type is supported
                        compileResult = KitsuneCompiler.CompileHTML(req, out document, projectDetails, languageEntity, partialPages, componentEntities: componentEntities);
                    }
                    //Validate the config file
                    else if (Helper.Constants.ConfigFileRegularExpression.IsMatch(req.SourcePath))
                    {
                        var byteStream = Convert.FromBase64String(req.FileContent);
                        req.FileContent = System.Text.Encoding.UTF8.GetString(byteStream);
                        compileResult   = KitsuneCompiler.ValidateJsonConfig(new ValidateConfigRequestModel
                        {
                            File = new ConfigFile {
                                Content = req.FileContent
                            },
                            UserEmail = req.UserEmail
                        });
                        req.UrlPattern = req.SourcePath;
                        req.IsStatic   = false;
                    }
                }
                catch (Exception ex)
                {
                }

                if (compileResult != null && compileResult.ErrorMessages?.Count() > 0)
                {
                    return(new ResourceCompilationResult {
                        Success = false, ErrorMessages = compileResult.ErrorMessages
                    });
                }
                else
                {
                    return new ResourceCompilationResult {
                               Success = true
                    }
                };
            }

            return(new ResourceCompilationResult {
                Success = false, ErrorMessages = new List <CompilerError> {
                    new CompilerError {
                        Message = "Input should not be empty"
                    }
                }
            });
        }
        public async Task <ProjectPreview> GetPreviewAsync(string userEmail, string projectId, GetResourceDetailsResponseModel resourceDetails,
                                                           GetProjectDetailsResponseModel projectDetails,
                                                           KEntity languageEntity,
                                                           GetPartialPagesDetailsResponseModel partialPages,
                                                           string fpTag, string userId)
        {
            var    watch        = new Stopwatch();
            string compilerTime = "";

            watch.Start();

            ProjectPreview result = null;

            if (projectId != null && resourceDetails != null)
            {
                var doc = new HtmlAgilityPack.HtmlDocument();

                var compileResult = KitsuneCompiler.CompileHTML(new CompileResourceRequest
                {
                    UserEmail   = userEmail,
                    FileContent = resourceDetails.HtmlSourceString,
                    IsDev       = true,
                    IsPublish   = true,
                    ProjectId   = projectId,
                    SourcePath  = resourceDetails.SourcePath,
                    ClassName   = resourceDetails.ClassName,
                    IsPreview   = true
                }, out doc, projectDetails, languageEntity, partialPages);
                compilerTime += ", CompileHTML : " + watch.ElapsedMilliseconds.ToString();

                watch.Restart();
                var previewRes = "";
                if (!compileResult.Success)
                {
                    previewRes = ErrorCodeConstants.CompilationError;
                }
                else if (resourceDetails.IsStatic)
                {
                    previewRes = compileResult.CompiledString;
                }
                else
                {
                    try
                    {
                        var client = new HttpClient();
                        client.BaseAddress = new Uri("http://kitsune-demo-identifier-952747768.ap-south-1.elb.amazonaws.com");
                        byte[] bytes  = Encoding.UTF8.GetBytes(compileResult.CompiledString);
                        string base64 = Convert.ToBase64String(bytes);
                        var    obData = new KitsunePreviewModel
                        {
                            DeveloperId       = userId,
                            FileContent       = base64,
                            NoCacheQueryParam = null,
                            ProjectId         = projectId,
                            View       = resourceDetails.SourcePath,
                            WebsiteTag = fpTag
                        };
                        var jsonData = JsonConvert.SerializeObject(obData);

                        var response = await client.PostAsync("/home/kpreview", new StringContent(jsonData, Encoding.UTF8, "application/json"));

                        if (!((int)response.StatusCode >= 200 && (int)response.StatusCode <= 300))//If status code is not 20X, error.
                        {
                            // Log(response?.Content?.ReadAsStringAsync()?.Result);
                            throw new Exception(ErrorCodeConstants.UnableToGetPreview);
                        }
                        previewRes = response.Content.ReadAsStringAsync().Result;
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
                var previewTime = watch.ElapsedMilliseconds;
                result = new ProjectPreview
                {
                    HtmlString   = previewRes,
                    CompilerTime = compilerTime,
                    PreviewTime  = previewTime
                };
            }
            return(result);
        }
Example #5
0
        private static void InjectPartialView(CompileResourceRequest request, KEntity kentity, GetProjectDetailsResponseModel projectDetails, GetPartialPagesDetailsResponseModel partialPages, string[] lines, int i)
        {
            var partialregex  = Constants.PartialPageRegularExpression;
            var partialresult = partialregex.Matches(lines[i]);

            if (partialPages != null && partialPages.Resources != null && partialPages.Resources.Any())
            {
                for (int mc = 0; mc < partialresult.Count; mc++)
                {
                    if (partialresult[mc].Groups.Count > 1)
                    {
                        var groupparam = partialresult[mc].Groups[1].Value?.Trim('(', ')').Trim('\'').ToLower();
                        if (!string.IsNullOrEmpty(groupparam))
                        {
                            var partialViewParams = groupparam.Split(',');
                            var viewName          = partialViewParams[0]?.Trim('\'');

                            if (projectDetails.Resources.Any(x => x.PageType == Models.Project.KitsunePageType.PARTIAL && x.SourcePath.ToLower() == viewName.ToLower()))
                            {
                                var htmlData = new HtmlDocument();
                                htmlData.LoadHtml(partialPages.Resources.FirstOrDefault(x => string.Compare(x.SourcePath, viewName, true) == 0).HtmlSourceString);
                                //Support partial page with Html body and without body tag
                                string partialbody       = htmlData.DocumentNode.SelectSingleNode("/html/body")?.InnerHtml ?? htmlData.DocumentNode.OuterHtml;
                                var    partialCompiledOb = KitsuneCompiler.CompileHTML(new CompileResourceRequest
                                {
                                    FileContent = partialbody,
                                    IsPublish   = true,
                                    SourcePath  = viewName,
                                    PageType    = Models.Project.KitsunePageType.PARTIAL,
                                    ProjectId   = request.ProjectId,
                                    UserEmail   = request.UserEmail
                                }, out htmlData, projectDetails, kentity, partialPages);
                                if (partialCompiledOb != null && partialCompiledOb.Success)
                                {
                                    lines[i] = lines[i].Replace(partialresult[mc].Value, partialCompiledOb.CompiledString);
                                }
                            }
                        }
                    }
                }
            }
        }
Example #6
0
        public static CompileResult CompileHTML(CompileResourceRequest req, out HtmlDocument documentRef,
                                                GetProjectDetailsResponseModel projectDetails,
                                                KEntity kentity,
                                                GetPartialPagesDetailsResponseModel partialPages = null, bool subsequentCompilation = false, List <KLanguageModel> componentEntities = null) // partialPage is required only for the publish/preview
        {
            ///TODO : Handle the kitsune-settings.xml saperatly
            documentRef = GetDocumentObject();
            var filePath = req.SourcePath.Trim('/');

            if (!string.IsNullOrEmpty(req.FileContent))
            {
                HtmlDocument             document;
                List <CompilerError>     nfUXErrors      = new List <CompilerError>();
                Dictionary <string, int> customVariables = new Dictionary <string, int>();
                string rootUrl;

                DocumentPreprocessor.PreprocessDocument(req, kentity, filePath, out document, nfUXErrors, out rootUrl);
                documentRef = document;

                /*
                 * if (document.ParseErrors.Count() > 0)
                 * {
                 *  return CompileResultHelper.GetCompileResult(nfUXErrors, req.SourcePath, false);
                 * }
                 */
                req.UrlPattern = req.SourcePath; //assigning default urlpattern

                if (!req.IsStatic)
                {
                    if (kentity == null)
                    {
                        return(CompileResultHelper.GetErrorCompileResult("Schema not found for this project.", req.SourcePath));
                    }
                    else if (kentity.EntityName == null)
                    {
                        kentity.EntityName = Constants.KPayDefaultSchema;
                    }

                    HtmlDocument documentClone = GetDocumentObject();
                    documentClone.LoadHtml(document.DocumentNode.OuterHtml);
                    DocumentValidator validator = new DocumentValidator();
                    validator.ValidateDocument(documentClone, req, nfUXErrors, kentity, customVariables, rootUrl, filePath, projectDetails, componentEntities?.Select(x => x.Entity)?.ToList());
                    if (nfUXErrors.Count == 0)
                    {
                        if (req.IsPublish)
                        {
                            var csrfPresent = Constants.CSRFRegularExpression.IsMatch(document.DocumentNode.OuterHtml);

                            UpdateForPublish(ref document, req, kentity, nfUXErrors, customVariables, projectDetails, partialPages, componentEntities, csrfPresent);

                            if (req.PageType != Models.Project.KitsunePageType.PARTIAL)
                            {
                                HandleScriptInjection(document, req, kentity, rootUrl, projectDetails, csrfPresent);
                            }
                        }
                    }

                    /*
                     * KitsunePage myPage = (new NewRootNodeProcessor()).Process(document.DocumentNode.OuterHtml);
                     * var jsonSerializeSettings = new JsonSerializerSettings();
                     * jsonSerializeSettings.TypeNameHandling = TypeNameHandling.Objects;
                     * string output = JsonConvert.SerializeObject(myPage, Formatting.None, jsonSerializeSettings);
                     * //KitsunePage myNewPage = JsonConvert.DeserializeObject<KitsunePage>(output, jsonSerializeSettings);
                     */
                }
                UpdatePathsForPreview(req, document);
                if (nfUXErrors.Count > 0)
                {
                    return new CompileResult {
                               Success = false, ErrorMessages = nfUXErrors, PageName = req.SourcePath
                    }
                }
                ;
                else
                {
                    return new CompileResult {
                               Success = true, CompiledString = document.DocumentNode.OuterHtml.ToString(), ErrorMessages = nfUXErrors, PageName = req.SourcePath, CustomVariables = customVariables
                    }
                };
            }

            return(new CompileResult
            {
                Success = false,
                ErrorMessages = new List <CompilerError> {
                    new CompilerError {
                        Message = "Input should not be empty"
                    }
                },
                PageName = req.SourcePath,
            });
        }