internal static void BuildReport(Library library, List <PDFDocument> pdf_documents) { FeatureTrackingManager.Instance.UseFeature(Features.Library_JSONAnnotationReport); AnnotationReportOptions annotation_report_options = new AnnotationReportOptions(); List <AnnotationWorkGenerator.AnnotationWork> annotation_works = AnnotationWorkGenerator.GenerateAnnotationWorks(library, pdf_documents, annotation_report_options); IEnumerable <AnnotationJSON> annotation_jsons = annotation_works.Select(annotation_work => new AnnotationJSON { fingerprint = annotation_work.pdf_document.Fingerprint, title = annotation_work.pdf_document.TitleCombined, page = annotation_work.pdf_annotation.Page, left = annotation_work.pdf_annotation.Left, top = annotation_work.pdf_annotation.Top, width = annotation_work.pdf_annotation.Width, height = annotation_work.pdf_annotation.Height, tags = annotation_work.pdf_annotation.Tags, text = annotation_work.pdf_annotation.Text, } ); string json = JsonConvert.SerializeObject(annotation_jsons, Formatting.Indented); string filename = Path.GetTempFileName() + ".json.txt"; File.WriteAllText(filename, json); Process.Start(filename); }
public async Task ModifiedIniFilesArePatchedAgainstFileWithSameName() { var profile = utils.AddProfile(); var mod = utils.AddMod(); var ini = utils.AddModFile(mod, @"foo.ini", 10); var meta = utils.AddModFile(mod, "meta.ini"); utils.Configure(); var archive = utils.AddManualDownload( new Dictionary <string, byte[]> { { "/baz/foo.ini", File.ReadAllBytes(ini) } }); File.WriteAllLines(meta, new[] { "[General]", $"installationFile={archive}", }); // Modify after creating mod archive in the downloads folder File.WriteAllText(ini, "Wabbajack, Wabbajack, Wabbajack!"); var modlist = await CompileAndInstall(profile); var directive = modlist.Directives.Where(m => m.To == $"mods\\{mod}\\foo.ini").FirstOrDefault(); Assert.IsNotNull(directive); Assert.IsInstanceOfType(directive, typeof(PatchedFromArchive)); }
internal static void Export(Library library, string base_path, Dictionary <string, PDFDocumentExportItem> pdf_document_export_items) { StringBuilder html = new StringBuilder(); html.AppendFormat("<html>\n"); html.AppendFormat(" <head>\n"); html.AppendFormat(" <title>Qiqqa Library Export</title>\n"); html.AppendFormat(" </head>\n"); html.AppendFormat("<body>\n"); html.AppendFormat(String.Format("<a href=\"{0}\"><image align=\"right\" src=\"Qiqqa.png\" border=\"0\"/></a>\n", WebsiteAccess.Url_QiqqaLibraryExportTrackReference)); html.AppendFormat("<h1>Qiqqa Library Export</h1>\n"); Export_HTML_Titles(html, library, base_path, pdf_document_export_items); Export_HTML_Authors(html, library, base_path, pdf_document_export_items); Export_HTML_Tags(html, library, base_path, pdf_document_export_items); Export_HTML_AutoTags(html, library, base_path, pdf_document_export_items); html.AppendFormat("</body>\n"); html.AppendFormat("</html>\n"); string image_filename = Path.GetFullPath(Path.Combine(base_path, @"Qiqqa.png")); BitmapImage image = Icons.GetAppIcon(Icons.Qiqqa); using (FileStream filestream = new FileStream(image_filename, FileMode.Create)) { PngBitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(image)); encoder.Save(filestream); } string filename = Path.GetFullPath(Path.Combine(base_path, @"Qiqqa.html")); File.WriteAllText(filename, html.ToString()); }
public static void ToJSON <T>(this T obj, string filename) { File.WriteAllText(filename, JsonConvert.SerializeObject(obj, Formatting.Indented, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto })); }
public string ScrapeURLToFile(string url, bool force_download = false, Dictionary <string, string> additional_headers = null) { string cache_key = StreamMD5.FromText(url); string directory = Path.GetFullPath(Path.Combine(base_directory, cache_key.Substring(0, 2))); string filename = Path.GetFullPath(Path.Combine(directory, cache_key)); if (!File.Exists(filename) || force_download) { Utilities.Files.DirectoryTools.CreateDirectory(directory); // Crude throttle if (true) { while (DateTime.UtcNow.Subtract(last_scrape_time).TotalMilliseconds < throttle_ms) { Thread.Sleep(50); } last_scrape_time = DateTime.UtcNow; } Logging.Info("Downloading from {0}", url); using (WebClient client = new WebClient()) { if (null != additional_headers) { foreach (var pair in additional_headers) { client.Headers.Add(pair.Key, pair.Value); } } if (!String.IsNullOrEmpty(userAgent)) { client.Headers.Add("User-agent", userAgent); } string temp_filename = filename + ".tmp"; try { client.DownloadFile(url, temp_filename); } catch (WebException ex) { File.WriteAllText(temp_filename, ex.ToString()); } File.Delete(filename); File.Move(temp_filename, filename); } string filename_manifest = Path.GetFullPath(Path.Combine(base_directory, @"manifest.txt")); string manifest_line = String.Format("{0}\t{1}", cache_key, url); using (StreamWriter sw = File.AppendText(filename_manifest)) { sw.WriteLine(manifest_line); } } return(filename); }
public void WriteMasterList() { Logging.Info("+WriteMasterList"); string filename_temp = Path.GetTempFileName(); Utilities.LockPerfTimer l1_clk = Utilities.LockPerfChecker.Start(); lock (locker) { l1_clk.LockPerfTimerStop(); FlushAllWords_LOCK(); PurgeAllWords_LOCK(); using (FileStream fs = File.Open(filename_temp, FileMode.Create)) { Headers headers = new Headers(); // First the documents { headers.documents = new List <DocumentMapHeader>(); foreach (var pair in fingerprint_to_document_ids) { DocumentMapHeader header = new DocumentMapHeader { Fingerprint = pair.Key, DocumentId = pair.Value }; headers.documents.Add(header); } } // Then the words { headers.words = new List <WordMapHeader>(); foreach (WordInWordIndex word_in_word_index in word_in_word_indexes) { WordMapHeader header = new WordMapHeader { Word = word_in_word_index.Word, WordId = word_in_word_index.WordId, DocCount = word_in_word_index.DocumentCount }; headers.words.Add(header); } } Serializer.Serialize <Headers>(fs, headers); } } Logging.Info("-WriteMasterList"); // Move the temp file over the library filename Directory.CreateDirectory(Path.GetDirectoryName(GetFilename_MasterList())); FileTools.MoveSafelyWithOverwriting(filename_temp, GetFilename_MasterList()); // Write the version of the index File.WriteAllText(VersionFilename, INDEX_VERSION); }
public static void ToJson <T>(this T obj, string filename) { if (File.Exists(filename)) { File.Delete(filename); } File.WriteAllText(filename, JsonConvert.SerializeObject(obj, Formatting.Indented, JsonSettings)); }
public async Task TestUpdating() { var profile = utils.AddProfile(); var mod = utils.AddMod(); var unchanged = utils.AddModFile(mod, @"Data\scripts\unchanged.pex", 10); var deleted = utils.AddModFile(mod, @"Data\scripts\deleted.pex", 10); var modified = utils.AddModFile(mod, @"Data\scripts\modified.pex", 10); utils.Configure(); utils.AddManualDownload( new Dictionary <string, byte[]> { { "/baz/unchanged.pex", File.ReadAllBytes(unchanged) }, { "/baz/deleted.pex", File.ReadAllBytes(deleted) }, { "/baz/modified.pex", File.ReadAllBytes(modified) }, }); await CompileAndInstall(profile); utils.VerifyInstalledFile(mod, @"Data\scripts\unchanged.pex"); utils.VerifyInstalledFile(mod, @"Data\scripts\deleted.pex"); utils.VerifyInstalledFile(mod, @"Data\scripts\modified.pex"); var unchanged_path = utils.PathOfInstalledFile(mod, @"Data\scripts\unchanged.pex"); var deleted_path = utils.PathOfInstalledFile(mod, @"Data\scripts\deleted.pex"); var modified_path = utils.PathOfInstalledFile(mod, @"Data\scripts\modified.pex"); var extra_path = utils.PathOfInstalledFile(mod, @"something_i_made.foo"); File.WriteAllText(extra_path, "bleh"); var extra_folder = Path.Combine(Path.GetDirectoryName(utils.PathOfInstalledFile(mod, @"something_i_made.foo")), "folder_i_made"); Directory.CreateDirectory(extra_folder); Assert.IsTrue(Directory.Exists(extra_folder)); var unchanged_modified = File.GetLastWriteTime(unchanged_path); var modified_modified = File.GetLastWriteTime(modified_path); File.WriteAllText(modified_path, "random data"); File.Delete(deleted_path); Assert.IsTrue(File.Exists(extra_path)); await CompileAndInstall(profile); utils.VerifyInstalledFile(mod, @"Data\scripts\unchanged.pex"); utils.VerifyInstalledFile(mod, @"Data\scripts\deleted.pex"); utils.VerifyInstalledFile(mod, @"Data\scripts\modified.pex"); Assert.AreEqual(unchanged_modified, File.GetLastWriteTime(unchanged_path)); Assert.AreNotEqual(modified_modified, File.GetLastWriteTime(modified_path)); Assert.IsFalse(File.Exists(extra_path)); Assert.IsFalse(Directory.Exists(extra_folder)); }
// Populated from http://www.kfunigraz.ac.at/~binder/texhelp/bibtx-7.html (not active anymore in 2019 A.D.) // Also at http://nwalsh.com/tex/texhelp/bibtx-7.html // // Other potential sources: // - http://bib-it.sourceforge.net/help/fieldsAndEntryTypes.php // - https://www.bibtex.com/e/book-entry/ // - https://en.wikipedia.org/wiki/BibTeX#Style_files // private EntryTypes() { string filename = EntryTypes.EntryTypesDefinitionFilename; // when the setup file does not exist, yak! if (!File.Exists(filename)) { Logging.Error("BibTeX entry types definition JSON file '{0}' does not exist! Your install may be boogered!", filename); // do it old skool style. Only a few so it's easily noticed by the user! AddEntryType( new EntryType( "book", new string[] { "author", "editor", "title", "publisher", "year" }, new string[] { "volume", "series", "address", "edition", "month", "note" } )); AddEntryType( new EntryType( "misc", null, new string[] { "title", "author", "year", "DOI", "PMID" } )); #if false && TEST string json = JsonConvert.SerializeObject(entry_types, Formatting.Indented); File.WriteAllText(filename, json); #endif } else { // file exists; load it to get all the goodness. try { string json = File.ReadAllText(filename, System.Text.Encoding.UTF8); entry_types = JsonConvert.DeserializeObject <Dictionary <string, EntryType> >(json); Logging.Info("Loaded {0} BibTeX entry types from configuration file '{1}':\n [{2}]", entry_types.Count, filename, String.Join(", ", entry_types.Keys)); } catch (Exception ex) { Logging.Error(ex, "Failed to load/parse the BibTeX entry types definition file '{0}'.", filename); } } // see if the 'common denominator' entry has been defined in there. // IFF it's not, we add it on the spot and barge on. if (!entry_types.ContainsKey("misc")) { AddEntryType( new EntryType( "misc", null, new string[] { "title", "author", "year", "DOI", "PMID" } )); } }
internal static void BuildReport(WebLibraryDetail web_library_detail, List <PDFDocument> pdf_documents) { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); FeatureTrackingManager.Instance.UseFeature(Features.Library_LinkedDocsAnnotationReport); StringBuilder sb_o2o = new StringBuilder(); StringBuilder sb_o2m = new StringBuilder(); foreach (var pdf_document in pdf_documents) { var citations = pdf_document.PDFDocumentCitationManager.GetLinkedDocuments(); if (null == citations || 0 == citations.Count) { continue; } // o2m { sb_o2m.AppendFormat("{0}", pdf_document.Fingerprint); sb_o2m.AppendFormat(","); foreach (var citation in citations) { sb_o2m.AppendFormat("{0}", citation.fingerprint_outbound); sb_o2m.AppendFormat(","); } sb_o2m.AppendLine(); } // o2o { foreach (var citation in citations) { sb_o2o.AppendFormat("{0}", pdf_document.Fingerprint); sb_o2o.AppendFormat(","); sb_o2o.AppendFormat("{0}", citation.fingerprint_inbound); sb_o2o.AppendLine(); } } } string filename_o2o = Path.GetTempFileName() + ".o2o.txt"; string filename_o2m = Path.GetTempFileName() + ".o2m.txt"; File.WriteAllText(filename_o2o, sb_o2o.ToString()); File.WriteAllText(filename_o2m, sb_o2m.ToString()); Process.Start(filename_o2o); Process.Start(filename_o2m); }
private void EnsureWarningFilesArePresent_TOUCH(string base_path, string filename) { string path = Path.GetFullPath(Path.Combine(base_path, filename)); try { if (!File.Exists(path)) { File.WriteAllText(path, ""); } } catch (Exception ex) { Logging.Warn(ex, "Problem writing Intranet Library mount point warnings (path: {0})", path); } }
public void TestRegexEolToken_Issue_210_MultiLine(bool useLongPath) { string destFolder = useLongPath ? GetLongPathDestination(Guid.NewGuid().ToString()) : destinationFolder; string path = Path.Combine(destFolder, @"Issue210"); if (Directory.Exists(path)) { Utils.DeleteFolder(path); } Directory.CreateDirectory(path); string line = @"24.4.2014 11:45:21.435;T1;End runSingle Job Wfd ID:1895 JobId:166078 JobType:RunWorkFlow Runtime:5.375 Queued:0.015 Total:5.390"; string content = line + '\r' + line + '\r' + line + '\r'; File.WriteAllText(Path.Combine(path, @"Issue210mac.txt"), content); File.WriteAllText(Path.Combine(path, @"Issue210oneline.txt"), line); content = line + '\n' + line + '\n' + line + '\n'; File.WriteAllText(Path.Combine(path, @"Issue210unix.txt"), content); content = line + "\r\n" + line + "\r\n" + line + "\r\n"; File.WriteAllText(Path.Combine(path, @"Issue210win.txt"), content); GrepCore core = new GrepCore(); List <GrepSearchResult> results = core.Search(Directory.GetFiles(path, "*.txt"), SearchType.Regex, @"[3-9]\d*?.\d\d\d$", GrepSearchOption.Multiline, -1); // should be four test files with no EOL, Windows, Unix, and Mac EOL Assert.Equal(4, results.Count); Assert.Equal(3, results[0].Matches.Count); Assert.Equal(1, results[1].Matches.Count); Assert.Equal(3, results[2].Matches.Count); Assert.Equal(3, results[3].Matches.Count); // verify the matches are recorded at the correct location in the files // with \r EOL Assert.Equal(378, results[0].Matches[2].StartLocation); Assert.Equal(383, results[0].Matches[2].EndPosition); // with \n EOL Assert.Equal(378, results[2].Matches[2].StartLocation); Assert.Equal(383, results[2].Matches[2].EndPosition); // with \r\n EOL Assert.Equal(380, results[3].Matches[2].StartLocation); Assert.Equal(385, results[3].Matches[2].EndPosition); }
public void WriteList(List <BlackWhiteListEntry> list) { StringBuilder sw = new StringBuilder(); sw.AppendLine("# Qiqqa AutoTag black/whitelist"); sw.AppendLine("# Version: 1"); sw.AppendLine("#"); sw.AppendLine("# Format is: <word>|<list_type>|<deleted>"); sw.AppendLine("#"); foreach (var entry in list) { string line = entry.ToFileString(); sw.AppendLine(line); } File.WriteAllText(Filename_Store, sw.ToString()); }
public override IEnumerable <ICompilationStep> GetStack() { var s = Consts.TestMode ? DownloadsFolder : VortexFolder; var userConfig = Path.Combine(s, "compilation_stack.yml"); if (File.Exists(userConfig)) { return(Serialization.Deserialize(File.ReadAllText(userConfig), this)); } var stack = MakeStack(); var compilationSteps = stack.ToList(); File.WriteAllText(Path.Combine(s, "_current_compilation_stack.yml"), Serialization.Serialize(compilationSteps)); return(compilationSteps); }
public LuceneIndex(string LIBRARY_INDEX_BASE_PATH) { this.LIBRARY_INDEX_BASE_PATH = LIBRARY_INDEX_BASE_PATH; CheckIndexVersion(); // Write the version of the index Directory.CreateDirectory(LIBRARY_INDEX_BASE_PATH); File.WriteAllText(VersionFilename, INDEX_VERSION); // Delete any old locks if (File.Exists(LuceneWriteLockFilename)) { Logging.Warn("The lucene file lock was still there (bad shutdown perhaps) - so deleting it"); File.Delete(LuceneWriteLockFilename); } // Create our common parts analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29, new Hashtable()); }
private void RunItJoe() { string csl = ObjCSLEditor.Text; string prepared_citation_javascript = ObjJavaScriptEditor.Text; // Write to file for processor string style_file_filename = Path.GetFullPath(Path.Combine(TempFile.TempDirectoryForQiqqa, @"CSLEditor_CSL.csl")); File.WriteAllText(style_file_filename, csl); // Validate the CSL List <string> csl_parse_results = CSLVerifier.Verify(style_file_filename); if (0 < csl_parse_results.Count) { foreach (string line in csl_parse_results) { LogMessage(line); } } CSLProcessor.GenerateCSLEditorCitations(style_file_filename, prepared_citation_javascript, OnBibliographyReady); }
internal static void DoCheck() { try { Logging.Info("Checking for Dropbox conflicts in {0} for machine {1}", ConfigurationManager.Instance.BaseDirectoryForQiqqa, Environment.MachineName); // Write our version string FULL_FILENAME = Path.GetFullPath(Path.Combine(ConfigurationManager.Instance.BaseDirectoryForQiqqa, PREAMBLE_FILENAME + @"." + Environment.MachineName + @".txt")); File.WriteAllText(FULL_FILENAME, WARNING); // Check for other's versions string[] matching_files = Directory.GetFiles(ConfigurationManager.Instance.BaseDirectoryForQiqqa, PREAMBLE_FILENAME + @"*", SearchOption.TopDirectoryOnly); if (1 < matching_files.Length) { // We have a problem, Houston... // Analytics it FeatureTrackingManager.Instance.UseFeature(Features.Diagnostics_DropBox); // Report it to user NotificationManager.Instance.AddPendingNotification( new NotificationManager.Notification( WARNING, "Danger using 3rd party cloud tools!", NotificationManager.NotificationType.Warning, Icons.No, "I understand!", IUnderstand ) ); } } catch (Exception ex) { Logging.Error(ex, "There was a problem checking for Dropbox."); } }
private void DoSave(string filename) { File.WriteAllText(filename, ObjCSLEditor.Text); }
public static void ExportBibTeX(List <PDFDocument> pdf_documents, string filename, Dictionary <string, PDFDocumentExportItem> pdf_document_export_items, bool include_additional_fields) { Logging.Info("Exporting entries to BibTex"); // Write out the header DateTime now = DateTime.Now; StringBuilder sb = new StringBuilder(); sb.AppendLine("% -------------------------------------------------------------------------"); sb.AppendLine(String.Format("% This BibTex file was generated by Qiqqa ({0}?ref=EXPBIB)", Common.Configuration.WebsiteAccess.Url_Documentation4Qiqqa)); sb.AppendLine(String.Format("% {0} {1}", now.ToLongDateString(), now.ToLongTimeString())); sb.AppendLine("% Version 3"); sb.AppendLine("% -------------------------------------------------------------------------"); sb.AppendLine(); // Write out the entries for (int i = 0; i < pdf_documents.Count; ++i) { PDFDocument pdf_document = pdf_documents[i]; try { StatusManager.Instance.UpdateStatus("BibTexExport", String.Format("Exporting entry {0} of {1}", i, pdf_documents.Count), i, pdf_documents.Count); // Get the bibtex string bibtex = pdf_document.BibTex; // If there is no bibtex, make a record if (String.IsNullOrEmpty(bibtex)) { bibtex = BibTexTools.GetEmptyArticleBibTeXTemplate(); string title = pdf_document.TitleCombined; if (Constants.TITLE_UNKNOWN != title) { bibtex = BibTexTools.SetAuthor(bibtex, title); } string author = pdf_document.AuthorsCombined; if (Constants.UNKNOWN_AUTHORS != author) { bibtex = BibTexTools.SetAuthor(bibtex, author); } string year = pdf_document.YearCombined; if (Constants.UNKNOWN_YEAR != year) { bibtex = BibTexTools.SetYear(bibtex, year); } } // NB: The ADDITION of the filename and tags causes the bibtex to be reparsed and formatted, // which currently loses all the nifty bibtex formatting language (e.g. double braces, etc) // // Once the bibtex parser is smarter, we can add this back in. Or perhaps make it an option... if (include_additional_fields) { // If we have an export filename, fill it in! if (pdf_document_export_items.ContainsKey(pdf_document.Fingerprint)) { string bibtex_filename = pdf_document_export_items[pdf_document.Fingerprint].filename; string bibtex_file = ConvertNormalFilenameToZoteroFilename(filename, bibtex_filename); bibtex = BibTexTools.SetField(bibtex, "filename", bibtex_filename); bibtex = BibTexTools.SetField(bibtex, "file", bibtex_file); } else { if (pdf_document.DocumentExists) { string bibtex_filename = pdf_document.DocumentPath; string bibtex_file = ConvertNormalFilenameToZoteroFilename(filename, bibtex_filename); bibtex = BibTexTools.SetField(bibtex, "filename", bibtex_filename); bibtex = BibTexTools.SetField(bibtex, "file", bibtex_file); } } // Fill in the tags and autotags { string tags = pdf_document.Tags; if (!String.IsNullOrEmpty(tags)) { bibtex = BibTexTools.SetField(bibtex, "Tags", tags); } HashSet <string> autotags_set = pdf_document.Library.AITagManager.AITags.GetTagsWithDocument(pdf_document.Fingerprint); string autotags = ArrayFormatter.ListElements(autotags_set.ToList(), ";"); if (!String.IsNullOrEmpty(autotags)) { bibtex = BibTexTools.SetField(bibtex, "AutoTags", autotags); } string keywords = BibTexTools.GetField(bibtex, "keywords"); if (!String.IsNullOrEmpty(tags)) { if (!String.IsNullOrEmpty(keywords)) { keywords = keywords + ";"; } keywords = keywords + tags; } if (!String.IsNullOrEmpty(autotags)) { if (!String.IsNullOrEmpty(keywords)) { keywords = keywords + ";"; } keywords = keywords + autotags; } if (!String.IsNullOrEmpty(keywords)) { bibtex = BibTexTools.SetField(bibtex, "keywords", keywords); } } } // Append the bibtex if (!String.IsNullOrEmpty(bibtex)) { sb.AppendLine(bibtex); sb.AppendLine(); } } catch (Exception ex) { Logging.Error(ex, "There was a problem exporting the bibtex for " + pdf_document); } } // Write to disk File.WriteAllText(filename, sb.ToString()); StatusManager.Instance.UpdateStatus("BibTexExport", String.Format("Exported your BibTex entries to {0}", filename)); }
/// <summary> /// Creates a new file, writes the specified string to the file using the specified encoding, and then closes the file. If the target file already exists, it is overwritten. /// </summary> /// <param name="path">The file to write to. </param> /// <param name="contents">The string to write to the file. </param> /// <exception cref="ArgumentException"><paramref name="path"/> is a zero-length string, contains only white space, or contains one or more invalid characters as defined by <see cref="Path.GetInvalidPathChars"/>.</exception> /// <exception cref="ArgumentNullException"><paramref name="path"/> is <see langword="null"/> or contents is empty.</exception> /// <exception cref="PathTooLongException"> /// The specified path, file name, or both exceed the system-defined maximum length. /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. /// </exception> /// <exception cref="DirectoryNotFoundException">The specified path is invalid (for example, it is on an unmapped drive).</exception> /// <exception cref="IOException">An I/O error occurred while opening the file.</exception> /// <exception cref="UnauthorizedAccessException"> /// path specified a file that is read-only. /// -or- /// This operation is not supported on the current platform. /// -or- /// path specified a directory. /// -or- /// The caller does not have the required permission. /// </exception> /// <exception cref="FileNotFoundException">The file specified in <paramref name="path"/> was not found.</exception> /// <exception cref="NotSupportedException"><paramref name="path"/> is in an invalid format.</exception> /// <exception cref="System.Security.SecurityException">The caller does not have the required permission.</exception> /// <remarks> /// This method uses UTF-8 encoding without a Byte-Order Mark (BOM), so using the <see cref="M:Encoding.GetPreamble"/> method will return an empty byte array. /// If it is necessary to include a UTF-8 identifier, such as a byte order mark, at the beginning of a file, use the <see cref="FileBase.WriteAllText(string,string,System.Text.Encoding)"/> method overload with <see cref="UTF8Encoding"/> encoding. /// <para> /// Given a string and a file path, this method opens the specified file, writes the string to the file, and then closes the file. /// </para> /// </remarks> public override void WriteAllText(string path, string contents) { AfsFile.WriteAllText(path, contents); }
/// <summary> /// Creates a new file, writes the specified string to the file using the specified encoding, and then closes the file. If the target file already exists, it is overwritten. /// </summary> /// <param name="path">The file to write to. </param> /// <param name="contents">The string to write to the file. </param> /// <param name="encoding">The encoding to apply to the string.</param> /// <exception cref="ArgumentException"><paramref name="path"/> is a zero-length string, contains only white space, or contains one or more invalid characters as defined by <see cref="Path.GetInvalidPathChars"/>.</exception> /// <exception cref="ArgumentNullException"><paramref name="path"/> is <see langword="null"/> or contents is empty.</exception> /// <exception cref="PathTooLongException"> /// The specified path, file name, or both exceed the system-defined maximum length. /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. /// </exception> /// <exception cref="DirectoryNotFoundException">The specified path is invalid (for example, it is on an unmapped drive).</exception> /// <exception cref="IOException">An I/O error occurred while opening the file.</exception> /// <exception cref="UnauthorizedAccessException"> /// path specified a file that is read-only. /// -or- /// This operation is not supported on the current platform. /// -or- /// path specified a directory. /// -or- /// The caller does not have the required permission. /// </exception> /// <exception cref="FileNotFoundException">The file specified in <paramref name="path"/> was not found.</exception> /// <exception cref="NotSupportedException"><paramref name="path"/> is in an invalid format.</exception> /// <exception cref="System.Security.SecurityException">The caller does not have the required permission.</exception> /// <remarks> /// Given a string and a file path, this method opens the specified file, writes the string to the file using the specified encoding, and then closes the file. /// The file handle is guaranteed to be closed by this method, even if exceptions are raised. /// </remarks> public override void WriteAllText(string path, string contents, Encoding encoding) { AfsFile.WriteAllText(path, contents, encoding); }
internal static void DoBundle() { string target_filename = null; try { // Get the destination location SaveFileDialog save_file_dialog = new SaveFileDialog(); save_file_dialog.AddExtension = true; save_file_dialog.CheckPathExists = true; save_file_dialog.DereferenceLinks = true; save_file_dialog.OverwritePrompt = true; save_file_dialog.ValidateNames = true; save_file_dialog.DefaultExt = "7z"; save_file_dialog.Filter = "7Z files (*.7z)|*.7z|All files (*.*)|*.*"; save_file_dialog.FileName = "QiqqaLogs.7z"; // Generate and save if (true == save_file_dialog.ShowDialog()) { target_filename = save_file_dialog.FileName; } } catch (Exception ex) { Logging.Warn(ex, "Problem zipping logs"); MessageBoxes.Error("Unfortunately there was a problem creating the log bundle. Please zip them manually, they are found at C:\\Temp\\Qiqqa.log*. There may be more than one. Thanks!"); target_filename = null; } if (target_filename != null) { int progress = 1; int wait_period = 300; const int MAX_PROGRESS = 100; StatusManager.Instance.UpdateStatus("LogBundler", "Bundling the logfile. Please wait...", progress, MAX_PROGRESS); SafeThreadPool.QueueUserWorkItem(o => { string environment_details_filename = null; try { // Delete the target filename if it exists... FileTools.Delete(target_filename); // Note: Path.GetFullPath() throws an exception when you feed it wildcards, e.g. '*' // hence we construct the search path in two steps: const string MAGIC_FILENAME = @"QQQ"; string file_list = Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData, Environment.SpecialFolderOption.Create), @"Quantisle/Qiqqa/Logs", MAGIC_FILENAME)); // and then we replace the 'magic file name' with the real thing: file_list = $"\"{Path.GetSuffixedDirectoryName(file_list)}Qiqqa*.log*\""; // Try get this info for us which could be useful... // If things are really broken, it may fail, that's ok. try { string environmentDetails = "Generated at:" + DateTime.UtcNow.ToString("yyyyMMdd HH:mm:ss") + Environment.NewLine; environmentDetails += ComputerStatistics.GetCommonStatistics(ConfigurationManager.GetCurrentConfigInfos()); environmentDetails += "\r\nConfiguration Bits:\r\n"; environmentDetails += $"Background Tasks: {(ConfigurationManager.Instance.ConfigurationRecord.DisableAllBackgroundTasks ? "Disabled ALL" : "Normal (Enabled)")}\r\n"; environmentDetails += $"Library OCR Task: {(ConfigurationManager.Instance.ConfigurationRecord.Library_OCRDisabled ? "Disabled" : "Normal (Enabled)")}\r\n"; environment_details_filename = TempFile.GenerateTempFilename("txt"); File.WriteAllText(environment_details_filename, environmentDetails); } catch (Exception ex) { Logging.Warn(ex, "Could not get environment details"); } if (environment_details_filename != null) { file_list += " \"" + environment_details_filename + "\""; } // STDOUT/STDERR string process_parameters = String.Format("a -t7z -mmt=on -mx9 -ssw \"{0}\" {1}", target_filename, file_list); Logging.Info($"Bundling the logfiles via command:\n {ConfigurationManager.Instance.Program7ZIP} {process_parameters}"); using (Process process = ProcessSpawning.SpawnChildProcess(ConfigurationManager.Instance.Program7ZIP, process_parameters, ProcessPriorityClass.Normal)) { using (ProcessOutputReader process_output_reader = new ProcessOutputReader(process)) { while (!process.WaitForExit(wait_period)) { progress = Math.Min(MAX_PROGRESS - 5, progress + 1); if (progress >= 25) { wait_period = 1000; } StatusManager.Instance.UpdateStatus("LogBundler", "Bundling the logfile. Please wait...", progress, MAX_PROGRESS); } Logging.Info("7ZIP Log Bundling progress:\n{0}", process_output_reader.GetOutputsDumpStrings()); } MessageBoxes.Info($"The Qiqqa logs with some diagnostic info have been zipped to the location you specified:\n{target_filename}\n\nPlease upload it as issue attachment in your issue filed at https://github.com/jimmejardine/qiqqa-open-source/issues if the support team has requested it. Many thanks!"); FileTools.BrowseToFileInExplorer(target_filename); } } catch (Exception ex) { Logging.Warn(ex, "Problem zipping logs"); MessageBoxes.Error("Unfortunately there was a problem creating the log bundle. Please zip them manually, they are found at C:\\Temp\\Qiqqa.log*. There may be more than one. Thanks!"); target_filename = null; } if (environment_details_filename != null) { FileTools.Delete(environment_details_filename); } }); } }
internal static void Export(WebLibraryDetail web_library_detail, List <PDFDocument> pdf_documents, string base_path, Dictionary <string, PDFDocumentExportItem> pdf_document_export_items) { Logging.Info("Exporting entries to BibTeXTAB separated"); // First work out what fields are available List <string> field_names = null; { HashSet <string> field_names_set = new HashSet <string>(); for (int i = 0; i < pdf_documents.Count; ++i) { PDFDocument pdf_document = pdf_documents[i]; if (!String.IsNullOrEmpty(pdf_document.BibTex)) { BibTexItem item = BibTexParser.ParseOne(pdf_document.BibTex, true); if (null != item) { foreach (var field in item.Fields) { field_names_set.Add(field.Key.ToLower()); } } } } field_names = new List <string>(field_names_set); field_names.Sort(); } // Write out the header DateTime now = DateTime.Now; StringBuilder sb = new StringBuilder(); sb.AppendLine("% -------------------------------------------------------------------------"); sb.AppendLine(String.Format("% This tab separated file was generated by Qiqqa ({0}?ref=EXPTAB)", Common.Configuration.WebsiteAccess.Url_Documentation4Qiqqa)); sb.AppendLine(String.Format("% {0} {1}", now.ToLongDateString(), now.ToLongTimeString())); sb.AppendLine("% Version 1"); sb.AppendLine("% -------------------------------------------------------------------------"); sb.AppendLine(); // Headers sb.AppendFormat("{0}\t", "Fingerprint"); sb.AppendFormat("{0}\t", "Filename"); sb.AppendFormat("{0}\t", "BibTexKey"); sb.AppendFormat("{0}\t", "BibTexType"); foreach (string field_name in field_names) { sb.AppendFormat("{0}\t", FormatFreeText(field_name)); } sb.AppendLine(); // Write out the entries for (int i = 0; i < pdf_documents.Count; ++i) { StatusManager.Instance.UpdateStatus("TabExport", String.Format("Exporting entry {0} of {1}", i, pdf_documents.Count), i, pdf_documents.Count); PDFDocument pdf_document = pdf_documents[i]; sb.AppendFormat("{0}\t", pdf_document.Fingerprint); sb.AppendFormat("{0}\t", pdf_document_export_items.ContainsKey(pdf_document.Fingerprint) ? pdf_document_export_items[pdf_document.Fingerprint].filename : ""); try { if (!String.IsNullOrEmpty(pdf_document.BibTex)) { BibTexItem item = BibTexParser.ParseOne(pdf_document.BibTex, true); if (null != item) { sb.AppendFormat("{0}\t", item.Key); sb.AppendFormat("{0}\t", item.Type); foreach (string field_name in field_names) { sb.AppendFormat("{0}\t", item.ContainsField(field_name) ? FormatFreeText(item[field_name]) : ""); } } } } catch (Exception ex) { Logging.Error(ex, "There was a problem exporting the tab representation for document {0}", pdf_document.Fingerprint); } sb.AppendLine(); } // Write to disk string filename = Path.GetFullPath(Path.Combine(base_path, @"Qiqqa.BibTeX.tab")); File.WriteAllText(filename, sb.ToString()); StatusManager.Instance.UpdateStatus("TabExport", String.Format("Exported your BibTeX tab entries to {0}", filename)); }
internal static void DoBundle() { try { // Try get this info for us which could be useful... // If things are really broken, it may fail, that's ok. string environment_details_filename = null; try { string environmentDetails = "Generated at:" + DateTime.UtcNow.ToString("yyyyMMdd HH:mm:ss") + Environment.NewLine; environmentDetails += ComputerStatistics.GetCommonStatistics(); environment_details_filename = TempFile.GenerateTempFilename("txt"); File.WriteAllText(environment_details_filename, environmentDetails); } catch (Exception ex) { Logging.Warn(ex, "Could not get environment details"); } // Get the destination location SaveFileDialog save_file_dialog = new SaveFileDialog(); save_file_dialog.AddExtension = true; save_file_dialog.CheckPathExists = true; save_file_dialog.DereferenceLinks = true; save_file_dialog.OverwritePrompt = true; save_file_dialog.ValidateNames = true; save_file_dialog.DefaultExt = "7z"; save_file_dialog.Filter = "7Z files (*.7z)|*.7z|All files (*.*)|*.*"; save_file_dialog.FileName = "QiqqaLogs.7z"; // Generate and save if (true == save_file_dialog.ShowDialog()) { string target_filename = save_file_dialog.FileName; string file_list = Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData, Environment.SpecialFolderOption.Create), @"Quantisle/Qiqqa/Logs", @"Qiqqa*.log*")); if (environment_details_filename != null) { file_list += " \"" + environment_details_filename + "\""; } // Delete the target filename if it exists... FileTools.Delete(target_filename); // STDOUT/STDERR string process_parameters = String.Format("a -t7z -mmt=on -mx9 -ssw \"{0}\" \"{1}\"", target_filename, file_list); using (Process process = ProcessSpawning.SpawnChildProcess(ConfigurationManager.Instance.Program7ZIP, process_parameters, ProcessPriorityClass.Normal)) { using (ProcessOutputReader process_output_reader = new ProcessOutputReader(process)) { process.WaitForExit(); Logging.Info("7ZIP Log Bundling progress:\n{0}", process_output_reader.GetOutputsDumpString()); } MessageBoxes.Info("The Qiqqa logs with some diagnostic info have been zipped to the location you specified. Please upload it as issue attachment in your issue filed at https://github.com/jimmejardine/qiqqa-open-source/issues if the support team has requested it. Many thanks!"); FileTools.BrowseToFileInExplorer(target_filename); } } FileTools.Delete(environment_details_filename); } catch (Exception ex) { Logging.Warn(ex, "Problem zipping logs"); MessageBoxes.Error("Unfortunately there was a problem creating the log bundle. Please zip them manually, they are found at C:\\Temp\\Qiqqa.log*. There may be more than one. Thanks!"); } }
private async Task CreateMetaFiles() { Utils.Log("Getting Nexus API key, please click authorize if a browser window appears"); var nexusClient = await NexusApiClient.Get(); var archives = Directory.EnumerateFiles(DownloadsFolder, "*", SearchOption.TopDirectoryOnly).Where(f => File.Exists(f) && Path.GetExtension(f) != Consts.MetaFileExtension && Path.GetExtension(f) != Consts.HashFileExtension && !File.Exists($"{f}.meta") && ActiveArchives.Contains(Path.GetFileNameWithoutExtension(f))); await archives.PMap(Queue, async f => { Info($"Creating meta file for {Path.GetFileName(f)}"); var metaString = "[General]\n" + "repository=Nexus\n" + $"gameName={GameName}\n"; string hash; using (var md5 = MD5.Create()) using (var stream = File.OpenRead(f)) { Utils.Log($"Calculating hash for {Path.GetFileName(f)}"); var cH = md5.ComputeHash(stream); hash = BitConverter.ToString(cH).Replace("-", "").ToLowerInvariant(); Utils.Log($"Hash is {hash}"); } var md5Response = await nexusClient.GetModInfoFromMD5(Game, hash); if (md5Response.Count >= 1) { var modInfo = md5Response[0].mod; metaString += $"modID={modInfo.mod_id}\n" + $"modName={modInfo.name}\n" + $"fileID={md5Response[0].file_details.file_id}\n" + $"version={md5Response[0].file_details.version}\n" + $"hash={hash}\n"; File.WriteAllText(f + Consts.MetaFileExtension, metaString, Encoding.UTF8); } else { Error("Error while getting information from NexusMods via MD5 hash!"); } }); var otherFiles = Directory.EnumerateFiles(DownloadsFolder, "*", SearchOption.TopDirectoryOnly).Where(f => Path.GetExtension(f) == Consts.MetaFileExtension && !ActiveArchives.Contains(Path.GetFileNameWithoutExtension(f))); await otherFiles.PMap(Queue, async f => { Info($"File {f} is not in ActiveArchives"); var lines = File.ReadAllLines(f); if (lines.Length == 0 || !lines.Any(line => lines.Contains("directURL="))) { if (lines.Length == 0) { return; } lines.Do(line => { var tag = ""; if (line.Contains("tag=")) { tag = line.Substring("tag=".Length); } if (tag != Consts.WABBAJACK_VORTEX_MANUAL) { return; } Info($"File {f} contains the {Consts.WABBAJACK_VORTEX_MANUAL} tag, adding to ActiveArchives"); ActiveArchives.Add(Path.GetFileNameWithoutExtension(f)); }); } else { Info($"File {f} appears to not be from the Nexus, adding to ActiveArchives"); ActiveArchives.Add(Path.GetFileNameWithoutExtension(f)); } }); Info("Checking for Steam Workshop Items..."); if (!_isSteamGame || _steamGame == null || !_hasSteamWorkshopItems) { return; } _steamGame.WorkshopItems.Do(item => { var filePath = Path.Combine(DownloadsFolder, $"steamWorkshopItem_{item.ItemID}.meta"); if (File.Exists(filePath)) { Utils.Log($"File {filePath} already exists, skipping"); return; } Utils.Log($"Creating meta file for {item.ItemID}"); var metaString = "[General]\n" + "repository=Steam\n" + $"gameName={GameName}\n" + $"steamID={_steamGame.ID}\n" + $"itemID={item.ItemID}\n" + $"itemSize={item.Size}\n"; try { File.WriteAllText(filePath, metaString); } catch (Exception e) { Utils.Error(e, $"Exception while writing to disk at {filePath}"); } }); }
internal static void Export(Library library, List <PDFDocument> pdf_documents, string base_path, Dictionary <string, PDFDocumentExportItem> pdf_document_export_items) { Logging.Info("Exporting entries to TAB separated"); // Write out the header DateTime now = DateTime.Now; StringBuilder sb = new StringBuilder(); sb.AppendLine("% -------------------------------------------------------------------------"); sb.AppendLine(String.Format("% This tab separated file was generated by Qiqqa ({0}?ref=EXPTAB)", Common.Configuration.WebsiteAccess.Url_Documentation4Qiqqa)); sb.AppendLine(String.Format("% {0} {1}", now.ToLongDateString(), now.ToLongTimeString())); sb.AppendLine("% Version 1"); sb.AppendLine("% -------------------------------------------------------------------------"); sb.AppendLine(); // Headers sb.AppendFormat( "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\t{13}\t{14}\t{15}\t{16}\t{17}\t{18}\t{19}\t{20}", "Fingerprint", "BibTexKey", "Year", "Title", "Authors", "Publication", "Rating", "ReadingStage", "IsFavourite", "IsVanillaReference", "Tags", "AutoTags", "DateAddedToDatabase", "DateLastRead", "DateLastModified", "Filename", "Comments", "Abstract", "", "", "" ); sb.AppendLine(); // Write out the entries for (int i = 0; i < pdf_documents.Count; ++i) { PDFDocument pdf_document = pdf_documents[i]; try { StatusManager.Instance.UpdateStatus("TabExport", String.Format("Exporting entry {0} of {1}", i, pdf_documents.Count), i, pdf_documents.Count); HashSet <string> autotags_set = pdf_document.Library.AITagManager.AITags.GetTagsWithDocument(pdf_document.Fingerprint); string autotags = ArrayFormatter.ListElements(autotags_set.ToList(), ";"); sb.AppendFormat( "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\t{13}\t{14}\t{15}\t{16}\t{17}\t{18}\t{19}\t{20}", pdf_document.Fingerprint, pdf_document.BibTexKey, pdf_document.YearCombined, pdf_document.TitleCombined, pdf_document.AuthorsCombined, pdf_document.Publication, pdf_document.Rating, pdf_document.ReadingStage, pdf_document.IsFavourite, pdf_document.IsVanillaReference, pdf_document.Tags, autotags, FormatDate(pdf_document.DateAddedToDatabase), FormatDate(pdf_document.DateLastRead), FormatDate(pdf_document.DateLastModified), pdf_document_export_items.ContainsKey(pdf_document.Fingerprint) ? pdf_document_export_items[pdf_document.Fingerprint].filename : "", FormatFreeText(pdf_document.Comments), FormatFreeText(pdf_document.Abstract), null, null, null ); sb.AppendLine(); } catch (Exception ex) { Logging.Error(ex, "There was a problem exporting the tab representation for " + pdf_document); } } // Write to disk string filename = Path.GetFullPath(Path.Combine(base_path, @"Qiqqa.tab")); File.WriteAllText(filename, sb.ToString()); StatusManager.Instance.UpdateStatus("TabExport", String.Format("Exported your tab entries to {0}", filename)); }
private int CountPDFPages() { string cached_count_filename = MakeFilename_PageCount(); int num; // Try the cached version try { if (File.Exists(cached_count_filename)) { num = Convert.ToInt32(File.ReadAllText(cached_count_filename)); if (0 != num) { return(num); } } } catch (Exception ex) { Logging.Warn(ex, "There was a problem loading the cached page count."); FileTools.Delete(cached_count_filename); } // If we get here, either the pagecountfile doesn't exist, or there was an exception Logging.Debug特("Using calculated PDF page count for file {0}", pdf_filename); num = PDFTools.CountPDFPages(pdf_filename); Logging.Info("The result is {1} for using calculated PDF page count for file {0}", pdf_filename, num); do { if (0 != num) { num_pages_calc_try_count = 0; // reset recalc fail counter try { Directory.CreateDirectory(Path.GetDirectoryName(cached_count_filename)); string outputText = Convert.ToString(num, 10); File.WriteAllText(cached_count_filename, outputText); // Open the file and read back what was written: we don't do a file lock for this one, but reckon all threads who // do this, will produce the same number = file content. // // Besides, we don't know if WriteAllText() is atomic; it probably is not. // Hence we read back to verify written content and if there's anything off about it, we // blow it out of the water and retry later, possibly. string readText = File.ReadAllText(cached_count_filename); if (readText != outputText) { throw new IOException("CountPDFPages: cache content as read back from cache file does not match written data. Cache file is untrustworthy."); } } catch (Exception ex) { Logging.Error(ex, "There was a problem using calculated PDF page count for file {0} / {1}", pdf_filename, cached_count_filename); FileTools.Delete(cached_count_filename); // we know the *calculated* pagecount is A-okay, so we can pass that on. // It's just the file I/O for caching the value that may have gone awry, // so we should retry that the next time we (re)calculate the pagecount number // as it is a heavy operation! // //num = 0; } } else { // Special case: when the CountPDFPages() API does not deliver a sane, that is non-zero, page count, // then we've got a PDF file issue on our hands, very probably a damaged PDF. // // Damaged PDF files SHOULD NOT burden us forever, hence we introduce the heauristic of Three Strikes: // when we've (re)calculated the PDF page count three times in a row with errors (num == 0), then we // don't retry ever again, at least not during this application run. // // we DO NOT count I/O errors around the cache file, we only count (re)calc errors: num_pages_calc_try_count++; if (num_pages_calc_try_count >= 3) { num = -1; // signal final failure Logging.Warn("Marking this PDF Document as uncompromisingly stubborn in its failure to be inspected for file {0}", pdf_filename); continue; // and cache this value } } break; } while (true); return(num); }
public static void CrashDump(Exception e) { File.WriteAllText($"{DateTime.Now.ToString("yyyyMMddTHHmmss_crash_log.txt")}", ExceptionToString(e)); }
private static void TextSave_NotRedundant(string filename, string animal_to_save) { File.WriteAllText(filename, animal_to_save); }
private int CountPDFPages() { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); string cached_count_filename = MakeFilename_PageCount(); int num; // Try the cached version try { if (File.Exists(cached_count_filename)) { num = Convert.ToInt32(File.ReadAllText(cached_count_filename)); if (num > 0) { return(num); } // NOTE: all fringe cases, that is CORRUPTED and EMPTY documents, will be re-analyzed this way on every run! // This prevents odd page numbers from creeping into the persisted cache. } } catch (Exception ex) { Logging.Warn(ex, "There was a problem loading the cached page count."); } // Nuke the cache file, iff it exists. When we get here, it contained undesirable data anyway. FileTools.Delete(cached_count_filename); // If we get here, either the pagecount-file doesn't exist, or there was an exception Logging.Debug特("Calculating PDF page count for file {0}", DocumentPath); if (!DocumentExists) { num = -2; } else { num = PDFTools.CountPDFPages(DocumentPath, PDFPassword); Logging.Info("The result is {1} for using calculated PDF page count for file {0}", DocumentPath, num); if (num > 0) { try { Directory.CreateDirectory(Path.GetDirectoryName(cached_count_filename)); string outputText = Convert.ToString(num, 10); File.WriteAllText(cached_count_filename, outputText); // Open the file and read back what was written: we don't do a file lock for this one, but reckon all threads who // do this, will produce the same number = file content. // // Besides, we don't know if WriteAllText() is atomic; it probably is not. // Hence we read back to verify written content and if there's anything off about it, we // blow it out of the water and retry later, possibly. string readText = File.ReadAllText(cached_count_filename); if (readText != outputText) { throw new IOException("CountPDFPages: cache content as read back from cache file does not match written data. Cache file is untrustworthy."); } return(num); } catch (Exception ex) { Logging.Error(ex, "There was a problem using calculated PDF page count for file {0} / {1}", DocumentPath, cached_count_filename); FileTools.Delete(cached_count_filename); // we know the *calculated* pagecount is A-okay, so we can pass that on. // It's just the file I/O for caching the value that may have gone awry, // so we should retry that the next time we (re)calculate the pagecount number // as it is a heavy operation! // //num = 0; return(num); } } // Special case: when the CountPDFPages() API does not deliver a sane, that is positive, page count, // then we've got a PDF file issue on our hands, very probably a damaged PDF. // // Damaged PDF files SHOULD NOT burden us forever, hence we introduce the heuristic of Retry At Restart: // all "suspect" page counts are used as is for now, but when the application is restarted at any time // later, those documents will be inspected once again. // // we DO NOT count I/O errors around the cache file. ASSERT.Test(num <= 0); Logging.Warn("Marking this PDF Document as uncompromisingly stubborn in its failure to be inspected for file {0}. Page count code: {1}", DocumentPath, num); } return(num); }