'Interrogate connected Kindle for bookmarks.
Discover bookmarks associated with books on Kindle downloaded by calibre.
Used in Descriptions to show reading progress, Last Read section showing date
last read. Kindle-specific, for AZW, MOBI, TAN and TXT formats.
Uses the system default save_template specified in
Preferences|Add/Save|Sending to device, not a customized one specified in
the Kindle plugin.
Inputs:
(): bookmarks from connected Kindle
Output:
bookmarked_books (dict): dict of Bookmarks'

def fetch_bookmarks(self):

    from calibre.devices.usbms.device import Device
    from calibre.devices.kindle.bookmark import Bookmark
    from calibre.ebooks.metadata import MetaInformation
    MBP_FORMATS = [u'azw', u'mobi', u'prc', u'txt']
    mbp_formats = set(MBP_FORMATS)
    PDR_FORMATS = [u'pdf']
    pdr_formats = set(PDR_FORMATS)
    TAN_FORMATS = [u'tpz', u'azw1']
    tan_formats = set(TAN_FORMATS)
    class BookmarkDevice(Device, ):
        def initialize(self, save_template):
            self._save_template = save_template
            self.SUPPORTS_SUB_DIRS = True
        def save_template(self):
            return self._save_template
    def _resolve_bookmark_paths(storage, path_map):
        pop_list = []
        book_ext = {}
        for id in path_map:
            file_fmts = set()
            for fmt in path_map[id]['fmts']:
                file_fmts.add(fmt)
            bookmark_extension = None
            if file_fmts.intersection(tan_formats):
                book_extension = list(file_fmts.intersection(tan_formats))[0]
                bookmark_extension = 'han'
            elif file_fmts.intersection(mbp_formats):
                book_extension = list(file_fmts.intersection(mbp_formats))[0]
                bookmark_extension = 'mbp'
            elif file_fmts.intersection(tan_formats):
                book_extension = list(file_fmts.intersection(tan_formats))[0]
                bookmark_extension = 'tan'
            elif file_fmts.intersection(pdr_formats):
                book_extension = list(file_fmts.intersection(pdr_formats))[0]
                bookmark_extension = 'pdr'
            if bookmark_extension:
                for vol in storage:
                    bkmk_path = path_map[id]['path'].replace(os.path.abspath('/<storage>'), vol)
                    bkmk_path = bkmk_path.replace('bookmark', bookmark_extension)
                    if os.path.exists(bkmk_path):
                        path_map[id] = bkmk_path
                        book_ext[id] = book_extension
                        break
                else:
                    pop_list.append(id)
            else:
                pop_list.append(id)
        for id in pop_list:
            path_map.pop(id)
        return (path_map, book_ext)
    self.bookmarked_books = {}
    if self.generate_recently_read:
        self.opts.log.info('                    Collecting    Kindle    bookmarks    matching    catalog    entries')
        d = BookmarkDevice(None)
        d.initialize(self.opts.connected_device['save_template'])
        bookmarks = {}
        for book in self.books_to_catalog:
            if ('formats' in book):
                path_map = {}
                id = book['id']
                original_title = (book['title'][(book['title'].find(':') + 2):] if book['series'] else book['title'])
                myMeta = MetaInformation(original_title, authors=book['authors'])
                myMeta.author_sort = book['author_sort']
                a_path = d.create_upload_path('/<storage>', myMeta, 'x.bookmark', create_dirs=False)
                path_map[id] = dict(path=a_path, fmts=[x.rpartition('.')[2] for x in book['formats']])
                (path_map, book_ext) = _resolve_bookmark_paths(self.opts.connected_device['storage'], path_map)
                if path_map:
                    bookmark_ext = path_map[id].rpartition('.')[2]
                    myBookmark = Bookmark(path_map[id], id, book_ext[id], bookmark_ext)
                    try:
                        book['percent_read'] = min(float(((100 * myBookmark.last_read) / myBookmark.book_length)), 100)
                    except:
                        book['percent_read'] = 0
                    dots = int(((book['percent_read'] + 5) / 10))
                    dot_string = (self.SYMBOL_PROGRESS_READ * dots)
                    empty_dots = (self.SYMBOL_PROGRESS_UNREAD * (10 - dots))
                    book['reading_progress'] = ('%s%s' % (dot_string, empty_dots))
                    bookmarks[id] = (myBookmark, book)
        self.bookmarked_books = bookmarks
