public static string StageBloomD(Book.Book book, BookServer bookServer, WebSocketProgress progress, Color backColor, AndroidPublishSettings settings = null) { progress.Message("PublishTab.Epub.PreparingPreview", "Preparing Preview"); // message shared with Epub publishing if (settings?.LanguagesToInclude != null) { var message = new LicenseChecker().CheckBook(book, settings.LanguagesToInclude.ToArray()); if (message != null) { progress.MessageWithoutLocalizing(message, MessageKind.Error); return(null); } } _stagingFolder?.Dispose(); if (AudioProcessor.IsAnyCompressedAudioMissing(book.FolderPath, book.RawDom)) { progress.Message("CompressingAudio", "Compressing audio files"); AudioProcessor.TryCompressingAudioAsNeeded(book.FolderPath, book.RawDom); } // We don't use the folder found here, but this method does some checks we want done. BookStorage.FindBookHtmlInFolder(book.FolderPath); _stagingFolder = new TemporaryFolder(StagingFolder); var modifiedBook = BloomReaderFileMaker.PrepareBookForBloomReader(book.FolderPath, bookServer, _stagingFolder, progress, settings: settings); progress.Message("Common.Done", "Shown in a list of messages when Bloom has completed a task.", "Done"); return(modifiedBook.FolderPath.ToLocalhost()); }
public void Should_Add_Book_Record_ToDb() { // Arrange string pathToFile = @"С:\Users\Dakosia\source\repos\CSharp\KazTourApp\KazTourApp.DAL\LiteDb.db"; var booking = new BookRecord ( 1, 1, 2, 1600000, new DateTime(2018, 08, 11), new DateTime(2018, 08, 25) ); BookStorage storage = new BookStorage(); int itemsCountBeforeInsert = storage.ReadAllBookings().Count; // Act storage.AddBooking(booking); // Assert Assert.IsTrue(File.Exists(pathToFile)); int itemsCountAfterInsert = storage.ReadAllBookings().Count; Assert.IsTrue(itemsCountBeforeInsert == itemsCountAfterInsert - 1); }
public static int Handle(SpreadsheetImportParameters options) { try { string folderPath = Directory.GetParent(options.BookPath).FullName; BookStorage.SaveCopyBeforeImportOverwrite(folderPath); var sheet = InternalSpreadsheet.ReadFromFile(options.InputPath); var dom = new HtmlDom(XmlHtmlConverter.GetXmlDomFromHtmlFile(options.BookPath, false)); var importer = new SpreadsheetImporter(null, dom, Path.GetDirectoryName(options.InputPath), folderPath); if (!string.IsNullOrEmpty(options.ParamsPath)) { importer.Params = SpreadsheetImportParams.FromFile(options.ParamsPath); } var messages = importer.Import(sheet); foreach (var message in messages) { Debug.WriteLine(message); Console.WriteLine(message); } // Review: A lot of other stuff happens in Book.Save() and BookStorage.SaveHtml(). // I doubt we need any of it for current purposes, but later we might. XmlHtmlConverter.SaveDOMAsHtml5(dom.RawDom, options.BookPath); Console.WriteLine("done"); return(0); // all went well } catch (Exception ex) { Debug.WriteLine(ex.Message); Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); return(1); } }
private void InitializeIoC() { var container = new RegisterByContainer().Container; _unitOfWork = container.GetInstance <IUnitOfWork>(); _typiconEntityService = container.With(_unitOfWork).GetInstance <ITypiconEntityService>(); GetTypiconEntityResponse response = _typiconEntityService.GetTypiconEntity(1);// _unitOfWork.Repository<TypiconEntity>().Get(c => c.Name == "Типикон"); _typiconEntity = response.TypiconEntity; _bookStorage = new BookStorage( container.With(_unitOfWork).GetInstance <IEvangelionContext>(), container.With(_unitOfWork).GetInstance <IApostolContext>(), container.With(_unitOfWork).GetInstance <IOldTestamentContext>(), container.With(_unitOfWork).GetInstance <IPsalterContext>(), container.With(_unitOfWork).GetInstance <IOktoikhContext>(), container.With(_unitOfWork).GetInstance <ITheotokionAppContext>(), container.With(_unitOfWork).GetInstance <IEasterContext>(), container.With(_unitOfWork).GetInstance <IKatavasiaContext>()); //EasterStorage.Instance.EasterDays = _unitOfWork.Repository<EasterItem>().GetAll().ToList(); IRuleSerializerRoot serializerRoot = container.With(_bookStorage).GetInstance <IRuleSerializerRoot>(); var settingsFactory = container.GetInstance <IRuleHandlerSettingsFactory>(); _scheduleService = container.With(settingsFactory).With(serializerRoot).GetInstance <IScheduleService>(); _docxTemplateService = container.With(_bookStorage.Oktoikh).GetInstance <IDocxTemplateService>(); }
static void Main(string[] args) { List <Book> test = new List <Book>() { new Book("clr Via c#", "Richter", "program", 2015, 6), new Book("Net pro perfomance", "Goldshtein", "program", 2016, 5), new Book("Solaris", "Lem", "Fantastic", 1961, 1), }; BookListService bookService = new BookListService(test, null); bookService.AddBook(new Book("test", "testAuthor", "testGenre", 2000, 1)); SerializeStorage serStorage = new SerializeStorage(@"C:\OldbooksStorage.txt", null); NoSerXMLStorage XMLstorage = new NoSerXMLStorage(@"C:\NewXMLstorage.xml", null); XMLstorage xmlStorage = new XMLstorage(@"C:\NewbooksStorage.txt", null); BookStorage storage = new BookStorage(@"C:\NewbooksStorage.txt", null); bookService.SaveToRepo(xmlStorage); bookService.SaveToRepo(serStorage); bookService.SaveToRepo(storage); bookService.SaveToRepo(XMLstorage); BookListService testXml = new BookListService(xmlStorage.Load(), null); BookListService testSer = new BookListService(serStorage.Load(), null); BookListService testOld = new BookListService(storage.Load(), null); BookListService testXML = new BookListService(XMLstorage.Load(), null); Console.ReadLine(); }
/// <summary> /// tempFolderPath is where to put the book. Note that a few files (e.g., customCollectionStyles.css) /// are copied into its parent in order to be in the expected location relative to the book, /// so that needs to be a folder we can write in. /// </summary> public static Book.Book MakeDeviceXmatterTempBook(string bookFolderPath, BookServer bookServer, string tempFolderPath, bool isTemplateBook, Dictionary <string, int> omittedPageLabels = null) { BookStorage.CopyDirectory(bookFolderPath, tempFolderPath); BookStorage.EnsureSingleHtmFile(tempFolderPath); // We can always save in a temp book var bookInfo = new BookInfo(tempFolderPath, true, new AlwaysEditSaveContext()) { UseDeviceXMatter = !isTemplateBook }; var modifiedBook = bookServer.GetBookFromBookInfo(bookInfo); modifiedBook.BringBookUpToDate(new NullProgress(), true); modifiedBook.RemoveNonPublishablePages(omittedPageLabels); var domForVideoProcessing = modifiedBook.OurHtmlDom; var videoContainerElements = HtmlDom.SelectChildVideoElements(domForVideoProcessing.RawDom.DocumentElement).Cast <XmlElement>(); if (videoContainerElements.Any()) { SignLanguageApi.ProcessVideos(videoContainerElements, modifiedBook.FolderPath); } modifiedBook.Save(); modifiedBook.UpdateSupportFiles(); return(modifiedBook); }
// Request from sign language tool to import a video. private void HandleImportVideoRequest(ApiRequest request) { string path = null; View.Invoke((Action)(() => { var videoFiles = LocalizationManager.GetString("EditTab.Toolbox.SignLanguage.FileDialogVideoFiles", "Video files"); var dlg = new DialogAdapters.OpenFileDialogAdapter { Multiselect = false, CheckFileExists = true, Filter = $"{videoFiles} (*.mp4)|*.mp4" }; var result = dlg.ShowDialog(); if (result == DialogResult.OK) { path = dlg.FileName; } })); if (!string.IsNullOrEmpty(path)) { _importedVideoIntoBloom = true; var newVideoPath = Path.Combine(BookStorage.GetVideoDirectoryAndEnsureExistence(CurrentBook.FolderPath), GetNewVideoFileName()); // Use a new name to defeat caching. RobustFile.Copy(path, newVideoPath); var relativePath = BookStorage.GetVideoFolderName + Path.GetFileName(newVideoPath); request.ReplyWithText(UrlPathString.CreateFromUnencodedString(relativePath).UrlEncodedForHttpPath); } else { // If the user canceled, we didn't exactly succeed, but having the user cancel is such a normal // event that posting a failure, which is a nuisance to ignore, is not warranted. request.ReplyWithText(""); } }
private void InitializeIoC() { var container = new RegisterByContainer().Container; var unitOfWork = container.GetInstance <IUnitOfWork>(); var typiconEntityService = container.With(unitOfWork).GetInstance <ITypiconEntityService>(); GetTypiconEntityResponse response = typiconEntityService.GetTypiconEntity(1);// _unitOfWork.Repository<TypiconEntity>().Get(c => c.Name == "Типикон"); typiconEntity = response.TypiconEntity; var bookStorage = new BookStorage( container.With(unitOfWork).GetInstance <IEvangelionContext>(), container.With(unitOfWork).GetInstance <IApostolContext>(), container.With(unitOfWork).GetInstance <IOldTestamentContext>(), container.With(unitOfWork).GetInstance <IPsalterContext>(), container.With(unitOfWork).GetInstance <IOktoikhContext>(), container.With(unitOfWork).GetInstance <ITheotokionAppContext>(), container.With(unitOfWork).GetInstance <IEasterContext>(), container.With(unitOfWork).GetInstance <IKatavasiaContext>()); IRuleSerializerRoot serializerRoot = container.With(bookStorage).GetInstance <IRuleSerializerRoot>(); settingsFactory = new CustomRuleSettingsFactory(); scheduleService = container.With(settingsFactory).With(serializerRoot).GetInstance <IScheduleService>(); }
public void BookStorageDeleteBookTest() { List <Genre> genres1 = new List <Genre> { new Genre("fantasy") }; BookInfo bookInfo1 = new BookInfo("Harry Potter and the Chamber of Secrets", "J.K.Rowling", genres1); Book book1 = new Book(bookInfo1, 500m, DateTime.Today); List <Genre> genres2 = new List <Genre> { new Genre("other") }; BookInfo bookInfo2 = new BookInfo("One Flew Over the Cuckoo's Nest", " Ken Kesey", genres2); Book book2 = new Book(bookInfo2, 600m, DateTime.Today.AddDays(-110)); BookStorage bookStorage = new BookStorage(); bookStorage.AddBook(book1); bookStorage.AddBook(book2); bookStorage.FindByGuidOrDefault(book1.Guid).Should().Be(book1); bookStorage.FindByGuidOrDefault(book2.Guid).Should().Be(book2); bookStorage.DeleteBook(book1); bookStorage.FindByGuidOrDefault(book1.Guid).Should().Be(null); bookStorage.FindByGuidOrDefault(book2.Guid).Should().Be(book2); }
public void Start(Book.Book book, CollectionSettings collectionSettings, Color backColor) { if (_wifiAdvertiser != null) { Stop(); } // This listens for a BloomReader to request a book. // It requires a firewall hole allowing Bloom to receive messages on _portToListen. // We initialize it before starting the Advertiser to avoid any chance of a race condition // where a BloomReader manages to request an advertised book before we start the listener. _wifiListener = new BloomReaderUDPListener(); _wifiListener.NewMessageReceived += (sender, args) => { var json = Encoding.UTF8.GetString(args.Data); try { dynamic settings = JsonConvert.DeserializeObject(json); // The property names used here must match the ones in BloomReader, doInBackground method of SendMessage, // a private class of NewBookListenerService. var androidIpAddress = (string)settings.deviceAddress; var androidName = (string)settings.deviceName; // This prevents the device (or other devices) from queuing up requests while we're busy with this one. // In effect, the Android is only allowed to request a retry after we've given up this try at sending. // Of course, there are async effects from network latency. But if we do get another request while // handling this one, we will ignore it, since StartSendBook checks for a transfer in progress. _wifiAdvertiser.Paused = true; StartSendBookOverWiFi(book, androidIpAddress, androidName, backColor); // Returns immediately. But we don't resume advertisements until the async send completes. } // If there's something wrong with the JSON (maybe an obsolete or newer version of reader?) // just ignore the request. catch (Exception ex) when(ex is JsonReaderException || ex is JsonSerializationException) { _progress.Error(id: "BadBookRequest", message: "Got a book request we could not process. Possibly the device is running an incompatible version of BloomReader?"); //this is too technical/hard to translate _progress.ErrorWithoutLocalizing($" Request contains {json}; trying to interpret as JSON we got {ex.Message}"); } }; var pathHtmlFile = book.GetPathHtmlFile(); _wifiAdvertiser = new WiFiAdvertiser(_progress) { BookTitle = BookStorage.SanitizeNameForFileSystem(book.Title), // must be the exact same name as the file we will send if requested TitleLanguage = collectionSettings.Language1Iso639Code, BookVersion = Book.Book.MakeVersionCode(File.ReadAllText(pathHtmlFile), pathHtmlFile) }; AndroidView.CheckBookLayout(book, _progress); _wifiAdvertiser.Start(); _progress.Message(id: "WifiInstructions1", message: "On the Android, run Bloom Reader, open the menu and choose 'Receive Books from computer'."); _progress.Message(id: "WifiInstructions2", message: "You can do this on as many devices as you like. Make sure each device is connected to the same network as this computer."); }
public BookServer CreateBookServer() { _collectionSettings = CreateDefaultCollectionsSettings(); var xmatterFinder = new XMatterPackFinder(new[] { BloomFileLocator.GetInstalledXMatterDirectory() }); var fileLocator = new BloomFileLocator(_collectionSettings, xmatterFinder, ProjectContext.GetFactoryFileLocations(), ProjectContext.GetFoundFileLocations(), ProjectContext.GetAfterXMatterFileLocations()); var starter = new BookStarter(fileLocator, (dir, forSelectedBook) => new BookStorage(dir, fileLocator, new BookRenamedEvent(), _collectionSettings), _collectionSettings); return(new BookServer( //book factory (bookInfo, storage) => { return new Bloom.Book.Book(bookInfo, storage, null, _collectionSettings, new PageSelection(), new PageListChangedEvent(), new BookRefreshEvent()); }, // storage factory (path, forSelectedBook) => { var storage = new BookStorage(path, fileLocator, new BookRenamedEvent(), _collectionSettings); storage.BookInfo = new BookInfo(path, true); return storage; }, // book starter factory () => starter, // configurator factory null)); }
// Request from sign language tool, issued when a complete recording has been captured. // It is passed as a binary blob that is the actual content that needs to be made into // an mp4 file. (At this point we don't try to handle recordings too big for this approach.) // We make a file (with an arbitrary guid name) and attempt to make it the recording for the // first page element with class bloom-videoContainer. private void HandleRecordedVideoRequest(ApiRequest request) { lock (request) { var videoFolder = BookStorage.GetVideoDirectoryAndEnsureExistence(CurrentBook.FolderPath); var fileName = GetNewVideoFileName(); var path = Path.Combine(videoFolder, fileName); using (var rawVideo = TempFile.CreateAndGetPathButDontMakeTheFile()) { using (var rawVideoOutput = new FileStream(rawVideo.Path, FileMode.Create)) { // Do NOT just get RawPostData and try to write it to a file; this // typically runs out of memory for anything more than about 2min of video. // (It write to a MemoryStream, and this seems to manage memory very badly. // 66MB should not be a huge problem, but somehow it is.) using (var rawVideoInput = request.RawPostStream) { rawVideoInput.CopyTo(rawVideoOutput); } } // The output stream should be closed before trying to access the newly written file. SaveVideoFile(path, rawVideo.Path); } var relativePath = BookStorage.GetVideoFolderName + Path.GetFileName(path); request.ReplyWithText(UrlPathString.CreateFromUnencodedString(relativePath).UrlEncodedForHttpPath); } }
/// <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) { dom.RecordAsLockedDown(true); XmlHtmlConverter.SaveDOMAsHtml5(dom.RawDom, htmlFile); } return(destinationPath); }
/// <summary> /// If we do not have enterprise enabled, copy the book and remove all enterprise level features. /// </summary> internal static bool PrepareBookForUpload(ref Book.Book book, BookServer bookServer, string tempFolderPath, IProgress progress) { if (book.CollectionSettings.HaveEnterpriseFeatures) { return(false); } // We need to be sure that any in-memory changes have been written to disk // before we start copying/loading the new book to/from disk book.Save(); Directory.CreateDirectory(tempFolderPath); BookStorage.CopyDirectory(book.FolderPath, tempFolderPath); var bookInfo = new BookInfo(tempFolderPath, true); var copiedBook = bookServer.GetBookFromBookInfo(bookInfo); copiedBook.BringBookUpToDate(new NullProgress(), true); var pages = new List <XmlElement>(); foreach (XmlElement page in copiedBook.GetPageElements()) { pages.Add(page); } ISet <string> warningMessages = new HashSet <string>(); PublishHelper.RemoveEnterpriseFeaturesIfNeeded(copiedBook, pages, warningMessages); PublishHelper.SendBatchedWarningMessagesToProgress(warningMessages, progress); copiedBook.Save(); copiedBook.Storage.UpdateSupportFiles(); book = copiedBook; return(true); }
private string GetPdfPath(string fname) { string path = null; // Sanitize fileName first string fileName = BookStorage.SanitizeNameForFileSystem(fname); for (int i = 0; i < 100; i++) { path = Path.Combine(Path.GetTempPath(), string.Format("{0}-{1}.pdf", fileName, i)); if (!RobustFile.Exists(path)) { break; } try { RobustFile.Delete(path); break; } catch (Exception) { //couldn't delete it? then increment the suffix and try again } } return(path); }
private BookStorage Get_NotYetConfigured_CalendardBookStorage() { var source = FileLocator.GetDirectoryDistributedWithApplication("factoryCollections", "Templates", "Wall Calendar"); var path = GetPathToHtml(_starter.CreateBookOnDiskFromTemplate(source, _libraryFolder.Path)); var bs = new BookStorage(Path.GetDirectoryName(path), _fileLocator, new BookRenamedEvent(), new CollectionSettings()); return(bs); }
public void Save_BookHadOnlyPaperSizeStyleSheet_StillHasIt() { File.WriteAllText(_bookPath, "<html><head><link rel='stylesheet' href='Basic Book.css' type='text/css' /></head><body><div class='bloom-page'></div></body></html>"); var storage = new BookStorage(_folder.FolderPath, _fileLocator, new BookRenamedEvent(), new CollectionSettings()); storage.Save(); AssertThatXmlIn.HtmlFile(_bookPath).HasSpecifiedNumberOfMatchesForXpath("//link[contains(@href, 'Basic Book')]", 1); }
// // [Test] // public void Delete_IsDeleted() // { // BookStorage storage = GetInitialStorage(); // Assert.IsTrue(Directory.Exists(_folder.Path)); // Assert.IsTrue(storage.DeleteBook()); // Thread.Sleep(2000); // Assert.IsFalse(Directory.Exists(_folder.Path)); // } private BookStorage GetInitialStorage() { File.WriteAllText(_bookPath, "<html><head> href='file://blahblah\\editMode.css' type='text/css' /></head><body><div class='bloom-page'></div></body></html>"); var storage = new BookStorage(_folder.Path, _fileLocator, new BookRenamedEvent(), new CollectionSettings()); storage.Save(); return(storage); }
private BookStorage GetInitialStorageWithCustomHead(string head) { File.WriteAllText(_bookPath, "<html><head>" + head + " </head></body></html>"); var storage = new BookStorage(_folder.Path, _fileLocator, new BookRenamedEvent(), new CollectionSettings()); storage.Save(); return(storage); }
private void HandleCopyImageCreditsForWholeBook(ApiRequest request) { var names = BookStorage.GetImagePathsRelativeToBook(_bookSelection.CurrentSelection.RawDom.DocumentElement); IEnumerable <string> langs = null; if (request.CurrentCollectionSettings != null) { langs = request.CurrentCollectionSettings.LicenseDescriptionLanguagePriorities; } else { langs = new List <string> { "en" } }; // emergency fall back -- probably never used. var credits = new List <string>(); var missingCredits = new List <string>(); foreach (var name in names) { var path = _bookSelection.CurrentSelection.FolderPath.CombineForPath(name); if (RobustFile.Exists(path)) { var meta = Metadata.FromFile(path); string id; var credit = meta.MinimalCredits(langs, out id); if (String.IsNullOrEmpty(credit) && name.ToLowerInvariant() != "license.png" && name.ToLowerInvariant() != "placeholder.png") { missingCredits.Add(name); } if (!String.IsNullOrEmpty(credit) && !credits.Contains(credit)) { credits.Add(credit); } } } var total = credits.Aggregate(new StringBuilder(), (all, credit) => { all.AppendFormat("<p>{0}</p>{1}", credit, System.Environment.NewLine); return(all); }); // Notify the user of images with missing credits. if (missingCredits.Count > 0) { var missing = LocalizationManager.GetString("EditTab.FrontMatter.PasteMissingCredits", "Missing credits:"); total.AppendFormat("<p>{0}", missing); for (var i = 0; i < missingCredits.Count; ++i) { if (i > 0) { total.Append(","); } total.AppendFormat(" {0}", missingCredits[i]); } total.AppendFormat("</p>{0}", System.Environment.NewLine); } request.ReplyWithText(total.ToString()); }
Bloom.Book.Book BookFactory(BookStorage storage, bool editable) { return(new Bloom.Book.Book(new BookInfo(storage.FolderPath, true), storage, null, new CollectionSettings(new NewCollectionSettings() { PathToSettingsFile = CollectionSettings.GetPathForNewSettings(_folder.Path, "test"), Language1Iso639Code = "xyz" }), null, new PageSelection(), new PageListChangedEvent(), new BookRefreshEvent())); }
public void Save_BookHadEditStyleSheet_NowHasPreviewAndBase() { File.WriteAllText(_bookPath, "<html><head> href='file://blahblah\\editMode.css' type='text/css' /></head><body><div class='bloom-page'></div></body></html>"); var storage = new BookStorage(_folder.FolderPath, _fileLocator, new BookRenamedEvent(), new CollectionSettings()); storage.Save(); AssertThatXmlIn.HtmlFile(_bookPath).HasSpecifiedNumberOfMatchesForXpath("//link[contains(@href, 'basePage')]", 1); AssertThatXmlIn.HtmlFile(_bookPath).HasSpecifiedNumberOfMatchesForXpath("//link[contains(@href, 'preview')]", 1); }
private void ChangeNameAndCheck(TemporaryFolder newFolder, BookStorage storage) { var newBookName = Path.GetFileName(newFolder.Path); storage.SetBookName(newBookName); var newPath = newFolder.Combine(newBookName + ".htm"); Assert.IsTrue(Directory.Exists(newFolder.Path), "Expected folder:" + newFolder.Path); Assert.IsTrue(File.Exists(newPath), "Expected file:" + newPath); }
private BookStorage GetInitialStorageWithCustomHtml(string html) { RobustFile.WriteAllText(_bookPath, html); var projectFolder = new TemporaryFolder("BookStorageTests_ProjectCollection"); var collectionSettings = new CollectionSettings(Path.Combine(projectFolder.Path, "test.bloomCollection")); var storage = new BookStorage(_folder.Path, _fileLocator, new BookRenamedEvent(), collectionSettings); storage.Save(); return(storage); }
public override bool TransferBook(BookStorage target, BookModel bookModel) { if (!base.TransferBook(target, bookModel)) { return(false); } missingBooks.Add(bookModel.book); return(true); }
public void RoundTripOfTemplateBookDoesNotLockIt() { var pair = UploadAndDownLoadNewBook("first", "book1", "Jack", "Jack's data", true); var originalFolder = pair.Item1; var newFolder = pair.Item2; var originalHtml = BookStorage.FindBookHtmlInFolder(originalFolder); var newHtml = BookStorage.FindBookHtmlInFolder(newFolder); AssertThatXmlIn.HtmlFile(originalHtml).HasNoMatchForXpath("//meta[@name='lockedDownAsShell' and @content='true']"); AssertThatXmlIn.HtmlFile(newHtml).HasNoMatchForXpath("//meta[@name='lockedDownAsShell' and @content='true']"); }
private BookStorage GetInitialStorageWithDifferentFileName(string bookName) { var bookPath = _folder.Combine(bookName + ".htm"); File.WriteAllText(bookPath, "<html><head> href='file://blahblah\\editMode.css' type='text/css' /></head><body><div class='bloom-page'></div></body></html>"); var projectFolder = new TemporaryFolder("BookStorageTests_ProjectCollection"); var collectionSettings = new CollectionSettings(Path.Combine(projectFolder.Path, "test.bloomCollection")); var storage = new BookStorage(_folder.Path, _fileLocator, new BookRenamedEvent(), collectionSettings); storage.Save(); return(storage); }
private BookStorage Get_NotYetConfigured_CalendardBookStorage() { var source = BloomFileLocator.GetFactoryBookTemplateDirectory("Wall Calendar"); var path = GetPathToHtml(_starter.CreateBookOnDiskFromTemplate(source, _libraryFolder.Path)); var projectFolder = new TemporaryFolder("ConfiguratorTests_ProjectCollection"); //review var collectionSettings = new CollectionSettings(Path.Combine(projectFolder.Path, "test.bloomCollection")); var bs = new BookStorage(Path.GetDirectoryName(path), _fileLocator, new BookRenamedEvent(), collectionSettings); return(bs); }
public void OneTimeSetup() { _testFolder = new TemporaryFolder("SpreadsheetImporterWithBookTests"); // We need 2 layers of temp folder because BringBookUpToDate will change the name of the book // folder to match an imported title. _bookFolder = new TemporaryFolder(_testFolder, "Book"); var settings = new NewCollectionSettings(); settings.Language1.Iso639Code = "en"; settings.Language1.SetName("English", false); settings.SettingsFilePath = Path.Combine(_bookFolder.FolderPath, "dummy"); var fileLocator = new BloomFileLocator(settings, new XMatterPackFinder(new string[] { }), ProjectContext.GetFactoryFileLocations(), ProjectContext.GetFoundFileLocations(), ProjectContext.GetAfterXMatterFileLocations()); var bookFilePath = Path.Combine(_bookFolder.FolderPath, "testBook.htm"); if (File.Exists(bookFilePath)) // Shouldn't ever happen, but... just being careful. { RobustFile.Delete(bookFilePath); } _dom = SetupTestDom(); // Write out our test book File.WriteAllText(bookFilePath, _dom.RawDom.OuterXml.ToString()); var storage = new BookStorage(_bookFolder.FolderPath, fileLocator, new BookRenamedEvent(), settings); var book = new Bloom.Book.Book(new BookInfo(_bookFolder.FolderPath, true), storage, null, settings, new Bloom.Edit.PageSelection(), new PageListChangedEvent(), new BookRefreshEvent()); // Create the regular production importer _importer = new SpreadsheetImporter(null, book, _bookFolder.FolderPath); // Set up the internal spreadsheet rows directly. var ss = new InternalSpreadsheet(); var columnForEn = ss.AddColumnForLang("en", "English"); var columnForImage = ss.GetColumnForTag(InternalSpreadsheet.ImageSourceColumnLabel); var newTitle = "My new book title"; var titleRow = new ContentRow(ss); titleRow.AddCell(InternalSpreadsheet.BookTitleRowLabel); titleRow.SetCell(columnForEn, newTitle); var coverImageRow = new ContentRow(ss); coverImageRow.AddCell(InternalSpreadsheet.CoverImageRowLabel); coverImageRow.SetCell(columnForImage, Path.Combine("images", "Othello 199.jpg")); _importer.Import(ss); _resultElement = ReadResultingBookToXml(newTitle); }
public void ImportWithProgress(string inputFilepath) { Debug.Assert(_pathToBookFolder != null, "Somehow we made it into ImportWithProgress() without a path to the book folder"); var mainShell = Application.OpenForms.Cast <Form>().FirstOrDefault(f => f is Shell); BrowserProgressDialog.DoWorkWithProgressDialog(_webSocketServer, "spreadsheet-import", () => new ReactDialog("progressDialogBundle", // props to send to the react component new { title = "Importing Spreadsheet", titleIcon = "", // enhance: add icon if wanted titleColor = "white", titleBackgroundColor = Palette.kBloomBlueHex, webSocketContext = "spreadsheet-import", showReportButton = "if-error" }, "Import Spreadsheet") // winforms dialog properties { Width = 620, Height = 550 }, (progress, worker) => { var hasAudio = _destinationDom.GetRecordedAudioSentences(_pathToBookFolder).Any(); var cannotImportEnding = " For this reason, we need to abandon the import. Instead, you can import into a blank book."; if (hasAudio) { progress.MessageWithoutLocalizing($"Warning: Spreadsheet import cannot currently preserve Talking Book audio that is already in this book." + cannotImportEnding, ProgressKind.Error); return(true); // leave progress window up so user can see error. } var hasActivities = _destinationDom.HasActivityPages(); if (hasActivities) { progress.MessageWithoutLocalizing($"Warning: Spreadsheet import cannot currently preserve quizzes, widgets, or other activities that are already in this book." + cannotImportEnding, ProgressKind.Error); return(true); // leave progress window up so user can see error. } var sheet = InternalSpreadsheet.ReadFromFile(inputFilepath, progress); if (sheet == null) { return(true); } if (!Validate(sheet, progress)) { return(true); // errors already reported to progress } progress.MessageWithoutLocalizing($"Making a backup of the original book..."); var backupPath = BookStorage.SaveCopyBeforeImportOverwrite(_pathToBookFolder); progress.MessageWithoutLocalizing($"Backup completed (at {backupPath})"); Import(sheet, progress); return(true); // always leave the dialog up until the user chooses 'close' }, null, mainShell); }
public async void OpenDirectory() { BookStorage BS = new BookStorage(); string[] ids = BS.GetIdList(); IEnumerable<LocalBook> Items = await Shared.Storage.GetLocalText( async ( x, i, l ) => { if ( i % 20 == 0 ) { Worker.UIInvoke( () => Loading = string.Format( "{0}/{1}", i, l ) ); await Task.Delay( 15 ); } LocalBook LB = new LocalBook( x ); LB.IsFav = ids.Contains( LB.aid ); return LB; } ); Loading = null; if ( Items != null && 0 < Items.Count() ) SearchSet = Items; }
public void Dispose() { try { AppSettings.PropertyChanged -= AppSettings_PropertyChanged; foreach ( Paragraph P in Data ) P.Dispose(); CL = null; BS = null; Data = null; } catch ( Exception ) { } }
protected override IEnumerable<ActiveItem> Filter( IEnumerable<ActiveItem> Items ) { if ( Items != null && FavOnly ) { string[] ids = new BookStorage().GetIdList(); Items = Items.Where( x => ids.Contains( ( x as LocalBook ).aid ) ); } return base.Filter( Items ); }
public async Task ToggleFavs() { if ( !FavOnly ) { BookStorage BS = new BookStorage(); string[] BookIds = BS.GetIdList(); List<ActiveItem> SS = new List<ActiveItem>(); foreach ( string Id in BookIds ) { if ( Data != null && Data.Any( x => ( x as LocalBook ).aid == Id ) ) { continue; } LocalBook LB = await LocalBook.CreateAsync( Id ); if ( !( LB.CanProcess || LB.ProcessSuccess ) ) { XParameter Param = BS.GetBook( Id ); LB.Name = Param.GetValue( AppKeys.GLOBAL_NAME ); LB.Desc = "Source is unavailable"; LB.CanProcess = false; } LB.IsFav = true; SS.Add( LB ); } if ( 0 < SS.Count ) { if ( Data == null ) Data = SS; else Data = Data.Concat( SS ); } FavOnly = true; } else { FavOnly = false; if ( Data != null ) { Data = Data.Where( x => { LocalBook LB = x as LocalBook; if ( LB.IsFav ) return LB.ProcessSuccess || LB.Processing || LB.CanProcess; return true; } ); } } NotifyChanged( "SearchSet" ); }
private async void ProcessVols() { StringResources stx = new StringResources( "LoadingMessage" ); string LoadText = stx.Str( "ProgressIndicator_Message" ); IEnumerable<string> BookIds = Shared.Storage.ListDirs( FileLinks.ROOT_LOCAL_VOL ); string[] favs = new BookStorage().GetIdList(); List<LocalBook> Items = new List<LocalBook>(); foreach ( string Id in BookIds ) { Loading = LoadText + ": " + Id; LocalBook LB = await LocalBook.CreateAsync( Id ); if ( LB.ProcessSuccess ) { Items.Add( LB ); LB.IsFav = favs.Contains( Id ); } } Action<string, SpiderBook> ProcessSpider = ( Id, LB ) => { Loading = LoadText + ": " + Id; if ( LB.aid != Id ) { try { Logger.Log( ID, "Fixing misplaced spider book" ); Shared.Storage.MoveDir( FileLinks.ROOT_SPIDER_VOL + Id, LB.MetaLocation ); } catch ( Exception ex ) { Logger.Log( ID , string.Format( "Unable to move script: {0} => {1}, {2} " , Id, LB.aid, ex.Message ) , LogType.WARNING ); } } if ( LB.ProcessSuccess || LB.CanProcess ) { Items.Add( LB ); LB.IsFav = favs.Contains( Id ); } else { try { Logger.Log( ID, "Removing invalid script: " + Id, LogType.INFO ); Shared.Storage.RemoveDir( LB.MetaRoot ); } catch ( Exception ex ) { Logger.Log( ID, "Cannot remove invalid script: " + ex.Message, LogType.WARNING ); } } }; BookIds = Shared.Storage.ListDirs( FileLinks.ROOT_SPIDER_VOL ); foreach ( string Id in BookIds ) { if ( Id[ 0 ] == ZONE_PFX ) { IEnumerable<string> ZoneItems = Shared.Storage.ListDirs( FileLinks.ROOT_SPIDER_VOL + Id + "/" ); foreach ( string SId in ZoneItems ) { /** * This code is a mess. I'll explain a bit more in here * First, the location of the Book.MetaLocation for ZoneItems * can only be retrived from BookInstruction * However ZoneId and Id are assinged by Spider on the fly, * restoring this information is a bit tricky */ // Create BookIntstruction just to retrieve the correct id pattern BookInstruction BInst = new BookInstruction( Id, SId ); /** * After 2 hours of investigations... * Welp, just outsmarted by myself, The CreateAsyncSpide works because: * Inside the TestProcessed method, the BookInstruction are created * using BoockInstruction( Id, Setings ) overload * the provided id is "this.aid" here BUT the full id is restored again * in InitProcMan() method * Fortunately, ssid will be set correctly inside the ReadInfo method */ ProcessSpider( BInst.Id, await SpiderBook.CreateAsyncSpider( BInst.Id ) ); } } else { ProcessSpider( Id, await SpiderBook.CreateAsyncSpider( Id ) ); } } if ( 0 < Items.Count ) SearchSet = Items; Loading = null; }
private void LSSync( object sender, RoutedEventArgs e ) { BookStorage BS = new BookStorage(); ( ( OneDriveButton ) sender ).SetSync( BS.SyncSettings ); }
private void AddOrRemoveFav( object sender, TappedRoutedEventArgs e ) { BookItem B = ( ( sender as FrameworkElement ).DataContext ) as BookItem; BookStorage BS = new BookStorage(); if ( B.IsFav ) { BS.RemoveBook( B.Id ); B.IsFav = false; } else { BS.SaveBook( B.Id, B.Title, B.RecentUpdateRaw, B.LatestSection ); B.IsFav = true; } }