UploadBook() public méthode

The thing here is that we need to guarantee unique names at the top level, so we wrap the books inside a folder with some unique name. As this involves copying the folder it is also a convenient place to omit any PDF files except the one we want.
public UploadBook ( string storageKeyOfBookFolder, string pathToBloomBookDirectory, IProgress progress, string pdfToInclude = null ) : void
storageKeyOfBookFolder string
pathToBloomBookDirectory string
progress IProgress
pdfToInclude string
Résultat void
Exemple #1
0
        static int Main(string[] arguments)
        {
            if (arguments.Length != 1)
            {
                Console.WriteLine("Usage: BloomBookUploader path-to-folder-containing-books");
                return 1;
            }
            if (!Directory.Exists(arguments[0]))
            {
                Console.WriteLine(arguments[0]+" not found");
                return 3;
            }

            var t = new Bloom.WebLibraryIntegration.BloomS3Client(BloomS3Client.SandboxBucketName);
            t.UploadBook(Guid.NewGuid().ToString(), arguments[0]);

            return 0;
        }
Exemple #2
0
        static int Main(string[] arguments)
        {
            if (arguments.Length != 1)
            {
                Console.WriteLine("Usage: BloomBookUploader path-to-folder-containing-books");
                return(1);
            }
            if (!Directory.Exists(arguments[0]))
            {
                Console.WriteLine(arguments[0] + " not found");
                return(3);
            }

            var t = new Bloom.WebLibraryIntegration.BloomS3Client(BloomS3Client.SandboxBucketName);

            t.UploadBook(Guid.NewGuid().ToString(), arguments[0], new NullProgress());

            return(0);
        }
Exemple #3
0
        public string UploadBook(string bookFolder, IProgress progress, out string parseId)
        {
            var metaDataText = MetaDataText(bookFolder);
            var metadata     = BookMetaData.FromString(metaDataText);

            // In case we somehow have a book with no ID, we must have one to upload it.
            if (string.IsNullOrEmpty(metadata.Id))
            {
                metadata.Id = Guid.NewGuid().ToString();
            }
            // And similarly it should have SOME title.
            if (string.IsNullOrEmpty(metadata.Title))
            {
                metadata.Title = Path.GetFileNameWithoutExtension(bookFolder);
            }
            metadata.SetUploader(UserId);
            var s3BookId = S3BookId(metadata);

            metadata.DownloadSource = s3BookId;
            // Any updated ID at least needs to become a permanent part of the book.
            // The file uploaded must also contain the correct DownloadSource data, so that it can be used
            // as an 'order' to download the book.
            // It simplifies unit testing if the metadata file is also updated with the uploadedBy value.
            // Not sure if there is any other reason to do it (or not do it).
            // For example, do we want to send/receive who is the latest person to upload?
            metadata.WriteToFolder(bookFolder);
            // The metadata is also a book order...but we need it on the server with the desired file name,
            // because we can't rename on download. The extension must be the one Bloom knows about,
            // and we want the file name to indicate which book, so use the name of the book folder.
            var metadataPath = BookMetaData.MetaDataPath(bookFolder);
            var orderPath    = Path.Combine(bookFolder, Path.GetFileName(bookFolder) + BookOrderExtension);

            File.Copy(metadataPath, orderPath, true);
            parseId = "";
            try
            {
                _s3Client.UploadBook(s3BookId, bookFolder, progress);
                metadata.BaseUrl   = _s3Client.BaseUrl;
                metadata.BookOrder = _s3Client.BookOrderUrl;
                progress.WriteStatus(LocalizationManager.GetString("PublishTab.Upload.UploadingBookMetadata", "Uploading book metadata", "In this step, Bloom is uploading things like title, languages, & topic tags to the bloomlibrary.org database."));
                // Do this after uploading the books, since the ThumbnailUrl is generated in the course of the upload.
                var response = _parseClient.SetBookRecord(metadata.Json);
                parseId = response.ResponseUri.LocalPath;
                int index = parseId.LastIndexOf('/');
                parseId = parseId.Substring(index + 1);
                if (parseId == "books")
                {
                    // For NEW books the response URL is useless...need to do a new query to get the ID.
                    var json = _parseClient.GetSingleBookRecord(metadata.Id);
                    parseId = json.objectId.Value;
                }
                //   if (!UseSandbox) // don't make it seem like there are more uploads than their really are if this a tester pushing to the sandbox
                {
                    Analytics.Track("UploadBook-Success", new Dictionary <string, string>()
                    {
                        { "url", metadata.BookOrder }, { "title", metadata.Title }
                    });
                }
            }
            catch (WebException e)
            {
                DisplayNetworkUploadProblem(e, progress);
                if (!UseSandbox)                 // don't make it seem like there are more upload failures than their really are if this a tester pushing to the sandbox
                {
                    Analytics.Track("UploadBook-Failure", new Dictionary <string, string>()
                    {
                        { "url", metadata.BookOrder }, { "title", metadata.Title }, { "error", e.Message }
                    });
                }
                return("");
            }
            catch (AmazonServiceException e)
            {
                DisplayNetworkUploadProblem(e, progress);
                if (!UseSandbox)                 // don't make it seem like there are more upload failures than their really are if this a tester pushing to the sandbox
                {
                    Analytics.Track("UploadBook-Failure", new Dictionary <string, string>()
                    {
                        { "url", metadata.BookOrder }, { "title", metadata.Title }, { "error", e.Message }
                    });
                }
                return("");
            }
            catch (Exception e)
            {
                progress.WriteError(LocalizationManager.GetString("PublishTab.Upload.UploadProblemNotice",
                                                                  "There was a problem uploading your book. You may need to restart Bloom or get technical help."));
                progress.WriteError(e.Message.Replace("{", "{{").Replace("}", "}}"));
                progress.WriteVerbose(e.StackTrace);
                if (!UseSandbox)                 // don't make it seem like there are more upload failures than their really are if this a tester pushing to the sandbox
                {
                    Analytics.Track("UploadBook-Failure", new Dictionary <string, string>()
                    {
                        { "url", metadata.BookOrder }, { "title", metadata.Title }, { "error", e.Message }
                    });
                }
                return("");
            }
            return(s3BookId);
        }
        private string UploadBook(string bookFolder, IProgress progress, out string parseId, string pdfToInclude = null, bool excludeAudio = true)
        {
            // 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 must never be locked.
            // So, typically we will 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(bookFolder);
            bool    wasLocked     = false;
            bool    allowLocking  = false;
            HtmlDom domForLocking = null;
            var     metaDataText  = MetaDataText(bookFolder);
            var     metadata      = BookMetaData.FromString(metaDataText);

            if (!string.IsNullOrEmpty(htmlFile))
            {
                var xmlDomFromHtmlFile = XmlHtmlConverter.GetXmlDomFromHtmlFile(htmlFile, false);
                domForLocking = new HtmlDom(xmlDomFromHtmlFile);
                wasLocked     = domForLocking.RecordedAsLockedDown;
                allowLocking  = !metadata.IsSuitableForMakingShells;
                if (allowLocking && !wasLocked)
                {
                    domForLocking.RecordAsLockedDown(true);
                    XmlHtmlConverter.SaveDOMAsHtml5(domForLocking.RawDom, htmlFile);
                }
            }
            string s3BookId;

            try
            {
                // In case we somehow have a book with no ID, we must have one to upload it.
                if (string.IsNullOrEmpty(metadata.Id))
                {
                    metadata.Id = Guid.NewGuid().ToString();
                }
                // And similarly it should have SOME title.
                if (string.IsNullOrEmpty(metadata.Title))
                {
                    metadata.Title = Path.GetFileNameWithoutExtension(bookFolder);
                }
                metadata.SetUploader(UserId);
                s3BookId = S3BookId(metadata);
                metadata.DownloadSource = s3BookId;
                // Any updated ID at least needs to become a permanent part of the book.
                // The file uploaded must also contain the correct DownloadSource data, so that it can be used
                // as an 'order' to download the book.
                // It simplifies unit testing if the metadata file is also updated with the uploadedBy value.
                // Not sure if there is any other reason to do it (or not do it).
                // For example, do we want to send/receive who is the latest person to upload?
                metadata.WriteToFolder(bookFolder);
                // The metadata is also a book order...but we need it on the server with the desired file name,
                // because we can't rename on download. The extension must be the one Bloom knows about,
                // and we want the file name to indicate which book, so use the name of the book folder.
                var metadataPath = BookMetaData.MetaDataPath(bookFolder);
                var orderPath    = Path.Combine(bookFolder, Path.GetFileName(bookFolder) + BookOrderExtension);
                RobustFile.Copy(metadataPath, orderPath, true);
                parseId = "";
                try
                {
                    _s3Client.UploadBook(s3BookId, bookFolder, progress, pdfToInclude, excludeAudio);
                    metadata.BaseUrl   = _s3Client.BaseUrl;
                    metadata.BookOrder = _s3Client.BookOrderUrlOfRecentUpload;
                    progress.WriteStatus(LocalizationManager.GetString("PublishTab.Upload.UploadingBookMetadata", "Uploading book metadata", "In this step, Bloom is uploading things like title, languages, and topic tags to the BloomLibrary.org database."));
                    // Do this after uploading the books, since the ThumbnailUrl is generated in the course of the upload.
                    var response = _parseClient.SetBookRecord(metadata.WebDataJson);
                    parseId = response.ResponseUri.LocalPath;
                    int index = parseId.LastIndexOf('/');
                    parseId = parseId.Substring(index + 1);
                    if (parseId == "books")
                    {
                        // For NEW books the response URL is useless...need to do a new query to get the ID.
                        var json = _parseClient.GetSingleBookRecord(metadata.Id);
                        parseId = json.objectId.Value;
                    }
                    //   if (!UseSandbox) // don't make it seem like there are more uploads than their really are if this a tester pushing to the sandbox
                    {
                        Analytics.Track("UploadBook-Success", new Dictionary <string, string>()
                        {
                            { "url", metadata.BookOrder }, { "title", metadata.Title }
                        });
                    }
                }
                catch (WebException e)
                {
                    DisplayNetworkUploadProblem(e, progress);
                    if (!UseSandbox)                     // don't make it seem like there are more upload failures than their really are if this a tester pushing to the sandbox
                    {
                        Analytics.Track("UploadBook-Failure", new Dictionary <string, string>()
                        {
                            { "url", metadata.BookOrder }, { "title", metadata.Title }, { "error", e.Message }
                        });
                    }
                    return("");
                }
                catch (AmazonS3Exception e)
                {
                    if (e.Message.Contains("The difference between the request time and the current time is too large"))
                    {
                        progress.WriteError(LocalizationManager.GetString("PublishTab.Upload.TimeProblem",
                                                                          "There was a problem uploading your book. This is probably because your computer is set to use the wrong timezone or your system time is badly wrong. See http://www.di-mgt.com.au/wclock/help/wclo_setsysclock.html for how to fix this."));
                        if (!UseSandbox)
                        {
                            Analytics.Track("UploadBook-Failure-SystemTime");
                        }
                    }
                    else
                    {
                        DisplayNetworkUploadProblem(e, progress);
                        if (!UseSandbox)
                        {
                            // don't make it seem like there are more upload failures than their really are if this a tester pushing to the sandbox
                            Analytics.Track("UploadBook-Failure",
                                            new Dictionary <string, string>()
                            {
                                { "url", metadata.BookOrder }, { "title", metadata.Title }, { "error", e.Message }
                            });
                        }
                    }
                    return("");
                }
                catch (AmazonServiceException e)
                {
                    DisplayNetworkUploadProblem(e, progress);
                    if (!UseSandbox)                     // don't make it seem like there are more upload failures than their really are if this a tester pushing to the sandbox
                    {
                        Analytics.Track("UploadBook-Failure", new Dictionary <string, string>()
                        {
                            { "url", metadata.BookOrder }, { "title", metadata.Title }, { "error", e.Message }
                        });
                    }
                    return("");
                }
                catch (Exception e)
                {
                    progress.WriteError(LocalizationManager.GetString("PublishTab.Upload.UploadProblemNotice",
                                                                      "There was a problem uploading your book. You may need to restart Bloom or get technical help."));
                    progress.WriteError(e.Message.Replace("{", "{{").Replace("}", "}}"));
                    progress.WriteVerbose(e.StackTrace);
                    if (!UseSandbox)                     // don't make it seem like there are more upload failures than their really are if this a tester pushing to the sandbox
                    {
                        Analytics.Track("UploadBook-Failure", new Dictionary <string, string>()
                        {
                            { "url", metadata.BookOrder }, { "title", metadata.Title }, { "error", e.Message }
                        });
                    }
                    return("");
                }
            }
            finally
            {
                if (domForLocking != null && allowLocking && !wasLocked)
                {
                    domForLocking.RecordAsLockedDown(false);
                    XmlHtmlConverter.SaveDOMAsHtml5(domForLocking.RawDom, htmlFile);
                }
            }
            return(s3BookId);
        }
Exemple #5
0
        private string UploadBook(string bookFolder, IProgress progress, out string parseId,
                                  string pdfToInclude = null, ISet <string> audioFilesToInclude = null, IEnumerable <string> videoFilesToInclude = null, string[] languages = null,
                                  CollectionSettings collectionSettings = null)
        {
            // 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 must never be locked.
            // So, typically we will 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(bookFolder);
            bool    wasLocked     = false;
            bool    allowLocking  = false;
            HtmlDom domForLocking = null;
            var     metaDataText  = MetaDataText(bookFolder);
            var     metadata      = BookMetaData.FromString(metaDataText);

            if (!String.IsNullOrEmpty(htmlFile))
            {
                var xmlDomFromHtmlFile = XmlHtmlConverter.GetXmlDomFromHtmlFile(htmlFile, false);
                domForLocking = new HtmlDom(xmlDomFromHtmlFile);
                wasLocked     = domForLocking.RecordedAsLockedDown;
                allowLocking  = !metadata.IsSuitableForMakingShells;
                if (allowLocking && !wasLocked)
                {
                    domForLocking.RecordAsLockedDown(true);
                    XmlHtmlConverter.SaveDOMAsHtml5(domForLocking.RawDom, htmlFile);
                }
            }
            string s3BookId;

            try
            {
                // In case we somehow have a book with no ID, we must have one to upload it.
                if (String.IsNullOrEmpty(metadata.Id))
                {
                    metadata.Id = Guid.NewGuid().ToString();
                }
                // And similarly it should have SOME title.
                if (String.IsNullOrEmpty(metadata.Title))
                {
                    metadata.Title = Path.GetFileNameWithoutExtension(bookFolder);
                }
                metadata.SetUploader(UserId);
                s3BookId = S3BookId(metadata);
#if DEBUG
                // S3 URL can be reasonably deduced, as long as we have the S3 ID, so print that out in Debug mode.
                // Format: $"https://s3.amazonaws.com/BloomLibraryBooks{isSandbox}/{s3BookId}/{title}"
                // Example: https://s3.amazonaws.com/BloomLibraryBooks-Sandbox/[email protected]/8d0d9043-a1bb-422d-aa5b-29726cdcd96a/AutoSplit+Timings
                var msgBookId = "s3BookId: " + s3BookId;
                progress.WriteMessage(msgBookId);
#endif
                metadata.DownloadSource = s3BookId;
                // If the collection has a default bookshelf, make sure the book has that tag.
                // Also make sure it doesn't have any other bookshelf tags (which would typically be
                // from a previous default bookshelf upload), including a duplicate of the one
                // we may be about to add.
                var tags = (metadata.Tags ?? new string[0]).Where(t => !t.StartsWith("bookshelf:"));

                if (!String.IsNullOrEmpty(collectionSettings?.DefaultBookshelf))
                {
                    tags = tags.Concat(new [] { "bookshelf:" + collectionSettings.DefaultBookshelf });
                }
                metadata.Tags = tags.ToArray();

                // Any updated ID at least needs to become a permanent part of the book.
                // The file uploaded must also contain the correct DownloadSource data, so that it can be used
                // as an 'order' to download the book.
                // It simplifies unit testing if the metadata file is also updated with the uploadedBy value.
                // Not sure if there is any other reason to do it (or not do it).
                // For example, do we want to send/receive who is the latest person to upload?
                metadata.WriteToFolder(bookFolder);
                // The metadata is also a book order...but we need it on the server with the desired file name,
                // because we can't rename on download. The extension must be the one Bloom knows about,
                // and we want the file name to indicate which book, so use the name of the book folder.
                var metadataPath = BookMetaData.MetaDataPath(bookFolder);
                RobustFile.Copy(metadataPath, BookInfo.BookOrderPath(bookFolder), true);
                parseId = "";
                try
                {
                    _s3Client.UploadBook(s3BookId, bookFolder, progress, pdfToInclude, audioFilesToInclude, videoFilesToInclude, languages);
                    metadata.BaseUrl   = _s3Client.BaseUrl;
                    metadata.BookOrder = _s3Client.BookOrderUrlOfRecentUpload;
                    var metaMsg = LocalizationManager.GetString("PublishTab.Upload.UploadingBookMetadata", "Uploading book metadata", "In this step, Bloom is uploading things like title, languages, and topic tags to the BloomLibrary.org database.");
                    if (IsDryRun)
                    {
                        metaMsg = "(Dry run) Would upload book metadata";                               // TODO: localize?
                    }
                    progress.WriteStatus(metaMsg);
                    // Do this after uploading the books, since the ThumbnailUrl is generated in the course of the upload.
                    if (!IsDryRun)
                    {
                        var response = ParseClient.SetBookRecord(metadata.WebDataJson);
                        parseId = response.ResponseUri.LocalPath;
                        int index = parseId.LastIndexOf('/');
                        parseId = parseId.Substring(index + 1);
                        if (parseId == "books")
                        {
                            // For NEW books the response URL is useless...need to do a new query to get the ID.
                            var json = ParseClient.GetSingleBookRecord(metadata.Id);
                            parseId = json.objectId.Value;
                        }
                        //   if (!UseSandbox) // don't make it seem like there are more uploads than their really are if this a tester pushing to the sandbox
                        {
                            Analytics.Track("UploadBook-Success", new Dictionary <string, string>()
                            {
                                { "url", metadata.BookOrder }, { "title", metadata.Title }
                            });
                        }
                    }
                }
                catch (WebException e)
                {
                    DisplayNetworkUploadProblem(e, progress);
                    if (IsProductionRun)                     // don't make it seem like there are more upload failures than their really are if this a tester pushing to the sandbox
                    {
                        Analytics.Track("UploadBook-Failure", new Dictionary <string, string>()
                        {
                            { "url", metadata.BookOrder }, { "title", metadata.Title }, { "error", e.Message }
                        });
                    }
                    return("");
                }
                catch (AmazonS3Exception e)
                {
                    if (e.Message.Contains("The difference between the request time and the current time is too large"))
                    {
                        progress.WriteError(LocalizationManager.GetString("PublishTab.Upload.TimeProblem",
                                                                          "There was a problem uploading your book. This is probably because your computer is set to use the wrong timezone or your system time is badly wrong. See http://www.di-mgt.com.au/wclock/help/wclo_setsysclock.html for how to fix this."));
                        if (IsProductionRun)
                        {
                            Analytics.Track("UploadBook-Failure-SystemTime");
                        }
                    }
                    else
                    {
                        DisplayNetworkUploadProblem(e, progress);
                        if (IsProductionRun)
                        {
                            // don't make it seem like there are more upload failures than there really are if this a tester pushing to the sandbox
                            Analytics.Track("UploadBook-Failure",
                                            new Dictionary <string, string>()
                            {
                                { "url", metadata.BookOrder }, { "title", metadata.Title }, { "error", e.Message }
                            });
                        }
                    }
                    return("");
                }
                catch (AmazonServiceException e)
                {
                    DisplayNetworkUploadProblem(e, progress);
                    if (IsProductionRun)                     // don't make it seem like there are more upload failures than there really are if this a tester pushing to the sandbox
                    {
                        Analytics.Track("UploadBook-Failure", new Dictionary <string, string>()
                        {
                            { "url", metadata.BookOrder }, { "title", metadata.Title }, { "error", e.Message }
                        });
                    }
                    return("");
                }
                catch (Exception e)
                {
                    var msg1 = LocalizationManager.GetString("PublishTab.Upload.UploadProblemNotice",
                                                             "There was a problem uploading your book. You may need to restart Bloom or get technical help.");
                    var msg2 = e.Message.Replace("{", "{{").Replace("}", "}}");
                    progress.WriteError(msg1);
                    progress.WriteError(msg2);
                    progress.WriteVerbose(e.StackTrace);

                    if (IsProductionRun)                     // don't make it seem like there are more upload failures than there really are if this a tester pushing to the sandbox
                    {
                        Analytics.Track("UploadBook-Failure", new Dictionary <string, string>()
                        {
                            { "url", metadata.BookOrder }, { "title", metadata.Title }, { "error", e.Message }
                        });
                    }
                    return("");
                }
            }
            finally
            {
                if (domForLocking != null && allowLocking && !wasLocked)
                {
                    domForLocking.RecordAsLockedDown(false);
                    XmlHtmlConverter.SaveDOMAsHtml5(domForLocking.RawDom, htmlFile);
                }
            }
            return(s3BookId);
        }