Exemplo n.º 1
0
        private void HangUntilFileChange(HttpListenerContext context)
        {
            SafeTask.Run(() =>
            {
                // Log it
                CoreLogger.Log("Waiting for file change signal...");

                // Wait here until files change
                mContentChangedResetEvent.WaitOne();

                // If we are stopping, just return
                if (Stopping)
                {
                    return;
                }

                // Log it
                CoreLogger.LogInformation("Refreshing web page request...");

                // Response code OK (200)
                context.Response.StatusCode = (int)HttpStatusCode.OK;

                // End stream
                context.Response.OutputStream.Close();
            });
        }
 /// <summary>
 /// Save the files contents to the destination location
 /// </summary>
 /// <param name="processingData"></param>
 /// <param name="outputPath"></param>
 /// <returns></returns>
 public override Task SaveFileContents(FileProcessingData processingData, FileOutputData outputPath)
 {
     return(SafeTask.Run(() =>
     {
         // Do normal file copy when saving static file
         FileManager.CopyFile(processingData.FullPath, outputPath.FullPath);
     }));
 }
Exemplo n.º 3
0
 protected override Task PreProcessFile(FileProcessingData data)
 {
     return(SafeTask.Run(() =>
     {
         // Set this file to partial if it starts with _
         data.IsPartial = Path.GetFileName(data.FullPath).StartsWith("_");
     }));
 }
 /// <summary>
 /// Specifies Sass output paths based on Dna configuration settings, if specified
 /// </summary>
 /// <param name="data"></param>
 /// <returns></returns>
 protected override Task PostProcessOutputPaths(FileProcessingData data)
 {
     return(SafeTask.Run(() =>
     {
         // For now just output in the same directory as Sass file
         data.OutputPaths.Add(new FileOutputData
         {
             FullPath = GetDefaultOutputPath(data),
             FileContents = data.UnprocessedFileContents
         });
     }));
 }
        /// <summary>
        /// Specifies output paths based on Dna configuration settings, if specified
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        protected override Task PostProcessOutputPaths(FileProcessingData data)
        {
            return(SafeTask.Run(() =>
            {
                // Output path is the destination folder
                var relativePath = data.FullPath.Substring(StaticFolderDetails.SourceFolder.Length + 1);
                var outputPath = Path.GetFullPath(Path.Combine(StaticFolderDetails.DestinationFolder, relativePath));

                data.OutputPaths.Add(new FileOutputData
                {
                    FullPath = outputPath,
                    FileContents = data.UnprocessedFileContents
                });
            }));
        }
        protected override Task PreProcessFile(FileProcessingData data)
        {
            return(SafeTask.Run(() =>
            {
                // We don't need any processing for static files
                // It is all done via the Static engine
                WillProcessDataTags = false;
                WillProcessMainTags = false;
                WillProcessOutputTags = false;
                WillProcessVariables = false;
                WillProcessLiveVariables = false;

                // Don't read the file into memory
                WillReadFileIntoMemory = false;
            }));
        }
        /// <summary>
        /// Delete the same folder at the destination
        /// </summary>
        /// <param name="path">The source folder that has been deleted</param>
        /// <returns></returns>
        protected override Task ProcessFolderDeletedAsync(string path)
        {
            return(SafeTask.Run(() =>
            {
                var relativePath = path.Substring(StaticFolderDetails.SourceFolder.Length + 1);
                var outputPath = Path.GetFullPath(Path.Combine(StaticFolderDetails.DestinationFolder, relativePath));

                // Sanity check we are still inside output path
                if (!outputPath.Replace("/", "\\").StartsWith(StaticFolderDetails.DestinationFolder + "\\"))
                {
                    CoreLogger.Log($"Ignoring folder delete as it appears outside of the destination folder. Source: '{path}' Destination: '{outputPath}'");
                    return;
                }

                // Log it
                CoreLogger.Log($"Deleting static folder {outputPath}", type: LogType.Warning);

                // Delete folder
                FileManager.DeleteFolder(outputPath);
            }));
        }
        protected override Task PreProcessFile(FileProcessingData data)
        {
            return(SafeTask.Run(() =>
            {
                // We don't need any processing for Sass files
                // It is all done via the Sass engine
                WillProcessDataTags = false;
                WillProcessMainTags = false;
                WillProcessOutputTags = false;
                WillProcessVariables = false;
                WillProcessLiveVariables = false;

                // Set this file to partial if it starts with _
                // As per the Sass rule
                data.IsPartial = Path.GetFileName(data.FullPath).StartsWith("_");

                // Ignore .sass-cache folder
                if (data.FullPath.Replace("\\", "/").Contains("/.sass-cache/"))
                {
                    data.SkipMessage = "Ignoring .sass-cache folder";
                }
            }));
        }
Exemplo n.º 9
0
        /// <summary>
        /// Starts listening on the specified <see cref="Port"/>
        /// </summary>
        /// <returns>Returns the URL that is being listened on</returns>
        public string Listen()
        {
            lock (mListenLock)
            {
                // If we are already listening...
                if (Listening)
                {
                    // Ignore
                    return(null);
                }

                #region Get Port

                try
                {
                    // Get port if one is not specified
                    if (Port <= 0)
                    {
                        // Log it
                        CoreLogger.Log("LiveServer getting available port...");

                        // Get next available port
                        Port = NextAvailablePort();
                    }
                }
                catch (Exception ex)
                {
                    // Log it
                    Debugger.Break();
                    CoreLogger.Log($"LiveServer failed to find an available port. {ex.Message}", type: LogType.Error);

                    // Go no further
                    return(null);
                }

                // Log port to be used
                CoreLogger.Log($"LiveServer will listen on port {Port}");

                #endregion

                // Expected listen URL
                var listenUrl = $"http://localhost:{Port}/";

                #region Listen

                try
                {
                    // Create new Http Listener
                    mListener = new HttpListener();

                    // Set port number
                    mListener.Prefixes.Add(listenUrl);

                    // Start listening
                    mListener.Start();

                    // Run new thread listening for content
                    // until we call Stop or Dispose
                    SafeTask.Run(() => ListenForContent());

                    // Set Listening flag
                    Listening = true;

                    // Log it
                    CoreLogger.Log($"LiveServer listening on http://localhost:{Port}, directory '{ServingDirectory}'", type: LogType.Information);
                }
                catch (Exception ex)
                {
                    // Log it
                    Debugger.Break();
                    CoreLogger.Log($"LiveServer failed to start on port {Port}, directory '{ServingDirectory}'. {ex.Message}", type: LogType.Error);

                    // Go no further
                    return(null);
                }

                #endregion

                #region File Change Watcher

                mFolderWatcher = new FolderWatcher
                {
                    Filter      = "*",
                    Path        = ServingDirectory,
                    UpdateDelay = 100
                };

                // Listen for file changes
                mFolderWatcher.FileChanged += FolderWatcher_FileChanged;

                mFolderWatcher.Start();

                #endregion

                // Return URL we are now listening on
                return(listenUrl);
            }
        }
        /// <summary>
        /// Replace C# specific tags
        /// </summary>
        /// <param name="data">The file data</param>
        /// <returns></returns>
        protected override Task PostProcessFile(FileProcessingData data)
        {
            return(SafeTask.Run(() =>
            {
                // For each output
                data.OutputPaths.ForEach(output =>
                {
                    // Find all C# data sets
                    Match match = null;

                    // No error to start with
                    data.Error = string.Empty;

                    // Loop through all matches
                    while (match == null || match.Success)
                    {
                        // Find the next data region
                        match = Regex.Match(output.FileContents, mCSharp2GroupRegex, RegexOptions.Singleline);

                        if (!match.Success)
                        {
                            return;
                        }

                        // NOTE: The first group is the full match
                        //       The second group is the type
                        //       Third group is data

                        // Make sure we have enough groups
                        if (match.Groups.Count < 3)
                        {
                            data.Error = $"Malformed match {match.Value}";
                            return;
                        }

                        // Take the first match as the header for the type of tag
                        var type = match.Groups[1].Value.Trim();
                        var datasString = match.Groups[2].Value.Trim();

                        // Split the data via ; and trim it
                        // Example data would be: group=DomIds; value=Something with space;
                        List <CSharpTagDataItem> propertyData = null;

                        try
                        {
                            propertyData = datasString.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(f =>
                            {
                                // Get data string
                                var dataString = f?.Trim();

                                // Make sure we have at least one = after a character
                                if (dataString.IndexOf('=') <= 0)
                                {
                                    throw new ArgumentException("Invalid CSharp data item: " + dataString);
                                }

                                // Get name and value
                                var name = dataString.Substring(0, dataString.IndexOf('='));
                                var value = dataString.Substring(dataString.IndexOf('=') + 1);

                                return new CSharpTagDataItem
                                {
                                    Name = name,
                                    Value = value
                                };
                            }).ToList();
                        }
                        catch (Exception ex)
                        {
                            data.Error = ex.Message;
                            return;
                        }

                        switch (type)
                        {
                        case "properties":

                            // Process the property data
                            ProcessPropertiesTab(data, output, match, propertyData);

                            // Check for success
                            if (!data.Successful)
                            {
                                // Return if it fails
                                return;
                            }

                            break;

                        default:
                            // Report error of unknown match
                            data.Error = $"Unknown match {match.Value}";
                            return;
                        }
                    }
                });
            }));
        }