private void LoadKnownWebLibraries(string filename, bool only_load_those_libraries_which_are_actually_present) { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); Logging.Info("+Loading known Web Libraries"); try { if (File.Exists(filename)) { ConfigurationManager.ThrowWhenActionIsNotEnabled(nameof(LoadKnownWebLibraries)); KnownWebLibrariesFile known_web_libraries_file = SerializeFile.ProtoLoad <KnownWebLibrariesFile>(filename); if (null != known_web_libraries_file.web_library_details) { foreach (WebLibraryDetail new_web_library_detail in known_web_libraries_file.web_library_details) { Logging.Info("We have known details for library '{0}' ({1})", new_web_library_detail.Title, new_web_library_detail.Id); if (!new_web_library_detail.IsPurged) { string libdir_path = WebLibraryDetail.GetLibraryBasePathForId(new_web_library_detail.Id); string libfile_path = LibraryDB.GetLibraryDBPath(libdir_path); if (File.Exists(libfile_path) || !only_load_those_libraries_which_are_actually_present) { UpdateKnownWebLibrary(new_web_library_detail); } else { Logging.Info("Not loading library {0} with Id {1} as it does not exist on disk. (library file path: {2})", new_web_library_detail.Title, new_web_library_detail.Id, libfile_path); } } else { Logging.Info("Not loading purged library {0} with id {1}.", new_web_library_detail.Title, new_web_library_detail.Id); } } } } } catch (Exception ex) { Logging.Error(ex, "There was a problem loading the known Web Libraries from config file {0}", filename); } Logging.Info("-Loading known Web Libraries"); }
public static bool LocateFirstPDFDocumentWithAnnotation(string library_fingerprint, string document_fingerprint, Guid annotation_guid, out PDFDocument out_pdf_document, out PDFAnnotation out_pdf_annotation) { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); // First attempt to find it in the specified library if (null != library_fingerprint) { WebLibraryDetail web_library_detail = WebLibraryManager.Instance.GetLibrary(library_fingerprint); if (null != web_library_detail) { PDFDocument pdf_document = web_library_detail.Xlibrary.GetDocumentByFingerprint(document_fingerprint); if (null != pdf_document) { PDFAnnotation pdf_annotation = pdf_document.GetAnnotationByGuid(annotation_guid); if (null != pdf_annotation) { out_pdf_document = pdf_document; out_pdf_annotation = pdf_annotation; return(true); } } } } // If we couldn't find it, then try in all the other libraries... foreach (WebLibraryDetail web_library_detail in WebLibraryManager.Instance.WebLibraryDetails_WorkingWebLibraries) { PDFDocument pdf_document = web_library_detail.Xlibrary.GetDocumentByFingerprint(document_fingerprint); if (null != pdf_document) { PDFAnnotation pdf_annotation = pdf_document.GetAnnotationByGuid(annotation_guid); if (null != pdf_annotation) { out_pdf_document = pdf_document; out_pdf_annotation = pdf_annotation; return(true); } } } // Out of luck! out_pdf_document = null; out_pdf_annotation = null; return(false); }
private static WebLibraryDetail PickWebLibrary_GUI(string message) { WebLibraryPicker web_library_picker = new WebLibraryPicker(); WebLibraryDetail rv = null; web_library_picker.Picked += delegate(object sender, PickedEventArgs e) { rv = e.pickedLibrary; }; if (null != message) { web_library_picker.TextMessage.Inlines.Clear(); web_library_picker.TextMessage.Inlines.Add(message); } web_library_picker.ShowDialog(); return(rv); }
// ************************************************************************************************************* private void AddLocalGuestLibraryIfMissing() { // Check if we have an existing Guest library foreach (var pair in web_library_details) { if (pair.Value.IsLocalGuestLibrary) { guest_web_library_detail = pair.Value; break; } } // If we did not have a guest library, create one... if (null == guest_web_library_detail) { WebLibraryDetail new_web_library_detail = new WebLibraryDetail(); new_web_library_detail.Id = "Guest"; new_web_library_detail.Title = "Local Guest Library"; new_web_library_detail.Description = "This is the library that comes with your Qiqqa guest account."; new_web_library_detail.Deleted = false; new_web_library_detail.IsReadOnly = false; new_web_library_detail.IsLocalGuestLibrary = true; UpdateKnownWebLibrary(new_web_library_detail); // Store this reference to guest guest_web_library_detail = new_web_library_detail; } // Import the Qiqqa manuals in the background, waiting until the library has loaded... SafeThreadPool.QueueUserWorkItem(o => { while (!guest_web_library_detail.library.LibraryIsLoaded) { if (Utilities.Shutdownable.ShutdownableManager.Instance.IsShuttingDown) { return; } System.Threading.Thread.Sleep(500); } QiqqaManualTools.AddManualsToLibrary(guest_web_library_detail.library); }); }
public WebLibraryDetail UpdateKnownWebLibraryFromBundleLibraryManifest(BundleLibraryManifest manifest) { Logging.Info("+Updating known Bundle Library {0} ({1})", manifest.Title, manifest.Id); WebLibraryDetail new_web_library_detail = new WebLibraryDetail(); new_web_library_detail.BundleManifestJSON = manifest.ToJSON(); new_web_library_detail.Id = manifest.Id; new_web_library_detail.Title = manifest.Title; new_web_library_detail.Description = manifest.Description; new_web_library_detail.IsReadOnly = true; new_web_library_detail.Deleted = false; UpdateKnownWebLibrary(new_web_library_detail); Logging.Info("-Updating known Bundle Library {0} ({1})", manifest.Title, manifest.Id); return(new_web_library_detail); }
public void UpdateKnownWebLibraryFromIntranet(string intranet_path) { Logging.Info("+Updating known Intranet Library from " + intranet_path); IntranetLibraryDetail intranet_library_detail = IntranetLibraryDetail.Read(IntranetLibraryTools.GetLibraryDetailPath(intranet_path)); WebLibraryDetail new_web_library_detail = new WebLibraryDetail(); new_web_library_detail.IntranetPath = intranet_path; new_web_library_detail.Id = intranet_library_detail.Id; new_web_library_detail.Title = intranet_library_detail.Title; new_web_library_detail.Description = intranet_library_detail.Description; new_web_library_detail.IsReadOnly = false; new_web_library_detail.Deleted = false; UpdateKnownWebLibrary(new_web_library_detail); Logging.Info("-Updating known Intranet Library from " + intranet_path); }
public void UpdateKnownWebLibraryFromIntranet(string intranet_path, bool suppress_flush_to_disk = true, string extra_info_message_on_skip = "") { Logging.Info("+Updating known Intranet Library from {0}", intranet_path); IntranetLibraryDetail intranet_library_detail = IntranetLibraryDetail.Read(IntranetLibraryTools.GetLibraryDetailPath(intranet_path)); WebLibraryDetail new_web_library_detail = new WebLibraryDetail(); new_web_library_detail.IntranetPath = intranet_path; //new_web_library_detail.IsIntranetLibrary = true; new_web_library_detail.Id = intranet_library_detail.Id; new_web_library_detail.Title = intranet_library_detail.Title; new_web_library_detail.Description = intranet_library_detail.Description; new_web_library_detail.IsReadOnly = false; new_web_library_detail.Deleted = false; UpdateKnownWebLibrary(new_web_library_detail, suppress_flush_to_disk, extra_info_message_on_skip); Logging.Info("-Updating known Intranet Library from {0}", intranet_path); }
public void UpdateKnownWebLibraryFromIntranet(string intranet_path, bool suppress_flush_to_disk = true, string extra_info_message_on_skip = "") { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); Logging.Info("+Updating known Intranet Library from {0}", intranet_path); IntranetLibraryDetail intranet_library_detail = IntranetLibraryDetail.Read(IntranetLibraryTools.GetLibraryDetailPath(intranet_path)); WebLibraryDetail new_web_library_detail = new WebLibraryDetail(); new_web_library_detail.IntranetPath = intranet_path; new_web_library_detail.Id = intranet_library_detail.Id; new_web_library_detail.Title = intranet_library_detail.Title; new_web_library_detail.Description = intranet_library_detail.Description; new_web_library_detail.Deleted = false; UpdateKnownWebLibrary(new_web_library_detail, suppress_flush_to_disk, extra_info_message_on_skip); Logging.Info("-Updating known Intranet Library from {0}", intranet_path); }
public WebLibraryDetail UpdateKnownWebLibraryFromBundleLibraryManifest(BundleLibraryManifest manifest, bool suppress_flush_to_disk = true) { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); Logging.Info("+Updating known Bundle Library {0} ({1})", manifest.Title, manifest.Id); WebLibraryDetail new_web_library_detail = new WebLibraryDetail(); new_web_library_detail.BundleManifestJSON = manifest.ToJSON(); //new_web_library_detail.IsBundleLibrary = true; new_web_library_detail.Id = manifest.Id; new_web_library_detail.Title = manifest.Title; new_web_library_detail.Description = manifest.Description; new_web_library_detail.Deleted = false; UpdateKnownWebLibrary(new_web_library_detail, suppress_flush_to_disk); Logging.Info("-Updating known Bundle Library {0} ({1})", manifest.Title, manifest.Id); return(new_web_library_detail); }
// ************************************************************************************************************* // *** MIGRATION TO OPEN SOURCE CODE *************************************************************************** // ************************************************************************************************************* private void AddLegacyWebLibrariesThatCanBeFoundOnDisk() { /** * Plan: * Iterate through all the folders in the Qiqqa data directory * If a folder contains a valid Library record and it is a WEB library, then add it to our list with the word '[LEGACY]' in front of it */ string base_directory_path = UpgradePaths.V037To038.SQLiteUpgrade.BaseDirectoryForQiqqa; Logging.Info("Going to scan for web libraries at: " + base_directory_path); if (Directory.Exists(base_directory_path)) { string[] library_directories = Directory.GetDirectories(base_directory_path); foreach (string library_directory in library_directories) { Logging.Info("Inspecting directory {0}", library_directory); string database_file = library_directory + @"\Qiqqa.library"; if (File.Exists(database_file)) { var library_id = Path.GetFileName(library_directory); if (web_library_details.ContainsKey(library_id)) { Logging.Info("We already know about this library, so skipping legacy locate: " + library_id); continue; } WebLibraryDetail new_web_library_detail = new WebLibraryDetail(); new_web_library_detail.Id = library_id; new_web_library_detail.Title = "Legacy Web Library - " + new_web_library_detail.Id.Substring(0, 8); new_web_library_detail.IsReadOnly = true; new_web_library_detail.library = new Library(new_web_library_detail); web_library_details[new_web_library_detail.Id] = new_web_library_detail; } } } }
private void WebLibraryDetailControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { drag_to_library_manager.DefaultLibrary = null; ObjTitleImage.Source = null; // Store the web library details web_library_detail = DataContext as WebLibraryDetail; if (null != web_library_detail) { // WEAK EVENT HANDLER FOR: web_library_detail.library.OnDocumentsChanged += library_OnDocumentsChanged; WeakEventHandler <Library.PDFDocumentEventArgs> .Register <Library, WebLibraryDetailControl>( web_library_detail.library, registerWeakEvent, deregisterWeakEvent, this, forwardWeakEvent ); drag_to_library_manager.DefaultLibrary = web_library_detail.library; } UpdateLibraryStatistics(); }
public static PDFDocument LocateFirstPDFDocument(string library_fingerprint, string document_fingerprint) { // First attempt to find it in the specified library if (null != library_fingerprint) { WebLibraryDetail web_library_detail = WebLibraryManager.Instance.GetLibrary(library_fingerprint); if (null != web_library_detail) { PDFDocument pdf_document = web_library_detail.Xlibrary.GetDocumentByFingerprint(document_fingerprint); if (null != pdf_document) { return(pdf_document); } else { Logging.Warn("WbLibraryDocumentLocator: Cannot find document anymore for fingerprint {0}", document_fingerprint); } } } // If we couldn't find it, then try in all the other libraries... foreach (WebLibraryDetail web_library_detail in WebLibraryManager.Instance.WebLibraryDetails_WorkingWebLibraries) { PDFDocument pdf_document = web_library_detail.Xlibrary.GetDocumentByFingerprint(document_fingerprint); if (null != pdf_document) { return(pdf_document); } else { Logging.Warn("WbLibraryDocumentLocator: Cannot find document anymore for fingerprint {0}", document_fingerprint); } } return(null); }
// ************************************************************************************************************* // *** MIGRATION TO OPEN SOURCE CODE *************************************************************************** // ************************************************************************************************************* private void AddLegacyWebLibrariesThatCanBeFoundOnDisk() { /** * Plan: * Iterate through all the folders in the Qiqqa data directory * If a folder contains a valid Library record and it is a WEB library, then add it to our list with the word '[LEGACY]' in front of it */ string base_directory_path = UpgradePaths.V037To038.SQLiteUpgrade.BaseDirectoryForQiqqa; Logging.Info("Going to scan for web libraries at: {0}", base_directory_path); if (Directory.Exists(base_directory_path)) { string[] library_directories = Directory.GetDirectories(base_directory_path); foreach (string library_directory in library_directories) { Logging.Info("Inspecting directory {0} - Phase 1 : Web & Known Libraries", library_directory); string databaselist_file = Path.GetFullPath(Path.Combine(library_directory, @"Qiqqa.known_web_libraries")); if (File.Exists(databaselist_file)) { LoadKnownWebLibraries(databaselist_file, true); } } foreach (string library_directory in library_directories) { Logging.Info("Inspecting directory {0} - Phase 2 : Intranet Libraries", library_directory); string databaselist_file = IntranetLibraryTools.GetLibraryDetailPath(library_directory); if (File.Exists(databaselist_file)) { IntranetLibraryDetail intranet_library_detail = IntranetLibraryDetail.Read(databaselist_file); UpdateKnownWebLibraryFromIntranet(library_directory, extra_info_message_on_skip: String.Format(" as obtained from file {0}", databaselist_file)); } } foreach (string library_directory in library_directories) { Logging.Info("Inspecting directory {0} - Phase 3 : Bundles", library_directory); // must be a qiqqa_bundle and/or qiqqa_bundle_manifest file set Logging.Warn("Auto bundle import at startup is not yet suppoerted."); } foreach (string library_directory in library_directories) { Logging.Info("Inspecting directory {0} - Phase 4 : Local and Legacy Libraries", library_directory); string database_file = Path.GetFullPath(Path.Combine(library_directory, @"Qiqqa.library")); if (File.Exists(database_file)) { var library_id = Path.GetFileName(library_directory); WebLibraryDetail new_web_library_detail = new WebLibraryDetail(); new_web_library_detail.Id = library_id; new_web_library_detail.Title = "Legacy Web Library - " + new_web_library_detail.Id; new_web_library_detail.IsReadOnly = false; // library: UNKNOWN type UpdateKnownWebLibrary(new_web_library_detail); } } } }
public Library GetLibrary(WebLibraryDetail web_library_detail) { return(web_library_detail.library); }
private void UpdateLibraryStatistics_Headers() { WPFDoEvents.AssertThisCodeIsRunningInTheUIThread(); TextLibraryCount.Text = ""; PanelForHyperlinks.Visibility = Visibility.Visible; PanelForget.Visibility = Visibility.Collapsed; PanelSetSyncPoint.Visibility = Visibility.Collapsed; PanelLocateSyncPoint.Visibility = Visibility.Collapsed; PanelEdit.Visibility = Visibility.Collapsed; PanelDelete.Visibility = Visibility.Collapsed; PanelPurge.Visibility = Visibility.Collapsed; ButtonAutoSync.Visibility = Visibility.Collapsed; ButtonReadOnly.Visibility = Visibility.Collapsed; ObjTitleImage.Source = null; // Store the web library details WebLibraryDetail web_library_detail = DataContext as WebLibraryDetail; // No need to wait until the library has been completely loaded! drag_to_library_manager.DefaultLibrary = web_library_detail; if (null != web_library_detail) { if (!web_library_detail.IsIntranetLibrary) { TextLibraryCount.Text = String.Format("{0} document(s) in this library", web_library_detail.Xlibrary?.PDFDocuments_IncludingDeleted_Count ?? 0); } else { TextLibraryCount.Text = String.Format("{0} document(s) in this library, {1}", web_library_detail.Xlibrary?.PDFDocuments_IncludingDeleted_Count ?? 0, web_library_detail.LastSynced.HasValue ? $"which was last synced on {web_library_detail.LastSynced.Value}" : @"which has never been synced yet"); } // The wizard stuff if (ConfigurationManager.Instance.ConfigurationRecord.GUI_IsNovice) { WizardDPs.SetPointOfInterest(ButtonIcon, "GuestLibraryOpenButton"); WizardDPs.SetPointOfInterest(TxtTitle, "GuestLibraryTitle"); } // The icon stuff { RenderOptions.SetBitmapScalingMode(ButtonIcon, BitmapScalingMode.HighQuality); ButtonIcon.Width = 64; ButtonIcon.Height = 64; if (web_library_detail.IsIntranetLibrary) { ButtonIcon.Source = Icons.GetAppIcon(Icons.LibraryTypeWeb); //ButtonIcon.Source = Icons.GetAppIcon(Icons.LibraryTypeIntranet); ButtonIcon.ToolTip = "This is an Intranet Library.\nYou can sync it via your Intranet to share with colleagues and across your company computers. Alternatively you can sync to a folder in Cloud Storage such as DropBox, Google Drive or Microsoft OneDrive and anyone with access to that shared folder can sync with your library."; } else if (web_library_detail.IsBundleLibrary) { ButtonIcon.Source = Icons.GetAppIcon(Icons.LibraryTypeBundle); ButtonIcon.ToolTip = "This is a Bundle Library.\nIt's contents will be updated automatically when the Bundle is updated by it's administrator."; } else { ButtonIcon.Source = Icons.GetAppIcon(Icons.LibraryTypeGuest); ButtonIcon.ToolTip = "This is a local Library.\nIts contents are local to this computer. When you assign this library a Sync Point, it can be synchronized with that backup location and possibly shared with other people and machines."; } } // The customization images stuff { string image_filename = CustomBackgroundFilename(); if (File.Exists(image_filename)) { try { ObjTitleImage.Source = BitmapImageTools.FromImage(ImageLoader.Load(image_filename)); } catch (Exception ex) { Logging.Warn(ex, "Problem with custom library background."); } } } { string image_filename = CustomIconFilename(); if (File.Exists(image_filename)) { try { ButtonIcon.Source = BitmapImageTools.FromImage(ImageLoader.Load(image_filename)); } catch (Exception ex) { Logging.Warn(ex, "Problem with custom library icon."); } } } // The autosync stuff if (web_library_detail.IsIntranetLibrary) { ButtonAutoSync.Visibility = Visibility.Visible; ButtonAutoSync.IsChecked = web_library_detail.AutoSync; } // The readonly stuff if (web_library_detail.IsReadOnlyLibrary) { ButtonReadOnly.Visibility = Visibility.Visible; } // The hyperlinks panel PanelEdit.Visibility = Visibility.Visible; PanelDelete.Visibility = Visibility.Visible; PanelForget.Visibility = Visibility.Visible; //PanelSetSyncPoint.Visibility = Visibility.Visible; //PanelLocateSyncPoint.Visibility = Visibility.Visible; PanelEdit.Visibility = Visibility.Visible; PanelDelete.Visibility = Visibility.Visible; //PanelPurge.Visibility = Visibility.Visible; if (web_library_detail.Deleted) { PanelPurge.Visibility = Visibility.Visible; } if (web_library_detail.IsIntranetLibrary) { PanelLocateSyncPoint.Visibility = Visibility.Visible; } if (!web_library_detail.IsReadOnlyLibrary) { PanelSetSyncPoint.Visibility = Visibility.Visible; } } }
public static void Test() { WebLibraryDetail web_library_detail = PickWebLibrary(); Logging.Info("You picked {0}", web_library_detail); }
private string CustomBackgroundFilename() { WebLibraryDetail web_library_detail = DataContext as WebLibraryDetail; return(Path.GetFullPath(Path.Combine(web_library_detail.LIBRARY_BASE_PATH ?? ConfigurationManager.Instance.BaseDirectoryForQiqqa, @"Qiqqa.library_custom_background.jpg"))); }
// ************************************************************************************************************* // *** MIGRATION TO OPEN SOURCE CODE *************************************************************************** // ************************************************************************************************************* private void AddLegacyWebLibrariesThatCanBeFoundOnDisk() { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); try { ConfigurationManager.ThrowWhenActionIsNotEnabled(nameof(AddLegacyWebLibrariesThatCanBeFoundOnDisk)); /** * Plan: * - Iterate through all the folders in the Qiqqa data directory. * - If a folder contains a valid Library record and it is a WEB library, * then add it to our list with the word '[LEGACY]' in front of it. */ string base_directory_path = UpgradePaths.V037To038.SQLiteUpgrade.BaseDirectoryForQiqqa; Logging.Info("Going to scan for web libraries at: {0}", base_directory_path); if (Directory.Exists(base_directory_path)) { string[] library_directories = Directory.GetDirectories(base_directory_path); foreach (string library_directory in library_directories) { Logging.Info("Inspecting directory {0} - Phase 1 : Web & Known Libraries", library_directory); string databaselist_file = Path.GetFullPath(Path.Combine(library_directory, @"Qiqqa.known_web_libraries")); if (File.Exists(databaselist_file)) { LoadKnownWebLibraries(databaselist_file, only_load_those_libraries_which_are_actually_present: true); } } foreach (string library_directory in library_directories) { Logging.Info("Inspecting directory {0} - Phase 2 : Intranet Libraries", library_directory); string databaselist_file = IntranetLibraryTools.GetLibraryDetailPath(library_directory); if (File.Exists(databaselist_file)) { IntranetLibraryDetail intranet_library_detail = IntranetLibraryDetail.Read(databaselist_file); UpdateKnownWebLibraryFromIntranet(library_directory, extra_info_message_on_skip: String.Format(" as obtained from file {0}", databaselist_file)); } } foreach (string library_directory in library_directories) { Logging.Info("Inspecting directory {0} - Phase 3 : Bundles", library_directory); // must be a qiqqa_bundle and/or qiqqa_bundle_manifest file set Logging.Warn("Auto bundle import at startup is not yet supported."); } foreach (string library_directory in library_directories) { Logging.Info("Inspecting directory {0} - Phase 4 : Local and Legacy Libraries", library_directory); string database_file = LibraryDB.GetLibraryDBPath(library_directory); string db_syncref_path = IntranetLibraryTools.GetLibraryMetadataPath(library_directory); // add/update only if this is not a Internet sync directory/DB! if (File.Exists(db_syncref_path)) { Logging.Info("Skip the Qiqqa Internet/Intranet Sync directory and the sync DB contained therein: '{0}'", db_syncref_path); // https://github.com/jimmejardine/qiqqa-open-source/issues/145 :: delete lib file when it is very small and was illegally // constructed by a previous v82beta Qiqqa release: if (File.Exists(database_file)) { long s3length = File.GetSize(database_file); if (6 * 1024 > s3length) { Logging.Warn("DELETE the wrongfully created DB file '{0}' in the Qiqqa Internet/Intranet Sync directory and the sync DB contained therein: '{1}', which has precedence!", database_file, db_syncref_path); FileTools.DeleteToRecycleBin(database_file); } else { Logging.Error("Inspect the Library DB file '{0}' in the Qiqqa Internet/Intranet Sync directory and the sync DB contained therein: '{1}', which MAY have precedence. Delete one of these manually to clean up your system as Qiqqa heuristics cannot tell which is the prevalent metadata database here!", database_file, db_syncref_path); } } continue; } if (File.Exists(database_file)) { var library_id = Path.GetFileName(library_directory); WebLibraryDetail new_web_library_detail = new WebLibraryDetail(); new_web_library_detail.Id = library_id; new_web_library_detail.Title = "Legacy Web Library - " + new_web_library_detail.Id; new_web_library_detail.IsReadOnly = false; // library: UNKNOWN type UpdateKnownWebLibrary(new_web_library_detail); } } } } catch (Exception ex) { Logging.Error(ex, "There was a problem while scanning for (legacy) libraries."); } }
void ObjWebLibraryListControl_OnWebLibrarySelected(WebLibraryDetail web_library_detail) { last_picked_web_library_detail = web_library_detail; this.Close(); }
void Cancel() { last_picked_web_library_detail = null; this.Close(); }
private void UpdateLibraryStatistics_Stats_Background_CoverFlow(WebLibraryDetail web_library_detail) { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); if (web_library_detail.Xlibrary == null) { return; } List <PDFDocument> pdf_documents_all = web_library_detail.Xlibrary.PDFDocuments; // The list of recommended items DocumentDisplayWorkManager ddwm = new DocumentDisplayWorkManager(); { int ITEMS_IN_LIST = 5; // Upcoming reading is: // interrupted // top priority // read again // recently added and no status pdf_documents_all.Sort(PDFDocumentListSorters.DateAddedToDatabase); foreach (string reading_stage in new string[] { Choices.ReadingStages_INTERRUPTED, Choices.ReadingStages_TOP_PRIORITY, Choices.ReadingStages_READ_AGAIN }) { foreach (PDFDocument pdf_document in pdf_documents_all) { if (!pdf_document.DocumentExists) { continue; } if (pdf_document.ReadingStage == reading_stage) { if (!ddwm.ContainsPDFDocument(pdf_document)) { ddwm.AddDocumentDisplayWork(DocumentDisplayWork.StarburstColor.Pink, reading_stage, pdf_document); if (ddwm.Count >= ITEMS_IN_LIST) { break; } } } } } } { int ITEMS_IN_LIST = 3; // Recently added { pdf_documents_all.Sort(PDFDocumentListSorters.DateAddedToDatabase); int num_added = 0; foreach (PDFDocument pdf_document in pdf_documents_all) { if (!pdf_document.DocumentExists) { continue; } if (!ddwm.ContainsPDFDocument(pdf_document)) { ddwm.AddDocumentDisplayWork(DocumentDisplayWork.StarburstColor.Green, "Added Recently", pdf_document); if (++num_added >= ITEMS_IN_LIST) { break; } } } } // Recently read { pdf_documents_all.Sort(PDFDocumentListSorters.DateLastRead); int num_added = 0; foreach (PDFDocument pdf_document in pdf_documents_all) { if (!pdf_document.DocumentExists) { continue; } if (!ddwm.ContainsPDFDocument(pdf_document)) { ddwm.AddDocumentDisplayWork(DocumentDisplayWork.StarburstColor.Blue, "Read Recently", pdf_document); if (++num_added >= ITEMS_IN_LIST) { break; } } } } } WPFDoEvents.InvokeAsyncInUIThread(() => { WPFDoEvents.AssertThisCodeIsRunningInTheUIThread(); // And fill the placeholders try { UpdateLibraryStatistics_Stats_Background_GUI_AddAllPlaceHolders(ddwm.ddws); SafeThreadPool.QueueUserWorkItem(o => { try { // Now render each document using (Font font = new Font("Times New Roman", 11.0f)) { using (StringFormat string_format = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }) { var color_matrix = new ColorMatrix(); color_matrix.Matrix33 = 0.9f; using (var image_attributes = new ImageAttributes()) { image_attributes.SetColorMatrix(color_matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); foreach (DocumentDisplayWork ddw in ddwm.ddws) { try { using (MemoryStream ms = new MemoryStream(SoraxPDFRenderer.GetPageByHeightAsImage(ddw.pdf_document.DocumentPath, ddw.pdf_document.PDFPassword, 1, (int)Math.Round(PREVIEW_IMAGE_HEIGHT / PREVIEW_IMAGE_PERCENTAGE), (int)Math.Round(PREVIEW_IMAGE_WIDTH / PREVIEW_IMAGE_PERCENTAGE)))) { Bitmap page_bitmap = (Bitmap)System.Drawing.Image.FromStream(ms); page_bitmap = page_bitmap.Clone(new RectangleF { Width = page_bitmap.Width, Height = (int)Math.Round(page_bitmap.Height * PREVIEW_IMAGE_PERCENTAGE) }, page_bitmap.PixelFormat); using (Graphics g = Graphics.FromImage(page_bitmap)) { int CENTER = 60; int RADIUS = 60; { BitmapImage starburst_bi = null; switch (ddw.starburst_color) { case DocumentDisplayWork.StarburstColor.Blue: starburst_bi = Icons.GetAppIcon(Icons.PageCornerBlue); break; case DocumentDisplayWork.StarburstColor.Green: starburst_bi = Icons.GetAppIcon(Icons.PageCornerGreen); break; case DocumentDisplayWork.StarburstColor.Pink: starburst_bi = Icons.GetAppIcon(Icons.PageCornerPink); break; default: starburst_bi = Icons.GetAppIcon(Icons.PageCornerOrange); break; } Bitmap starburst_image = BitmapImageTools.ConvertBitmapSourceToBitmap(starburst_bi); g.SmoothingMode = SmoothingMode.AntiAlias; g.DrawImage( starburst_image, new Rectangle(CENTER - RADIUS, CENTER - RADIUS, 2 * RADIUS, 2 * RADIUS), 0, 0, starburst_image.Width, starburst_image.Height, GraphicsUnit.Pixel, image_attributes ); } using (Matrix mat = new Matrix()) { mat.RotateAt(-50, new PointF(CENTER / 2, CENTER / 2)); g.Transform = mat; string wrapped_caption = ddw.starburst_caption; wrapped_caption = wrapped_caption.ToLower(); wrapped_caption = Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(wrapped_caption); wrapped_caption = wrapped_caption.Replace(" ", "\n"); g.DrawString(wrapped_caption, font, Brushes.Black, new PointF(CENTER / 2, CENTER / 2), string_format); } } BitmapSource page_bitmap_source = BitmapImageTools.CreateBitmapSourceFromImage(page_bitmap); ddw.page_bitmap_source = page_bitmap_source; } #if false // do this bit further below, all at once for all entries, in the UI thread! try { UpdateLibraryStatistics_Stats_Background_GUI_FillPlaceHolder(ddw); } catch (Exception ex) { Logging.Error(ex, "UpdateLibraryStatistics_Stats_Background_CoverFlow: Error occurred."); throw; } #endif } catch (Exception ex) { Logging.Warn(ex, "There was a problem loading a preview image for document {0}", ddw.pdf_document.Fingerprint); Logging.Error(ex, "UpdateLibraryStatistics_Stats_Background_CoverFlow: Error occurred."); // do not rethrow the error: allow the other pages in the pages to be rendered... ddw.page_bitmap_source = Backgrounds.GetBackground(Backgrounds.PageRenderingFailed_ClassicNews); } } } } } } catch (Exception ex) { Logging.Error(ex, "UpdateLibraryStatistics_Stats_Background_CoverFlow: Error occurred."); } // Don't care if there were errors in the process so far: the pages which got rendered, SHOULD make it into the UI anyway! WPFDoEvents.InvokeAsyncInUIThread(() => { foreach (DocumentDisplayWork ddw in ddwm.ddws) { try { UpdateLibraryStatistics_Stats_Background_GUI_FillPlaceHolder(ddw); } catch (Exception ex) { Logging.Error(ex, "UpdateLibraryStatistics_Stats_Background_CoverFlow: Error occurred."); Logging.Warn(ex, "There was a problem loading a preview image for document {0}", ddw.pdf_document.Fingerprint); } } if (0 == ddwm.ddws.Count) { ButtonCoverFlow.IsChecked = false; UpdateLibraryStatistics(); } }); }); } catch (Exception ex) { Logging.Error(ex, "UpdateLibraryStatistics_Stats_Background_CoverFlow: Error occurred."); } if (0 == ddwm.ddws.Count) { ButtonCoverFlow.IsChecked = false; UpdateLibraryStatistics(); } }); }
private void UpdateKnownWebLibrary(WebLibraryDetail new_web_library_detail, bool suppress_flush_to_disk = true, string extra_info_message_on_skip = "") { WebLibraryDetail old; if (web_library_details.TryGetValue(new_web_library_detail.Id, out old)) { bool use_old = true; bool use_new = true; // don't work with the old find if it has been purged if (old.IsPurged) { use_old = false; } // don't work with the new find if it has been purged if (new_web_library_detail.IsPurged) { use_new = false; } // don't work with the old find if it has been deleted and the new one has not: if (old.Deleted && !new_web_library_detail.Deleted && use_new) { use_old = false; } // and vice versa: if (!old.Deleted && new_web_library_detail.Deleted && use_old) { use_new = false; } // skip when there's nothing new to pick up: if (!use_new) { return; } // only do the mix/collision resolution when both old and new are viable: if (use_old) { int state = 0x00; // bit 0: prefer to use old, bit 1: prefer to use fresh, bit 2: used old, bit 3: used fresh, 0: don't know yet. // if there's already an entry present, see if we should 'upgrade' the info or stick with what we have: DateTime?dt = MixOldAndNew(old.LastServerSyncNotificationDate, new_web_library_detail.LastServerSyncNotificationDate, new_web_library_detail.Id + "::" + nameof(old.LastServerSyncNotificationDate), ref state); old.LastServerSyncNotificationDate = dt ?? DATE_ZERO; old.LastBundleManifestDownloadTimestampUTC = MixOldAndNew(old.LastBundleManifestDownloadTimestampUTC, new_web_library_detail.LastBundleManifestDownloadTimestampUTC, new_web_library_detail.Id + "::" + nameof(old.LastBundleManifestDownloadTimestampUTC), ref state); old.LastBundleManifestIgnoreVersion = MixOldAndNew(old.LastBundleManifestIgnoreVersion, new_web_library_detail.LastBundleManifestIgnoreVersion, new_web_library_detail.Id + "::" + nameof(old.LastBundleManifestIgnoreVersion), ref state); old.LastSynced = MixOldAndNew(old.LastSynced, new_web_library_detail.LastSynced, new_web_library_detail.Id + "::" + nameof(old.LastSynced), ref state); old.IntranetPath = MixOldAndNew(old.IntranetPath, new_web_library_detail.IntranetPath, new_web_library_detail.Id + "::" + nameof(old.IntranetPath), ref state, PathsMixCollisionComparer); old.ShortWebId = MixOldAndNew(old.ShortWebId, new_web_library_detail.ShortWebId, new_web_library_detail.Id + "::" + nameof(old.ShortWebId), ref state); old.FolderToWatch = MixOldAndNew(old.FolderToWatch, new_web_library_detail.FolderToWatch, new_web_library_detail.Id + "::" + nameof(old.FolderToWatch), ref state, PathsMixCollisionComparer); old.Title = MixOldAndNew(old.Title, new_web_library_detail.Title, new_web_library_detail.Id + "::" + nameof(old.Title), ref state); old.Description = MixOldAndNew(old.Description, new_web_library_detail.Description, new_web_library_detail.Id + "::" + nameof(old.Description), ref state); old.BundleManifestJSON = MixOldAndNew(old.BundleManifestJSON, new_web_library_detail.BundleManifestJSON, new_web_library_detail.Id + "::" + nameof(old.BundleManifestJSON), ref state); /* old.DescriptiveTitle = */ //MixOldAndNew(old.DescriptiveTitle, new_web_library_detail.DescriptiveTitle, new_web_library_detail.Id + "::" + nameof(old.DescriptiveTitle), ref state); MixOldAndNew(old.LibraryType(), new_web_library_detail.LibraryType(), new_web_library_detail.Id + "::" + nameof(old.LibraryType), ref state); old.Deleted = MixOldAndNew(old.Deleted, new_web_library_detail.Deleted, new_web_library_detail.Id + "::" + nameof(old.Deleted), ref state); old.AutoSync = MixOldAndNew(old.AutoSync, new_web_library_detail.AutoSync, new_web_library_detail.Id + "::" + nameof(old.AutoSync), ref state); old.IsAdministrator = MixOldAndNew(old.IsAdministrator, new_web_library_detail.IsAdministrator, new_web_library_detail.Id + "::" + nameof(old.IsAdministrator), ref state); /* old.IsBundleLibrary = */ MixOldAndNew(old.IsBundleLibrary, new_web_library_detail.IsBundleLibrary, new_web_library_detail.Id + "::" + nameof(old.IsBundleLibrary), ref state); /* old.IsIntranetLibrary = */ MixOldAndNew(old.IsIntranetLibrary, new_web_library_detail.IsIntranetLibrary, new_web_library_detail.Id + "::" + nameof(old.IsIntranetLibrary), ref state); /* old.IsWebLibrary = */ MixOldAndNew(old.IsWebLibrary, new_web_library_detail.IsWebLibrary, new_web_library_detail.Id + "::" + nameof(old.IsWebLibrary), ref state); old.IsLocalGuestLibrary = MixOldAndNew(old.IsLocalGuestLibrary, new_web_library_detail.IsLocalGuestLibrary, new_web_library_detail.Id + "::" + nameof(old.IsLocalGuestLibrary), ref state); old.IsReadOnly = MixOldAndNew(old.IsReadOnly, new_web_library_detail.IsReadOnly, new_web_library_detail.Id + "::" + nameof(old.IsReadOnly), ref state); // fixup: if (old.LibraryType() != "UNKNOWN" && old.IsReadOnly) { // reset ReadOnly for everyone who is ex-Premium(Plus) for all their known libraries. old.IsReadOnly = false; } old.library?.Dispose(); old.library = new_web_library_detail.library; if ((state & 0x0c) == 0x0c) { Logging.Warn("library info has been mixed as part of collision resolution for library {0}.", old.Id); } else if ((state & 0x04) == 0x04) { Logging.Info("library info has been kept as-is as part of collision resolution for library {0}.", old.Id); } if ((state & 0x08) == 0x08) { Logging.Warn("library info has been picked up from the new entry as part of collision resolution for library {0}.", old.Id); } new_web_library_detail = old; } } if (null == new_web_library_detail.library) { new_web_library_detail.library = new Library(new_web_library_detail); } web_library_details[new_web_library_detail.Id] = new_web_library_detail; if (!suppress_flush_to_disk) { SaveKnownWebLibraries(); FireWebLibrariesChanged(); } }
public void WaitForLibraryToLoad(WebLibraryDetail web_library_detail, Action exec_after_load) { // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // TBD TBD TBD TBD TBD TBD }
private void UpdateKnownWebLibrary(WebLibraryDetail new_web_library_detail, bool suppress_flush_to_disk = true, string extra_info_message_on_skip = "") { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); WebLibraryDetail old; if (web_library_details.TryGetValue(new_web_library_detail.Id, out old)) { bool use_old = true; bool use_new = true; // don't work with the old find if it has been purged if (old.IsPurged) { use_old = false; } // don't work with the new find if it has been purged if (new_web_library_detail.IsPurged) { use_new = false; } // don't work with the old find if it has been deleted and the new one has not: if (old.Deleted && !new_web_library_detail.Deleted && use_new) { use_old = false; } // and vice versa: if (!old.Deleted && new_web_library_detail.Deleted && use_old) { use_new = false; } // skip when there's nothing new to pick up: if (!use_new) { return; } // only do the mix/collision resolution when both old and new are viable: if (use_old) { int state = 0x00; // bit 0: prefer to use old, bit 1: prefer to use fresh, bit 2: used old, bit 3: used fresh, 0: don't know yet. // if there's already an entry present, see if we should 'upgrade' the info or stick with what we have: old.LastBundleManifestDownloadTimestampUTC = MixOldAndNew(old.LastBundleManifestDownloadTimestampUTC, new_web_library_detail.LastBundleManifestDownloadTimestampUTC, new_web_library_detail.Id + "::" + nameof(old.LastBundleManifestDownloadTimestampUTC), ref state); old.LastBundleManifestIgnoreVersion = MixOldAndNew(old.LastBundleManifestIgnoreVersion, new_web_library_detail.LastBundleManifestIgnoreVersion, new_web_library_detail.Id + "::" + nameof(old.LastBundleManifestIgnoreVersion), ref state); old.LastSynced = MixOldAndNew(old.LastSynced, new_web_library_detail.LastSynced, new_web_library_detail.Id + "::" + nameof(old.LastSynced), ref state); old.IntranetPath = MixOldAndNew(old.IntranetPath, new_web_library_detail.IntranetPath, new_web_library_detail.Id + "::" + nameof(old.IntranetPath), ref state, PathsMixCollisionComparer); old.FolderToWatch = MixOldAndNew(old.FolderToWatch, new_web_library_detail.FolderToWatch, new_web_library_detail.Id + "::" + nameof(old.FolderToWatch), ref state, PathsMixCollisionComparer); old.Title = MixOldAndNew(old.Title, new_web_library_detail.Title, new_web_library_detail.Id + "::" + nameof(old.Title), ref state); old.Description = MixOldAndNew(old.Description, new_web_library_detail.Description, new_web_library_detail.Id + "::" + nameof(old.Description), ref state); old.BundleManifestJSON = MixOldAndNew(old.BundleManifestJSON, new_web_library_detail.BundleManifestJSON, new_web_library_detail.Id + "::" + nameof(old.BundleManifestJSON), ref state); /* old.DescriptiveTitle = */ //MixOldAndNew(old.DescriptiveTitle, new_web_library_detail.DescriptiveTitle, new_web_library_detail.Id + "::" + nameof(old.DescriptiveTitle), ref state); MixOldAndNew(old.LibraryType(), new_web_library_detail.LibraryType(), new_web_library_detail.Id + "::" + nameof(old.LibraryType), ref state); old.Deleted = MixOldAndNew(old.Deleted, new_web_library_detail.Deleted, new_web_library_detail.Id + "::" + nameof(old.Deleted), ref state); old.AutoSync = MixOldAndNew(old.AutoSync, new_web_library_detail.AutoSync, new_web_library_detail.Id + "::" + nameof(old.AutoSync), ref state); /* old.IsBundleLibrary = */ MixOldAndNew(old.IsBundleLibrary, new_web_library_detail.IsBundleLibrary, new_web_library_detail.Id + "::" + nameof(old.IsBundleLibrary), ref state); /* old.IsIntranetLibrary = */ MixOldAndNew(old.IsIntranetLibrary, new_web_library_detail.IsIntranetLibrary, new_web_library_detail.Id + "::" + nameof(old.IsIntranetLibrary), ref state); /* old.IsWebLibrary = */ ASSERT.Test(old.Xlibrary != null ? new_web_library_detail.Xlibrary == null : true); #if false // this code is not needed in the current use of the API as long as the ASSERTions above hold old.library?.Dispose(); if (new_web_library_detail.library != null) { old.library = new_web_library_detail.library; } // and update it's internal (cyclic) web_library_detail reference: if (old.library != null) { old.library.WebLibraryDetail = old; } #endif if ((state & 0x0c) == 0x0c) { Logging.Warn("library info has been mixed as part of collision resolution for library {0}.", old.Id); } else if ((state & 0x04) == 0x04) { Logging.Info("library info has been kept as-is as part of collision resolution for library {0}.", old.Id); } if ((state & 0x08) == 0x08) { Logging.Warn("library info has been picked up from the new entry as part of collision resolution for library {0}.", old.Id); } new_web_library_detail = old; } } //ASSERT.Test(new_web_library_detail.Xlibrary == null); web_library_details[new_web_library_detail.Id] = new_web_library_detail; if (!suppress_flush_to_disk) { SaveKnownWebLibraries(); StatusManager.Instance.ClearStatus("LibraryInitialLoad"); FireWebLibrariesChanged(); } }
private void UpdateLibraryStatistics_Stats_Background_Charts(WebLibraryDetail web_library_detail) { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); // The chart of the recently read and the recently added... const int WEEK_HISTORY = 4 * 3; DateTime NOW = DateTime.UtcNow; // Get the buckets for the past few weeks of READING CountingDictionary <DateTime> date_buckets_read = new CountingDictionary <DateTime>(); if (web_library_detail.Xlibrary != null) { List <DateTime> recently_reads = web_library_detail.Xlibrary.RecentlyReadManager.GetRecentlyReadDates(); foreach (DateTime recently_read in recently_reads) { for (int week = 1; week < WEEK_HISTORY; ++week) { DateTime cutoff = NOW.AddDays(-7 * week); if (recently_read >= cutoff) { date_buckets_read.TallyOne(cutoff); break; } } } } // Get the buckets for the past few weeks of ADDING CountingDictionary <DateTime> date_buckets_added = new CountingDictionary <DateTime>(); if (web_library_detail.Xlibrary != null) { foreach (PDFDocument pdf_document in web_library_detail.Xlibrary.PDFDocuments) { for (int week = 1; week < WEEK_HISTORY; ++week) { DateTime cutoff = NOW.AddDays(-7 * week); if (pdf_document.DateAddedToDatabase >= cutoff) { date_buckets_added.TallyOne(cutoff); break; } } } } WPFDoEvents.InvokeAsyncInUIThread(() => { // Plot the pretty pretty List <ChartItem> chart_items_read = new List <ChartItem>(); List <ChartItem> chart_items_added = new List <ChartItem>(); for (int week = 1; week < WEEK_HISTORY; ++week) { DateTime cutoff = NOW.AddDays(-7 * week); int num_read = date_buckets_read.GetCount(cutoff); int num_added = date_buckets_added.GetCount(cutoff); chart_items_read.Add(new ChartItem { Title = "Read", Timestamp = cutoff, Count = num_read }); chart_items_added.Add(new ChartItem { Title = "Added", Timestamp = cutoff, Count = num_added }); } UpdateLibraryStatistics_Stats_Background_GUI(chart_items_read, chart_items_added); }); }