Esempio n. 1
0
    def get_installed_books(self):
        '''
        For each book, construct a BookStruct object with the book's metadata.
        Starred items are minimally required.
           BookStruct properties:
            *active: [True|False]
            *author: "John Smith"
             author_sort: (if known)
            *book_id: an int uniquely identifying the book.
                     Highlights are associated with books through book_id
             genre: "Fiction" (if known)
            *reader_app: self.app_name
            *title: "The Story of John Smith"
             title_sort: "Story of John Smith, The" (if known)
             uuid: Calibre's uuid for this book, if known
        '''

        self._log_location("Start!!!!")
        self._log("%s:get_installed_books()" % self.app_name)
        self.installed_books = []

        self.device = self.opts.gui.device_manager.device
        self._log("%s:get_installed_books() - about to call self.get_path_map" % self.app_name)
        path_map = self.get_path_map()
#        self._log(path_map)

        # Get books added to Kindle by calibre
        self._log("%s:get_installed_books() - about to call self._get_installed_books" % self.app_name)
#        resolved_path_map = self._get_installed_books(path_map)

        # Calibre already knows what books are on the device, so use it.
        db = self.opts.gui.library_view.model().db
        self.onDeviceIds = set(db.search_getting_ids('ondevice:True', None, sort_results=False, use_virtual_library=False))

        self._log("%s:get_installed_books() - about to call self.generate_books_db_name" % self.app_name)
        self.books_db = self.generate_books_db_name(self.app_name_, self.opts.device_name)
        installed_books = set([])

        # Used by get_active_annotations() to look up metadata based on title
        self.installed_books_by_title = {}

        # Create the books table
        self.create_books_table(self.books_db)

        # Initialize the progress bar
        self.opts.pb.set_label("Getting installed books from %s" % self.app_name)
        self.opts.pb.set_value(0)
        self.opts.pb.set_maximum(len(self.onDeviceIds))
        self._log("Number of books on the device=%d" % len(self.onDeviceIds))

        #  Add installed books to the database
        for book_id in self.onDeviceIds:
            mi = db.get_metadata(book_id, index_is_id=True)
#            self._log_location("book: {0} - {1}".format(mi.authors, mi.title))
#            self._log("mi={0}".format(mi))
            installed_books.add(book_id)

            #self._log(mi.standard_field_keys())
            # Populate a BookStruct with available metadata
            book_mi = BookStruct()
#            book_mi.path = resolved_path_map[book_id]            # Add book_id to list of installed_books (make this a sql function)
            installed_books.add(book_id)

            # Populate a BookStruct with available metadata
            book_mi = BookStruct()

            # Required items
            book_mi.active = True
            # Massage last, first authors back to normalcy
            book_mi.author = ''
            for i, author in enumerate(mi.authors):
#                self._log_location("author=%s, author.__class__=%s" % (author, author.__class__))
                this_author = author.split(', ')
                this_author.reverse()
                book_mi.author += ' '.join(this_author)
                if i < len(mi.authors) - 1:
                    book_mi.author += ' & '

            book_mi.book_id = book_id
            book_mi.reader_app = self.app_name
            book_mi.title = mi.title

            # Optional items
#            if mi.tags:
#                book_mi.genre = ', '.join([tag for tag in mi.tags])
#            if 'News' in mi.tags:
#                book_mi.book_id = self.news_clippings_cid

            if hasattr(mi, 'author_sort'):
                book_mi.author_sort = mi.author_sort

            if hasattr(mi, 'title_sort'):
                book_mi.title_sort = mi.title_sort
            else:
                book_mi.title_sort = re.sub('^\s*A\s+|^\s*The\s+|^\s*An\s+', '', mi.title).rstrip()

            if hasattr(mi, 'uuid'):
                book_mi.uuid = mi.uuid

            # Add book to self.books_db
            self.add_to_books_db(self.books_db, book_mi)

            # Add book to indexed_books
            self.installed_books_by_title[mi.title] = {'book_id': book_id, 'author_sort': mi.author_sort}

            # Increment the progress bar
            self.opts.pb.increment()

        # Update the timestamp
        self.update_timestamp(self.books_db)
        self.commit()

        self.installed_books = list(installed_books)
        self._log_location("Finish!!!!")
    def get_installed_books(self):
        '''
        For each book, construct a BookStruct object with the book's metadata.
        Starred items are minimally required.
           BookStruct properties:
            *active: [True|False]
            *author: "John Smith"
             author_sort: (if known)
            *book_id: an int uniquely identifying the book.
                     Highlights are associated with books through book_id
             genre: "Fiction" (if known)
            *reader_app: self.app_name
            *title: "The Story of John Smith"
             title_sort: "Story of John Smith, The" (if known)
             uuid: Calibre's uuid for this book, if known
        '''
        # Sample installed books indexed by book_id
        dict_of_books = {}
        dict_of_books[1] = {
            'author': 'John Smith',
            'author_sort': 'Smith, John',
            'title': 'The Book by John Smith',
            'title_sort': 'Book by John Smith, The'
        }
        dict_of_books[2] = {
            'author': 'William Jones',
            'author_sort': 'Jones, William',
            'title': 'Learning Programming',
            'title_sort': 'Learning Programming'
        }
        dict_of_books[3] = {
            'author': 'Matthew Williams',
            'author_sort': 'Williams, Matthew',
            'title': 'A Book With No Annotations',
            'title_sort': 'Book With No Annotations, A'
        }

        self._log("%s:get_installed_books()" % self.app_name)
        self.installed_books = []

        # Don't change the template of books_db string
        books_db = "%s_books_%s" % (re.sub(
            ' ', '_', self.app_name), re.sub(' ', '_', self.opts.device_name))
        installed_books = set([])

        # Create the books table
        self.create_books_table(books_db)

        # Initialize the progress bar
        self.opts.pb.set_label("Getting installed books from %s" %
                               self.app_name)
        self.opts.pb.set_value(0)
        self.opts.pb.set_maximum(len(dict_of_books))

        #  Add installed books to the database
        for book_id in dict_of_books:
            # Add book_id to list of installed_books (make this a sql function)
            installed_books.add(book_id)

            # Populate a BookStruct with available metadata
            book_mi = BookStruct()

            # Required items
            book_mi.active = True
            book_mi.author = dict_of_books[book_id]['author']
            book_mi.book_id = book_id
            book_mi.reader_app = self.app_name
            book_mi.title = dict_of_books[book_id]['title']

            # Optional items
            if 'author_sort' in dict_of_books[book_id]:
                book_mi.author_sort = dict_of_books[book_id]['author_sort']
            if 'genre' in dict_of_books[book_id]:
                book_mi.genre = dict_of_books[book_id]['genre']
            if 'title_sort' in dict_of_books[book_id]:
                book_mi.title_sort = dict_of_books[book_id]['title_sort']
            if 'uuid' in dict_of_books[book_id]:
                book_mi.uuid = dict_of_books[book_id]['uuid']

            # Add book to books_db
            self.add_to_books_db(books_db, book_mi)

            # Increment the progress bar
            self.opts.pb.increment()

        # Update the timestamp
        self.update_timestamp(books_db)
        self.commit()

        self.installed_books = list(installed_books)
Esempio n. 3
0
    def get_installed_books(self):
        '''
        For each book, construct a BookStruct object with the book's metadata.
        Starred items are minimally required.
           BookStruct properties:
            *active: [True|False]
            *author: "John Smith"
             author_sort: (if known)
            *book_id: an int uniquely identifying the book.
                     Highlights are associated with books through book_id
             genre: "Fiction" (if known)
            *reader_app: self.app_name
            *title: "The Story of John Smith"
             title_sort: "Story of John Smith, The" (if known)
             uuid: Calibre's uuid for this book, if known
        '''
        self._log("%s:get_installed_books()" % self.app_name)
        self.installed_books = []

        self.device = self.opts.gui.device_manager.device
        path_map = self.get_path_map()

        # Calibre already knows what books are on the device, so use it.
        db = self.opts.gui.library_view.model().db
        self.onDeviceIds = set(
            db.search_getting_ids('ondevice:True',
                                  None,
                                  sort_results=False,
                                  use_virtual_library=False))

        # Add books added to Tolino by WhisperNet or download
        #         resolved_path_map = self._get_imported_books(resolved_path_map)

        self.books_db = self.generate_books_db_name(self.app_name_,
                                                    self.opts.device_name)

        installed_books = set([])

        # Used by get_active_annotations() to look up metadata based on title
        self.installed_books_by_title = {}

        # Create the books table
        self.create_books_table(self.books_db)

        # Initialize the progress bar
        self.opts.pb.set_label("Getting installed books from %s" %
                               self.app_name)
        self.opts.pb.set_value(0)
        self.opts.pb.show()
        self.opts.pb.set_maximum(len(self.onDeviceIds))

        #  Add installed books to the database
        for book_id in self.onDeviceIds:
            try:
                library_mi = mi = db.get_metadata(book_id, index_is_id=True)
            except Exception as e:
                self._log("Unable to get metadata from book. book_id='%s'" %
                          (book_id))
                self._log(" Exception thrown was=%s" % (str(e)))
                continue

            self._log("Book on device title: '%s'" % (mi.title))
            for model in (self.opts.gui.memory_view.model(),
                          self.opts.gui.card_a_view.model(),
                          self.opts.gui.card_b_view.model()):
                model_paths = model.paths_for_db_ids(set([book_id]),
                                                     as_map=True)[book_id]
                if model_paths:
                    device_path = model_paths[0].path
                    self._log(" Book on device path: '%s'" % (device_path, ))
                    mi = self._get_metadata(device_path)
                    #                     self._log(" Book on device path: '%s'" % (mi,))
                    break

            if 'News' in mi.tags:
                if not self.collect_news_clippings:
                    continue
                installed_books.add(self.news_clippings_cid)
            else:
                installed_books.add(book_id)

            #self._log(mi.standard_field_keys())
            # Populate a BookStruct with available metadata
            book_mi = BookStruct()
            #             book_mi.path = resolved_path_map[book_id]

            # Required items
            book_mi.active = True

            # Massage last, first authors back to normalcy
            book_mi.author = ''
            for i, author in enumerate(mi.authors):
                this_author = author.split(', ')
                this_author.reverse()
                book_mi.author += ' '.join(this_author)
                if i < len(mi.authors) - 1:
                    book_mi.author += ' & '

            book_mi.book_id = book_id
            book_mi.reader_app = self.app_name
            book_mi.title = mi.title.strip()
            # Add book to indexed_books
            self.installed_books_by_title[mi.title] = {
                'book_id': book_id,
                'author_sort': mi.author_sort
            }

            # Optional items
            if mi.tags:
                book_mi.genre = ', '.join([tag for tag in mi.tags])
            if 'News' in mi.tags:
                book_mi.book_id = self.news_clippings_cid

            if hasattr(mi, 'author_sort'):
                book_mi.author_sort = mi.author_sort
            self.installed_books_by_title[
                mi.title]['author_sort'] = mi.author_sort

            if hasattr(mi, 'title_sort'):
                book_mi.title_sort = mi.title_sort
            else:
                book_mi.title_sort = re.sub('^\s*A\s+|^\s*The\s+|^\s*An\s+',
                                            '', mi.title).rstrip()

            if hasattr(library_mi, 'uuid'):
                self._log(" Book on has uuid: '%s'" % (library_mi.uuid, ))
                book_mi.uuid = library_mi.uuid
                self.installed_books_by_title[mi.title]['uuid'] = book_mi.uuid

            # Add book to self.books_db
            self.add_to_books_db(self.books_db, book_mi)

            # Increment the progress bar
            self.opts.pb.increment()

        self.opts.pb.hide()
        # Update the timestamp
        self.update_timestamp(self.books_db)
        self.commit()

        self.installed_books = list(installed_books)
Esempio n. 4
0
    def get_installed_books(self):
        '''
        For each book, construct a BookStruct object with the book's metadata.
        Starred items are minimally required.
           BookStruct properties:
            *active: [True|False]
            *author: "John Smith"
             author_sort: (if known)
            *book_id: an int uniquely identifying the book.
                     Highlights are associated with books through book_id
             genre: "Fiction" (if known)
            *reader_app: self.app_name
            *title: "The Story of John Smith"
             title_sort: "Story of John Smith, The" (if known)
             uuid: Calibre's uuid for this book, if known
        '''
        self._log("%s:get_installed_books()" % self.app_name)
        self.installed_books = []

        self.device = self.opts.gui.device_manager.device
        path_map = self.get_path_map()

        # Get books added to Kindle by calibre
        resolved_path_map = self._get_installed_books(path_map)

        # Add books added to Kindle by WhisperNet or download
        resolved_path_map = self._get_imported_books(resolved_path_map)

        self.books_db = self.generate_books_db_name(self.app_name_, self.opts.device_name)

        installed_books = set([])

        # Used by get_active_annotations() to look up metadata based on title
        self.installed_books_by_title = {}

        # Create the books table
        self.create_books_table(self.books_db)

        # Initialize the progress bar
        self.opts.pb.set_label("Getting installed books from %s" % self.app_name)
        self.opts.pb.set_value(0)
        self.opts.pb.show()
        self.opts.pb.set_maximum(len(resolved_path_map))

        #  Add installed books to the database
        for book_id in resolved_path_map:
            try:
                mi = self._get_metadata(resolved_path_map[book_id])
            except Exception as e:
                self._log("Unable to get metadata from book. path='%s'" % (resolved_path_map[book_id]))
                self._log(" Exception thrown was=%s" % (str(e)))
                continue

            self._log("Book on device title: '%s'" % (mi.title))
            if 'News' in mi.tags:
                if not self.collect_news_clippings:
                    continue
                installed_books.add(self.news_clippings_cid)
            else:
                installed_books.add(book_id)

            #self._log(mi.standard_field_keys())
            # Populate a BookStruct with available metadata
            book_mi = BookStruct()
            book_mi.path = resolved_path_map[book_id]

            # Required items
            book_mi.active = True

            # Massage last, first authors back to normalcy
            book_mi.author = ''
            for i, author in enumerate(mi.authors):
                this_author = author.split(', ')
                this_author.reverse()
                book_mi.author += ' '.join(this_author)
                if i < len(mi.authors) - 1:
                    book_mi.author += ' & '

            book_mi.book_id = book_id
            book_mi.reader_app = self.app_name
            book_mi.title = mi.title.strip()

            # Optional items
            if mi.tags:
                book_mi.genre = ', '.join([tag for tag in mi.tags])
            if 'News' in mi.tags:
                book_mi.book_id = self.news_clippings_cid

            if hasattr(mi, 'author_sort'):
                book_mi.author_sort = mi.author_sort

            if hasattr(mi, 'title_sort'):
                book_mi.title_sort = mi.title_sort
            else:
                book_mi.title_sort = re.sub('^\s*A\s+|^\s*The\s+|^\s*An\s+', '', mi.title).rstrip()

            if hasattr(mi, 'uuid'):
                book_mi.uuid = mi.uuid

            # Add book to self.books_db
            self.add_to_books_db(self.books_db, book_mi)

            # Add book to indexed_books
            self.installed_books_by_title[mi.title.strip()] = {'book_id': book_id, 'author_sort': mi.author_sort}

            # Increment the progress bar
            self.opts.pb.increment()

        self.opts.pb.hide()
        # Update the timestamp
        self.update_timestamp(self.books_db)
        self.commit()

        self.installed_books = list(installed_books)
Esempio n. 5
0
    def get_installed_books(self):
        """
        Fetch installed books from mainDb.sqlite or cached_db
        Populate self.tocs: {book_id: {toc_entries} ...}
        """
        self._log("%s:get_installed_books()" % self.app_name)

        self.opts.pb.set_label("Getting installed books from %s" %
                               self.app_name)
        self.opts.pb.set_value(0)

        db_profile = self._localize_database_path(self.app_id,
                                                  self.books_subpath)
        self.books_db = db_profile['path']

        cached_db = self.generate_books_db_name(self.app_name_,
                                                self.ios.device_name)

        if self.opts.disable_caching or not self._cache_is_current(
                db_profile['stats'], cached_db):
            # (Re)load installed books from device
            self._log(" fetching installed books from %s on %s" %
                      (self.app_name, self.ios.device_name))

            # Mount the ios container
            self.ios.mount_ios_app(app_id=self.app_id)

            installed_books = set([])
            self.tocs = {}

            # Create the books table as needed
            self.create_books_table(cached_db)

            con = sqlite3.connect(self.books_db)
            with con:
                con.row_factory = sqlite3.Row
                cur = con.cursor()
                cur.execute('''SELECT
                                  Author,
                                  AuthorSort,
                                  Title,
                                  CalibreTitleSort,
                                  FileName,
                                  Books.ID AS id_,
                                  UUID
                               FROM Books
                            ''')
                rows = cur.fetchall()
                self.opts.pb.set_maximum(len(rows))
                for row in rows:
                    self.opts.pb.increment()
                    this_is_news = False

                    path = self._fix_Marvin_path(row[b'FileName'])
                    book_id = row[b'id_']

                    # Get the genre(s) for this book
                    genre_cur = con.cursor()
                    genre_cur.execute("""SELECT
                                            Subject
                                         FROM BookSubjects
                                         WHERE BookID = '{0}'
                                      """.format(book_id))
                    genres = None
                    genre_rows = genre_cur.fetchall()
                    if genre_rows is not None:
                        genres = ', '.join(
                            [genre[b'Subject'] for genre in genre_rows])
                    genre_cur.close()

                    if 'News' in genres:
                        if not self.collect_news_clippings:
                            continue
                        this_is_news = True

                    installed_books.add(book_id)

                    # Populate a BookStruct
                    b_mi = BookStruct()
                    b_mi.active = True
                    b_mi.author = row[b'Author']
                    b_mi.author_sort = row[b'AuthorSort']
                    b_mi.book_id = book_id
                    b_mi.genre = genres
                    b_mi.title = row[b'Title']
                    b_mi.title_sort = row[b'CalibreTitleSort']
                    b_mi.uuid = row[b'UUID']

                    # Add book to books_db
                    self.add_to_books_db(cached_db, b_mi)

                    # Get the library cid, confidence
                    toc_entries = None
                    if this_is_news:
                        cid = self.news_clippings_cid
                        confidence = 5
                        if path is not None:
                            toc_entries = self._get_epub_toc(
                                path=path, prepend_title=b_mi.title)
                    else:
                        cid, confidence = self.parent.generate_confidence(b_mi)
                        if confidence >= 2:
                            toc_entries = self._get_epub_toc(cid=cid,
                                                             path=path)
                        elif path is not None:
                            toc_entries = self._get_epub_toc(path=path)
                    self.tocs[book_id] = toc_entries

                # Update the timestamp
                self.update_timestamp(cached_db)
                self.commit()

            self.ios.disconnect_idevice()

            installed_books = list(installed_books)

        else:
            # Load installed books from cache
            self._log(" retrieving cached books from %s" % cached_db)
            self.opts.pb.set_maximum(2)
            self.opts.pb.set_value(1)
            Application.processEvents()
            installed_books = self._get_cached_books(cached_db)

        self.installed_books = installed_books
Esempio n. 6
0
    def get_installed_books(self):
        '''
        For each book, construct a BookStruct object with the book's metadata.
        Starred items are minimally required.
           BookStruct properties:
            *active: [True|False]
            *author: "John Smith"
             author_sort: (if known)
            *book_id: an int uniquely identifying the book.
                     Highlights are associated with books through book_id
             genre: "Fiction" (if known)
            *reader_app: self.app_name
            *title: "The Story of John Smith"
             title_sort: "Story of John Smith, The" (if known)
             uuid: Calibre's uuid for this book, if known
        '''

        self._log_location("Start!!!!")
        self._log("%s:get_installed_books()" % self.app_name)
        self.installed_books = []

        self.device = self.opts.gui.device_manager.device

        # Calibre already knows what books are on the device, so use it.
        db = self.opts.gui.library_view.model().db
        self.onDeviceIds = set(db.search_getting_ids('ondevice:True', None, sort_results=False, use_virtual_library=False))
        self._log("%s:get_installed_books() - self.onDeviceIds=" % self.onDeviceIds)

        self._log("%s:get_installed_books() - about to call self.generate_books_db_name" % self.app_name)
        self.books_db = self.generate_books_db_name(self.app_name_, self.opts.device_name)
        installed_books = set([])

        # Used by get_active_annotations() to look up metadata based on title
        self.installed_books_by_title = {}

        # Create the books table
        self.create_books_table(self.books_db)

        # Initialize the progress bar
        self.opts.pb.set_label("Getting installed books from %s" % self.app_name)
        self.opts.pb.set_value(0)
        self.opts.pb.set_maximum(len(self.onDeviceIds))
        self._log("Number of books on the device=%d" % len(self.onDeviceIds))

        #  Add installed books to the database
        for book_id in self.onDeviceIds:
            mi = db.get_metadata(book_id, index_is_id=True)
#            self._log_location("book: {0} - {1}".format(mi.authors, mi.title))
#            self._log("mi={0}".format(mi))
            installed_books.add(book_id)

            # Populate a BookStruct with available metadata
            book_mi = BookStruct()
#            book_mi.path = resolved_path_map[book_id]            # Add book_id to list of installed_books (make this a sql function)
            installed_books.add(book_id)

            # Populate a BookStruct with available metadata
            book_mi = BookStruct()

            # Required items
            book_mi.active = True
            # Massage last, first authors back to normalcy
            book_mi.author = ''
            for i, author in enumerate(mi.authors):
#                self._log_location("author=%s, author.__class__=%s" % (author, author.__class__))
                this_author = author.split(', ')
                this_author.reverse()
                book_mi.author += ' '.join(this_author)
                if i < len(mi.authors) - 1:
                    book_mi.author += ' & '

            book_mi.book_id = book_id
            book_mi.reader_app = self.app_name
            book_mi.title = mi.title

            if hasattr(mi, 'author_sort'):
                book_mi.author_sort = mi.author_sort

            if hasattr(mi, 'title_sort'):
                book_mi.title_sort = mi.title_sort
            else:
                book_mi.title_sort = re.sub('^\s*A\s+|^\s*The\s+|^\s*An\s+', '', mi.title).rstrip()

            if hasattr(mi, 'uuid'):
                book_mi.uuid = mi.uuid

            # Add book to self.books_db
            self.add_to_books_db(self.books_db, book_mi)

            # Add book to indexed_books
            self.installed_books_by_title[mi.title] = {'book_id': book_id, 'author_sort': mi.author_sort}

            # Increment the progress bar
            self.opts.pb.increment()

        # Update the timestamp
        self.update_timestamp(self.books_db)
        self.commit()

        self.installed_books = list(installed_books)
        self._log_location("Finish!!!!")
Esempio n. 7
0
    def get_installed_books(self):
        """
        Fetch installed books from iBooks_*.sqlite or cache
        """
        self._log("%s:get_installed_books()" % self.app_name)

        self.opts.pb.set_label("Getting installed books from %s" %
                               self.app_name)
        self.opts.pb.set_value(0)

        db_profile = self._localize_database_path(self.app_id,
                                                  self.books_subpath)
        self.books_db = db_profile['path']

        cached_db = self.generate_books_db_name(self.app_name_,
                                                self.ios.device_name)

        # Test timestamp against cached value
        if self.opts.disable_caching or not self._cache_is_current(
                db_profile['stats'], cached_db):
            # (Re)load installed books from device
            self._log(" fetching installed books from %s on %s" %
                      (self.app_name, self.ios.device_name))

            # Mount the Media folder
            self.ios.mount_ios_media_folder()

            installed_books = set([])
            self.tocs = {}

            # Create the books table as needed
            self.create_books_table(cached_db)

            con = sqlite3.connect(self.books_db)
            with con:
                con.row_factory = sqlite3.Row
                cur = con.cursor()
                cur.execute('''SELECT ZASSETURL,
                                      ZBOOKAUTHOR,
                                      ZSORTAUTHOR,
                                      ZBOOKTITLE,
                                      ZSORTTITLE,
                                      ZDATABASEKEY
                               FROM ZBKBOOKINFO
                               WHERE ZASSETURL LIKE 'file://localhost%' AND
                                     ZASSETURL LIKE '%.epub/'
                            ''')
                rows = cur.fetchall()
                self.opts.pb.set_maximum(len(rows))
                for row in rows:
                    self.opts.pb.increment()
                    this_is_news = False

                    path = self._fix_iBooks_path(row[b'ZASSETURL'])
                    mi = self._get_metadata(path, row[b'ZBOOKTITLE'])
                    genres = mi['genre'].split(', ')
                    if 'News' in genres:
                        if not self.collect_news_clippings:
                            continue
                        this_is_news = True

                    book_id = row[b'ZDATABASEKEY']
                    installed_books.add(book_id)

                    # Populate a BookStruct
                    b_mi = BookStruct()
                    b_mi.active = True
                    b_mi.author = row[b'ZBOOKAUTHOR']
                    b_mi.author_sort = row[b'ZSORTAUTHOR']
                    b_mi.book_id = book_id
                    b_mi.genre = mi['genre']
                    b_mi.title = row[b'ZBOOKTITLE']
                    b_mi.title_sort = row[b'ZSORTTITLE']
                    b_mi.uuid = mi['uuid']

                    # Add book to books_db
                    self.add_to_books_db(cached_db, b_mi)

                    # Get the library cid, confidence
                    toc_entries = None
                    if this_is_news:
                        cid = self.news_clippings_cid
                        confidence = 5
                        if path is not None:
                            toc_entries = self._get_epub_toc(
                                path=path, prepend_title=b_mi.title)
                    elif self.ios.exists(path):
                        cid, confidence = self.parent.generate_confidence(b_mi)
                        if confidence >= 2:
                            toc_entries = self._get_epub_toc(cid=cid,
                                                             path=path)
                        elif path is not None:
                            toc_entries = self._get_epub_toc(path=path)
                    self.tocs[book_id] = toc_entries

                # Update the timestamp
                self.update_timestamp(cached_db)
                self.commit()

            self.ios.dismount_ios_media_folder()
            installed_books = list(installed_books)

        else:
            self._log(" retrieving cached books from %s" % cached_db)
            self.opts.pb.set_maximum(2)
            self.opts.pb.set_value(1)
            Application.processEvents()
            installed_books = self._get_cached_books(cached_db)

        self.installed_books = installed_books
    def get_installed_books(self):
        '''
        For each book, construct a BookStruct object with the book's metadata.
        Starred items are minimally required.
           BookStruct properties:
            *active: [True|False]
            *author: "John Smith"
             author_sort: (if known)
            *book_id: an int uniquely identifying the book.
                     Highlights are associated with books through book_id
             genre: "Fiction" (if known)
            *reader_app: self.app_name
            *title: "The Story of John Smith"
             title_sort: "Story of John Smith, The" (if known)
             uuid: Calibre's uuid for this book, if known
        '''
        # Sample installed books indexed by book_id
        dict_of_books = {}
        dict_of_books[1] = {'author': 'John Smith',
                            'author_sort': 'Smith, John',
                            'title': 'The Book by John Smith',
                            'title_sort': 'Book by John Smith, The'}
        dict_of_books[2] = {'author': 'William Jones',
                            'author_sort': 'Jones, William',
                            'title': 'Learning Programming',
                            'title_sort': 'Learning Programming'}
        dict_of_books[3] = {'author': 'Matthew Williams',
                            'author_sort': 'Williams, Matthew',
                            'title': 'A Book With No Annotations',
                            'title_sort': 'Book With No Annotations, A'}

        self._log("%s:get_installed_books()" % self.app_name)
        self.installed_books = []

        # Don't change the template of books_db string
        books_db = "%s_books_%s" % (re.sub(' ', '_', self.app_name), re.sub(' ', '_', self.opts.device_name))
        installed_books = set([])

        # Create the books table
        self.create_books_table(books_db)

        # Initialize the progress bar
        self.opts.pb.set_label("Getting installed books from %s" % self.app_name)
        self.opts.pb.set_value(0)
        self.opts.pb.set_maximum(len(dict_of_books))

        #  Add installed books to the database
        for book_id in dict_of_books:
            # Add book_id to list of installed_books (make this a sql function)
            installed_books.add(book_id)

            # Populate a BookStruct with available metadata
            book_mi = BookStruct()

            # Required items
            book_mi.active = True
            book_mi.author = dict_of_books[book_id]['author']
            book_mi.book_id = book_id
            book_mi.reader_app = self.app_name
            book_mi.title = dict_of_books[book_id]['title']

            # Optional items
            if 'author_sort' in dict_of_books[book_id]:
                book_mi.author_sort = dict_of_books[book_id]['author_sort']
            if 'genre' in dict_of_books[book_id]:
                book_mi.genre = dict_of_books[book_id]['genre']
            if 'title_sort' in dict_of_books[book_id]:
                book_mi.title_sort = dict_of_books[book_id]['title_sort']
            if 'uuid' in dict_of_books[book_id]:
                book_mi.uuid = dict_of_books[book_id]['uuid']

            # Add book to books_db
            self.add_to_books_db(books_db, book_mi)

            # Increment the progress bar
            self.opts.pb.increment()

        # Update the timestamp
        self.update_timestamp(books_db)
        self.commit()

        self.installed_books = list(installed_books)
Esempio n. 9
0
    def get_installed_books(self):
        """
        Fetch installed books from mainDb.sqlite or cached_db
        Populate self.tocs: {book_id: {toc_entries} ...}
        """
        self._log("%s:get_installed_books()" % self.app_name)

        self.opts.pb.set_label("Getting installed books from %s" % self.app_name)
        self.opts.pb.set_value(0)

        db_profile = self._localize_database_path(self.app_id, self.books_subpath)
        self.books_db = db_profile['path']

        cached_db = self.generate_books_db_name(self.app_name_, self.ios.device_name)

        if self.opts.disable_caching or not self._cache_is_current(db_profile['stats'], cached_db):
            # (Re)load installed books from device
            self._log(" fetching installed books from %s on %s" % (self.app_name, self.ios.device_name))

            # Mount the ios container
            self.ios.mount_ios_app(app_id=self.app_id)

            installed_books = set([])
            self.tocs = {}

            # Create the books table as needed
            self.create_books_table(cached_db)

            con = sqlite3.connect(self.books_db)
            with con:
                con.row_factory = sqlite3.Row
                cur = con.cursor()
                cur.execute('''SELECT
                                  Author,
                                  AuthorSort,
                                  Title,
                                  CalibreTitleSort,
                                  FileName,
                                  Books.ID AS id_,
                                  UUID
                               FROM Books
                            ''')
                rows = cur.fetchall()
                self.opts.pb.set_maximum(len(rows))
                for row in rows:
                    self.opts.pb.increment()
                    this_is_news = False

                    path = self._fix_Marvin_path(row[b'FileName'])
                    book_id = row[b'id_']

                    # Get the genre(s) for this book
                    genre_cur = con.cursor()
                    genre_cur.execute("""SELECT
                                            Subject
                                         FROM BookSubjects
                                         WHERE BookID = '{0}'
                                      """.format(book_id))
                    genres = None
                    genre_rows = genre_cur.fetchall()
                    if genre_rows is not None:
                        genres = ', '.join([genre[b'Subject'] for genre in genre_rows])
                    genre_cur.close()

                    if 'News' in genres:
                        if not self.collect_news_clippings:
                            continue
                        this_is_news = True

                    installed_books.add(book_id)

                    # Populate a BookStruct
                    b_mi = BookStruct()
                    b_mi.active = True
                    b_mi.author = row[b'Author']
                    b_mi.author_sort = row[b'AuthorSort']
                    b_mi.book_id = book_id
                    b_mi.genre = genres
                    b_mi.title = row[b'Title']
                    b_mi.title_sort = row[b'CalibreTitleSort']
                    b_mi.uuid = row[b'UUID']

                    # Add book to books_db
                    self.add_to_books_db(cached_db, b_mi)

                    # Get the library cid, confidence
                    toc_entries = None
                    if this_is_news:
                        cid = self.news_clippings_cid
                        confidence = 5
                        if path is not None:
                            toc_entries = self._get_epub_toc(path=path, prepend_title=b_mi.title)
                    else:
                        cid, confidence = self.parent.generate_confidence(b_mi)
                        if confidence >= 2:
                            toc_entries = self._get_epub_toc(cid=cid, path=path)
                        elif path is not None:
                            toc_entries = self._get_epub_toc(path=path)
                    self.tocs[book_id] = toc_entries

                # Update the timestamp
                self.update_timestamp(cached_db)
                self.commit()

            self.ios.disconnect_idevice()

            installed_books = list(installed_books)

        else:
            # Load installed books from cache
            self._log(" retrieving cached books from %s" % cached_db)
            self.opts.pb.set_maximum(2)
            self.opts.pb.set_value(1)
            Application.processEvents()
            installed_books = self._get_cached_books(cached_db)

        self.installed_books = installed_books
Esempio n. 10
0
    def get_installed_books(self):
        """
        Fetch installed books from iBooks_*.sqlite or cache
        """
        self._log("%s:get_installed_books()" % self.app_name)

        self.opts.pb.set_label("Getting installed books from %s" % self.app_name)
        self.opts.pb.set_value(0)

        db_profile = self._localize_database_path(self.app_id,  self.books_subpath)
        self.books_db = db_profile['path']

        cached_db = self.generate_books_db_name(self.app_name_, self.ios.device_name)

        # Test timestamp against cached value
        if self.opts.disable_caching or not self._cache_is_current(db_profile['stats'], cached_db):
            # (Re)load installed books from device
            self._log(" fetching installed books from %s on %s" % (self.app_name, self.ios.device_name))

            # Mount the Media folder
            self.ios.mount_ios_media_folder()

            installed_books = set([])
            self.tocs = {}

            # Create the books table as needed
            self.create_books_table(cached_db)

            con = sqlite3.connect(self.books_db)
            with con:
                con.row_factory = sqlite3.Row
                cur = con.cursor()
                cur.execute('''SELECT ZASSETURL,
                                      ZBOOKAUTHOR,
                                      ZSORTAUTHOR,
                                      ZBOOKTITLE,
                                      ZSORTTITLE,
                                      ZDATABASEKEY
                               FROM ZBKBOOKINFO
                               WHERE ZASSETURL LIKE 'file://localhost%' AND
                                     ZASSETURL LIKE '%.epub/'
                            ''')
                rows = cur.fetchall()
                self.opts.pb.set_maximum(len(rows))
                for row in rows:
                    self.opts.pb.increment()
                    this_is_news = False

                    path = self._fix_iBooks_path(row[b'ZASSETURL'])
                    mi = self._get_metadata(path, row[b'ZBOOKTITLE'])
                    genres = mi['genre'].split(', ')
                    if 'News' in genres:
                        if not self.collect_news_clippings:
                            continue
                        this_is_news = True

                    book_id = row[b'ZDATABASEKEY']
                    installed_books.add(book_id)

                    # Populate a BookStruct
                    b_mi = BookStruct()
                    b_mi.active = True
                    b_mi.author = row[b'ZBOOKAUTHOR']
                    b_mi.author_sort = row[b'ZSORTAUTHOR']
                    b_mi.book_id = book_id
                    b_mi.genre = mi['genre']
                    b_mi.title = row[b'ZBOOKTITLE']
                    b_mi.title_sort = row[b'ZSORTTITLE']
                    b_mi.uuid = mi['uuid']

                    # Add book to books_db
                    self.add_to_books_db(cached_db, b_mi)

                    # Get the library cid, confidence
                    toc_entries = None
                    if this_is_news:
                        cid = self.news_clippings_cid
                        confidence = 5
                        if path is not None:
                            toc_entries = self._get_epub_toc(path=path, prepend_title=b_mi.title)
                    elif self.ios.exists(path):
                            cid, confidence = self.parent.generate_confidence(b_mi)
                            if confidence >= 2:
                                toc_entries = self._get_epub_toc(cid=cid, path=path)
                            elif path is not None:
                                toc_entries = self._get_epub_toc(path=path)
                    self.tocs[book_id] = toc_entries

                # Update the timestamp
                self.update_timestamp(cached_db)
                self.commit()

            self.ios.dismount_ios_media_folder()
            installed_books = list(installed_books)

        else:
            self._log(" retrieving cached books from %s" % cached_db)
            self.opts.pb.set_maximum(2)
            self.opts.pb.set_value(1)
            Application.processEvents()
            installed_books = self._get_cached_books(cached_db)

        self.installed_books = installed_books