Example #1
0
        /// <summary>
        /// Given a storage file, returns a read-in book mark file object. This is a little
        /// harder than it looks (and hence it's beeing a class.
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        private static async Task <BookMarkFile> ReadFileAsBookMarkFileAsync(StorageFolder folder, string bookmarkfilename)
        {
            var str = await BookmarkFileDirectory.ReadFileAsync(folder, bookmarkfilename);

            BookMarkFile bmf = null;

            try
            {
                // Try to be a little smart just so that I get fewer exceptions. Old files start with [ because they are just
                // arrays; the new file starts with { because it's an object.
                // "old": version used for a couple of weeks early in 2020
                // "new" every other version
                if (!str.StartsWith("["))
                {
                    bmf = JsonConvert.DeserializeObject <BookMarkFile>(str);
                }
            }
            catch (Exception)
            {
            }
            if (bmf == null)
            {
                // Try to read files which are just a raw list of books.
                try
                {
                    var list = JsonConvert.DeserializeObject <List <BookData> >(str);
                    if (list != null)
                    {
                        bmf = new BookMarkFile()
                        {
                            SavedFromName = "unknown-computer",
                            SaveTime      = DateTimeOffset.FromUnixTimeSeconds(24 * 60 * 60),
                            BookMarkList  = list,
                        };
                    }
                }
                catch (Exception)
                {
                }
            }
            return(bmf);
        }
Example #2
0
        public static BookMarkFile CreateBookMarkFile(BookMarkFileType fileType)
        {
            var retval = new BookMarkFile();
            var bookdb = BookDataContext.Get();

            var list = fileType == BookMarkFileType.FullFile
                ? CommonQueries.BookGetAllWhichHaveUserData(bookdb)
                : CommonQueries.BookGetRecentWhichHaveUserData(bookdb);

            // We only save some of the BookData fields in a book mark file.
            // Don't bother with the full file list (total waste of time), or the people list.
            var trimmedList = new List <BookData>();

            foreach (var book in list)
            {
                trimmedList.Add(CreateBookMarkBookData(book));
            }

            retval.BookMarkList = trimmedList;
            return(retval);
        }
Example #3
0
        /// <summary>
        /// Merges the changes from a single read-in bookmarkfile into the local database.
        /// </summary>
        /// <param name="bmf"></param>
        /// <returns></returns>
        private static async Task <int> MergeAsync(BookMarkFile bmf)
        {
            int nchanges = 0;
            // Now let's be very smart about combining this file in with the original.
            var       bookdb           = BookDataContext.Get();
            var       currbooks        = CommonQueries.BookGetAllWhichHaveUserData(bookdb);
            const int CHANGES_PER_SAVE = 1000;
            int       nextDbSaveChange = CHANGES_PER_SAVE;

            foreach (var external in bmf.BookMarkList)
            {
                var book = currbooks.Find(b => b.BookId == external.BookId);
                if (book == null)
                {
                    book = CommonQueries.BookGet(bookdb, external.BookId);
                }
                if (book == null)
                {
                    // Prepend the BookMarkSource so that the book is clearly labeled
                    // as being from a bookmark file (and therefore this is kind of a fake entry)
                    if (!external.BookSource.StartsWith(BookData.BookSourceBookMarkFile))
                    {
                        external.BookSource = BookData.BookSourceBookMarkFile + external.BookSource;
                    }
                    // Must set all these ids to zero so that they get re-set by EF.
                    if (external.Review != null)
                    {
                        external.Review.Id = 0;
                    }
                    if (external.Notes != null)
                    {
                        external.Notes.Id = 0;
                        foreach (var note in external.Notes.Notes)
                        {
                            note.Id = 0;
                        }
                    }
                    if (external.NavigationData != null)
                    {
                        external.NavigationData.Id = 0;
                    }
                    external.DownloadData = null; // on this computer, nothing has been downloaded.

                    CommonQueries.BookAdd(bookdb, external, CommonQueries.ExistHandling.IfNotExists);
                    nchanges++;
                    App.Error($"NOTE: adding external {external.BookId} name {external.Title}");
                }
                else
                {
                    // Great -- now I can merge the UserReview, Notes, and BookNavigationData.
                    int nbookchanges = 0;
                    if (external.Review != null)
                    {
                        if (book.Review == null)
                        {
                            external.Review.Id = 0; // clear it out so that EF will set to the correct value.
                            book.Review        = external.Review;
                            nbookchanges++;
                        }
                        else
                        {
                            nbookchanges += book.Review.Merge(external.Review);
                        }
                    }

                    if (external.NavigationData != null)
                    {
                        if (book.NavigationData == null)
                        {
                            external.NavigationData.Id = 0; // clear it out so that EF will set to the correct value.
                            book.NavigationData        = external.NavigationData;
                            nbookchanges++;
                        }
                        else
                        {
                            nbookchanges += book.NavigationData.Merge(external.NavigationData);
                        }
                    }

                    if (external.Notes != null)
                    {
                        if (book.Notes == null)
                        {
                            // Copy them all over
                            book.Notes = new BookNotes()
                            {
                                BookId = external.Notes.BookId,
                            };
                            foreach (var note in external.Notes.Notes)
                            {
                                note.Id = 0; // reset to zero to insert into the currrent book.
                                book.Notes.Notes.Add(note);
                            }
                            nbookchanges++;
                        }
                        else
                        {
                            // Add in only the changed notes. The ids will not be the same
                            nbookchanges += book.Notes.Merge(external.Notes);
                        }
                    }

                    if (nbookchanges > 0)
                    {
                        ; // hook to hang the debugger on.
                    }
                    nchanges += nbookchanges;

                    if (nchanges > nextDbSaveChange)
                    {
                        await bookdb.SaveChangesAsync();

                        nextDbSaveChange = nchanges + CHANGES_PER_SAVE;
                    }
                }
            }

            // And save at the end!
            if (nchanges > 0)
            {
                await bookdb.SaveChangesAsync();
            }

            return(nchanges);
        }