예제 #1
0
        public void CreateBookOnDiskFromTemplateStarter_IsTemplate_ButNotTemplateFactory()
        {
            var source = BloomFileLocator.GetFactoryBookTemplateDirectory("Template Starter");

            var path        = _starter.CreateBookOnDiskFromTemplate(source, _projectFolder.Path);
            var newMetaData = BookMetaData.FromFolder(path);

            Assert.That(newMetaData.IsSuitableForMakingShells, Is.True);
            Assert.That(newMetaData.IsSuitableForMakingTemplates, Is.False);
        }
        /// <summary>
        /// Creates the .bloomd and bloomdigital folders
        /// </summary>
        private static CreateArtifactsExitCode CreateBloomDigitalArtifacts(string bookPath, string creator, string zippedBloomDOutputPath, string unzippedBloomDigitalOutputPath)
        {
#if DEBUG
            // Useful for allowing debugging of Bloom while running the harvester
            //MessageBox.Show("Attach debugger now");
#endif
            var exitCode = CreateArtifactsExitCode.Success;

            using (var tempBloomD = TempFile.CreateAndGetPathButDontMakeTheFile())
            {
                if (String.IsNullOrEmpty(zippedBloomDOutputPath))
                {
                    zippedBloomDOutputPath = tempBloomD.Path;
                }

                BookServer bookServer = _projectContext.BookServer;

                var  metadata       = BookMetaData.FromFolder(bookPath);
                bool isTemplateBook = metadata.IsSuitableForMakingShells;

                using (var folderForUnzipped = new TemporaryFolder("BloomCreateArtifacts_Unzipped"))
                {
                    // Ensure directory exists, just in case.
                    Directory.CreateDirectory(Path.GetDirectoryName(zippedBloomDOutputPath));
                    // Make the bloomd
                    string unzippedPath = Publish.Android.BloomPubMaker.CreateBloomPub(
                        zippedBloomDOutputPath,
                        bookPath,
                        bookServer,
                        System.Drawing.Color.Azure,                 // TODO: What should this be?
                        new Bloom.web.NullWebSocketProgress(),
                        folderForUnzipped,
                        creator,
                        isTemplateBook);

                    // Currently the zipping process does some things we actually need, like making the cover picture
                    // transparent (BL-7437). Eventually we plan to separate the preparation and zipping steps (BL-7445).
                    // Until that is done, the most reliable way to get an unzipped BloomD for our preview is to actually
                    // unzip the BloomD.
                    if (!String.IsNullOrEmpty(unzippedBloomDigitalOutputPath))
                    {
                        SIL.IO.RobustIO.DeleteDirectory(unzippedBloomDigitalOutputPath, recursive: true);                           // In case the folder isn't already empty

                        // Ensure directory exists, just in case.
                        Directory.CreateDirectory(Path.GetDirectoryName(unzippedBloomDigitalOutputPath));

                        ZipFile.ExtractToDirectory(zippedBloomDOutputPath, unzippedBloomDigitalOutputPath);

                        exitCode |= RenameBloomDigitalFiles(unzippedBloomDigitalOutputPath);
                    }
                }
            }

            return(exitCode);
        }
예제 #3
0
        public void CreateBookOnDiskFromTemplate_OriginalIsTemplate_CopyIsNotTemplate()
        {
            var source           = BloomFileLocator.GetFactoryBookTemplateDirectory("Basic Book");
            var originalMetaData = BookMetaData.FromFolder(source);

            Assert.That(originalMetaData.IsSuitableForMakingShells);
            var path        = _starter.CreateBookOnDiskFromTemplate(source, _projectFolder.Path);
            var newMetaData = BookMetaData.FromFolder(path);

            Assert.That(newMetaData.IsSuitableForMakingShells, Is.False);
        }
        /// <summary>
        /// Review: this is fragile and expensive. We're doing real internet traffic and creating real objects on S3 and parse.com
        /// which (to a very small extent) costs us real money. This will be slow. Also, under S3 eventual consistency rules,
        /// there is no guarantee that the data we just created will actually be retrievable immediately.
        /// </summary>
        /// <param name="bookName"></param>
        /// <param name="id"></param>
        /// <param name="uploader"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public Tuple <string, string> UploadAndDownLoadNewBook(string bookName, string id, string uploader, string data, bool isTemplate = false)
        {
            //  Create a book folder with meta.json that includes an uploader and id and some other files.
            var originalBookFolder = MakeBook(bookName, id, uploader, data, true);

            if (isTemplate)
            {
                var metadata = BookMetaData.FromFolder(originalBookFolder);
                metadata.IsSuitableForMakingShells = true;
                metadata.WriteToFolder(originalBookFolder);
            }
            // The files that actually get uploaded omit some of the ones in the folder.
            // The only omitted one that messes up current unit tests is meta.bak
            var filesToUpload = Directory.GetFiles(originalBookFolder).Where(p => !p.EndsWith(".bak") && !p.Contains(BookStorage.PrefixForCorruptHtmFiles));
            int fileCount     = filesToUpload.Count();

            Login();
            //HashSet<string> notifications = new HashSet<string>();

            var progress = new SIL.Progress.StringBuilderProgress();
            var s3Id     = _uploader.UploadBook(originalBookFolder, progress);

            var uploadMessages = progress.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

            var expectedFileCount = fileCount + 2;             // should get one per file, plus one for metadata, plus one for book order

#if DEBUG
            ++expectedFileCount;                // and if in debug mode, then plus one for S3 ID
#endif
            Assert.That(uploadMessages.Length, Is.EqualTo(expectedFileCount), "Uploaded file counts do not match");
            Assert.That(progress.Text, Does.Contain(
                            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.")));
            Assert.That(progress.Text, Does.Contain(Path.GetFileName(filesToUpload.First())));

            _uploader.WaitUntilS3DataIsOnServer(BloomS3Client.UnitTestBucketName, originalBookFolder);
            var dest = _workFolderPath.CombineForPath("output");
            Directory.CreateDirectory(dest);
            _downloadedBooks.Clear();
            var url           = BookUpload.BloomS3UrlPrefix + BloomS3Client.UnitTestBucketName + "/" + s3Id;
            var newBookFolder = _downloader.HandleDownloadWithoutProgress(url, dest);

            Assert.That(Directory.GetFiles(newBookFolder).Length, Is.EqualTo(fileCount + 1), "Book order was not added during upload");             // book order is added during upload

            Assert.That(_downloadedBooks.Count, Is.EqualTo(1));
            Assert.That(_downloadedBooks[0].FolderPath, Is.EqualTo(newBookFolder));
            // Todo: verify that metadata was transferred to Parse.com
            return(new Tuple <string, string>(originalBookFolder, newBookFolder));
        }
예제 #5
0
        // Wait (up to three seconds) for data uploaded to become available.
        // Currently only used in unit testing.
        // I have no idea whether 3s is an adequate time to wait for 'eventual consistency'. So far it seems to work.
        internal void WaitUntilS3DataIsOnServer(string bookPath)
        {
            var s3Id  = S3BookId(BookMetaData.FromFolder(bookPath));
            var count = Directory.GetFiles(bookPath).Length;

            for (int i = 0; i < 30; i++)
            {
                var uploaded = _s3Client.GetBookFileCount(s3Id);
                if (uploaded >= count)
                {
                    return;
                }
                Thread.Sleep(100);
            }
            throw new ApplicationException("S3 is very slow today");
        }
예제 #6
0
        // Wait (up to three seconds) for data uploaded to become available.
        // Currently only used in unit testing.
        // I have no idea whether 3s is an adequate time to wait for 'eventual consistency'. So far it seems to work.
        internal void WaitUntilS3DataIsOnServer(string bucket, string bookPath)
        {
            var s3Id = S3BookId(BookMetaData.FromFolder(bookPath));
            // There's a few files we don't upload, but meta.bak is the only one that regularly messes up the count.
            // Some tests also deliberately include a _broken_ file to check they aren't uploaded,
            // so we'd better not wait for that to be there, either.
            var count = Directory.GetFiles(bookPath).Count(p => !p.EndsWith(".bak") && !p.Contains(BookStorage.PrefixForCorruptHtmFiles));

            for (int i = 0; i < 30; i++)
            {
                var uploaded = _s3Client.GetBookFileCount(bucket, s3Id);
                if (uploaded >= count)
                {
                    return;
                }
                Thread.Sleep(100);
            }
            throw new ApplicationException("S3 is very slow today");
        }
예제 #7
0
        /// <summary>
        /// Creates the .bloompub and bloomdigital folders
        /// </summary>
        private static CreateArtifactsExitCode CreateBloomDigitalArtifacts(string bookPath, string creator, string zippedBloomPubOutputPath, string unzippedBloomDigitalOutputPath)
        {
#if DEBUG
            // Useful for allowing debugging of Bloom while running the harvester
            //MessageBox.Show("Attach debugger now");
#endif
            var exitCode = CreateArtifactsExitCode.Success;

            using (var tempBloomPub = TempFile.CreateAndGetPathButDontMakeTheFile())
            {
                if (String.IsNullOrEmpty(zippedBloomPubOutputPath))
                {
                    zippedBloomPubOutputPath = tempBloomPub.Path;
                }

                BookServer bookServer = _projectContext.BookServer;

                var  metadata       = BookMetaData.FromFolder(bookPath);
                bool isTemplateBook = metadata.IsSuitableForMakingShells;

                // Build artifacts the same way from the harvester as on the user's local machine.
                // (similarly to a bulk publish operation)
                // See https://issues.bloomlibrary.org/youtrack/issue/BL-10300.
                var bookInfo = new BookInfo(bookPath, false);
                var settings = AndroidPublishSettings.GetPublishSettingsForBook(bookServer, bookInfo);

                using (var folderForUnzipped = new TemporaryFolder("BloomCreateArtifacts_Unzipped"))
                {
                    // Ensure directory exists, just in case.
                    Directory.CreateDirectory(Path.GetDirectoryName(zippedBloomPubOutputPath));
                    // Make the bloompub
                    string unzippedPath = BloomPubMaker.CreateBloomPub(
                        zippedBloomPubOutputPath,
                        bookPath,
                        bookServer,
                        new Bloom.web.NullWebSocketProgress(),
                        folderForUnzipped,
                        creator,
                        isTemplateBook,
                        settings);

                    // Currently the zipping process does some things we actually need, like making the cover picture
                    // transparent (BL-7437). Eventually we plan to separate the preparation and zipping steps (BL-7445).
                    // Until that is done, the most reliable way to get an unzipped BloomPUB for our preview is to actually
                    // unzip the BloomPUB.
                    if (!String.IsNullOrEmpty(unzippedBloomDigitalOutputPath))
                    {
                        SIL.IO.RobustIO.DeleteDirectory(unzippedBloomDigitalOutputPath, recursive: true);                           // In case the folder isn't already empty

                        // Ensure directory exists, just in case.
                        Directory.CreateDirectory(Path.GetDirectoryName(unzippedBloomDigitalOutputPath));

                        ZipFile.ExtractToDirectory(zippedBloomPubOutputPath, unzippedBloomDigitalOutputPath);

                        exitCode |= RenameBloomDigitalFiles(unzippedBloomDigitalOutputPath);
                    }
                }
            }

            return(exitCode);
        }