Beispiel #1
0
        /// <summary><![CDATA[
        /// Process Carbide dependencies on startup
        /// ]]></summary>
        private void InjectCarbideDependencies(object sender, EventArgs e)
        {
            var tabExists = false;
            var file      = "/config/Dashboard.config";
            var aliases   = Config.GetConfigFileValues(file, "//dashBoard/section/@alias");

            foreach (var alias in aliases)
            {
                if (alias == "CarbideContentTools")
                {
                    tabExists = true;
                    break;
                }
            }

            if (Config.GetKeyValue <bool>("Tabs.Content.Enabled", true, "Fynydd.Carbide"))
            {
                if (tabExists == false)
                {
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(StorageHelpers.MapPath(file));

                    XmlNode     root     = xmlDoc.DocumentElement;
                    XmlDocument fragment = new XmlDocument();
                    fragment.LoadXml(StorageHelpers.CarbideEmbeddedHtml("DashControl.xml"));
                    XmlNode tab = xmlDoc.ImportNode(fragment.DocumentElement, true);

                    root.InsertBefore(tab, root.FirstChild);

                    xmlDoc.Save(StorageHelpers.MapPath(file));
                }
            }

            else
            {
                if (tabExists == true)
                {
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(StorageHelpers.MapPath(file));

                    XmlNodeList xnList = xmlDoc.SelectNodes("//dashBoard/section[@alias='CarbideContentTools']");

                    foreach (XmlNode node in xnList)
                    {
                        node.ParentNode.RemoveChild(node);
                    }

                    xmlDoc.Save(StorageHelpers.MapPath(file));
                }
            }

            // Remove event hook to ensure it only runs once
            UmbracoApplicationBase.ApplicationInit -= InjectCarbideDependencies;
        }
Beispiel #2
0
        /// <summary><![CDATA[
        /// Retrieve XML node data from a config file.
        /// ]]></summary>
        /// <param name="configFilePath">Web style path to the config file</param>
        /// <param name="nodePath">XPath for node selection</param>
        /// <returns>Enumerable string array of values</returns>
        public static string[] GetConfigFileValues(string configFilePath, string nodePath)
        {
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.Load(StorageHelpers.MapPath(configFilePath));
            XmlNodeList   nodeList = xmlDoc.DocumentElement.SelectNodes(nodePath);
            List <string> result   = new List <string>();

            foreach (XmlNode node in nodeList)
            {
                result.Add(node.InnerText);
            }

            return(result.ToArray());
        }
Beispiel #3
0
        /// <summary><![CDATA[
        /// Generate CSV data from a SQL Server data request, and write it to a file. Converts quotation marks to "&quot;".
        /// ]]></summary>
        /// <param name="select">SQL Server command to execute, which retrieves a dataset.</param>
        /// <param name="connectionStringName">Connection string name in the Web.config file.</param>
        /// <param name="includeHeaders">Include column names as a header row in the CSV file.</param>
        /// <param name="alwaysUseQuotes">Wrap all values in quotation marks. False will omit quotation marks around numeric values.</param>
        /// <param name="filePath">Web-style path and filename for the output of the data.</param>
        /// <returns>True if the file was written successfully.</returns>
        public static bool ExportCSV(string select, string connectionStringName, bool includeHeaders, bool alwaysUseQuotes, string filePath)
        {
            bool result = false;

            StringBuilder CSV = new StringBuilder();

            CSV = GenerateCSV(select, connectionStringName, includeHeaders, alwaysUseQuotes);

            StorageHelpers.WriteFile(filePath, CSV.ToString());

            if (StorageHelpers.FileExists(filePath))
            {
                result = true;
            }

            return(result);
        }
Beispiel #4
0
        /// <summary><![CDATA[
        /// Wrapper method for building CSS from SCSS files, with partial injection.
        /// Will check and build every "Scss.BuildCheck.Seconds" when debug=true if there are file changes (production).
        /// Will check and build every page load when debug=true if there are file changes.
        /// Requires the following Carbide config items:
        /// ]]></summary>
        /// <example>
        /// <code><![CDATA[
        /// <add key="Scss.BuildCheck.Seconds" value="3600" />
        /// <add key="Scss.Root" value="/scss/" />
        /// <add key="Scss.Partials.Root" value="/scss/custom/" />
        /// <add key="Scss.Filename.Base" value="application" />
        /// <add key="Scss.Output.Root" value="/css/" />
        /// ]]></code>
        /// </example>
        public static void RunConfiguredScssBuild()
        {
            var scssPath         = Config.GetKeyValue("Scss.Root", "/scss/", "Fynydd.Carbide");
            var scssPartialsPath = Config.GetKeyValue("Scss.Partials.Root", "/scss/custom/", "Fynydd.Carbide");
            var scssFilenameBase = Config.GetKeyValue("Scss.Filename.Base", "application", "Fynydd.Carbide");
            var scssOutputPath   = Config.GetKeyValue("Scss.Output.Root", "/css/", "Fynydd.Carbide");

            var debugging = AppStateHelpers.IsDebugging();
            var buildScss = debugging; // Always run in debug mode

            if (debugging == false)
            {
                // Only run the check periodically on production unless the file doesn't exist

                if (FileExists(scssOutputPath + scssFilenameBase + ".css") == false)
                {
                    buildScss = true;
                }

                TemporalHelpers.TaskIntervalInit("ScssProductionBuild", Config.GetKeyValue <double>("Scss.BuildCheck.Seconds", 60 * 60 * 24, "Fynydd.Carbide"));

                if (TemporalHelpers.TaskShouldBeRun("ScssProductionBuild"))
                {
                    buildScss = true;
                }
            }

            if (buildScss == true)
            {
                if (debugging == false)
                {
                    TemporalHelpers.TaskIntervalStart("ScssProductionBuild");
                }

                StorageHelpers.InjectScssPartials(scssPath, scssFilenameBase + ".scss", scssPartialsPath);
                StorageHelpers.BuildScss(scssPath + scssFilenameBase + ".scss", scssOutputPath + scssFilenameBase + ".css", debugMode: debugging);

                if (debugging == false)
                {
                    TemporalHelpers.TaskIntervalStop("ScssProductionBuild");
                }
            }
        }
Beispiel #5
0
        public HttpResponseMessage Svg(int id, bool clean = false, string color = "") // /umbraco/api/carbidefile/svg/?id=1024&color=008BFF
        {
            string result = "";

            try
            {
                var umbracoHelper = new UmbracoHelper(Carbide.ContextHelpers.EnsureUmbracoContext());
                var svg           = umbracoHelper.TypedMedia(id);

                if (svg != null)
                {
                    result = StorageHelpers.ReadFile(svg.Url);

                    if (result.Length > 0)
                    {
                        if (result.Contains("<svg "))
                        {
                            if (clean)
                            {
                                result = MediaHelpers.CleanSvg(result, removeStyles: false, fixStyles: false, removeXmlHeader: false);
                            }

                            if (color != "" && color.Length < 10)
                            {
                                result = MediaHelpers.CleanSvg(result, removeStyles: true, fixStyles: false, removeXmlHeader: false);
                                result = Regex.Replace(result, "#[0-9a-fA-F]{6,8}", color.FixHexColor(), RegexOptions.Singleline);
                                result = result.Replace("<svg ", "<svg style=\"fill: " + color.FixHexColor() + ";\" ");
                            }
                        }
                    }
                }
            }

            catch
            {
            }

            var response = new HttpResponseMessage(HttpStatusCode.OK);

            response.Content = new StringContent(result, Encoding.UTF8, "image/svg+xml");
            return(response);
        }
Beispiel #6
0
        /// <summary><![CDATA[
        /// Remove comments and style attributes from SVG markup.
        /// ]]></summary>
        /// <param name="svg">SVG markup to clean.</param>
        /// <param name="removeStyles">If true, svg style property is removed.</param>
        /// <param name="fixStyles">Ensure unique svg id and style classes are scoped to that id.</param>
        /// <param name="removeXmlHeader">Removes the XML document header.</param>
        /// <returns>Cleaned SVG markup.</returns>
        public static string CleanSvg(string svg, bool removeStyles = false, bool fixStyles = true, bool removeXmlHeader = true)
        {
            var result = svg;
            var svgId  = "SVG" + StorageHelpers.MakeUniqueFilenameFromExtension("").TrimEnd(".");

            // Remove comments
            result = Regex.Replace(result, "<!--.*?-->", String.Empty, RegexOptions.Singleline);

            if (removeXmlHeader)
            {
                // Remove XML header
                result = Regex.Replace(result, @"<[\?]xml.*?[\?]>", String.Empty, RegexOptions.Singleline);
            }

            // Remove styles?
            if (removeStyles)
            {
                // Removes embedded style blocks
                // result = Regex.Replace(result, "<style.*?</style>", String.Empty, RegexOptions.Singleline);

                MatchCollection matches = Regex.Matches(result, @"<svg[^>]* (style=['\""].*?['\""])[^>]*>", RegexOptions.Singleline);

                if (matches.Count > 0)
                {
                    foreach (Match match in matches)
                    {
                        foreach (Group group in match.Groups)
                        {
                            if (!group.Value.StartsWith("<svg"))
                            {
                                result = result.Replace(group.Value, "");
                            }
                        }
                    }
                }
            }

            // Fix embedded styles to class names are scoped locally
            else
            {
                if (fixStyles)
                {
                    // Assign a unique id to prevent in-page conflicts
                    MatchCollection matches = Regex.Matches(result, @"<svg[^>]* id=['\""](.*?)['\""][^>]*>", RegexOptions.Singleline);

                    if (matches.Count > 0)
                    {
                        foreach (Match match in matches)
                        {
                            foreach (Group group in match.Groups)
                            {
                                if (!group.Value.StartsWith("<svg"))
                                {
                                    result = result.Replace("id=\"" + group.Value, "id=\"" + svgId);
                                    result = result.Replace("id='" + group.Value, "id='" + svgId);
                                }
                            }
                        }
                    }

                    else
                    {
                        result = result.Replace("<svg ", "<svg id=\"" + svgId + "\" ");
                    }

                    if (result.Contains("<style"))
                    {
                        matches = Regex.Matches(result, @"\s*>*}*(\.[\w\d-]*)\s*{.*?", RegexOptions.Singleline);

                        foreach (Match match in matches)
                        {
                            foreach (Group group in match.Groups)
                            {
                                if (!group.Value.EndsWith("{"))
                                {
                                    result = result.Replace(group.Value, "#" + svgId + " " + group.Value);
                                }
                            }
                        }
                    }
                }
            }

            return(result.Trim());
        }
Beispiel #7
0
        /// <summary><![CDATA[
        /// Include a URL asset into a web page using relative paths. Optionally add dynamic cachebuster and minify JS and CSS files.
        /// ]]></summary>
        /// <param name="url">UrlHelper object</param>
        /// <param name="contentPath">Relative path to the asset</param>
        /// <param name="addCacheBuster">If true, appends a cachebuster to the generated URL from the file modification date</param>
        /// <param name="minify">If true minifies CSS and JS assets as new files and points the URL to them instead</param>
        /// <param name="fallback">If cachebuster fails, use this fallback value</param>
        /// <returns></returns>
        public static string Content(this UrlHelper url, string contentPath, bool addCacheBuster = false, bool minify = false, string fallback = "")
        {
            var queryString = contentPath.QueryString();
            var filePath    = contentPath.RemoveQueryString();

            try
            {
                if (minify && !filePath.StartsWith("_carbide.generated."))
                {
                    if (filePath.EndsWith(".js") || filePath.EndsWith(".css"))
                    {
                        bool proceed        = true;
                        var  newContentpath = "";

                        if (filePath.Contains("/"))
                        {
                            newContentpath = filePath.Substring(0, filePath.LastIndexOf("/") + 1) + "_carbide.generated." + filePath.Substring(filePath.LastIndexOf("/") + 1);
                        }

                        else
                        {
                            newContentpath = "_carbide.generated." + filePath;
                        }

                        FileInfo fileInfo     = new FileInfo(StorageHelpers.MapPath(filePath));
                        DateTime lastModified = fileInfo.LastWriteTime;
                        var      item         = fileInfo.Length + "|" + lastModified.DateFormat(Carbide.Constants.DateFormats.Utc);

                        if (HttpContext.Current.Application.KeyExists(StorageHelpers.ConvertFilePathToKey(filePath)))
                        {
                            if (HttpContext.Current.Application[StorageHelpers.ConvertFilePathToKey(filePath)].ToString() == item)
                            {
                                if (StorageHelpers.FileExists(newContentpath))
                                {
                                    filePath = newContentpath;
                                    proceed  = false;
                                }
                            }

                            else
                            {
                                if (StorageHelpers.FileExists(filePath) == false)
                                {
                                    filePath = newContentpath;
                                    proceed  = false;
                                }
                            }
                        }

                        else
                        {
                            if (StorageHelpers.FileExists(filePath) == false)
                            {
                                proceed = false;
                            }
                        }

                        if (proceed)
                        {
                            if (StorageHelpers.FileExists(newContentpath))
                            {
                                StorageHelpers.DeleteFiles(newContentpath);
                            }

                            var minified = "";

                            if (filePath.EndsWith(".js"))
                            {
                                var jsc = new JavaScriptCompressor();
                                minified = jsc.Compress(StorageHelpers.ReadFile(filePath));
                            }

                            if (filePath.EndsWith(".css"))
                            {
                                var cssc = new CssCompressor();
                                minified = cssc.Compress(StorageHelpers.ReadFile(filePath));
                            }

                            StorageHelpers.WriteFile(newContentpath, minified);

                            Debug.WriteLine("MINIFIED TO " + newContentpath);

                            fileInfo     = new FileInfo(StorageHelpers.MapPath(filePath));
                            lastModified = fileInfo.LastWriteTime;
                            item         = fileInfo.Length + "|" + lastModified.DateFormat(Carbide.Constants.DateFormats.Utc);

                            HttpContext.Current.Application[StorageHelpers.ConvertFilePathToKey(filePath)] = item;

                            filePath = newContentpath;
                        }

                        else
                        {
                            Debug.WriteLine("SKIPPED MINIFICATION FOR " + filePath);
                        }
                    }
                }

                if (addCacheBuster)
                {
                    queryString += (queryString.Contains("?") ? "&" : "?") + "_cachebuster=" + StorageHelpers.MakeCacheBuster(filePath, fallback);
                }
            }

            catch (Exception e)
            {
                Debug.WriteLine(e);
            }

            return(url.Content(filePath + queryString));
        }
Beispiel #8
0
        public HttpResponseMessage RebuildImageCache() // /umbraco/api/carbidesupport/rebuildimagecache/
        {
            string result = "";

            if (HttpContext.Current.Application["RebuildCacheStatus"] == null)
            {
                var context = HttpContext.Current;

                context.Application["RebuildCacheStatus"]  = "running";
                context.Application["RebuildCacheHistory"] = "<h4 style=\"font-size: 1.1rem; margin-bottom: 1.5rem;\">Started " + TemporalHelpers.DateFormat(DateTime.Now, DateFormats.European).ToUpper() + " @ " + TemporalHelpers.TimeFormat(DateTime.Now, TimeFormats.SqlMilitary) + "</h4>";

                result = context.Application["RebuildCacheHistory"].ToString();

                Thread workerThread = new Thread(new ThreadStart(() =>
                {
                    StopWatch timer  = new StopWatch();
                    StopWatch timer2 = new StopWatch();

                    try
                    {
                        timer.Start();
                        context.Server.ScriptTimeout = 100000;

                        context.Application["RebuildCacheHistory"] += "<ol style=\"padding: 0.25rem 0 0 1rem;\">";

                        context.Application["RebuildCacheHistory"] += "<li style=\"padding-bottom: 1rem;\">Clearing cached images... ";
                        timer2.Start();

                        foreach (var folder in StorageHelpers.GetFolders("/App_Data/cache/"))
                        {
                            StorageHelpers.DeleteDirectory("/App_Data/cache/" + folder);

                            if (StorageHelpers.DirectoryExists("/App_Data/cache/" + folder))
                            {
                                // Retry up to 5 times after pausing...

                                int retry = 0;

                                string original = context.Application["RebuildCacheHistory"].ToString();

                                while (retry < 5)
                                {
                                    retry++;

                                    context.Application["RebuildCacheHistory"] = original + "cache/" + folder + " retry " + retry;

                                    TemporalHelpers.PauseExecution(1);

                                    if (StorageHelpers.DirectoryExists("/App_Data/cache/" + folder))
                                    {
                                        StorageHelpers.DeleteDirectory("/App_Data/cache/" + folder);
                                    }

                                    if (!StorageHelpers.DirectoryExists("/App_Data/cache/" + folder))
                                    {
                                        retry = 5;
                                    }
                                }

                                context.Application["RebuildCacheHistory"] = original;

                                if (StorageHelpers.DirectoryExists("/App_Data/cache/" + folder))
                                {
                                    context.Application["RebuildCacheHistory"] += "<strong style='color:#b94a48;'>cache/" + folder + " locked...</strong> ";
                                }
                            }
                        }

                        timer2.Stop();
                        context.Application["RebuildCacheHistory"] += "<strong>completed in " + timer2.GetSeconds <int>() + " seconds</strong></li>";

                        timer.Stop();

                        context.Application.SafeRemove("RebuildCacheStatus");

                        context.Application["RebuildCacheHistory"] += "</ol>";

                        context.Application["RebuildCacheHistory"] += "<h4 style=\"font-size: 1.1rem;\">Finished in " + timer.GetSeconds <int>() + " seconds</h4>";
                    }

                    catch (Exception e)
                    {
                        timer.Stop();
                        timer2.Stop();

                        context.Application.SafeRemove("RebuildCacheStatus");

                        context.Application["RebuildCacheHistory"] = "</li></ol><p><strong>Error in " + timer.GetSeconds <int>() + " seconds on " + TemporalHelpers.DateFormat(DateTime.Now, DateFormats.European).ToUpper() + " @ " + TemporalHelpers.TimeFormat(DateTime.Now, TimeFormats.SqlMilitary) + "</strong></p>" + e.Message;

                        result = context.Application["RebuildCacheHistory"].ToString();
                    }
                }))
                {
                    IsBackground = true
                };
                workerThread.Start();

                while (HttpContext.Current.Application["RebuildCacheStatus"] == null)
                {
                    // Wait for worker thread to start up and initialize
                    System.Threading.Thread.Sleep(50);
                }
            }

            else
            {
                result = HttpContext.Current.Application["RebuildCacheHistory"].ToString();
            }

            var response = new HttpResponseMessage(HttpStatusCode.OK);

            response.Content = new StringContent(result, Encoding.UTF8, "text/plain");
            return(response);
        }
Beispiel #9
0
        /// <summary><![CDATA[
        /// Read a folder of filenames (SCSS partials) and inject them into a SCSS file as import statements.
        /// Add the following to your SCSS file so the method knows where to inject the import statements,
        /// including the leading "// ":
        /// // $CARBIDE_PARTIALS:BEGIN
        /// // $CARBIDE_PARTIALS:END
        /// ]]></summary>
        /// <param name="scssPath">Relative web path to the SCSS files (e.g. "/scss/").</param>
        /// <param name="scssFilename">File name for the SCSS file in which to inject the partials as import statements (e.g. "application.scss").</param>
        /// <param name="partialPath">Relative web path to the folder containing the SCSS partials to read (e.g. "/scss/custom/").</param>
        public static void InjectScssPartials(string scssPath, string scssFilename, string partialPath)
        {
            try
            {
                var _scssPath    = "/" + scssPath.ToLower().Trim('/') + "/";
                var _partialPath = "/" + partialPath.ToLower().Trim('/') + "/";
                _partialPath = _partialPath.Replace(_scssPath, "");
                var      scss   = StorageHelpers.ReadFile(_scssPath + scssFilename);
                string[] delims = { "// $CARBIDE_PARTIALS:BEGIN", "// $CARBIDE_PARTIALS:END" };

                if (scss.Length > (delims[0].Length + delims[1].Length))
                {
                    if (scss.Contains(delims[0]) && scss.Contains(delims[1]))
                    {
                        if (scss.IndexOf(delims[0]) < scss.IndexOf(delims[1]))
                        {
                            List <string> chunks  = new List <string>(scss.Split(delims, StringSplitOptions.RemoveEmptyEntries));
                            var           oldList = "";

                            if (chunks.Count == 3)
                            {
                                oldList = chunks[1];
                                chunks.RemoveAt(1);
                            }

                            if (chunks.Count == 2)
                            {
                                var       inject  = "";
                                ArrayList folders = GetWebFolders(_scssPath + _partialPath, includeRoot: true);

                                foreach (var folder in folders)
                                {
                                    var _files = StorageHelpers.GetFiles(folder.ToString(), "*.scss");
                                    _files.Sort();

                                    if (_files.Count > 0)
                                    {
                                        foreach (var file in _files)
                                        {
                                            inject += "@import \"" + folder.ToString().Replace(_scssPath, "") + file + "\";\r\n";
                                        }
                                    }
                                }

                                // Only write imports if there are changes...
                                if (oldList == "" || inject.ToLower().Trim().Replace("\r\n", "|").Replace("\r", "|").Replace("\n", "|") != oldList.ToLower().Trim().Replace("\r\n", "|").Replace("\r", "|").Replace("\n", "|"))
                                {
                                    var finalFile = chunks[0] + delims[0] + "\r\n" + inject + delims[1] + chunks[1];

                                    StorageHelpers.WriteFile(_scssPath + scssFilename, finalFile);

                                    Debug.WriteLine("SCSS import changes detected, writing to " + _scssPath + scssFilename);
                                }

                                else
                                {
                                    Debug.WriteLine("No SCSS import changes detected in " + _scssPath + scssFilename + ", skipping");
                                }
                            }
                        }
                    }
                }
            }

            catch (Exception e)
            {
                Debug.WriteLine("EXCEPTION: Carbide.StorageHelpers.InjectScssPartials() - " + e.Message);
            }
        }