A BookInfo has everything needed to display a title and thumbnail, and (eventually) do common searching filtering operations, without accessing the actual contents of the book. A related responsibility is to wrap the meta.json file which stores this search/display data in a form suitable for uploading to our web server.
Exemplo n.º 1
0
        public Book GetBookFromBookInfo(BookInfo bookInfo)
        {
            //Review: Note that this isn't doing any caching yet... worried that caching will just eat up memory, but if anybody is holding onto these, then the memory won't be freed anyhow

            var book = _bookFactory(bookInfo, _storageFactory(bookInfo.FolderPath));
            return book;
        }
Exemplo n.º 2
0
 public void CreateBookOnDiskFromTemplate_FromBasicBook_AllowUploadIsTrue()
 {
     var source = BloomFileLocator.GetFactoryBookTemplateDirectory( "Basic Book");
     string bookFolderPath = _starter.CreateBookOnDiskFromTemplate(source, _projectFolder.Path);
      var metadata = new BookInfo(bookFolderPath, false);
     Assert.IsTrue(metadata.AllowUploading);
 }
Exemplo n.º 3
0
        public static int Handle(HydrateParameters options)
        {
            if (!Directory.Exists(options.Path))
            {
                if (options.Path.Contains(".htm"))
                {
                    Debug.WriteLine("Supply only the directory, not the path to the file.");
                    Console.Error.WriteLine("Supply only the directory, not the path to the file.");
                }
                else
                {
                    Debug.WriteLine("Could not find " + options.Path);
                    Console.Error.WriteLine("Could not find " + options.Path);
                }
                return 1;
            }
            Console.WriteLine("Starting Hydrating.");

            var layout = new Layout
            {
                SizeAndOrientation = SizeAndOrientation.FromString(options.SizeAndOrientation)
            };

            var collectionSettings = new CollectionSettings
            {
                XMatterPackName = "Video",
                Language1Iso639Code = options.VernacularIsoCode,
                Language2Iso639Code = options.NationalLanguage1IsoCode,
                Language3Iso639Code = options.NationalLanguage2IsoCode
            };

            XMatterPackFinder xmatterFinder = new XMatterPackFinder(new[] { BloomFileLocator.GetInstalledXMatterDirectory() });
            var locator = new BloomFileLocator(collectionSettings, xmatterFinder, ProjectContext.GetFactoryFileLocations(),
                ProjectContext.GetFoundFileLocations(), ProjectContext.GetAfterXMatterFileLocations());

            var bookInfo = new BookInfo(options.Path, true);
            var book = new Book.Book(bookInfo, new BookStorage(options.Path, locator, new BookRenamedEvent(), collectionSettings),
                null, collectionSettings, null, null, new BookRefreshEvent());

            if (null == book.OurHtmlDom.SelectSingleNodeHonoringDefaultNS("//script[contains(text(),'bloomPlayer.js')]"))
            {
                var element = book.OurHtmlDom.Head.AppendChild(book.OurHtmlDom.RawDom.CreateElement("script")) as XmlElement;
                element.IsEmpty = false;
                element.SetAttribute("type", "text/javascript");
                element.SetAttribute("src", "bloomPlayer.js");
            }

            AddRequisiteJsFiles(options.Path);

            //we might change this later, or make it optional, but for now, this will prevent surprises to processes
            //running this CLI... the folder name won't change out from under it.
            book.LockDownTheFileAndFolderName = true;

            book.SetLayout(layout);
            book.BringBookUpToDate(new NullProgress());
            Console.WriteLine("Finished Hydrating.");
            Debug.WriteLine("Finished Hydrating.");
            return 0;
        }
 public void InsertBook_NotPresent_InsertsInEmptyList()
 {
     var infoNew = new BookInfo("book11", true);
     var state = new List<BookInfo>();
     var collection = new BookCollection(state);
     collection.InsertBookInfo(infoNew);
     Assert.That(state[0], Is.EqualTo(infoNew), "book info should be inserted between book10 and book20");
 }
Exemplo n.º 5
0
 public void Constructor_LoadsMetaDataFromJson()
 {
     var jsonPath = Path.Combine(_folder.Path, BookInfo.MetaDataFileName);
     File.WriteAllText(jsonPath, @"{'folio':'true','experimental':'true','suitableForMakingShells':'true'}");
     var bi = new BookInfo(_folder.Path, true);
     Assert.That(bi.IsExperimental);
     Assert.That(bi.IsFolio);
     Assert.That(bi.IsSuitableForMakingShells);
 }
Exemplo n.º 6
0
        public void CreateBookOnDiskFromTemplate_FromBasicBook_BookLineageSetToIdOfSourceBook()
        {
            var source = FileLocator.GetDirectoryDistributedWithApplication("factoryCollections", "Templates", "Basic Book");

            string bookFolderPath = _starter.CreateBookOnDiskFromTemplate(source, _projectFolder.Path);

            var jsonFile = Path.Combine(bookFolderPath, BookInfo.MetaDataFileName);
            Assert.That(File.Exists(jsonFile), "Creating a book should create a metadata json file meta.json");
            var metadata = new BookInfo(bookFolderPath, false);

            var kIdOfBasicBook = "056B6F11-4A6C-4942-B2BC-8861E62B03B3";
            Assert.That(metadata.BookLineage, Is.EqualTo(kIdOfBasicBook));
            //we should get our own id, not reuse our parent's
            Assert.That(metadata.Id, Is.Not.EqualTo(kIdOfBasicBook), "New book should get its own ID, not reuse parent's");
        }
Exemplo n.º 7
0
        public void Constructor_FallsBackToTags()
        {
            var tagsPath = Path.Combine(_folder.Path, "tags.txt");
            File.WriteAllText(tagsPath, @"folio\nexperimental\nsuitableForMakingShells\n");
            var bi = new BookInfo(_folder.Path, true);
            Assert.That(bi.IsExperimental);
            Assert.That(bi.IsFolio);
            Assert.That(bi.IsSuitableForMakingShells);

            // Check that json takes precedence
            var jsonPath = Path.Combine(_folder.Path, BookInfo.MetaDataFileName);
            File.WriteAllText(jsonPath, @"{'folio':'false','experimental':'true','suitableForMakingShells':'false'}");
            bi = new BookInfo(_folder.Path, true);
            Assert.That(bi.IsExperimental);
            Assert.That(bi.IsFolio, Is.False);
            Assert.That(bi.IsSuitableForMakingShells, Is.False);
        }
Exemplo n.º 8
0
        public Book CreateFromSourceBook(string sourceBookFolder, string containingDestinationFolder)
        {
            string pathToFolderOfNewBook = null;

            Logger.WriteMinorEvent("Starting CreateFromSourceBook({0})", sourceBookFolder);
            try
            {
                var starter = _bookStarterFactory();
                pathToFolderOfNewBook = starter.CreateBookOnDiskFromTemplate(sourceBookFolder, containingDestinationFolder);
                if (Configurator.IsConfigurable(pathToFolderOfNewBook))
                {
                    var c = _configuratorFactory(containingDestinationFolder);
                    if (DialogResult.Cancel == c.ShowConfigurationDialog(pathToFolderOfNewBook))
                    {
                        SIL.IO.RobustIO.DeleteDirectory(pathToFolderOfNewBook, true);
                        return null; // the template had a configuration page and they clicked "cancel"
                    }
                    c.ConfigureBook(BookStorage.FindBookHtmlInFolder(pathToFolderOfNewBook));
                }

                var newBookInfo = new BookInfo(pathToFolderOfNewBook,true); // _bookInfos.Find(b => b.FolderPath == pathToFolderOfNewBook);
                if (newBookInfo is ErrorBookInfo)
                {
                    throw ((ErrorBookInfo) newBookInfo).Exception;
                }

                Book newBook = GetBookFromBookInfo(newBookInfo);

                //Hack: this is a bit of a hack, to handle problems where we make the book with the suggested initial name, but the title is still something else
                var name = Path.GetFileName(newBookInfo.FolderPath); // this way, we get "my book 1", "my book 2", etc.
                newBook.SetTitle(name);

                Logger.WriteMinorEvent("Finished CreateFromnewBook({0})", newBook.FolderPath);
                Logger.WriteEvent("CreateFromSourceBook({0})", newBook.FolderPath);
                return newBook;
            }
            catch (Exception)
            {
                Logger.WriteEvent("Cleaning up after error CreateFromSourceBook({0})", pathToFolderOfNewBook);
                //clean up this ill-fated book folder up
                if (!string.IsNullOrEmpty(pathToFolderOfNewBook) && Directory.Exists(pathToFolderOfNewBook))
                    SIL.IO.RobustIO.DeleteDirectory(pathToFolderOfNewBook, true);
                throw;
            }
        }
Exemplo n.º 9
0
        public void RoundTrips_AllowUploading()
        {
            var jsonPath = Path.Combine(_folder.Path, BookInfo.MetaDataFileName);
            File.WriteAllText(jsonPath, @"{'allowUploadingToBloomLibrary':'false'}");
            var bi = new BookInfo(_folder.Path, true);
            Assert.False(bi.AllowUploading, "CHECK YOUR FixBloomMetaInfo ENV variable! Initial Read Failed to get false. Contents: " + File.ReadAllText(jsonPath));
            bi.Save();
            var bi2 = new BookInfo(_folder.Path, true);
            Assert.False(bi2.AllowUploading, "Read after Save() Failed  to get false. Contents: " + File.ReadAllText(jsonPath));

            File.WriteAllText(jsonPath, @"{'allowUploadingToBloomLibrary':'true'}");
            var bi3 = new BookInfo(_folder.Path, true);
            Assert.That(bi3.AllowUploading,  "Initial Read Failed to get true. Contents: " + File.ReadAllText(jsonPath));
            bi3.Save();
            var bi4 = new BookInfo(_folder.Path, true);
            Assert.That(File.ReadAllText(jsonPath).Contains("allowUploadingToBloomLibrary"), "The file doesn't contain 'allowUploadingToBloomLibrary'");
            Assert.That(bi4.AllowUploading, "Read after Save() Failed  to get true. Contents: " + File.ReadAllText(jsonPath));
        }
Exemplo n.º 10
0
        public void InsertBook_NotPresent_InsertsInCorrectOrder()
        {
            var info1 = new BookInfo("book1", true);
            var info2 = new BookInfo("book2", true);
            var info3 = new BookInfo("book10", true);
            var info4 = new BookInfo("book20", true);
            var infoNew = new BookInfo("book11", true);
            var state = new List<BookInfo>(new[] {info1, info2, info3, info4});
            var collection = new BookCollection(state);
            collection.InsertBookInfo(infoNew);
            Assert.That(state[3], Is.EqualTo(infoNew), "book info should be inserted between book10 and book20");

            var infoLast = new BookInfo("book30", true);
            collection.InsertBookInfo(infoLast);
            Assert.That(state[5], Is.EqualTo(infoLast), "book info should be inserted at end");

            var infoFirst = new BookInfo("abc", true);
            collection.InsertBookInfo(infoFirst);
            Assert.That(state[0], Is.EqualTo(infoFirst), "book info should be inserted at start");
        }
Exemplo n.º 11
0
        public Book(BookInfo info, IBookStorage storage, ITemplateFinder templateFinder,
		   CollectionSettings collectionSettings, HtmlThumbNailer thumbnailProvider,
			PageSelection pageSelection,
			PageListChangedEvent pageListChangedEvent,
			BookRefreshEvent bookRefreshEvent)
        {
            BookInfo = info;

            Guard.AgainstNull(storage,"storage");

            // This allows the _storage to
            storage.MetaData = info;

            _storage = storage;

            //this is a hack to keep these two in sync (in one direction)
            _storage.FolderPathChanged +=(x,y)=>BookInfo.FolderPath = _storage.FolderPath;

            _templateFinder = templateFinder;

            _collectionSettings = collectionSettings;

            _thumbnailProvider = thumbnailProvider;
            _pageSelection = pageSelection;
            _pageListChangedEvent = pageListChangedEvent;
            _bookRefreshEvent = bookRefreshEvent;
            _bookData = new BookData(OurHtmlDom,
                    _collectionSettings, UpdateImageMetadataAttributes);

            if (IsEditable && !HasFatalError)
            {
                _bookData.SynchronizeDataItemsThroughoutDOM();

                WriteLanguageDisplayStyleSheet(); //NB: if you try to do this on a file that's in program files, access will be denied
                OurHtmlDom.AddStyleSheet(@"languageDisplay.css");
            }

            FixBookIdAndLineageIfNeeded();
            _storage.Dom.RemoveExtraContentTypesMetas();
            Guard.Against(OurHtmlDom.RawDom.InnerXml=="","Bloom could not parse the xhtml of this document");
        }
Exemplo n.º 12
0
        private static Book MakeBook(CollectionSettings collectionSettings, string sourceBookFolderPath)
        {
            var xmatterLocations = new List<string>();
            xmatterLocations.Add(ProjectContext.XMatterAppDataFolder);
            xmatterLocations.Add(FileLocator.GetDirectoryDistributedWithApplication( kpathToSHRPTemplates));
            xmatterLocations.Add(FileLocator.GetDirectoryDistributedWithApplication("xMatter"));
            var locator = new BloomFileLocator(collectionSettings, new XMatterPackFinder(xmatterLocations), new string[] {});

            var starter = new BookStarter(locator,
                                          path =>
                                          new BookStorage(path, locator, new BookRenamedEvent(),
                                                          collectionSettings),
                                          collectionSettings);
            var pathToFolderOfNewBook = starter.CreateBookOnDiskFromTemplate(sourceBookFolderPath, collectionSettings.FolderPath);

            var newBookInfo = new BookInfo(pathToFolderOfNewBook, false /*saying not editable works us around a langdisplay issue*/);

            BookStorage bookStorage = new BookStorage(pathToFolderOfNewBook, locator, new BookRenamedEvent(), collectionSettings);
            var book = new Book(newBookInfo, bookStorage, null,
                            collectionSettings, null, null, null, null);

            return book;
        }
Exemplo n.º 13
0
        // For now, when there is no UI for multiple tags, we make Tags a single item, the book topic.
        // It's not clear what we will want to do when the topic changes and there is a UI for (possibly multiple) tags.
        // Very likely we still want to add the new topic (if it is not already present).
        // Should we still remove the old one?
        private void UpdateTags(BookInfo info)
        {
            NamedMutliLingualValue tagData;
            string tag = null;

            if (_dataset.TextVariables.TryGetValue("topic", out tagData))
            {
                tag = tagData.TextAlternatives.GetBestAlternativeString(WritingSystemIdsToTry);
            }

            if (info != null && tag != null)
            {
                // In case we're running localized, for now we'd like to record in the metadata the original English tag.
                // This allows the book to be found by this tag in the current, non-localized version of bloom library.
                // Eventually it will make it easier, we think, to implement localization of bloom library.
                string originalTag;
                if (RuntimeInformationInjector.TopicReversal == null ||
                    !RuntimeInformationInjector.TopicReversal.TryGetValue(tag, out originalTag))
                {
                    originalTag = tag;                     // just use it unmodified if we don't have anything
                }
                info.TagsList = originalTag;
            }
        }
Exemplo n.º 14
0
        /// <summary>
        /// Create or update the data div with all the data-book values in the document
        /// </summary>
        /// <param name="elementToReadFrom">This is either the whole document, or a page div that we just edited and want to read from.</param>
        private void UpdateVariablesAndDataDiv(XmlNode elementToReadFrom, BookInfo info = null)
        {
            Debug.WriteLine("before update: " + _dataDiv.OuterXml);

            var     itemsToDelete = new HashSet <Tuple <string, string> >();
            DataSet incomingData  = SynchronizeDataItemsFromContentsOfElement(elementToReadFrom, itemsToDelete);

            incomingData.UpdateGenericLanguageString("contentLanguage1", _collectionSettings.Language1Iso639Code, false);
            incomingData.UpdateGenericLanguageString("contentLanguage2",
                                                     String.IsNullOrEmpty(MultilingualContentLanguage2)
                                                                                                 ? null
                                                                                                 : MultilingualContentLanguage2, false);
            incomingData.UpdateGenericLanguageString("contentLanguage3",
                                                     String.IsNullOrEmpty(MultilingualContentLanguage3)
                                                                                                 ? null
                                                                                                 : MultilingualContentLanguage3, false);

            //Debug.WriteLine("xyz: " + _dataDiv.OuterXml);
            foreach (var v in incomingData.TextVariables)
            {
                if (!v.Value.IsCollectionValue)
                {
                    UpdateSingleTextVariableInDataDiv(v.Key, v.Value.TextAlternatives);
                }
            }
            foreach (var tuple in itemsToDelete)
            {
                UpdateSingleTextVariableInDataDiv(tuple.Item1, tuple.Item2, "");
            }
            Debug.WriteLine("after update: " + _dataDiv.OuterXml);

            UpdateTitle(info);            //this may change our "bookTitle" variable if the title is based on a template that reads other variables (e.g. "Primer Term2-Week3")
            UpdateIsbn(info);
            UpdateTags(info);
            UpdateCredits(info);
        }
Exemplo n.º 15
0
 public bool CanSaveChanges(BookInfo info)
 {
     return(true);
 }
Exemplo n.º 16
0
        private void SetLineageAndId(BookStorage storage, string sourceFolderPath)
        {
            string parentId = null;
            string lineage = null;
            if (File.Exists(Path.Combine(sourceFolderPath, BookInfo.MetaDataFileName)))
            {
                var sourceMetaData = new BookInfo(sourceFolderPath, false);
                parentId = sourceMetaData.Id;
                lineage = sourceMetaData.BookLineage;
            }
            else
            {
                // No parent meta.json, try for legacy embedded metadata in html
                parentId = GetMetaValue(storage.Dom.RawDom, "bloomBookId", "");
                lineage = GetMetaValue(storage.Dom.RawDom, "bloomBookLineage", "");
                if (string.IsNullOrEmpty(lineage))
                {
                    lineage = GetMetaValue(storage.Dom.RawDom, "bookLineage", ""); //try the old name for this value
                }
            }

            if (!string.IsNullOrEmpty(lineage))
                lineage += ",";
            if (!string.IsNullOrEmpty(parentId))
            {
                storage.MetaData.BookLineage = lineage + parentId;
            }
            storage.MetaData.Id = Guid.NewGuid().ToString();
            storage.Dom.RemoveMetaElement("bloomBookLineage"); //old metadata
            storage.Dom.RemoveMetaElement("bookLineage"); // even older name
        }
Exemplo n.º 17
0
 private bool IsSuitableSourceForThisEditableCollection(BookInfo bookInfo)
 {
     return (_model.IsShellProject && bookInfo.IsSuitableForMakingShells) ||
            (!_model.IsShellProject && bookInfo.IsSuitableForVernacularLibrary);
 }
Exemplo n.º 18
0
 private void HighlightBookButtonAndShowContextMenuButton(BookInfo bookInfo)
 {
     foreach (var btn in AllBookButtons())
     {
         var bookButtonInfo = btn.Tag as BookButtonInfo;
         if (bookButtonInfo.BookInfo == bookInfo)
         {
             // BL-2678 don't display menu triangle if there's no menu to display
             if(!bookButtonInfo.HasNoContextMenu) btn.Paint += btn_Paint;
             btn.FlatAppearance.BorderColor = Palette.TextAgainstDarkBackground;
         }
         else
         {
             btn.Paint -= btn_Paint;
             btn.FlatAppearance.BorderColor = BackColor;
         }
     }
 }
Exemplo n.º 19
0
 private Button FindBookButton(BookInfo bookInfo)
 {
     return AllBookButtons().FirstOrDefault(b => GetBookInfoFromButton(b) == bookInfo);
 }
Exemplo n.º 20
0
        private void AddOneBook(BookInfo bookInfo, FlowLayoutPanel flowLayoutPanel, BookCollection collection)
        {
            string title = bookInfo.QuickTitleUserDisplay;
            if (collection.IsFactoryInstalled)
                title = LocalizationManager.GetDynamicString("Bloom", "TemplateBooks.BookName." + title, title);

            var button = new Button
            {
                Size = new Size(ButtonWidth, ButtonHeight),
                Font = bookInfo.IsEditable ? _editableBookFont : _collectionBookFont,
                TextImageRelation = TextImageRelation.ImageAboveText,
                ImageAlign = ContentAlignment.TopCenter,
                TextAlign = ContentAlignment.BottomCenter,
                FlatStyle = FlatStyle.Flat,
                ForeColor = Palette.TextAgainstDarkBackground,
                UseMnemonic = false, //otherwise, it tries to interpret '&' as a shortcut
                ContextMenuStrip = _bookContextMenu,
                AutoSize = false,

                Tag = new BookButtonInfo(bookInfo, collection, collection == _model.TheOneEditableCollection)
            };

            button.MouseDown += OnClickBook; //we need this for right-click menu selection, which needs to 1st select the book
            //doesn't work: item.DoubleClick += (sender,arg)=>_model.DoubleClickedBook();

            button.Text = ShortenTitleIfNeeded(title, button);
            button.FlatAppearance.BorderSize = 1;
            button.FlatAppearance.BorderColor = BackColor;

            toolTip1.SetToolTip(button, title);

            Image thumbnail = Resources.PagePlaceHolder;
            _bookThumbnails.Images.Add(bookInfo.Id, thumbnail);
            button.ImageIndex = _bookThumbnails.Images.Count - 1;
            flowLayoutPanel.Controls.Add(button); // important to add it before RefreshOneThumbnail; uses parent flow to decide whether primary

            // Can't use this test until after we add button (uses parent info)
            if (!IsUsableBook(button))
                button.ForeColor = Palette.DisabledTextAgainstDarkBackColor;

            Image img;
            var refreshThumbnail = false;
            //review: we could do this at idle time, too:
            if (bookInfo.TryGetPremadeThumbnail(out img))
            {
                RefreshOneThumbnail(bookInfo, img);
            }
            else
            {
                //show this one for now, in the background someone will do the slow work of getting us a better one
                RefreshOneThumbnail(bookInfo,Resources.placeHolderBookThumbnail);
                refreshThumbnail = true;
            }
            _buttonsNeedingSlowUpdate.Enqueue(new ButtonRefreshInfo(button, refreshThumbnail));
        }
Exemplo n.º 21
0
 public BookButtonInfo(BookInfo bookInfo, BookCollection collection, bool isVernacular)
 {
     _bookInfo = bookInfo;
     _collection = collection;
 }
Exemplo n.º 22
0
        private void UpdateCredits(BookInfo info)
        {
            if (info == null)
                return;

            NamedMutliLingualValue creditsData;
            string credits = "";
            var idsToTry = WritingSystemIdsToTry.ToList();
            while (string.IsNullOrWhiteSpace(credits) && idsToTry.Count > 0)
            {
                if (_dataset.TextVariables.TryGetValue("originalAcknowledgments", out creditsData))
                {
                    credits = creditsData.TextAlternatives.GetBestAlternativeString(idsToTry);
                }
                try
                {
                    // This cleans out various kinds of markup, especially <br >, <p>, <b>, etc.
                    var elt = XElement.Parse("<div>" + credits + "</div>", LoadOptions.PreserveWhitespace);
                    // For some reason Value yields \n rather than platform newlines, even when the original
                    // has \r\n.
                    credits = elt.Value.Replace("\n", Environment.NewLine);
                }
                catch (XmlException ex)
                {
                    // If we can't parse it...maybe the user really did type some XML? Just keep what we have
                }
                // If the most promising alternative is empty (e.g., vernacular usually is <p>\r\n</p>)
                // try again.
                idsToTry.RemoveAt(0);
            }
            info.Credits = credits;
        }
Exemplo n.º 23
0
 Bloom.Book.Book BookFactory(BookInfo bookInfo, IBookStorage storage, bool editable)
 {
     return new Bloom.Book.Book(bookInfo,  storage, null, new CollectionSettings(new NewCollectionSettings() { PathToSettingsFile = CollectionSettings.GetPathForNewSettings(_folder.Path, "test"),  Language1Iso639Code = "xyz" }), null,
                                               new PageSelection(),
                                               new PageListChangedEvent(), new BookRefreshEvent());
 }
Exemplo n.º 24
0
 public void TitleSetter_FixesTitleWithXml()
 {
     var jsonPath = Path.Combine(_folder.Path, BookInfo.MetaDataFileName);
     File.WriteAllText(jsonPath,
         "{'title':'<span class=\"sentence-too-long\" data-segment=\"sentence\">Book on &lt;span&gt;s\r\n</span>'}");
     var bi = new BookInfo(_folder.Path, true); // loads metadata, but doesn't use Title setter
     // SUT
     bi.Title = bi.Title; // exercises setter
     Assert.AreEqual("Book on <span>s\r\n", bi.Title);
 }
Exemplo n.º 25
0
 public void InsertBook_Present_Replaces()
 {
     var info1 = new BookInfo("book1", true);
     var info2 = new BookInfo("book2", true);
     var info3 = new BookInfo("book10", true);
     var info4 = new BookInfo("book20", true);
     var infoNew = new BookInfo("book10", true);
     var state = new List<BookInfo>(new[] { info1, info2, info3, info4 });
     var collection = new BookCollection(state);
     collection.InsertBookInfo(infoNew);
     Assert.That(state[2], Is.EqualTo(infoNew), "book info should replace existing book");
     Assert.That(state, Has.Count.EqualTo(4));
 }
Exemplo n.º 26
0
 public void UpdateVariablesAndDataDivThroughDOM(BookInfo info = null)
 {
     UpdateVariablesAndDataDiv(_dom.RawDom.FirstChild, info);
 }
Exemplo n.º 27
0
        public Book(BookInfo info, IBookStorage storage, ITemplateFinder templateFinder,
		   CollectionSettings collectionSettings,
			PageSelection pageSelection,
			PageListChangedEvent pageListChangedEvent,
			BookRefreshEvent bookRefreshEvent)
        {
            BookInfo = info;
            UserPrefs = UserPrefs.LoadOrMakeNew(Path.Combine(info.FolderPath, "book.userPrefs"));

            Guard.AgainstNull(storage,"storage");

            // This allows the _storage to
            storage.MetaData = info;

            _storage = storage;

            //this is a hack to keep these two in sync (in one direction)
            _storage.FolderPathChanged += _storage_FolderPathChanged;

            _templateFinder = templateFinder;

            _collectionSettings = collectionSettings;

            _pageSelection = pageSelection;
            _pageListChangedEvent = pageListChangedEvent;
            _bookRefreshEvent = bookRefreshEvent;
            _bookData = new BookData(OurHtmlDom,
                    _collectionSettings, UpdateImageMetadataAttributes);

            InjectStringListingActiveLanguagesOfBook();

            if (!HasFatalError && IsEditable)
            {
                _bookData.SynchronizeDataItemsThroughoutDOM();
            }

            //if we're showing the user a shell/template book, pick a color for it
            //If it is editable, then we don't want to change to the next color, we
            //want to use the color that we used for the sample shell/template we
            //showed them previously.
            if (!info.IsEditable)
            {
                Book.SelectNextCoverColor(); // we only increment when showing a template or shell
                InitCoverColor();
            }

            // If it doesn't already have a cover color give it one.
            if (OurHtmlDom.SafeSelectNodes("//head/style/text()[contains(., 'coverColor')]").Count == 0)
            {
                InitCoverColor(); // should use the same color as what they saw in the preview of the template/shell
            }
            FixBookIdAndLineageIfNeeded();
            _storage.Dom.RemoveExtraBookTitles();
            _storage.Dom.RemoveExtraContentTypesMetas();
            Guard.Against(OurHtmlDom.RawDom.InnerXml=="","Bloom could not parse the xhtml of this document");
        }
Exemplo n.º 28
0
 internal static void ConvertTagsToMetaData(string oldTagsPath, BookInfo bookMetaData)
 {
     var oldTags = RobustFile.ReadAllText(oldTagsPath);
     bookMetaData.IsFolio = oldTags.Contains("folio");
     bookMetaData.IsExperimental = oldTags.Contains("experimental");
 }
Exemplo n.º 29
0
 public Book.Book GetBookFromBookInfo(BookInfo bookInfo)
 {
     return _bookServer.GetBookFromBookInfo(bookInfo);
 }
Exemplo n.º 30
0
        private void SelectBook(BookInfo bookInfo)
        {
            try
            {
                _bookSelection.SelectBook(_model.GetBookFromBookInfo(bookInfo));

                _bookContextMenu.Enabled = true;
                //Debug.WriteLine("before selecting " + SelectedBook.Title);
                _model.SelectBook(SelectedBook);
                //Debug.WriteLine("after selecting " + SelectedBook.Title);
                //didn't help: _listView.Focus();//hack we were losing clicks
                SelectedBook.ContentsChanged -= new EventHandler(OnContentsOfSelectedBookChanged); //in case we're already subscribed
                SelectedBook.ContentsChanged += new EventHandler(OnContentsOfSelectedBookChanged);

                deleteMenuItem.Enabled = _model.CanDeleteSelection;
                _updateThumbnailMenu.Visible = _model.CanUpdateSelection;
                exportToWordOrLibreOfficeToolStripMenuItem.Visible = _model.CanExportSelection;
                _updateFrontMatterToolStripMenu.Visible = _model.CanUpdateSelection;
            }
            catch (Exception error)
            {
                //skip over the dependency injection layer
                if (error.Source == "Autofac" && error.InnerException != null)
                    error = error.InnerException;

                SIL.Reporting.ErrorReport.NotifyUserOfProblem(error, "Bloom cannot display that book.");
            }
        }
Exemplo n.º 31
0
        public virtual void Setup()
        {
            _storage = new Moq.Mock<IBookStorage>();
            _storage.Setup(x => x.GetLooksOk()).Returns(true);
            _bookDom = new HtmlDom(GetThreePageDom());
            _storage.SetupGet(x => x.Dom).Returns(() => _bookDom);
            _storage.SetupGet(x => x.Key).Returns("testkey");
            _storage.SetupGet(x => x.FileName).Returns("testTitle");
            _storage.Setup(x => x.GetRelocatableCopyOfDom(It.IsAny<IProgress>())).Returns(() =>
            {
                return
                    _bookDom.Clone();
            });// review: the real thing does more than just clone
            _storage.Setup(x => x.MakeDomRelocatable(It.IsAny<HtmlDom>(), It.IsAny<IProgress>())).Returns(
                (HtmlDom x, IProgress y) => { return x.Clone(); });// review: the real thing does more than just clone

            _storage.Setup(x => x.GetFileLocator()).Returns(() => _fileLocator.Object);

            _testFolder = new TemporaryFolder("BookTests");
            _tempFolder = new TemporaryFolder(_testFolder, "book");
            MakeSamplePngImageWithMetadata(Path.Combine(_tempFolder.Path, "original.png"));
            _storage.SetupGet(x => x.FolderPath).Returns(_tempFolder.Path);// review: the real thing does more than just clone
            _metadata = new BookInfo(_tempFolder.Path, true);
            _storage.SetupGet(x => x.MetaData).Returns(_metadata);
            _storage.Setup(x => x.HandleRetiredXMatterPacks(It.IsAny<HtmlDom>(), It.IsAny<string>()))
                .Returns((HtmlDom dom, string y) => { return y == "BigBook" ? "Factory" : y; });

            _templateFinder = new Moq.Mock<ITemplateFinder>();
            _fileLocator = new Moq.Mock<IFileLocator>();
            string root = FileLocator.GetDirectoryDistributedWithApplication(BloomFileLocator.BrowserRoot);
            string xMatter = BloomFileLocator.GetInstalledXMatterDirectory();
            _fileLocator.Setup(x => x.LocateFileWithThrow("languageDisplay.css")).Returns("../notareallocation/languageDisplay.css");
            _fileLocator.Setup(x => x.LocateFileWithThrow("previewMode.css")).Returns("../notareallocation/previewMode.css");
            _fileLocator.Setup(x => x.LocateFileWithThrow("origami.css")).Returns("../notareallocation/origami.css");
            _fileLocator.Setup(x => x.LocateFileWithThrow("editMode.css")).Returns("../notareallocation/editMode.css");
            _fileLocator.Setup(x => x.LocateFileWithThrow("editTranslationMode.css")).Returns("../notareallocation/editTranslationMode.css");
            _fileLocator.Setup(x => x.LocateFileWithThrow("editOriginalMode.css")).Returns("../notareallocation/editOriginalMode.css");
            _fileLocator.Setup(x => x.LocateFileWithThrow("editPaneGlobal.css")).Returns("../notareallocation/editPaneGlobal.css");
            _fileLocator.Setup(x => x.LocateFileWithThrow("basePage.css")).Returns("../notareallocation/basePage.css");
            _fileLocator.Setup(x => x.LocateFileWithThrow("bloomBootstrap.js")).Returns("../notareallocation/bloomBootstrap.js");
            _fileLocator.Setup(x => x.LocateFileWithThrow("bloomPreviewBootstrap.js")).Returns("../notareallocation/bloomPreviewBootstrap.js");
            _fileLocator.Setup(x => x.LocateFileWithThrow("baseEPUB.css")).Returns("../notareallocation/baseEPUB.css");
            _fileLocator.Setup(x => x.LocateFileWithThrow("customBookStyles.css")).Returns(Path.Combine(_tempFolder.Path, "customBookStyles.css"));
            _fileLocator.Setup(x => x.LocateFileWithThrow("settingsCollectionStyles.css")).Returns(Path.Combine(_testFolder.Path, "settingsCollectionStyles.css"));
            _fileLocator.Setup(x => x.LocateFileWithThrow("customCollectionStyles.css")).Returns(Path.Combine(_testFolder.Path, "customCollectionStyles.css"));

            _fileLocator.Setup(x => x.LocateDirectory("Factory-XMatter")).Returns(xMatter.CombineForPath("Factory-XMatter"));
            _fileLocator.Setup(x => x.LocateDirectoryWithThrow("Factory-XMatter")).Returns(xMatter.CombineForPath("Factory-XMatter"));
            _fileLocator.Setup(x => x.LocateDirectory("Factory-XMatter", It.IsAny<string>())).Returns(xMatter.CombineForPath("Factory-XMatter"));
            _fileLocator.Setup(x => x.LocateFileWithThrow("Factory-XMatter".CombineForPath("Factory-XMatter.htm"))).Returns(xMatter.CombineForPath("Factory-XMatter", "Factory-XMatter.htm"));

            _fileLocator.Setup(x => x.LocateDirectory("Traditional-XMatter")).Returns(xMatter.CombineForPath("Traditional-XMatter"));
            _fileLocator.Setup(x => x.LocateDirectoryWithThrow("Traditional-XMatter")).Returns(xMatter.CombineForPath("Traditional-XMatter"));
            _fileLocator.Setup(x => x.LocateDirectory("Traditional-XMatter", It.IsAny<string>())).Returns(xMatter.CombineForPath("Traditional-XMatter"));
            _fileLocator.Setup(x => x.LocateFileWithThrow("Traditional-XMatter".CombineForPath("Traditional-XMatter.htm"))).Returns(xMatter.CombineForPath("Traditional-XMatter", "Factory-XMatter.htm"));

            _fileLocator.Setup(x => x.LocateDirectory("BigBook-XMatter")).Returns(xMatter.CombineForPath("BigBook-XMatter"));
            _fileLocator.Setup(x => x.LocateDirectoryWithThrow("BigBook-XMatter")).Returns(xMatter.CombineForPath("BigBook-XMatter"));
            _fileLocator.Setup(x => x.LocateDirectory("BigBook-XMatter", It.IsAny<string>())).Returns(xMatter.CombineForPath("BigBook-XMatter"));
            _fileLocator.Setup(x => x.LocateFileWithThrow("BigBook-XMatter".CombineForPath("BigBook-XMatter.htm"))).Returns(xMatter.CombineForPath("BigBook-XMatter", "BigBook-XMatter.htm"));

            //warning: we're neutering part of what the code under test is trying to do here:
            _fileLocator.Setup(x => x.CloneAndCustomize(It.IsAny<IEnumerable<string>>())).Returns(_fileLocator.Object);

            _thumbnailer = new Moq.Mock<HtmlThumbNailer>(new object[] { new NavigationIsolator() });
            _pageSelection = new Mock<PageSelection>();
            _pageListChangedEvent = new PageListChangedEvent();
        }
Exemplo n.º 32
0
 private void UpdateDownloadedBooks(string pathToChangedBook)
 {
     var newBook = new BookInfo(pathToChangedBook, false);
     // It's always worth reloading...maybe we didn't have a button before because it was not
     // suitable for making vernacular books, but now it is! Or maybe the metadata changed some
     // other way...we want the button to have valid metadata for the book.
     // Optimize: maybe it would be worth trying to find the right place to insert or replace just one button?
     LoadSourceCollectionButtons();
     if (Enabled && CollectionTabIsActive)
         SelectBook(newBook);
 }
Exemplo n.º 33
0
        /// <summary>
        /// Internal for testing because it's not yet clear this is the appropriate public routine.
        /// Probably some API gets a list of BloomInfo objects from the parse.com data, and we pass one of
        /// them as the argument for the public method.
        /// </summary>
        /// <param name="bucket"></param>
        /// <param name="s3BookId"></param>
        /// <param name="dest"></param>
        /// <returns></returns>
        internal string DownloadBook(string bucket, string s3BookId, string dest)
        {
            var destinationPath = _s3Client.DownloadBook(bucket, s3BookId, dest, _progressDialog);
            if (BookDownLoaded != null)
            {
                var bookInfo = new BookInfo(destinationPath, false); // A downloaded book is a template, so never editable.
                BookDownLoaded(this, new BookDownloadedEventArgs() {BookDetails = bookInfo});
            }
            // Books in the library should generally show as locked-down, so new users are automatically in localization mode.
            // Occasionally we may want to upload a new authoring template, that is, a 'book' that is suitableForMakingShells.
            // Such books should not be locked down.
            // So, we try to lock it. What we want to do is Book.RecordedAsLockedDown = true; Book.Save().
            // But all kinds of things have to be set up before we can create a Book. So we duplicate a few bits of code.
            var htmlFile = BookStorage.FindBookHtmlInFolder(destinationPath);
            if (htmlFile == "")
                return destinationPath; //argh! we can't lock it.
            var xmlDomFromHtmlFile = XmlHtmlConverter.GetXmlDomFromHtmlFile(htmlFile, false);
            var dom = new HtmlDom(xmlDomFromHtmlFile);
            if (!BookMetaData.FromString(MetaDataText(destinationPath)).IsSuitableForMakingShells)
            {
                Book.Book.RecordAsLockedDown(dom, true);
                XmlHtmlConverter.SaveDOMAsHtml5(dom.RawDom, htmlFile);
            }

            return destinationPath;
        }
Exemplo n.º 34
0
        private void UpdateIsbn(BookInfo info)
        {
            if (info == null)
                return;

            NamedMutliLingualValue isbnData;
            string isbn = null;
            if (_dataset.TextVariables.TryGetValue("ISBN", out isbnData))
            {
                isbn = isbnData.TextAlternatives.GetBestAlternativeString(WritingSystemIdsToTry); // Review: not really multilingual data, do we need this?
            }
            info.Isbn = isbn ?? "";
        }