Beispiel #1
0
        private async Task DownloadBookAsync(BookDataContext bookdb, BookData book, FilenameAndFormatData file)
        {
            Uri uri;
            var fileName = FileWizards.UriWizard.FixupUrl(file.FileName);
            var status   = Uri.TryCreate(fileName, UriKind.Absolute, out uri);

            if (!status)
            {
                var md = new MessageDialog($"Internal error: {fileName} is invalid")
                {
                    Title = "Can't download file",
                };
                await md.ShowAsync();

                return;
            }
            // Uri is e.g. http://www.gutenberg.org/ebooks/14.epub.noimages

            var folder = await FolderMethods.EnsureDownloadFolder();

            var(outfilename, ext) = FileWizards.UriWizard.GetUriFilename(uri);
            var preferredFilename = book.GetBestTitleForFilename() + ext;

            var collisionOption = PCLStorage.CreationCollisionOption.FailIfExists;
            var exists          = await folder.CheckExistsAsync(preferredFilename);

            if (exists == PCLStorage.ExistenceCheckResult.FileExists)
            {
                var md = new ContentDialog()
                {
                    Content             = $"Already downloaded file {preferredFilename}",
                    Title               = "File exists",
                    PrimaryButtonText   = "Skip",
                    SecondaryButtonText = "Delete existing file",
                };
                var command = await md.ShowAsync();

                switch (command)
                {
                case ContentDialogResult.Primary:
                    return;

                case ContentDialogResult.Secondary:
                    collisionOption = PCLStorage.CreationCollisionOption.ReplaceExisting;
                    break;
                }
            }
            PCLStorage.IFile outfile;
            try
            {
                outfile = await folder.CreateFileAsync(preferredFilename, collisionOption);
            }
            catch (Exception ex)
            {
                var md = new MessageDialog($"Already downloaded file {preferredFilename} {ex.Message}")
                {
                    Title = "File already exists",
                };
                await md.ShowAsync();

                return;
            }

            // Just do a quick download....
            try
            {
                EnableDownloadProgressPanel(true);
                uiDownloadButton.Visibility       = Visibility.Collapsed;
                uiCancelDownloadButton.Visibility = Visibility.Visible;
                cts = new CancellationTokenSource();

                ulong totalLength = 0;
                uiDownloadProgress.IsIndeterminate = true;
                uiDownloadProgress.ShowError       = false;
                var getTask = hc.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead);
#if NEVER_EVER_DEFINED
                getTask.Progress += async(response, progress) =>
                {
                    await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                                                   () =>
                    {
                        if (totalLength == 0 && progress.TotalBytesToReceive.HasValue && progress.TotalBytesToReceive.Value > 0)
                        {
                            // Now we know how many bytes we will get!
                            uiDownloadProgress.IsIndeterminate = false;
                            uiDownloadProgress.Minimum         = 0;
                            uiDownloadProgress.Maximum         = progress.TotalBytesToReceive.Value;
                            uiDownloadProgress.Value           = 0;
                            totalLength = progress.TotalBytesToReceive.Value;
                        }
                        if (progress.BytesReceived > 0)
                        {
                            uiDownloadProgress.Value = progress.BytesReceived;
                        }
                        NotifyUser($"GET Progress: stage {progress.Stage} bytes={progress.BytesReceived} of {progress.TotalBytesToReceive}");
                    });
                };
#endif
                // Get some level of progress....
                var responseMessage     = await getTask;
                var contentLengthHeader = responseMessage.Content.Headers.ContentLength;
                if (totalLength == 0 && contentLengthHeader.HasValue && contentLengthHeader.Value > 0)
                {
                    // Now we know how many bytes we will get!
                    uiDownloadProgress.IsIndeterminate = false;
                    uiDownloadProgress.Minimum         = 0;
                    uiDownloadProgress.Maximum         = contentLengthHeader.Value;
                    uiDownloadProgress.Value           = 0;
                    totalLength = (ulong)contentLengthHeader.Value;
                }
                NotifyUser($"GET Progress: stage Got Headers");


                var stream = await responseMessage.Content.ReadAsStreamAsync(); // gest entire buffer at once.

                byte[]      tbuffer  = new byte[8 * 1024];
                List <byte> buffer   = new List <byte>();
                int         nbytes   = 0;
                int         progress = 0;
                while ((nbytes = await stream.ReadAsync(tbuffer, 0, tbuffer.Length)) > 0)
                {
                    for (int i = 0; i < nbytes; i++)
                    {
                        buffer.Add(tbuffer[i]);
                    }
                    await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                                                   () =>
                    {
                        progress += nbytes;
                        uiDownloadProgress.Value = progress;
                        NotifyUser($"GET Progress: bytes={progress} of {totalLength}\n");
                    });
                }

                //var buffer = await bufferTask.AsTask(cts.Token);
                uiDownloadProgress.Value = buffer.Count;

                bool isOk = responseMessage.IsSuccessStatusCode;
                if (isOk)
                {
                    NotifyUser($"GET complete with {buffer.Count} bytes");

                    if (buffer.Count > 2000)
                    {
                        uiDownloadFinished.Visibility           = Visibility.Visible;
                        uiDownloadFinishedShowButton.Visibility = Visibility.Collapsed;

                        await outfile.WriteBytesAsync(buffer);

                        CommonQueries.DownloadedBookEnsureFileMarkedAsDownloaded(bookdb, book.BookId, folder.Path, outfile.Name);

                        uiDownloadFinishedShowButton.Visibility = Visibility.Visible;
                    }
                    else
                    {
                        var md = new MessageDialog($"Download file error -- too small")
                        {
                            Title = "Corrupt downloaded file",
                        };
                        await md.ShowAsync();
                    }
                    NotifyUser($"Download complete -- file size {buffer.Count} bytes");
                }
                else
                {
                    NotifyUser($"Failed to download file; error {responseMessage.ReasonPhrase} length {buffer.Count}");
                    uiDownloadFinished.Visibility           = Visibility.Visible;
                    uiDownloadFinishedShowButton.Visibility = Visibility.Collapsed;
                }


                uiDownloadProgress.IsIndeterminate = false;
                uiDownloadProgress.Value           = 0;
                EnableDownloadProgressPanel(false);
            }
            catch (Exception ex)
            {
                NotifyUser($"Unable to download file because {ex.Message}");
                await outfile.DeleteAsync();

                uiDownloadProgress.IsIndeterminate = false;
                uiDownloadProgress.ShowError       = true;
                EnableDownloadProgressPanel(false);
            }
            finally
            {
                uiDownloadButton.Visibility       = Visibility.Visible;
                uiCancelDownloadButton.Visibility = Visibility.Collapsed;
            }
        }
Beispiel #2
0
        private static async Task <BookData> InsertFileIntoDatabase(BookDataContext bookdb, IFolder folder, string filename, bool getFullData = false)
        {
            BookData bookData = null;

            if (bookdb == null)
            {
                bookdb = BookDataContext.Get();
            }
            string fullfname = $"{folder.Path}\\{filename}";
            var    wd        = new WizardData()
            {
                FilePath = fullfname, FileName = filename
            };

            try
            {
                wd = await GutenbergFileWizard.GetDataAsync(wd, getFullData);

                if (!string.IsNullOrEmpty(wd.BookId))
                {
                    bookData = CommonQueries.BookGet(bookdb, wd.BookId);

                    //TODO: when I drop a book that's been added to the database because it was
                    // in a bookmark file (which should happen reasonably often!)
                    // then the bookData here is non-null, but also not really filled in well.
                    if (bookData == null || bookData.BookSource.StartsWith(BookData.BookSourceBookMarkFile))
                    {
                        if (wd.BD != null)
                        {
                            // Gotcha! Add to the main book database!
                            if (!string.IsNullOrEmpty(wd.BD.BookId))
                            {
                                wd.BD.Files.Add(new FilenameAndFormatData()
                                {
                                    FileName = filename,
                                    BookId   = wd.BookId,
                                    MimeType = "application/epub+zip"
                                });
                                wd.BD.BookSource = BookData.BookSourceUser;

                                // Add in possible data from the bookData set by the user
                                if (bookData != null)
                                {
                                    wd.BD.NavigationData = bookData.NavigationData;
                                    wd.BD.Review         = bookData.Review;
                                    wd.BD.Notes          = bookData.Notes;

                                    //TODO: now get this book into the database.
                                    // via some kind of merge??
                                }
                                else
                                {
                                    CommonQueries.BookAdd(bookdb, wd.BD, CommonQueries.ExistHandling.IfNotExists);
                                    CommonQueries.BookSaveChanges(bookdb);
                                    bookData = wd.BD;
                                }
                            }
                            else
                            {
                                App.Error($"ERROR: {filename} ({wd.BookId}) was unable to wizard read and get ID");
                            }
                        }
                        else
                        {
                            App.Error($"ERROR: {filename} ({wd.BookId}) was unable to wizard read");
                        }
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine($"{filename}({wd.BookId}) is {bookData.GetBestTitleForFilename()}");
                    }
                    var fullpath = folder.Path;
                    if (fullpath.Contains(@"AppX\Assets\PreinstalledBooks"))
                    {
                        // Whoops. The initial database might incorrectly have a developer path hard-coded.
                        // Replace with correct location.
                        fullpath = $"PreinstalledBooks:";
                    }
                    CommonQueries.DownloadedBookEnsureFileMarkedAsDownloaded(bookdb, wd.BookId, fullpath, filename);
                }
                else
                {
                    App.Error($"{filename} with id {wd.BookId} is not a known type of e-book");
                }
            }
            catch (Exception)
            {
                App.Error($"{filename} is not a readable e-book");
            }
            return(bookData);
        }