示例#1
0
        public void Invoke()
        {
            var traceListener = new ConsolidatedConsoleTraceListener(
                new Dictionary<string, string>
                    {
                        {
                            "LostDoc.Core.Template",
                            "Template"
                        },
                        {
                            "LostDoc.Core.Bundle",
                            "Bundle"
                        },
                        {
                            "LostDoc.Core.Template.AssetResolver",
                            "Resolve"
                        }
                    });

            
            TraceSources.TemplateSource.Listeners.Add(traceListener);
            TraceSources.AssetResolverSource.Listeners.Add(traceListener);
            try
            {
                if (this.Verbose.IsPresent)
                {
                    const SourceLevels verboseLevel = SourceLevels.All;
                    TraceSources.TemplateSource.Switch.Level = verboseLevel;
                    TraceSources.AssetResolverSource.Switch.Level = verboseLevel;
                    TraceSources.BundleSource.Listeners.Add(traceListener);
                }
                else
                {
                    const SourceLevels normalLevel = SourceLevels.Information | SourceLevels.Warning | SourceLevels.Error | SourceLevels.ActivityTracing;
                    TraceSources.TemplateSource.Switch.Level = normalLevel;
                    TraceSources.AssetResolverSource.Switch.Level = normalLevel;
                }

                LinkedList<FileInfo> includedFiles = new LinkedList<FileInfo>();

                if (File.Exists(this.Path))
                    includedFiles.AddLast(new FileInfo(this.Path));
                else if (Directory.Exists(this.Path))
                {
                    Directory.GetFiles(this.Path, "*.ldoc", SearchOption.AllDirectories)
                             .Aggregate(includedFiles,
                                        (l, f) => l.AddLast(new FileInfo(f)).List);
                }
                else
                    throw new FileNotFoundException(System.IO.Path.GetFullPath(this.Path));


                Bundle bundle = new Bundle(this.IgnoreVersionComponent);

                TraceSources.TemplateSource.TraceInformation("Merging LostDoc files into bundle.");

                var xmlSettings = new XmlReaderSettings
                {
                    CheckCharacters = false
                };

                foreach (FileInfo file in includedFiles)
                {
                    TraceSources.TemplateSource.TraceEvent(TraceEventType.Information, 0, "Path: {0}", file.Name);
                    XDocument fileDoc;
                    using (var reader = XmlReader.Create(file.FullName, xmlSettings))
                        fileDoc = XDocument.Load(reader);

                    bundle.Add(fileDoc);
                }

                // find template
                string appDir = Assembly.GetExecutingAssembly().Location;
                string cwDir = Directory.GetCurrentDirectory();


                IFileProvider fsProvider = new DirectoryFileProvider();
                IFileProvider resourceProvider = new ResourceFileProvider("LBi.LostDoc.ConsoleApplication.Templates");

                IFileProvider selectedFileProvider = null;
                string templatePath = null;

                if (System.IO.Path.IsPathRooted(this.Template) &&
                    fsProvider.FileExists(System.IO.Path.Combine(this.Template, "template.xml")))
                {
                    selectedFileProvider = fsProvider;
                    templatePath = this.Template;
                }
                else if (!System.IO.Path.IsPathRooted(this.Template))
                {
                    string tmp = System.IO.Path.Combine(cwDir, this.Template, "template.xml");
                    if (fsProvider.FileExists(tmp))
                    {
                        selectedFileProvider = fsProvider;
                        templatePath = tmp;
                    }
                    else
                    {
                        tmp = System.IO.Path.Combine(appDir, this.Template, "template.xml");
                        if (fsProvider.FileExists(tmp))
                        {
                            selectedFileProvider = fsProvider;
                            templatePath = tmp;
                        }
                        else
                        {
                            tmp = System.IO.Path.Combine(this.Template, "template.xml");
                            if (resourceProvider.FileExists(tmp))
                            {
                                selectedFileProvider = resourceProvider;
                                templatePath = tmp;
                            }
                        }
                    }
                }

                if (templatePath == null)
                    throw new FileNotFoundException(this.Template);

                string outputDir = this.Output
                                   ?? (Directory.Exists(this.Path)
                                           ? this.Path
                                           : System.IO.Path.GetDirectoryName(this.Path));

                Template template = new Template(selectedFileProvider);

                template.Load(templatePath);
                AssetRedirectCollection assetRedirects;
                XDocument mergedDoc = bundle.Merge(out assetRedirects);
                var templateData = new TemplateData
                                       {
                                           OverwriteExistingFiles = this.Force.IsPresent,
                                           AssetRedirects = assetRedirects,
                                           Document = mergedDoc,
                                           IgnoredVersionComponent = this.IgnoreVersionComponent,
                                           Arguments = this.Arguments,
                                           TargetDirectory = outputDir
                                       };

                template.Generate(templateData);
            }
            finally
            {
                TraceSources.TemplateSource.Listeners.Remove(traceListener);
                TraceSources.AssetResolverSource.Listeners.Remove(traceListener);
            }
        }
示例#2
0
        /// <summary>
        /// This method will construct a three folder structure inside <paramref name="targetDirectory"/> containing: Html, Index, and Source
        /// </summary>
        /// <param name="sourceDirectory">Directory containing ldoc files</param>
        /// <param name="targetDirectory">Output directory</param>
        public void Build(string sourceDirectory, string targetDirectory)
        {
            if (Directory.Exists(targetDirectory) && Directory.EnumerateFileSystemEntries(targetDirectory).Any())
                throw new InvalidOperationException("Target path is not empty.");

            this.OnStateChanged(State.Preparing);

            string htmlRoot = Path.Combine(targetDirectory, "Html");
            string indexRoot = Path.Combine(targetDirectory, "Index");
            string sourceRoot = Path.Combine(targetDirectory, "Source");

            DirectoryInfo htmlDir = Directory.CreateDirectory(htmlRoot);
            DirectoryInfo indexDir = Directory.CreateDirectory(indexRoot);
            DirectoryInfo sourceDir = Directory.CreateDirectory(sourceRoot);

            var sourceFiles = Directory.EnumerateFiles(sourceDirectory, "*.ldoc", SearchOption.TopDirectoryOnly);

            // copy all source files to output directory and add to bundle
            Bundle bundle = new Bundle(this.IgnoreVersionComponent);
            foreach (var sourceFile in sourceFiles)
            {
                string targetFile = Path.Combine(sourceDir.FullName, Path.GetFileName(sourceFile));
                File.Copy(sourceFile, targetFile);
                bundle.Add(XDocument.Load(targetFile));
            }

            // merge ldoc files
            this.OnStateChanged(State.Merging);
            AssetRedirectCollection assetRedirects;
            var mergedDoc = bundle.Merge(out assetRedirects);

            // generate output
            var templateData = new TemplateData
                                   {
                                       AssetRedirects = assetRedirects,
                                       Document = mergedDoc,
                                       IgnoredVersionComponent = this.IgnoreVersionComponent,
                                       TargetDirectory = htmlDir.FullName
                                   };

            this.OnStateChanged(State.Templating);
            TemplateOutput templateOutput = this.Template.Generate(templateData);


            this.OnStateChanged(State.Indexing);
            // one stop-word per line
            StringReader stopWordsReader = new StringReader(@"missing");

            // index output
            using (var directory = FSDirectory.Open(indexDir))
            using (stopWordsReader)
            {
                Analyzer analyzer = new StandardAnalyzer(global::Lucene.Net.Util.Version.LUCENE_29, stopWordsReader);
                Analyzer titleAnalyzer = new TitleAnalyzer();
                IDictionary fieldAnalyzers = new Dictionary<string, Analyzer>
                                                 {
                                                     { "title", titleAnalyzer } 
                                                 };
                
                PerFieldAnalyzerWrapper analyzerWrapper = new PerFieldAnalyzerWrapper(analyzer, fieldAnalyzers);
                
                using (var writer = new IndexWriter(directory, analyzerWrapper, IndexWriter.MaxFieldLength.UNLIMITED))
                {
                    foreach (WorkUnitResult result in templateOutput.Results)
                    {
                        //string absPath = Path.Combine(htmlDir.FullName, result.SavedAs);

                        //HtmlDocument htmlDoc = new HtmlDocument();
                        //htmlDoc.Load(absPath);

                        //string htmlTitle = string.Empty;
                        //var titleNode = htmlDoc.DocumentNode.SelectSingleNode("/html/head/title");

                        //if (titleNode != null)
                        //    htmlTitle = HtmlEntity.DeEntitize(titleNode.InnerText);
                        //        //.Replace('.', ' ')
                        //        //.Replace('<', ' ')
                        //        //.Replace('>', ' ')
                        //        //.Replace('[', ' ')
                        //        //.Replace(']', ' ')
                        //        //.Replace('(', ' ')
                        //        //.Replace(')', ' ');

                        //HtmlNode contentNode = htmlDoc.GetElementbyId("content");

                        //HtmlNode summaryNode = contentNode.SelectSingleNode(".//p[@class='summary']");

                        //string summary = string.Empty;

                        //if (summaryNode != null && summaryNode.SelectSingleNode("span[@class='error']") == null)
                        //    summary = HtmlEntity.DeEntitize(summaryNode.InnerText);

                        //string body = HtmlEntity.DeEntitize(contentNode.InnerText);

                        //var doc = new Document();

                        //doc.Add(new Field("uri", new Uri(result.SavedAs, UriKind.Relative).ToString(), Field.Store.YES, Field.Index.NO));
                        //doc.Add(new Field("aid", result.Asset, Field.Store.YES, Field.Index.NOT_ANALYZED));
                        //foreach (AssetIdentifier aid in result.Aliases)
                        //    doc.Add(new Field("alias", aid, Field.Store.NO, Field.Index.NOT_ANALYZED));

                        //foreach (var section in result.Sections)
                        //{
                        //    doc.Add(new Field("section", section.AssetIdentifier,
                        //                      Field.Store.NO,
                        //                      Field.Index.NOT_ANALYZED));
                        //}

                        //doc.Add(new Field("title", htmlTitle, Field.Store.YES, Field.Index.ANALYZED));
                        //doc.Add(new Field("summary", summary, Field.Store.YES, Field.Index.ANALYZED));
                        //doc.Add(new Field("content", body, Field.Store.YES, Field.Index.ANALYZED));
                        //TraceSources.ContentBuilderSource.TraceVerbose("Indexing document: {0}", doc.ToString());
                        //writer.AddDocument(doc);
                    }

                    writer.Optimize();
                    writer.Commit();
                    writer.Close();
                }
                analyzerWrapper.Close();
                analyzer.Close();
                directory.Close();
            }
            this.OnStateChanged(State.Finalizing);

            var infoDoc = new XDocument(
                new XElement("content",
                             new XAttribute("created",
                                            XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc)),
                             templateOutput.Results.Select(ConvertToXml)));

            infoDoc.Save(Path.Combine(targetDirectory, "info.xml"));

            this.OnStateChanged(State.Idle);
        }
示例#3
0
        /// <summary>
        /// This method will construct a three folder structure inside <paramref name="targetDirectory"/> containing: Html, Index, and Source
        /// </summary>
        /// <param name="sourceDirectory">Directory containing ldoc files</param>
        /// <param name="targetDirectory">Output directory</param>
        public void Build(string sourceDirectory, string targetDirectory)
        {
            if (Directory.Exists(targetDirectory) && Directory.EnumerateFileSystemEntries(targetDirectory).Any())
                throw new InvalidOperationException("Target path is not empty.");

            this.OnStateChanged(State.Preparing);

            string htmlRoot = Path.Combine(targetDirectory, "Html");
            string indexRoot = Path.Combine(targetDirectory, "Index");
            string sourceRoot = Path.Combine(targetDirectory, "Source");
            string logRoot = Path.Combine(targetDirectory, "Logs");


            DirectoryInfo htmlDir = Directory.CreateDirectory(htmlRoot);
            DirectoryInfo indexDir = Directory.CreateDirectory(indexRoot);
            DirectoryInfo sourceDir = Directory.CreateDirectory(sourceRoot);
            DirectoryInfo logDir = Directory.CreateDirectory(logRoot);
            var sourceFiles = Directory.EnumerateFiles(sourceDirectory, "*.ldoc", SearchOption.TopDirectoryOnly);

            // copy all source files to output directory and add to bundle
            Bundle bundle = new Bundle(this.IgnoreVersionComponent);
            foreach (var sourceFile in sourceFiles)
            {
                string targetFile = Path.Combine(sourceDir.FullName, Path.GetFileName(sourceFile));
                File.Copy(sourceFile, targetFile);
                bundle.Add(XDocument.Load(targetFile));
            }

            TemplateOutput templateOutput;

            // wire up logging
            using (TextWriterTraceListener traceListener =
                new TextWriterTraceListener(Path.Combine(logDir.FullName,
                                                         string.Format(
                                                             "template_{0:yyyy'_'MM'_'dd'__'HH'_'mm'_'ss}.log",
                                                             DateTime.Now))))
            {

                // log everything
                traceListener.Filter = new EventTypeFilter(SourceLevels.All);
                LBi.LostDoc.Core.Diagnostics.TraceSources.TemplateSource.Switch.Level = SourceLevels.All;
                LBi.LostDoc.Core.Diagnostics.TraceSources.BundleSource.Switch.Level = SourceLevels.All;
                LBi.LostDoc.Core.Diagnostics.TraceSources.AssetResolverSource.Switch.Level = SourceLevels.All;
                LBi.LostDoc.Core.Diagnostics.TraceSources.TemplateSource.Listeners.Add(traceListener);
                LBi.LostDoc.Core.Diagnostics.TraceSources.BundleSource.Listeners.Add(traceListener);
                LBi.LostDoc.Core.Diagnostics.TraceSources.AssetResolverSource.Listeners.Add(traceListener);

                // merge ldoc files
                this.OnStateChanged(State.Merging);
                AssetRedirectCollection assetRedirects;
                var mergedDoc = bundle.Merge(out assetRedirects);

                // generate output
                var templateData = new TemplateData(mergedDoc)
                                       {
                                           AssetRedirects = assetRedirects,
                                           IgnoredVersionComponent = this.IgnoreVersionComponent,
                                           TargetDirectory = htmlDir.FullName,
                                           Arguments = new Dictionary<string, object> {{"SearchUri", "/search/"}}
                                       };

                this.OnStateChanged(State.Templating);
                templateOutput = this.Template.Generate(templateData);

                LBi.LostDoc.Core.Diagnostics.TraceSources.TemplateSource.Listeners.Remove(traceListener);
                LBi.LostDoc.Core.Diagnostics.TraceSources.BundleSource.Listeners.Remove(traceListener);
                LBi.LostDoc.Core.Diagnostics.TraceSources.AssetResolverSource.Listeners.Remove(traceListener);
            }

            this.OnStateChanged(State.Indexing);

            using (TextWriterTraceListener traceListener =
                new TextWriterTraceListener(Path.Combine(logDir.FullName,
                                                         string.Format(
                                                             "index_{0:yyyy'_'MM'_'dd'__'HH'_'mm'_'ss}.log",
                                                             DateTime.Now))))
            {
                // log everything
                traceListener.Filter = new EventTypeFilter(SourceLevels.All);
                TraceSources.ContentBuilderSource.Switch.Level = SourceLevels.All;
                TraceSources.ContentBuilderSource.Listeners.Add(traceListener);
                

                // one stop-word per line
                StringReader stopWordsReader = new StringReader(@"missing");

                // index output
                using (var directory = FSDirectory.Open(indexDir))
                using (stopWordsReader)
                {
                    Analyzer analyzer = new StandardAnalyzer(global::Lucene.Net.Util.Version.LUCENE_30, stopWordsReader);
                    Analyzer titleAnalyzer = new TitleAnalyzer();
                    IDictionary<string, Analyzer> fieldAnalyzers = new Dictionary<string, Analyzer>
                                                                       {
                                                                           {"title", titleAnalyzer}
                                                                       };

                    PerFieldAnalyzerWrapper analyzerWrapper = new PerFieldAnalyzerWrapper(analyzer, fieldAnalyzers);

                    using (
                        var writer = new IndexWriter(directory, analyzerWrapper, IndexWriter.MaxFieldLength.UNLIMITED))
                    {
                        var saResults =
                            templateOutput.Results.Select(wur => wur.WorkUnit).OfType<StylesheetApplication>();

                        var saDict = saResults.ToDictionary(sa => sa.Asset);

                        var indexResults = saDict.Values.Where(sa => sa.SaveAs.EndsWith(".xml"));

                        foreach (var sa in indexResults)
                        {
                            string absPath = Path.Combine(htmlDir.FullName, sa.SaveAs);

                            XDocument indexDoc = XDocument.Load(absPath);

                            string assetId = indexDoc.Root.Attribute("assetId").Value;
                            string title = indexDoc.Root.Element("title").Value.Trim();
                            string summary = indexDoc.Root.Element("summary").Value.Trim();
                            string text = indexDoc.Root.Element("text").Value.Trim();

                            var ssApplication = saDict[AssetIdentifier.Parse(assetId)];


                            var doc = new Document();

                            doc.Add(new Field("uri",
                                              new Uri(ssApplication.SaveAs, UriKind.Relative).ToString(),
                                              Field.Store.YES,
                                              Field.Index.NO));
                            doc.Add(new Field("aid", ssApplication.Asset, Field.Store.YES, Field.Index.NOT_ANALYZED));
                            foreach (AssetIdentifier aid in ssApplication.Aliases)
                                doc.Add(new Field("alias", aid, Field.Store.NO, Field.Index.NOT_ANALYZED));

                            foreach (var section in ssApplication.Sections)
                            {
                                doc.Add(new Field("section",
                                                  section.AssetIdentifier,
                                                  Field.Store.NO,
                                                  Field.Index.NOT_ANALYZED));
                            }

                            doc.Add(new Field("title", title, Field.Store.YES, Field.Index.ANALYZED));
                            doc.Add(new Field("summary", summary, Field.Store.YES, Field.Index.ANALYZED));
                            doc.Add(new Field("content", text, Field.Store.NO, Field.Index.ANALYZED));
                            TraceSources.ContentBuilderSource.TraceVerbose("Indexing document: {0}", doc.ToString());
                            writer.AddDocument(doc);
                        }

                        writer.Optimize();
                        writer.Commit();
                    }
                    analyzerWrapper.Close();
                    analyzer.Close();
                }

                TraceSources.ContentBuilderSource.Listeners.Remove(traceListener);
            }
            this.OnStateChanged(State.Finalizing);

            var infoDoc = new XDocument(
                new XElement("content",
                             new XAttribute("created",
                                            XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc)),
                             templateOutput.Results.Select(ConvertToXml)));

            infoDoc.Save(Path.Combine(targetDirectory, "info.xml"));

            this.OnStateChanged(State.Idle);
        }