예제 #1
0
파일: driver.py 프로젝트: 089git/calibre
 def __init__(self, path):
     if not os.path.isdir(path):
         raise IOError, 'Path is not a folder'
     path = USBMS.normalize_path(path)
     if path.endswith(os.sep):
         self._main_prefix = path
     else:
         self._main_prefix = path + os.sep
     self.booklist_class = BookList
     self.is_connected = True
예제 #2
0
 def __init__(self, path):
     if not os.path.isdir(path):
         raise OSError('Path is not a folder')
     path = USBMS.normalize_path(path)
     if path.endswith(os.sep):
         self._main_prefix = path
     else:
         self._main_prefix = path + os.sep
     self.booklist_class = BookList
     self.is_connected = True
예제 #3
0
    def _fetch_annotations(self):
        self._log_location("Start!!!!")

        count_bookmark_query = ('''
            SELECT COUNT(*) AS num_bookmarks FROM Tags t
            WHERE TagID = 102 AND VAL IS NOT 'bookmark'
            AND ItemID IN (SELECT OID from Items WHERE State = 0)
            ''')

        books_metadata_query = ('''
            SELECT b.OID AS book_oid, i.format, p.Path || f.filename AS filepath, Title, Authors FROM Books b
            LEFT JOIN (SELECT MAX(OID), BookID, PathID, Name AS filename FROM Files GROUP BY BookID) f ON b.OID = f.BookID
            LEFT JOIN (SELECT ItemID, Val AS format FROM Tags WHERE TagID = 17) i ON b.OID = i.ItemID
            LEFT JOIN Paths p ON p.OID = PathID
            WHERE b.OID IN (SELECT DISTINCT ParentID FROM Items WHERE TypeID = 4 ORDER BY ParentID)
            GROUP BY b.OID
            ORDER BY b.OID
            ''')

        # For 104 (highlight_txt) either use json_extract(text), or import JSON using python
        # as notes edited in the PB notes app loose their Begin/End JSON fields.
        annotation_data_query = ('''
            SELECT i.OID AS item_oid, i.TimeAlt, t.TagID, t.Val FROM Items i
            LEFT JOIN Tags t ON i.OID=t.ItemID
            WHERE ParentID = ? AND State = 0
            ORDER BY i.OID, t.TagID
            ''')

        def get_device_path_from_id(id_):
            paths = []
            for x in ('memory', 'card_a', 'card_b'):
                x = getattr(self.opts.gui, x + '_view').model()
                paths += x.paths_for_db_ids(set([id_]), as_map=True)[id_]
            return paths[0].path if paths else None

        # Modified.
        def generate_annotation_paths(ids, mode="default"):
            path_map = {}
            for id in ids:
                fullpath = get_device_path_from_id(id)
                if not fullpath:
                    continue

                if mode == "default":
                    pbmainroot = "/mnt/ext1/"
                    pbcardroot = "/mnt/ext2/"

                if self.device._main_prefix in fullpath:
                    path_map[os.path.join(
                        pbmainroot,
                        os.path.relpath(fullpath,
                                        start=self.device._main_prefix))] = id
                elif self.device._card_a_prefix in fullpath:
                    path_map[os.path.join(
                        pbcardroot,
                        os.path.relpath(
                            fullpath, start=self.device._card_a_prefix))] = id
                elif fullpath.startswith(('/var/', '/tmp/')):
                    continue
                else:
                    self._log("Path not matched: %s" % (fullpath))

            return path_map

        def generate_title_map(ids, db):
            title_map = {}
            for id in ids:
                title = db.get_metadata(id, index_is_id=True).title
                if title:
                    title_map[title] = {}
                    title_map[title]['book_id'] = id
                    title_map[title]['authors'] = db.get_metadata(
                        id, index_is_id=True).format_authors()
                else:
                    continue

            return title_map

        # Get DB location (only stock or default profile)
        self._log("Getting DB location")
        locations = [
            os.path.join(self.device._main_prefix, 'system/config/books.db'),
            os.path.join(self.device._main_prefix,
                         'system/profiles/default/config/books.db')
        ]
        paths = [path for path in locations if os.path.exists(path)]
        if paths:
            db_location = USBMS.normalize_path(paths[0])
        else:
            self._log(
                "No DB found. Currently only supports default profiles, with DB based notes. Stopping"
            )
            return

        # Borrowed from Kobo
        db = self.opts.gui.library_view.model().db
        if not self.onDeviceIds:
            self.onDeviceIds = set(
                db.search_getting_ids('ondevice:True',
                                      None,
                                      sort_results=False,
                                      use_virtual_library=False))

        if len(self.onDeviceIds) == 0:
            return
        self._log("_fetch_annotations - onDeviceIds={0}".format(
            self.onDeviceIds))

        path_map = generate_annotation_paths(self.onDeviceIds)
        title_map = generate_title_map(self.onDeviceIds, db)

        # Start fetching annotations
        from contextlib import closing
        import apsw
        with closing(apsw.Connection(db_location)) as connection:
            self.opts.pb.set_label(_("Fetch annotations from database"))
            #connection.setrowtrace(self.row_factory)

            cursor = connection.cursor()
            cursor.execute(count_bookmark_query)
            try:
                result = next(cursor)
                count_bookmarks = result[0]
            except StopIteration:
                count_bookmarks = 0
            self._log(
                "_fetch_annotations - Total number of bookmarks={0}".format(
                    count_bookmarks))
            self._log("_fetch_annotations - About to get annotations")
            self._read_database_annotations(connection,
                                            books_metadata_query,
                                            annotation_data_query,
                                            path_map,
                                            title_map,
                                            fetchbookmarks=False)
            self._log("_fetch_annotations - Finished getting annotations")

        self._log_location("Finish!!!!")