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)); } }
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; } }
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); }
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); } } } } } } }
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, }); }