Example #1
0
 public ApiRequest(IRequestInfo requestinfo, CollectionSettings currentCollectionSettings, Book.Book currentBook)
 {
     _requestInfo = requestinfo;
     CurrentCollectionSettings = currentCollectionSettings;
     CurrentBook = currentBook;
     Parameters = requestinfo.GetQueryParameters();
 }
        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;
        }
Example #3
0
        private void HandleOneReadyDeviceFound(Book.Book book, Color backColor, AndroidPublishSettings settings = null)
        {
            _progress.MessageWithParams(idSuffix: "Connected",
                                        message: "Connected to {0} via USB...",
                                        comment: "{0} is a the name of the device Bloom connected to",
                                        progressKind: ProgressKind.Progress,
                                        parameters: _androidDeviceUsbConnection.GetDeviceName());

            SendBookAsync(book, backColor, settings);
        }
Example #4
0
        private static void UpdateToolState(Book.Book book, string toolName, string state)
        {
            var tools = book.BookInfo.Tools;
            var item  = tools.FirstOrDefault(t => t.ToolId == toolName);

            if (item != null)
            {
                item.State = state;
            }
        }
Example #5
0
 public Book.Book LoadBookIfNeeded()
 {
     if (_currentlyLoadedBook != BookSelection.CurrentSelection)
     {
         _currentlyLoadedBook = BookSelection.CurrentSelection;
         // In case we have any new settings since the last time we were in the Edit tab (BL-3881)
         _currentlyLoadedBook.BringBookUpToDate(new NullProgress());
     }
     return(_currentlyLoadedBook);
 }
 /// <summary>
 /// Generates a web thumbnail image from the book's front cover image.
 /// The resulting image will fit into a 200px x 200px box with no loss of aspect ratio.
 /// This means that either the height or the width will be 200px.
 /// </summary>
 /// <param name="book"></param>
 public static void GenerateImageForWeb(Book.Book book)
 {
     HtmlThumbNailer.ThumbnailOptions options = new HtmlThumbNailer.ThumbnailOptions
     {
         Height = 200,
         Width  = 200,
         CenterImageUsingTransparentPadding = false,
         FileName = "coverImage200.jpg"
     };
     CreateThumbnailOfCoverImage(book, options);
 }
Example #7
0
 public static void RemoveEnterpriseFeaturesIfNeeded(Book.Book book, List <XmlElement> pageElts, ISet <string> warningMessages)
 {
     if (RemoveEnterprisePagesIfNeeded(book.BookData, book.Storage.Dom, pageElts))
     {
         warningMessages.Add(LocalizationManager.GetString("Publish.RemovingEnterprisePages", "Removing one or more pages which require Bloom Enterprise to be enabled"));
     }
     if (!book.CollectionSettings.HaveEnterpriseFeatures)
     {
         RemoveEnterpriseOnlyAssets(book);
     }
 }
Example #8
0
 private void StartSendBookOverWiFi(Book.Book book, string androidIpAddress, string androidName, Color backColor)
 {
     try
     {
         StartSendBookToClientOnLocalSubNet(book, androidIpAddress, androidName, backColor);
     }
     catch (Exception e)
     {
         ReportException(e);
     }
 }
        /// <summary>
        /// Return an error for every textbox that is missing some text
        /// </summary>
        /// <returns>returns an enumerator of strings describing any problems it finds</returns>
        public static IEnumerable <Problem> CheckAudioForAllText(Book.Book book)
        {
            var messageTemplate = L10NSharp.LocalizationManager.GetString("AccessibilityCheck.AudioForAllText.MissingOnPage",
                                                                          "Some text is missing a recording on page {0}",
                                                                          "The {0} is where the page number will be inserted.");

            foreach (var p in InnerCheckAudio(book, messageTemplate, "not(contains(@class, 'bloom-imageDescription'))"))
            {
                yield return(p);
            }
        }
Example #10
0
        private static List <ToolboxTool> GetToolsToDisplay(Book.Book book, string[] idsOfToolsThisVersionKnowsAbout)
        {
            var toolsThatHaveDataInBookInfo =
                book.BookInfo.Tools.Where(t => idsOfToolsThisVersionKnowsAbout.Contains(t.ToolId)).ToList();
            var toolsToDisplay = toolsThatHaveDataInBookInfo;

            toolsToDisplay.AddRange(
                idsOfToolsThisVersionKnowsAbout.Except(
                    toolsThatHaveDataInBookInfo.Select(t => t.ToolId)).Select(ToolboxTool.CreateFromToolId));
            return(toolsToDisplay.Where(t => t.Enabled || t.AlwaysEnabled).ToList());
        }
Example #11
0
 public bool ReturnBook(Book.Book b)
 {
     if (books.Contains(b.Title))
     {
         books.Remove(b.Title);
         return(true);
     }
     else
     {
         return(false);
     }
 }
Example #12
0
        private static void UpdateActiveToolSetting(Book.Book book, string toolName, bool enabled)
        {
            var tools = book.BookInfo.Tools;
            var item  = tools.FirstOrDefault(t => t.ToolId == toolName);

            if (item == null)
            {
                item = ToolboxToolState.CreateFromToolId(toolName);
                tools.Add(item);
            }
            item.Enabled = enabled;
        }
Example #13
0
        /// <summary>
        /// Common routine used in normal upload and bulk upload.
        /// </summary>
        /// <param name="book"></param>
        /// <param name="progressBox"></param>
        /// <param name="publishView"></param>
        /// <param name="languages"></param>
        /// <param name="parseId"></param>
        /// <param name="excludeAudio"></param>
        /// <returns></returns>
        internal string FullUpload(Book.Book book, LogBox progressBox, PublishView publishView, string[] languages, out string parseId, bool excludeAudio = true)
        {
            var bookFolder = book.FolderPath;

            parseId = "";             // in case of early return
            // Set this in the metadata so it gets uploaded. Do this in the background task as it can take some time.
            // These bits of data can't easily be set while saving the book because we save one page at a time
            // and they apply to the book as a whole.
            book.BookInfo.LanguageTableReferences = _parseClient.GetLanguagePointers(book.CollectionSettings.MakeLanguageUploadData(languages));
            book.BookInfo.PageCount = book.GetPages().Count();
            book.BookInfo.Save();
            progressBox.WriteStatus(LocalizationManager.GetString("PublishTab.Upload.MakingThumbnail", "Making thumbnail image..."));
            //the largest thumbnail I found on Amazon was 300px high. Prathambooks.org about the same.
            _thumbnailer.MakeThumbnailOfCover(book, 70);             // this is a sacrificial one to prime the pump, to fix BL-2673
            _thumbnailer.MakeThumbnailOfCover(book, 70);
            if (progressBox.CancelRequested)
            {
                return("");
            }
            _thumbnailer.MakeThumbnailOfCover(book, 256);
            if (progressBox.CancelRequested)
            {
                return("");
            }

            // It is possible the user never went back to the Collection tab after creating/updating the book, in which case
            // the 'normal' thumbnail never got created/updating. See http://issues.bloomlibrary.org/youtrack/issue/BL-3469.
            _thumbnailer.MakeThumbnailOfCover(book);
            if (progressBox.CancelRequested)
            {
                return("");
            }

            var uploadPdfPath = UploadPdfPath(bookFolder);

            // If there is not already a locked preview in the book folder
            // (which we take to mean the user has created a customized one that he prefers),
            // make sure we have a current correct preview and then copy it to the book folder so it gets uploaded.
            if (!FileUtils.IsFileLocked(uploadPdfPath))
            {
                progressBox.WriteStatus(LocalizationManager.GetString("PublishTab.Upload.MakingPdf", "Making PDF Preview..."));
                publishView.MakePublishPreview();
                if (RobustFile.Exists(publishView.PdfPreviewPath))
                {
                    RobustFile.Copy(publishView.PdfPreviewPath, uploadPdfPath, true);
                }
            }
            if (progressBox.CancelRequested)
            {
                return("");
            }
            return(UploadBook(bookFolder, progressBox, out parseId, Path.GetFileName(uploadPdfPath), excludeAudio));
        }
Example #14
0
        public bool DeleteBook(Book.Book book, BookCollection collection = null)
        {
            if (collection == null)
            {
                collection = TheOneEditableCollection;
            }
            Debug.Assert(book.FolderPath == _bookSelection.CurrentSelection?.FolderPath);

            if (_bookSelection.CurrentSelection != null && _bookSelection.CurrentSelection.CanDelete)
            {
                if (IsCurrentBookInCollection())
                {
                    if (!_bookSelection.CurrentSelection.IsSaveable)
                    {
                        var msg = LocalizationManager.GetString("TeamCollection.CheckOutForDelete",
                                                                "Please check out the book before deleting it.");
                        ErrorReport.NotifyUserOfProblem(msg);
                        return(false);
                    }

                    if (_tcManager.CannotDeleteBecauseDisconnected(_bookSelection.CurrentSelection.FolderPath))
                    {
                        var msg = LocalizationManager.GetString("TeamCollection.ConnectForDelete",
                                                                "Please connect to the Team Collection before deleting books that are part of it.");
                        ErrorReport.NotifyUserOfProblem(msg);
                        return(false);
                    }
                }
                var bookName = _bookSelection.CurrentSelection.NameBestForUserDisplay;
                var confirmRecycleDescription = L10NSharp.LocalizationManager.GetString("CollectionTab.ConfirmRecycleDescription", "The book '{0}'");
                if (ConfirmRecycleDialog.JustConfirm(string.Format(confirmRecycleDescription, bookName), false, "Palaso"))
                {
                    // The sequence of these is a bit arbitrary. We'd like to delete the book in both places.
                    // Either could conceivably fail. If something goes wrong with removing the selection
                    // from it (very unlikely), we may as well leave nothing changed. If we delete it from
                    // the local collection but fail to delete it from the repo, it will come back at the
                    // next startup. If we delete it from the repo but fail to delete it locally,
                    // it will just stick around, and at least the desired team collection result has
                    // been achieved and the local result won't be a surprise later. So it seems marginally
                    // better to do them in this order.
                    _bookSelection.SelectBook(null);
                    if (collection == TheOneEditableCollection)
                    {
                        _tcManager.CurrentCollection?.DeleteBookFromRepo(book.FolderPath);
                    }
                    collection.DeleteBook(book.BookInfo);
                    return(true);
                }
            }
            return(false);
        }
Example #15
0
        /// <summary>
        /// Conditionally exclude .mp3 files for narration and music.
        /// Always exclude .wav files for narration.
        /// </summary>
        private static ISet <string> GetAudioFilesToInclude(Book.Book book, bool excludeNarrationAudio, bool excludeMusic)
        {
            HashSet <string> result = new HashSet <string>();

            if (!excludeNarrationAudio)
            {
                result.AddRange(book.Storage.GetNarrationAudioFileNamesReferencedInBook(false));
            }
            if (!excludeMusic)
            {
                result.AddRange(book.Storage.GetBackgroundMusicFileNamesReferencedInBook());
            }
            return(result);
        }
Example #16
0
        public void UpdateLabelOfBookInEditableCollection(Book.Book book)
        {
            // We can find a more efficient way to do this if necessary.
            //ReloadEditableCollection();
            // This allows it to get resorted. Is that good? It may move dramatically, even disappear from the screen.
            TheOneEditableCollection.UpdateBookInfo(book.BookInfo);
            // This actually changes the label. (One would think that re-rendering the collection would do this,
            // but somehow the way we are caching the book title as state in anticipation of the following
            // message was preventing this. It might be redundant now.)
            BookCommandsApi.UpdateButtonTitle(_webSocketServer, book.BookInfo, book.NameBestForUserDisplay);

            // happens as a side effect
            //_webSocketServer.SendEvent("editableCollectionList", "reload:" + _bookCollections[0].PathToDirectory);
        }
Example #17
0
        public void ShowExportToSpreadsheetUI(Book.Book book)
        {
            // Throw up a Requires Bloom Enterprise dialog if it's not turned on
            if (!_collectionModel.CollectionSettings.HaveEnterpriseFeatures)
            {
                Enterprise.ShowRequiresEnterpriseNotice(Form.ActiveForm, "Export to Spreadsheet");
                return;
            }

            dynamic messageBundle = new DynamicJson();

            messageBundle.folderPath = GetSpreadsheetFolderFor(book, true);
            _webSocketServer.LaunchDialog("SpreadsheetExportDialog", messageBundle);
        }
Example #18
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     = options.XMatter,
                Language1Iso639Code = options.VernacularIsoCode,
                Language2Iso639Code = string.IsNullOrWhiteSpace(options.NationalLanguage1IsoCode) ? options.VernacularIsoCode : 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(), new BookSavedEvent());

            //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);
        }
Example #19
0
        private IBook ConvertJsonBook(BookJson bookJson)
        {
            IBook book = new Book.Book(bookJson.Title);

            foreach (var item in bookJson.Paragraphs)
            {
                IParagraph paragraph = new Paragraph.Paragraph(item.Id, item.Label, item.ColorStart, item.ColorEnd);
                foreach (var answer in item.Answers)
                {
                    paragraph.AddAnswer(new Answer.Answer(answer.Label, answer.Id));
                }
                book.AddParagraph(paragraph);
            }
            return(book);
        }
Example #20
0
 private void HandleBringBookUpToDate(Book.Book book)
 {
     try
     {
         // Currently this works on the current book, so the argument is ignored.
         // That's OK for now as currently the book passed will always be the current one.
         _collectionModel.BringBookUpToDate();
     }
     catch (Exception error)
     {
         var msg = LocalizationManager.GetString("Errors.ErrorUpdating",
                                                 "There was a problem updating the book.  Restarting Bloom may fix the problem.  If not, please report the problem to us.");
         ErrorReport.NotifyUserOfProblem(error, msg);
     }
 }
        /// <summary>
        /// Attempt to establish a connection with a device which has the Bloom Reader app,
        /// then send it the book.
        /// </summary>
        public void ConnectAndSendToOneDevice(Book.Book book, Color backColor)
        {
            _stopLookingForDevice = false;
            _device = null;

            //The UX here is to only allow one device plugged in a time.
            while (!_stopLookingForDevice && _device == null)
            {
                var devices = EnumerateAllDevices();
                if (!ConnectAndSendToOneDeviceInternal(devices, book, backColor))
                {
                    Thread.Sleep(1000);
                }
            }
        }
Example #22
0
        public bool AddBook(Book.Book b)
        {
            if (books.Contains(b.Title))
            {
                return(false);
            }
            else
            {
                books.Add(b.Title);
                return(true);
            }


            return(true);
        }
Example #23
0
        /// <summary>
        /// Attempt to connect to a device
        /// </summary>
        /// <param name="book"></param>
        public void Connect(Book.Book book, Color backColor)
        {
            try
            {
                // Calls to this come from JavaScript, not sure they will always be on the UI thread.
                // Before I added this, I definitely saw race conditions with more than one thread trying
                // to figure out what was connected.
                lock (this)
                {
                    AndroidView.CheckBookLayout(book, _progress);
                    if (_connectionHandler != null)
                    {
                        // we're in an odd state...should only be able to click the button that calls this
                        // while stopped.
                        // Try to really get into the right state in case the user tries again.
                        _androidDeviceUsbConnection.StopFindingDevice();
                        return;
                    }
                    // Create this while locked...once we have it, can't enter the main logic of this method
                    // on another thread.
                    _connectionHandler = new BackgroundWorker();
                }
                _progress.Message(id: "LookingForDevice",
                                  message: "Looking for an Android device connected by USB cable and set up for MTP...",
                                  comment: "This is a progress message; MTP is an acronym for the system that allows computers to access files on devices.");

                _androidDeviceUsbConnection.OneReadyDeviceFound    = HandleFoundAReadyDevice;
                _androidDeviceUsbConnection.OneReadyDeviceNotFound = HandleFoundOneNonReadyDevice;
                // Don't suppress the first message after (re)starting.
                _previousDeviceNotFoundReportType = DeviceNotFoundReportType.Unknown;


                _connectionHandler.DoWork             += (sender, args) => _androidDeviceUsbConnection.ConnectAndSendToOneDevice(book, backColor);
                _connectionHandler.RunWorkerCompleted += (sender, args) =>
                {
                    if (args.Error != null)
                    {
                        UsbFailConnect(args.Error);
                    }
                    _connectionHandler = null;                     // now OK to try to connect again.
                };
                _connectionHandler.RunWorkerAsync();
            }
            catch (Exception e)
            {
                UsbFailConnect(e);
            }
        }
        private void GetThumbNailOfBookCover(Book.Book book, HtmlThumbNailer.ThumbnailOptions thumbnailOptions, Action <Image> callback, Action <Exception> errorCallback, bool async)
        {
            if (book is ErrorBook)
            {
                callback(Resources.Error70x70);
                return;
            }
            try
            {
                if (book.HasFatalError)                 //NB: we might not know yet... we don't fully load every book just to show its thumbnail
                {
                    callback(Resources.Error70x70);
                    return;
                }
                GenerateImageForWeb(book);

                Image thumb;
                if (book.Storage.TryGetPremadeThumbnail(thumbnailOptions.FileName, out thumb))
                {
                    callback(thumb);
                    return;
                }

#if USE_HTMLTHUMBNAILER_FOR_COVER
                var dom = book.GetPreviewXmlDocumentForFirstPage();
                if (dom == null)
                {
                    callback(Resources.Error70x70);
                    return;
                }
                string folderForCachingThumbnail;

                folderForCachingThumbnail = book.StoragePageFolder;
                _thumbnailProvider.GetThumbnail(folderForCachingThumbnail, book.Storage.Key, dom, thumbnailOptions, callback, errorCallback, async);
#else
                if (!CreateThumbnailOfCoverImage(book, thumbnailOptions, callback))
                {
                    callback(Resources.Error70x70);
                }
#endif
            }
            catch (Exception err)
            {
                callback(Resources.Error70x70);
                errorCallback(err);
                Debug.Fail(err.Message);
            }
        }
Example #25
0
        private void OnBookSelectionChanged(object sender, EventArgs e)
        {
            //prevent trying to save this page in whatever comes next
            var wasNull = _domForCurrentPage == null;

            _domForCurrentPage      = null;
            _currentlyDisplayedBook = null;
            if (Visible)
            {
                _view.ClearOutDisplay();
                if (!wasNull)
                {
                    _view.UpdatePageList(false);
                }
            }
        }
Example #26
0
 // internal virtual for testing only
 protected virtual void SendBookDoWork(Book.Book book, Color backColor)
 {
     PublishToAndroidApi.SendBook(book, _bookServer,
                                  null, (publishedFileName, path) =>
     {
         _lastPublishedBloomdSize = GetSizeOfBloomdFile(path);
         _androidDeviceUsbConnection.SendBook(path);
     },
                                  _progress,
                                  (publishedFileName, bookTitle) =>
                                  _androidDeviceUsbConnection.BookExists(publishedFileName) ?
                                  _progress.GetTitleMessage("ReplacingBook", "Replacing existing \"{0}\"...", bookTitle) :
                                  _progress.GetTitleMessage("SendingBook", "Sending \"{0}\" to your Android device...", bookTitle),
                                  publishedFileName => _androidDeviceUsbConnection.BookExists(publishedFileName),
                                  backColor);
     PublishToAndroidApi.ReportAnalytics("usb", book);
 }
Example #27
0
        public static void DoClient(TcpClient socket)
        {
            Stream       ns = socket.GetStream();
            StreamReader sr = new StreamReader(ns);
            StreamWriter sw = new StreamWriter(ns);

            sw.AutoFlush = true;

            string message = sr.ReadLine();
            string answer  = "";


            while (message != null && message != "")
            {
                string[] messageArray = message.Split(' ');
                string   param        = message.Substring(message.IndexOf(' ') + 1);
                string   command      = messageArray[0];

                switch (command)
                {
                case "GetAll":
                    sw.WriteLine("Get all recieved");
                    sw.WriteLine(JsonConvert.SerializeObject(books));
                    break;

                case "Get":
                    sw.WriteLine("Get request recieved - Isbn " + messageArray[1] + "requested");
                    sw.WriteLine(JsonConvert.SerializeObject(books.Find(id => id.ISBN13 == param)));
                    break;

                case "Save":
                    sw.WriteLine("Save recieved");
                    Book.Book saveBook = JsonConvert.DeserializeObject <Book.Book>(param);
                    books.Add(saveBook);
                    break;

                default:
                    sw.WriteLine("Den er gal");
                    break;
                }
                message = sr.ReadLine();
            }

            ns.Close();
            socket.Close();
        }
Example #28
0
        public static void RemoveEnterpriseFeaturesIfNeeded(Book.Book book, List <XmlElement> pageElts, ISet <string> warningMessages)
        {
            var omittedPages = RemoveEnterprisePagesIfNeeded(book.BookData, book.Storage.Dom, pageElts);

            if (omittedPages.Count > 0)
            {
                warningMessages.Add(LocalizationManager.GetString("Publish.RemovingEnterprisePages", "Removing one or more pages which require Bloom Enterprise to be enabled"));
                foreach (var label in omittedPages.Keys.OrderBy(x => x))
                {
                    warningMessages.Add($"{omittedPages[label]} {label}");
                }
            }
            if (!book.CollectionSettings.HaveEnterpriseFeatures)
            {
                RemoveEnterpriseOnlyAssets(book);
            }
        }
        public bool DeleteBook(Book.Book book)        //, BookCollection collection)
        {
            Debug.Assert(book == _bookSelection.CurrentSelection);

            if (_bookSelection.CurrentSelection != null && _bookSelection.CurrentSelection.CanDelete)
            {
                var title = _bookSelection.CurrentSelection.TitleBestForUserDisplay;
                var confirmRecycleDescription = L10NSharp.LocalizationManager.GetString("CollectionTab.ConfirmRecycleDescription", "The book '{0}'");
                if (ConfirmRecycleDialog.JustConfirm(string.Format(confirmRecycleDescription, title), false, "Palaso"))
                {
                    TheOneEditableCollection.DeleteBook(book.BookInfo);
                    _bookSelection.SelectBook(null);
                    _sendReceiver.CheckInNow(string.Format("Deleted '{0}'", title));
                    return(true);
                }
            }
            return(false);
        }
        /// <summary>
        /// Make a thumbnail image of a book's front cover.
        /// </summary>
        /// <param name="book"></param>
        /// <param name="height">Optional parameter. If unspecified, use defaults</param>
        public void MakeThumbnailOfCover(Book.Book book, int height = -1)
        {
            HtmlThumbNailer.ThumbnailOptions options = new HtmlThumbNailer.ThumbnailOptions
            {
                //since this is destined for HTML, it's much easier to handle if there is no pre-padding
                CenterImageUsingTransparentPadding = false
            };

            if (height != -1)
            {
                options.Height   = height;
                options.Width    = -1;
                options.FileName = "thumbnail-" + height + ".png";
            }
            // else use the defaults

            RebuildThumbNailNow(book, options);
        }
Example #31
0
        /// <summary>
        /// This is our primary entry point for importing from a spreadsheet. There is also a CLI command,
        /// but we shouldn't need that one much, now that we have this on our book thumb context menus.
        /// </summary>
        public void HandleImportContentFromSpreadsheet(Book.Book book)
        {
            if (!_collectionModel.CollectionSettings.HaveEnterpriseFeatures)
            {
                Enterprise.ShowRequiresEnterpriseNotice(Form.ActiveForm, "Import to Spreadsheet");
                return;
            }

            var bookPath = book.GetPathHtmlFile();

            try
            {
                string inputFilepath;
                using (var dlg = new DialogAdapters.OpenFileDialogAdapter())
                {
                    dlg.Filter           = "xlsx|*.xlsx";
                    dlg.RestoreDirectory = true;
                    dlg.InitialDirectory = GetSpreadsheetFolderFor(book, false);
                    if (DialogResult.Cancel == dlg.ShowDialog())
                    {
                        return;
                    }
                    inputFilepath = dlg.FileName;
                    var spreadsheetFolder = Path.GetDirectoryName(inputFilepath);
                    SetSpreadsheetFolder(book, spreadsheetFolder);
                }

                var importer = new SpreadsheetImporter(_webSocketServer, book, Path.GetDirectoryName(inputFilepath));
                importer.ImportWithProgress(inputFilepath);

                // The importer now does BringBookUpToDate() which accomplishes everything this did,
                // plus it may have actually changed the folder (and subsequent 'bookPath')
                // due to a newly imported title. That would cause this call to fail.
                //XmlHtmlConverter.SaveDOMAsHtml5(book.OurHtmlDom.RawDom, bookPath);
                book.ReloadFromDisk(null);
                BookHistory.AddEvent(book, TeamCollection.BookHistoryEventType.ImportSpreadsheet);
                _bookSelection.InvokeSelectionChanged(false);
            }
            catch (Exception ex)
            {
                var msg = LocalizationManager.GetString("Spreadsheet:ImportFailed", "Import failed: ");
                NonFatalProblem.Report(ModalIf.All, PassiveIf.None, msg + ex.Message, exception: ex, showSendReport: false);
            }
        }
Example #32
0
        // intended to be private except for WebThumnailList
        internal IPage PageFromId(string id)
        {
            lock (_currentBookPages)
            {
                if (_pagesBook != CurrentBook)
                {
                    _currentBookPages.Clear();
                    _pagesBook = CurrentBook;
                    foreach (var page in _pagesBook.GetPages())
                    {
                        _currentBookPages[page.Id] = page;
                    }
                }

                IPage result;
                _currentBookPages.TryGetValue(id, out result);
                return(result);
            }
        }
Example #33
0
        public void ViewVisibleNowDoSlowStuff()
        {
            if(_currentlyDisplayedBook != CurrentBook)
            {
                CurrentBook.PrepareForEditing();
            }

            _currentlyDisplayedBook = CurrentBook;

            var errors = _currentlyDisplayedBook.GetErrorsIfNotCheckedBefore();
            if (!string.IsNullOrEmpty(errors))
            {
                ErrorReport.NotifyUserOfProblem(errors);
                return;
            }

            // BL-2339: try to choose the last edited page
            var page = _currentlyDisplayedBook.GetPageByIndex(_currentlyDisplayedBook.UserPrefs.MostRecentPage) ?? _currentlyDisplayedBook.FirstPage;
            try
            {
                _inProcessOfLoading = true;
                if (page != null)
                    _pageSelection.SelectPage(page);

                if (_view != null)
                {
                    _view.UpdatePageList(false);
                }
            }
            finally
            {
                _inProcessOfLoading = false;
            }
        }
Example #34
0
        public void LoadBook(BackgroundWorker worker, DoWorkEventArgs doWorkEventArgs)
        {
            _currentlyLoadedBook = BookSelection.CurrentSelection;

            try
            {
                // In case we have any new settings since the last time we were in the Edit tab (BL-3881)
                _currentlyLoadedBook.BringBookUpToDate(new NullProgress());

                using(var tempHtml = MakeFinalHtmlForPdfMaker())
                {
                    if (doWorkEventArgs.Cancel)
                        return;

                    BookletLayoutMethod layoutMethod;
                    if (this.BookletPortion == BookletPortions.AllPagesNoBooklet)
                        layoutMethod = BookletLayoutMethod.NoBooklet;
                    else
                        layoutMethod = BookSelection.CurrentSelection.GetDefaultBookletLayout();

                    // Check memory for the benefit of developers.  The user won't see anything.
                    SIL.Windows.Forms.Reporting.MemoryManagement.CheckMemory(true, "about to create PDF file", false);
                    _pdfMaker.MakePdf(tempHtml.Key, PdfFilePath, PageLayout.SizeAndOrientation.PageSizeName,
                        PageLayout.SizeAndOrientation.IsLandScape, _currentlyLoadedBook.UserPrefs.ReducePdfMemoryUse,
                        LayoutPagesForRightToLeft, layoutMethod, BookletPortion, worker, doWorkEventArgs, View);
                    // Warn the user if we're starting to use too much memory.
                    SIL.Windows.Forms.Reporting.MemoryManagement.CheckMemory(false, "finished creating PDF file", true);
                }
            }
            catch (Exception e)
            {
                //we can't safely do any ui-related work from this thread, like putting up a dialog
                doWorkEventArgs.Result = e;
                //                SIL.Reporting.ErrorReport.NotifyUserOfProblem(e, "There was a problem creating a PDF from this book.");
                //                SetDisplayMode(DisplayModes.WaitForUserToChooseSomething);
                //                return;
            }
        }
Example #35
0
        public void ViewVisibleNowDoSlowStuff()
        {
            if(_currentlyDisplayedBook != CurrentBook)
            {
                CurrentBook.PrepareForEditing();
            }

            _currentlyDisplayedBook = CurrentBook;

            var errors = _bookSelection.CurrentSelection.GetErrorsIfNotCheckedBefore();
            if (!string.IsNullOrEmpty(errors))
            {
                Palaso.Reporting.ErrorReport.NotifyUserOfProblem(errors);
                return;
            }
            var page = _bookSelection.CurrentSelection.FirstPage;
            if (page != null)
                _pageSelection.SelectPage(page);

            if (_view != null)
            {
                if(ShowTemplatePanel)
                {
                    _view.UpdateTemplateList();
                }
                _view.UpdatePageList(false);
            }
        }
Example #36
0
 private void OnBookSelectionChanged(object sender, EventArgs e)
 {
     //prevent trying to save this page in whatever comes next
     var wasNull = _domForCurrentPage == null;
     _domForCurrentPage = null;
     _currentlyDisplayedBook = null;
     if (Visible)
     {
         _view.ClearOutDisplay();
         if (!wasNull)
             _view.UpdatePageList(false);
     }
 }
 public ProblemReporterDialog(Control targetOfScreenshot, BookSelection bookSelection)
     : this(targetOfScreenshot)
 {
     Book = bookSelection.CurrentSelection;
 }
        public BloomLibraryPublishControl(PublishView parentView, BookTransfer bookTransferrer, LoginDialog login, Book.Book book)
        {
            _parentView = parentView;
            _bookTransferrer = bookTransferrer;
            _loginDialog = login;
            _book = book;
            InitializeComponent();
            _originalLoginText = _loginLink.Text; // Before anything might modify it (but after InitializeComponent creates it).
            _titleLabel.Text = book.BookInfo.Title;

            _progressBox.ShowDetailsMenuItem = true;
            _progressBox.ShowCopyToClipboardMenuItem = true;
            _progressBox.LinkClicked += _progressBox_LinkClicked;

            var metadata = book.GetLicenseMetadata();
            // This is usually redundant, but might not be on old books where the license was set before the new
            // editing code was written.
            book.SetMetadata(metadata);
            var license = metadata.License;
            if (license == null || (license is NullLicense && string.IsNullOrWhiteSpace(metadata.CopyrightNotice)))
            {
                // A null license and no copyright indicates they never even opened the ClearShare dialog to choose a license.
                _usingCcControls = false;
                _usingNotesLabel = false;
                _licenseSuggestion.Text = _pleaseSetThis;
                _okToUpload = false;
            }
            else if (license is CreativeCommonsLicense)
            {
                _creativeCommonsLink.Text = license.Token.ToUpperInvariant();
                _usingNotesSuggestion = false;
                if (string.IsNullOrWhiteSpace(license.RightsStatement))
                {
                    _licenseNotesLabel.Hide();
                }
                else
                {
                    _licenseNotesLabel.Text = LocalizationManager.GetString("PublishTab.Upload.AdditionalRequests", "Additional Requests: ") + license.RightsStatement;
                }
            }
            else if (license is NullLicense)
            {
                _usingCcControls = false;
                _licenseNotesLabel.Text = LocalizationManager.GetString("PublishTab.Upload.AllReserved", "All rights reserved (Contact the Copyright holder for any permissions.)");
                if (!string.IsNullOrWhiteSpace(license.RightsStatement))
                {
                    _licenseNotesLabel.Text += Environment.NewLine + license.RightsStatement;
                }
                _licenseSuggestion.Text = LocalizationManager.GetString("PublishTab.Upload.SuggestAssignCC", "Suggestion: Assigning a Creative Commons License makes it easy for you to clearly grant certain permissions to everyone.");

            }
            else
            {
                // So far, this means it must be custom license (with non-blank rights...actually, currently, the palaso dialog will not allow a custom license with no rights statement).
                _usingCcControls = false;
                _licenseNotesLabel.Text = license.RightsStatement;
                _licenseSuggestion.Text = LocalizationManager.GetString("PublishTab.Upload.SuggestChangeCC", "Suggestion: Creative Commons Licenses make it much easier for others to use your book, even if they aren't fluent in the language of your custom license.");
            }

            _copyrightLabel.Text = book.BookInfo.Copyright;

            var allLanguages = book.AllLanguages;
            foreach (var lang in allLanguages.Keys)
            {
                var checkBox = new CheckBox();
                checkBox.Text = _book.PrettyPrintLanguage(lang);
                if (allLanguages[lang])
                    checkBox.Checked = true;
                else
                {
                    checkBox.Text += @" " + LocalizationManager.GetString("PublishTab.Upload.Partial", "(partial)");
                }
                checkBox.Size = new Size(TextRenderer.MeasureText(checkBox.Text, checkBox.Font).Width + 50, checkBox.Height);
                checkBox.Tag = lang;
                checkBox.CheckStateChanged += delegate(object sender, EventArgs args)
                {
                    bool someLangChecked = _languagesFlow.Controls.Cast<CheckBox>().Any(b => b.Checked);
                    _langsLabel.ForeColor = someLangChecked ? Color.Black : Color.Red;
                    if (_okToUploadDependsOnLangsChecked)
                    {
                        _okToUpload = someLangChecked;
                        UpdateDisplay();
                    }
                };
                _languagesFlow.Controls.Add(checkBox);
            }

            _creditsLabel.Text = book.BookInfo.Credits;
            _summaryBox.Text = book.BookInfo.Summary;

            try
            {
                _loginDialog.LogIn(); // See if saved credentials work.
            }
            catch (Exception e)
            {
                SIL.Reporting.ErrorReport.NotifyUserOfProblem(e,
                    LocalizationManager.GetString("PublishTab.Upload.LoginFailure",
                        "Bloom could not log in to BloomLibrary.org using your saved credentials. Please check your network connection."));
            }
            _optional1.Left = _summaryBox.Right - _optional1.Width; // right-align these (even if localization changes their width)
            RequireValue(_copyrightLabel);
            RequireValue(_titleLabel);

            if (BookTransfer.UseSandbox)
            {
                var oldTextWidth = TextRenderer.MeasureText(_uploadButton.Text, _uploadButton.Font).Width;
                _uploadButton.Text = LocalizationManager.GetString("PublishTab.Upload.UploadSandbox","Upload Book (to Sandbox)");
                var neededWidth = TextRenderer.MeasureText(_uploadButton.Text, _uploadButton.Font).Width;
                _uploadButton.Width += neededWidth - oldTextWidth;
            }
            // After considering all the factors except whether any languages are selected,
            // if we can upload at this point, whether we can from here on depends on whether one is checked.
            // This test needs to come after evaluating everything else uploading depends on (except login)
            _okToUploadDependsOnLangsChecked = _okToUpload;
            if (!allLanguages.Keys.Any())
            {
                _langsLabel.Text += " " + LocalizationManager.GetString("PublishTab.Upload.NoLangsFound", "(None found)");
                _langsLabel.ForeColor = Color.Red;
                _okToUpload = false;
            }
        }
Example #39
0
        public void LoadBook(DoWorkEventArgs doWorkEventArgs)
        {
            _currentlyLoadedBook = BookSelection.CurrentSelection;

            try
            {
                using(var tempHtml = MakeFinalHtmlForPdfMaker())
                {
                    if (doWorkEventArgs.Cancel)
                        return;

                    BookletLayoutMethod layoutMethod;
                    if (this.BookletPortion == BookletPortions.AllPagesNoBooklet)
                        layoutMethod = BookletLayoutMethod.NoBooklet;
                    else
                        layoutMethod = BookSelection.CurrentSelection.GetDefaultBookletLayout();

                    _pdfMaker.MakePdf(tempHtml.Path, PdfFilePath, PageLayout.SizeAndOrientation.PageSizeName, PageLayout.SizeAndOrientation.IsLandScape,
                                      layoutMethod, BookletPortion, doWorkEventArgs);
                }
            }
            catch (Exception e)
            {
                //we can't safely do any ui-related work from this thread, like putting up a dialog
                doWorkEventArgs.Result = e;
                //                Palaso.Reporting.ErrorReport.NotifyUserOfProblem(e, "There was a problem creating a PDF from this book.");
                //                SetDisplayMode(DisplayModes.NoBook);
                //                return;
            }
        }