Beispiel #1
0
def main(args=sys.argv):
    parser = option_parser()
    opts, args = parser.parse_args(args)
    if len(args) < 2:
        parser.print_help()
        prints(_('No file specified'), file=sys.stderr)
        return 1
    path = args[1]
    stream_type = os.path.splitext(path)[1].replace('.', '').lower()

    trying_to_set = False
    for pref in config().option_set.preferences:
        if pref.name in ('to_opf', 'get_cover'):
            continue
        if getattr(opts, pref.name) is not None:
            trying_to_set = True
            break
    with open(path, 'rb') as stream:
        mi = get_metadata(stream, stream_type, force_read_metadata=True)
    if trying_to_set:
        prints(_('Original metadata')+'::')
    metadata = unicode_type(mi)
    if trying_to_set:
        metadata = '\t'+'\n\t'.join(metadata.split('\n'))
    prints(metadata, safe_encode=True)

    if trying_to_set:
        with open(path, 'r+b') as stream:
            do_set_metadata(opts, mi, stream, stream_type)
            stream.seek(0)
            stream.flush()
            lrf = None
            if stream_type == 'lrf':
                if opts.lrf_bookid is not None:
                    lrf = LRFMetaFile(stream)
                    lrf.book_id = opts.lrf_bookid
            mi = get_metadata(stream, stream_type, force_read_metadata=True)
        prints('\n' + _('Changed metadata') + '::')
        metadata = unicode_type(mi)
        metadata = '\t'+'\n\t'.join(metadata.split('\n'))
        prints(metadata, safe_encode=True)
        if lrf is not None:
            prints('\tBookID:', lrf.book_id)

    if opts.to_opf is not None:
        from calibre.ebooks.metadata.opf2 import OPFCreator
        opf = OPFCreator(getcwd(), mi)
        with open(opts.to_opf, 'wb') as f:
            opf.render(f)
        prints(_('OPF created in'), opts.to_opf)

    if opts.get_cover is not None:
        if mi.cover_data and mi.cover_data[1]:
            with open(opts.get_cover, 'wb') as f:
                f.write(mi.cover_data[1])
                prints(_('Cover saved to'), f.name)
        else:
            prints(_('No cover found'), file=sys.stderr)

    return 0
Beispiel #2
0
def main(args=sys.argv):
    parser = option_parser()
    opts, args = parser.parse_args(args)
    if len(args) < 2:
        parser.print_help()
        prints(_('No file specified'), file=sys.stderr)
        return 1
    path = args[1]
    stream = open(path, 'r+b')
    stream_type = os.path.splitext(path)[1].replace('.', '').lower()

    trying_to_set = False
    for pref in config().option_set.preferences:
        if pref.name in ('to_opf', 'get_cover'):
            continue
        if getattr(opts, pref.name) is not None:
            trying_to_set = True
            break
    mi = get_metadata(stream, stream_type, force_read_metadata=True)
    if trying_to_set:
        prints(_('Original metadata') + '::')
    metadata = unicode(mi)
    if trying_to_set:
        metadata = '\t' + '\n\t'.join(metadata.split('\n'))
    prints(metadata, safe_encode=True)

    if trying_to_set:
        stream.seek(0)
        do_set_metadata(opts, mi, stream, stream_type)
        stream.seek(0)
        stream.flush()
        lrf = None
        if stream_type == 'lrf':
            if opts.lrf_bookid is not None:
                lrf = LRFMetaFile(stream)
                lrf.book_id = opts.lrf_bookid
        mi = get_metadata(stream, stream_type, force_read_metadata=True)
        prints('\n' + _('Changed metadata') + '::')
        metadata = unicode(mi)
        metadata = '\t' + '\n\t'.join(metadata.split('\n'))
        prints(metadata, safe_encode=True)
        if lrf is not None:
            prints('\tBookID:', lrf.book_id)

    if opts.to_opf is not None:
        from calibre.ebooks.metadata.opf2 import OPFCreator
        opf = OPFCreator(os.getcwdu(), mi)
        with open(opts.to_opf, 'wb') as f:
            opf.render(f)
        prints(_('OPF created in'), opts.to_opf)

    if opts.get_cover is not None:
        if mi.cover_data and mi.cover_data[1]:
            with open(opts.get_cover, 'wb') as f:
                f.write(mi.cover_data[1])
                prints(_('Cover saved to'), f.name)
        else:
            prints(_('No cover found'), file=sys.stderr)

    return 0
Beispiel #3
0
def get_metadata(stream):
    from calibre.ebooks.metadata.meta import get_metadata
    from calibre.ebooks.metadata.archive import is_comic
    stream_type = None
    zf = ZipFile(stream, 'r')
    names = zf.namelist()
    if is_comic(names):
        # Is probably a comic
        return get_metadata(stream, 'cbz')

    for f in names:
        stream_type = os.path.splitext(f)[1].lower()
        if stream_type:
            stream_type = stream_type[1:]
            if stream_type in ('lit', 'opf', 'prc', 'mobi', 'fb2', 'epub',
                               'rb', 'imp', 'pdf', 'lrf', 'azw', 'azw1', 'azw3'):
                with TemporaryDirectory() as tdir:
                    with CurrentDir(tdir):
                        path = zf.extract(f)
                        mi = get_metadata(open(path,'rb'), stream_type)
                        if stream_type == 'opf' and mi.application_id is None:
                            try:
                                # zip archive opf files without an application_id were assumed not to have a cover
                                # reparse the opf and if cover exists read its data from zip archive for the metadata
                                nmi = zip_opf_metadata(path, zf)
                                nmi.timestamp = None
                                return nmi
                            except:
                                pass
                        mi.timestamp = None
                        return mi
    raise ValueError('No ebook found in ZIP archive (%s)' % os.path.basename(getattr(stream, 'name', '') or '<stream>'))
Beispiel #4
0
def get_metadata(stream):
    from calibre.ebooks.metadata.archive import is_comic
    from calibre.ebooks.metadata.meta import get_metadata

    path = getattr(stream, 'name', False)
    if not path:
        pt = PersistentTemporaryFile('_rar-meta.rar')
        pt.write(stream.read())
        pt.close()
        path = pt.name
    path = os.path.abspath(path)
    file_names = list(names(path))
    if is_comic(file_names):
        return get_metadata(stream, 'cbr')
    for f in file_names:
        stream_type = os.path.splitext(f)[1].lower()
        if stream_type:
            stream_type = stream_type[1:]
            if stream_type in ('lit', 'opf', 'prc', 'mobi', 'fb2', 'epub',
                               'rb', 'imp', 'pdf', 'lrf', 'azw'):
                with TemporaryDirectory() as tdir:
                    with CurrentDir(tdir):
                       stream = extract_member(path, match=None, name=f,
                               as_file=True)[1]
                return get_metadata(stream, stream_type)
    raise ValueError('No ebook found in RAR archive')
Beispiel #5
0
def get_metadata(stream):
    from calibre.ebooks.metadata.meta import get_metadata
    from calibre.ebooks.metadata.archive import is_comic
    stream_type = None
    zf = ZipFile(stream, 'r')
    names = zf.namelist()
    if is_comic(names):
        # Is probably a comic
        return get_metadata(stream, 'cbz')

    for f in names:
        stream_type = os.path.splitext(f)[1].lower()
        if stream_type:
            stream_type = stream_type[1:]
            if stream_type in ('lit', 'opf', 'prc', 'mobi', 'fb2', 'epub',
                               'rb', 'imp', 'pdf', 'lrf', 'azw', 'azw1', 'azw3'):
                with TemporaryDirectory() as tdir:
                    with CurrentDir(tdir):
                        path = zf.extract(f)
                        mi = get_metadata(open(path,'rb'), stream_type)
                        if stream_type == 'opf' and mi.application_id is None:
                            try:
                                # zip archive opf files without an application_id were assumed not to have a cover
                                # reparse the opf and if cover exists read its data from zip archive for the metadata
                                nmi = zip_opf_metadata(path, zf)
                                nmi.timestamp = None
                                return nmi
                            except:
                                pass
                        mi.timestamp = None
                        return mi
    raise ValueError('No ebook found in ZIP archive (%s)' % os.path.basename(getattr(stream, 'name', '') or '<stream>'))
Beispiel #6
0
def get_metadata(stream):
    from calibre.ebooks.metadata.archive import is_comic
    from calibre.ebooks.metadata.meta import get_metadata

    path = getattr(stream, 'name', False)
    if not path:
        pt = PersistentTemporaryFile('_rar-meta.rar')
        pt.write(stream.read())
        pt.close()
        path = pt.name
    path = os.path.abspath(path)
    file_names = list(names(path))
    if is_comic(file_names):
        return get_metadata(stream, 'cbr')
    for f in file_names:
        stream_type = os.path.splitext(f)[1].lower()
        if stream_type:
            stream_type = stream_type[1:]
            if stream_type in ('lit', 'opf', 'prc', 'mobi', 'fb2', 'epub',
                               'rb', 'imp', 'pdf', 'lrf', 'azw'):
                with TemporaryDirectory() as tdir:
                    with CurrentDir(tdir):
                        stream = extract_member(path,
                                                match=None,
                                                name=f,
                                                as_file=True)[1]
                return get_metadata(stream, stream_type)
    raise ValueError('No ebook found in RAR archive')
Beispiel #7
0
    def convert_to_html_add_to_library(self, vtt_dir, main_lang, sub_lang,
                                       cover_file_path):
        '''
        return book_id when the html is added to library
        '''
        html_file = PersistentTemporaryFile('.html', dir=self.temp_dir)
        convert.convert_webvtt_to_html(vtt_dir, main_lang, sub_lang,
                                       html_file.name)
        # add to library
        new_api = self.db.new_api
        from calibre.ebooks.metadata.meta import get_metadata
        with lopen(html_file.name, 'rb') as stream:
            mi = get_metadata(stream,
                              stream_type='html',
                              use_libprs_metadata=True)
        mi.tags = ['subtitles']
        if cover_file_path != None:
            ext = cover_file_path.rpartition('.')[-1].lower().strip()
            if ext not in ('png', 'jpg', 'jpeg'):
                ext = 'jpg'
            with lopen(cover_file_path, 'rb') as stream:
                mi.cover_data = (ext, stream.read())

        # add book in html format
        book_ids, duplicates = new_api.add_books([(mi, {
            'HTML': html_file.name
        })],
                                                 run_hooks=False)
        self.db.data.books_added(book_ids)
        self.gui.library_view.model().books_added(1)

        # remove temp directory
        #shutil.rmtree(self.temp_dir)

        return book_ids[0]
Beispiel #8
0
def add_catalog(cache, path, title):
    from calibre.ebooks.metadata.book.base import Metadata
    from calibre.ebooks.metadata.meta import get_metadata
    from calibre.utils.date import utcnow

    fmt = os.path.splitext(path)[1][1:].lower()
    with lopen(path, 'rb') as stream, cache.write_lock:
        matches = cache._search('title:="%s" and tags:="%s"' % (title.replace('"', '\\"'), _('Catalog')), None)
        db_id = None
        if matches:
            db_id = list(matches)[0]
        try:
            mi = get_metadata(stream, fmt)
            mi.authors = ['calibre']
        except:
            mi = Metadata(title, ['calibre'])
        mi.title, mi.authors = title, ['calibre']
        mi.tags = [_('Catalog')]
        mi.pubdate = mi.timestamp = utcnow()
        if fmt == 'mobi':
            mi.cover, mi.cover_data = None, (None, None)
        if db_id is None:
            db_id = cache._create_book_entry(mi, apply_import_tags=False)
        else:
            cache._set_metadata(db_id, mi)
        cache._add_format(db_id, fmt, stream)

    return db_id
Beispiel #9
0
def cdb_add_book(ctx, rd, job_id, add_duplicates, filename, library_id):
    '''
    Add a file as a new book. The file contents must be in the body of the request.

    The response will also have the title/authors/languages read from the
    metadata of the file/filename. It will contain a `book_id` field specifying the id of the newly added book,
    or if add_duplicates is not specified and a duplicate was found, no book_id will be present. It will also
    return the value of `job_id` as the `id` field and `filename` as the `filename` field.
    '''
    db = get_db(ctx, rd, library_id)
    if ctx.restriction_for(rd, db):
        raise HTTPForbidden('Cannot use the add book interface with a user who has per library restrictions')
    if not filename:
        raise HTTPBadRequest('An empty filename is not allowed')
    sfilename = sanitize_file_name_unicode(filename)
    fmt = os.path.splitext(sfilename)[1]
    fmt = fmt[1:] if fmt else None
    if not fmt:
        raise HTTPBadRequest('An filename with no extension is not allowed')
    if isinstance(rd.request_body_file, BytesIO):
        raise HTTPBadRequest('A request body containing the file data must be specified')
    add_duplicates = add_duplicates in ('y', '1')
    path = os.path.join(rd.tdir, sfilename)
    rd.request_body_file.name = path
    rd.request_body_file.seek(0)
    mi = get_metadata(rd.request_body_file, stream_type=fmt, use_libprs_metadata=True)
    rd.request_body_file.seek(0)
    ids, duplicates = db.add_books([(mi, {fmt: rd.request_body_file})], add_duplicates=add_duplicates)
    ans = {'title': mi.title, 'authors': mi.authors, 'languages': mi.languages, 'filename': filename, 'id': job_id}
    if ids:
        ans['book_id'] = ids[0]
        books_added(ids)
    return ans
Beispiel #10
0
    def convert(self, stream, options, file_ext, log,
                accelerators):
        from calibre.ebooks.metadata.opf2 import OPFCreator
        from calibre.ebooks.pdf.pdftohtml import pdftohtml

        log.debug('Converting file to html...')
        # The main html file will be named index.html
        self.opts, self.log = options, log
        if options.new_pdf_engine:
            return self.convert_new(stream, accelerators)
        pdftohtml(os.getcwdu(), stream.name, options.no_images)

        from calibre.ebooks.metadata.meta import get_metadata
        log.debug('Retrieving document metadata...')
        mi = get_metadata(stream, 'pdf')
        opf = OPFCreator(os.getcwdu(), mi)

        manifest = [(u'index.html', None)]

        images = os.listdir(os.getcwdu())
        images.remove('index.html')
        for i in images:
            manifest.append((i, None))
        log.debug('Generating manifest...')
        opf.create_manifest(manifest)

        opf.create_spine([u'index.html'])
        log.debug('Rendering manifest...')
        with open(u'metadata.opf', 'wb') as opffile:
            opf.render(opffile)

        return os.path.join(os.getcwdu(), u'metadata.opf')
Beispiel #11
0
def add_news(cache, path, arg, dbapi=None):
    from calibre.ebooks.metadata.meta import get_metadata
    from calibre.utils.date import utcnow

    fmt = os.path.splitext(getattr(path, 'name', path))[1][1:].lower()
    stream = path if hasattr(path, 'read') else lopen(path, 'rb')
    stream.seek(0)
    mi = get_metadata(stream, fmt, use_libprs_metadata=False,
            force_read_metadata=True)
    # Force the author to calibre as the auto delete of old news checks for
    # both the author==calibre and the tag News
    mi.authors = ['calibre']
    stream.seek(0)
    with cache.write_lock:
        if mi.series_index is None:
            mi.series_index = cache._get_next_series_num_for(mi.series)
        mi.tags = [_('News')]
        if arg['add_title_tag']:
            mi.tags += [arg['title']]
        if arg['custom_tags']:
            mi.tags += arg['custom_tags']
        if mi.pubdate is None:
            mi.pubdate = utcnow()
        if mi.timestamp is None:
            mi.timestamp = utcnow()

        db_id = cache._create_book_entry(mi, apply_import_tags=False)
    cache.add_format(db_id, fmt, stream, dbapi=dbapi)  # Cant keep write lock since post-import hooks might run

    if not hasattr(path, 'read'):
        stream.close()
    return db_id
Beispiel #12
0
 def get_selected_format_metadata(self, db, id_):
     old = prefs['read_file_metadata']
     if not old:
         prefs['read_file_metadata'] = True
     try:
         row = self.formats.currentRow()
         fmt = self.formats.item(row)
         if fmt is None:
             if self.formats.count() == 1:
                 fmt = self.formats.item(0)
             if fmt is None:
                 error_dialog(self, _('No format selected'),
                              _('No format selected')).exec_()
                 return None, None
         ext = fmt.ext.lower()
         if fmt.path is None:
             stream = db.format(id_, ext, as_file=True, index_is_id=True)
         else:
             stream = open(fmt.path, 'r+b')
         try:
             with stream:
                 mi = get_metadata(stream, ext)
             return mi, ext
         except:
             error_dialog(self, _('Could not read metadata'),
                          _('Could not read metadata from %s format') %
                          ext).exec_()
         return None, None
     finally:
         if old != prefs['read_file_metadata']:
             prefs['read_file_metadata'] = old
Beispiel #13
0
def add_news(cache, path, arg):
    from calibre.ebooks.metadata.meta import get_metadata
    from calibre.utils.date import utcnow

    fmt = os.path.splitext(getattr(path, 'name', path))[1][1:].lower()
    stream = path if hasattr(path, 'read') else lopen(path, 'rb')
    stream.seek(0)
    mi = get_metadata(stream, fmt, use_libprs_metadata=False,
            force_read_metadata=True)
    # Force the author to calibre as the auto delete of old news checks for
    # both the author==calibre and the tag News
    mi.authors = ['calibre']
    stream.seek(0)
    with cache.write_lock:
        if mi.series_index is None:
            mi.series_index = cache._get_next_series_num_for(mi.series)
        mi.tags = [_('News')]
        if arg['add_title_tag']:
            mi.tags += [arg['title']]
        if arg['custom_tags']:
            mi.tags += arg['custom_tags']
        if mi.pubdate is None:
            mi.pubdate = utcnow()
        if mi.timestamp is None:
            mi.timestamp = utcnow()

        db_id = cache._create_book_entry(mi, apply_import_tags=False)
    cache.add_format(db_id, fmt, stream)  # Cant keep write lock since post-import hooks might run

    if not hasattr(path, 'read'):
        stream.close()
    return db_id
Beispiel #14
0
 def _get_metadata(self, id, args, kwargs):
     from calibre.ebooks.metadata.meta import get_metadata
     try:
         mi = get_metadata(*args, **kwargs)
     except:
         mi = MetaInformation('', [_('Unknown')])
     self.metadata.emit(id, mi)
Beispiel #15
0
    def test_srv_add_book(self):  # {{{
        with self.create_server(auth=True, auth_mode='basic') as server:
            server.handler.ctx.user_manager.add_user('12', 'test')
            server.handler.ctx.user_manager.add_user('ro', 'test', readonly=True)
            conn = server.connect()

            ae = self.assertEqual

            def a(filename, data=None, status=OK, method='POST', username='******', add_duplicates='n', job_id=1):
                r, data = make_request(conn, '/cdb/add-book/{}/{}/{}'.format(job_id, add_duplicates, quote(filename.encode('utf-8')).decode('ascii')),
                                       username=username, password='******', prefix='', method=method, data=data)
                ae(status, r.status)
                return data

            def d(book_ids, username='******', status=OK):
                book_ids = ','.join(map(str, book_ids))
                r, data = make_request(conn, '/cdb/delete-books/{}'.format(book_ids),
                                       username=username, password='******', prefix='', method='POST')
                ae(status, r.status)
                return data

            a('test.epub', None, username='******', status=FORBIDDEN)
            content = b'content'
            filename = 'test add - XXX.txt'
            data = a(filename, content)
            s = BytesIO(content)
            s.name = filename
            mi = get_metadata(s, stream_type='txt')
            ae(data,  {'title': mi.title, 'book_id': data['book_id'], 'authors': mi.authors, 'languages': mi.languages, 'id': '1', 'filename': filename})
            r, q = make_request(conn, '/get/txt/{}'.format(data['book_id']), username='******', password='******', prefix='')
            ae(r.status, OK)
            ae(q, content)
            d((1,), username='******', status=FORBIDDEN)
            d((1, data['book_id']))
Beispiel #16
0
def add_quick_start_guide(library_view, db_images):
    from calibre.ebooks.metadata.meta import get_metadata
    from calibre.ebooks import calibre_cover
    from calibre.utils.zipfile import safe_replace
    from calibre.utils.localization import get_lang, canonicalize_lang
    from calibre.ptempfile import PersistentTemporaryFile

    l = canonicalize_lang(get_lang()) or "eng"
    gprefs["quick_start_guide_added"] = True
    imgbuf = BytesIO(calibre_cover(_("Quick Start Guide"), "", author_size=8))
    try:
        with open(P("quick_start/%s.epub" % l), "rb") as src:
            buf = BytesIO(src.read())
    except EnvironmentError as err:
        if err.errno != errno.ENOENT:
            raise
        with open(P("quick_start/eng.epub"), "rb") as src:
            buf = BytesIO(src.read())
    safe_replace(buf, "images/cover.jpg", imgbuf)
    buf.seek(0)
    mi = get_metadata(buf, "epub")
    with PersistentTemporaryFile(".epub") as tmp:
        tmp.write(buf.getvalue())
    library_view.model().add_books([tmp.name], ["epub"], [mi])
    os.remove(tmp.name)
    library_view.model().books_added(1)
    if hasattr(db_images, "reset"):
        db_images.reset()
    if library_view.model().rowCount(None) < 3:
        library_view.resizeColumnsToContents()
Beispiel #17
0
 def _get_metadata(self, id, args, kwargs):
     from calibre.ebooks.metadata.meta import get_metadata
     try:
         mi = get_metadata(*args, **kwargs)
     except:
         mi = MetaInformation('', [_('Unknown')])
     self.emit(SIGNAL('metadata(PyQt_PyObject, PyQt_PyObject)'), id, mi)
Beispiel #18
0
def render(pathtoebook,
           output_dir,
           book_hash=None,
           serialize_metadata=False,
           extract_annotations=False):
    mi = None
    if serialize_metadata:
        from calibre.ebooks.metadata.meta import get_metadata
        from calibre.customize.ui import quick_metadata
        with lopen(pathtoebook, 'rb') as f, quick_metadata:
            mi = get_metadata(f, os.path.splitext(pathtoebook)[1][1:].lower())
    container = Container(pathtoebook,
                          output_dir,
                          book_hash=book_hash,
                          save_bookmark_data=extract_annotations,
                          book_metadata=mi)
    if serialize_metadata:
        from calibre.utils.serialize import json_dumps
        from calibre.ebooks.metadata.book.serialize import metadata_as_dict
        d = metadata_as_dict(mi)
        d.pop('cover_data', None)
        serialize_datetimes(d), serialize_datetimes(d.get('user_metadata', {}))
        with lopen(os.path.join(output_dir, 'calibre-book-metadata.json'),
                   'wb') as f:
            f.write(json_dumps(d))
    if extract_annotations:
        annotations = None
        if container.bookmark_data:
            annotations = json_dumps(tuple(get_stored_annotations(container)))
        if annotations:
            with lopen(
                    os.path.join(output_dir, 'calibre-book-annotations.json'),
                    'wb') as f:
                f.write(annotations)
Beispiel #19
0
    def convert(self, stream, options, file_ext, log, accelerators):
        from calibre.ebooks.metadata.opf2 import OPFCreator
        from calibre.ebooks.pdf.pdftohtml import pdftohtml

        log.debug('Converting file to html...')
        # The main html file will be named index.html
        self.opts, self.log = options, log
        if options.new_pdf_engine:
            return self.convert_new(stream, accelerators)
        pdftohtml(os.getcwdu(), stream.name, options.no_images)

        from calibre.ebooks.metadata.meta import get_metadata
        log.debug('Retrieving document metadata...')
        mi = get_metadata(stream, 'pdf')
        opf = OPFCreator(os.getcwdu(), mi)

        manifest = [(u'index.html', None)]

        images = os.listdir(os.getcwdu())
        images.remove('index.html')
        for i in images:
            manifest.append((i, None))
        log.debug('Generating manifest...')
        opf.create_manifest(manifest)

        opf.create_spine([u'index.html'])
        log.debug('Rendering manifest...')
        with open(u'metadata.opf', 'wb') as opffile:
            opf.render(opffile)

        return os.path.join(os.getcwdu(), u'metadata.opf')
Beispiel #20
0
def add_catalog(cache, path, title):
    from calibre.ebooks.metadata.book.base import Metadata
    from calibre.ebooks.metadata.meta import get_metadata
    from calibre.utils.date import utcnow

    fmt = os.path.splitext(path)[1][1:].lower()
    with lopen(path, 'rb') as stream:
        with cache.write_lock:
            matches = cache._search(
                'title:="%s" and tags:="%s"' %
                (title.replace('"', '\\"'), _('Catalog')), None)
            db_id = None
            if matches:
                db_id = list(matches)[0]
            try:
                mi = get_metadata(stream, fmt)
                mi.authors = ['calibre']
            except:
                mi = Metadata(title, ['calibre'])
            mi.title, mi.authors = title, ['calibre']
            mi.tags = [_('Catalog')]
            mi.pubdate = mi.timestamp = utcnow()
            if fmt == 'mobi':
                mi.cover, mi.cover_data = None, (None, None)
            if db_id is None:
                db_id = cache._create_book_entry(mi, apply_import_tags=False)
            else:
                cache._set_metadata(db_id, mi)
        cache.add_format(
            db_id, fmt,
            stream)  # Cant keep write lock since post-import hooks might run

    return db_id
Beispiel #21
0
def render(pathtoebook, output_dir, book_hash=None, serialize_metadata=False, extract_annotations=False, virtualize_resources=True, max_workers=1):
    pathtoebook = os.path.abspath(pathtoebook)
    with RenderManager(max_workers) as render_manager:
        mi = None
        if serialize_metadata:
            from calibre.customize.ui import quick_metadata
            from calibre.ebooks.metadata.meta import get_metadata
            with lopen(pathtoebook, 'rb') as f, quick_metadata:
                mi = get_metadata(f, os.path.splitext(pathtoebook)[1][1:].lower())
        book_fmt, opfpath, input_fmt = extract_book(pathtoebook, output_dir, log=default_log)
        container, bookmark_data = process_exploded_book(
            book_fmt, opfpath, input_fmt, output_dir, render_manager,
            book_hash=book_hash, save_bookmark_data=extract_annotations,
            book_metadata=mi, virtualize_resources=virtualize_resources
        )
        if serialize_metadata:
            from calibre.ebooks.metadata.book.serialize import metadata_as_dict
            d = metadata_as_dict(mi)
            d.pop('cover_data', None)
            serialize_datetimes(d), serialize_datetimes(d.get('user_metadata', {}))
            with lopen(os.path.join(output_dir, 'calibre-book-metadata.json'), 'wb') as f:
                f.write(json_dumps(d))
        if extract_annotations:
            annotations = None
            if bookmark_data:
                annotations = json_dumps(tuple(get_stored_annotations(container, bookmark_data)))
            if annotations:
                with lopen(os.path.join(output_dir, 'calibre-book-annotations.json'), 'wb') as f:
                    f.write(annotations)
Beispiel #22
0
def add_quick_start_guide(library_view, refresh_cover_browser=None):
    from calibre.ebooks.metadata.meta import get_metadata
    from calibre.ebooks import calibre_cover
    from calibre.utils.zipfile import safe_replace
    from calibre.utils.localization import get_lang, canonicalize_lang
    from calibre.ptempfile import PersistentTemporaryFile
    l = canonicalize_lang(get_lang()) or 'eng'
    gprefs['quick_start_guide_added'] = True
    imgbuf = BytesIO(calibre_cover(_('Quick Start Guide'), '', author_size=8))
    try:
        with open(P('quick_start/%s.epub' % l), 'rb') as src:
            buf = BytesIO(src.read())
    except EnvironmentError as err:
        if err.errno != errno.ENOENT:
            raise
        with open(P('quick_start/eng.epub'), 'rb') as src:
            buf = BytesIO(src.read())
    safe_replace(buf, 'images/cover.jpg', imgbuf)
    buf.seek(0)
    mi = get_metadata(buf, 'epub')
    with PersistentTemporaryFile('.epub') as tmp:
        tmp.write(buf.getvalue())
    library_view.model().add_books([tmp.name], ['epub'], [mi])
    os.remove(tmp.name)
    library_view.model().books_added(1)
    if refresh_cover_browser is not None:
        refresh_cover_browser()
    if library_view.model().rowCount(None) < 3:
        library_view.resizeColumnsToContents()
Beispiel #23
0
 def get_selected_format_metadata(self, db, id_):
     old = prefs['read_file_metadata']
     if not old:
         prefs['read_file_metadata'] = True
     try:
         row = self.formats.currentRow()
         fmt = self.formats.item(row)
         if fmt is None:
             if self.formats.count() == 1:
                 fmt = self.formats.item(0)
             if fmt is None:
                 error_dialog(self, _('No format selected'),
                     _('No format selected')).exec_()
                 return None, None
         ext = fmt.ext.lower()
         if fmt.path is None:
             stream = db.format(id_, ext, as_file=True, index_is_id=True)
         else:
             stream = open(fmt.path, 'r+b')
         try:
             with stream:
                 mi = get_metadata(stream, ext)
             return mi, ext
         except:
             error_dialog(self, _('Could not read metadata'),
                         _('Could not read metadata from %s format')%ext).exec_()
         return None, None
     finally:
         if old != prefs['read_file_metadata']:
             prefs['read_file_metadata'] = old
Beispiel #24
0
def add_catalog(cache, path, title, dbapi=None):
    from calibre.ebooks.metadata.book.base import Metadata
    from calibre.ebooks.metadata.meta import get_metadata
    from calibre.utils.date import utcnow

    fmt = os.path.splitext(path)[1][1:].lower()
    new_book_added = False
    with lopen(path, 'rb') as stream:
        with cache.write_lock:
            matches = cache._search('title:="%s" and tags:="%s"' % (title.replace('"', '\\"'), _('Catalog')), None)
            db_id = None
            if matches:
                db_id = list(matches)[0]
            try:
                mi = get_metadata(stream, fmt)
                mi.authors = ['calibre']
            except:
                mi = Metadata(title, ['calibre'])
            mi.title, mi.authors = title, ['calibre']
            mi.author_sort = 'calibre'  # The MOBI/AZW3 format sets author sort to date
            mi.tags = [_('Catalog')]
            mi.pubdate = mi.timestamp = utcnow()
            if fmt == 'mobi':
                mi.cover, mi.cover_data = None, (None, None)
            if db_id is None:
                db_id = cache._create_book_entry(mi, apply_import_tags=False)
                new_book_added = True
            else:
                cache._set_metadata(db_id, mi)
        cache.add_format(db_id, fmt, stream, dbapi=dbapi)  # Cant keep write lock since post-import hooks might run

    return db_id, new_book_added
Beispiel #25
0
def add_quick_start_guide(library_view, refresh_cover_browser=None):
    from calibre.ebooks.metadata.meta import get_metadata
    from calibre.ebooks.covers import calibre_cover2
    from calibre.utils.zipfile import safe_replace
    from calibre.utils.localization import get_lang, canonicalize_lang
    from calibre.ptempfile import PersistentTemporaryFile
    l = canonicalize_lang(get_lang()) or 'eng'
    gprefs['quick_start_guide_added'] = True
    imgbuf = BytesIO(calibre_cover2(_('Quick Start Guide'), ''))
    try:
        with lopen(P('quick_start/%s.epub' % l), 'rb') as src:
            buf = BytesIO(src.read())
    except EnvironmentError as err:
        if err.errno != errno.ENOENT:
            raise
        with lopen(P('quick_start/eng.epub'), 'rb') as src:
            buf = BytesIO(src.read())
    safe_replace(buf, 'images/cover.jpg', imgbuf)
    buf.seek(0)
    mi = get_metadata(buf, 'epub')
    with PersistentTemporaryFile('.epub') as tmp:
        tmp.write(buf.getvalue())
    library_view.model().add_books([tmp.name], ['epub'], [mi])
    os.remove(tmp.name)
    library_view.model().books_added(1)
    if refresh_cover_browser is not None:
        refresh_cover_browser()
    if library_view.model().rowCount(None) < 3:
        library_view.resizeColumnsToContents()
Beispiel #26
0
    def test_srv_add_book(self):  # {{{
        with self.create_server(auth=True, auth_mode='basic') as server:
            server.handler.ctx.user_manager.add_user('12', 'test')
            server.handler.ctx.user_manager.add_user('ro', 'test', readonly=True)
            conn = server.connect()

            ae = self.assertEqual

            def a(filename, data=None, status=OK, method='POST', username='******', add_duplicates='n', job_id=1):
                r, data = make_request(conn, '/cdb/add-book/{}/{}/{}'.format(job_id, add_duplicates, quote(filename.encode('utf-8'))),
                                       username=username, password='******', prefix='', method=method, data=data)
                ae(status, r.status)
                return data

            def d(book_ids, username='******', status=OK):
                book_ids = ','.join(map(str, book_ids))
                r, data = make_request(conn, '/cdb/delete-books/{}'.format(book_ids),
                                       username=username, password='******', prefix='', method='POST')
                ae(status, r.status)
                return data

            a('test.epub', None, username='******', status=FORBIDDEN)
            content = b'content'
            filename = 'test add - XXX.txt'
            data = a(filename, content)
            s = BytesIO(content)
            s.name = filename
            mi = get_metadata(s, stream_type='txt')
            ae(data,  {'title': mi.title, 'book_id': data['book_id'], 'authors': mi.authors, 'languages': mi.languages, 'id': '1', 'filename': filename})
            r, q = make_request(conn, '/get/txt/{}'.format(data['book_id']), username='******', password='******', prefix='')
            ae(r.status, OK)
            ae(q, content)
            d((1,), username='******', status=FORBIDDEN)
            d((1, data['book_id']))
Beispiel #27
0
 def _get_metadata(self, id, args, kwargs):
     from calibre.ebooks.metadata.meta import get_metadata
     try:
         mi = get_metadata(*args, **kwargs)
     except:
         mi = MetaInformation('', [_('Unknown')])
     self.emit(SIGNAL('metadata(PyQt_PyObject, PyQt_PyObject)'), id, mi)
Beispiel #28
0
 def _get_metadata(self, id, args, kwargs):
     from calibre.ebooks.metadata.meta import get_metadata
     try:
         mi = get_metadata(*args, **kwargs)
     except:
         mi = MetaInformation('', [_('Unknown')])
     self.metadata.emit(id, mi)
 def run(self, path_to_ebook):
     from calibre.ebooks.metadata.meta import get_metadata, set_metadata
     with open(path_to_ebook, 'r+b') as file:
         ext  = os.path.splitext(path_to_ebook)[-1][1:].lower()
         mi = get_metadata(file, ext)
         mi.publisher = 'Hello World'
         set_metadata(file, mi, ext)
     return path_to_ebook
Beispiel #30
0
 def run(self, path_to_ebook):
     from calibre.ebooks.metadata.meta import get_metadata, set_metadata
     file = open(path_to_ebook, 'r+b')
     ext  = os.path.splitext(path_to_ebook)[-1][1:].lower()
     mi = get_metadata(file, ext)
     mi.publisher = 'Hello World'
     set_metadata(file, mi, ext)
     return path_to_ebook
Beispiel #31
0
    def run(self, path_to_ebook):
        # print("run FanficAuthorsNetCSSFix")
        # logger.warn("logger")
        book_format = 'epub'

        ## Really crude brute force check to see if it's a
        ## fanficauthors.net epub:

        epub = ZipFile(
            path_to_ebook,
            'r')  # works equally well with inputio as a path or a blob
        tocfile = "content/toc.ncx"
        if not (tocfile in epub.namelist()
                and "fanficauthors.net" in epub.read(tocfile)):
            # bail without doing anything
            return path_to_ebook

        print("It's a fanficauthors.net epub!")

        tmpfile = self.temporary_file('.' + book_format)

        outputepub = ZipFile(tmpfile, "w", compression=ZIP_STORED)
        outputepub.debug = 3
        outputepub.writestr("mimetype", "application/epub+zip")
        outputepub.close()

        ## Re-open file for content.
        outputepub = ZipFile(tmpfile, "a", compression=ZIP_DEFLATED)
        outputepub.debug = 3

        for fname in epub.namelist():
            if fname.endswith('.html'):
                outputepub.writestr(
                    fname,
                    epub.read(fname).replace(
                        """body {
	margin-top: 0px;
    padding-top: 0px;
}""", """body { background-color: #FFFFFF;
        text-align: justify;
        margin: 2%;
	adobe-hyphenate: none; }"""))
            elif fname != "mimetype":
                outputepub.writestr(fname, epub.read(fname))

        for zf in outputepub.filelist:
            zf.create_system = 0
        outputepub.close()

        # file = open(path_to_ebook, 'r+b')
        ext = os.path.splitext(path_to_ebook)[-1][1:].lower()
        mi = get_metadata(tmpfile, ext)
        mi.publisher = "fanficauthors.net"
        set_metadata(tmpfile, mi, ext)
        # return path_to_ebook

        return tmpfile.name
Beispiel #32
0
 def read_file_metadata(self, mtp_file):
     from calibre.ebooks.metadata.meta import get_metadata
     from calibre.customize.ui import quick_metadata
     ext = mtp_file.name.rpartition('.')[-1].lower()
     stream = self.get_mtp_file(mtp_file)
     with quick_metadata:
         return get_metadata(stream, stream_type=ext,
                 force_read_metadata=True,
                 pattern=self.build_template_regexp())
Beispiel #33
0
    def convert(self, stream, options, file_ext, log, accelerators):
        from calibre.ebooks.metadata.toc import TOC
        from calibre.ebooks.metadata.opf2 import OPFCreator
        from calibre.utils.zipfile import ZipFile

        self.options = options
        self.log = log
        pages, images = [], []
        toc = TOC()

        if file_ext == 'pmlz':
            log.debug('De-compressing content to temporary directory...')
            with TemporaryDirectory('_unpmlz') as tdir:
                zf = ZipFile(stream)
                zf.extractall(tdir)

                pmls = glob.glob(os.path.join(tdir, '*.pml'))
                for pml in pmls:
                    html_name = os.path.splitext(
                        os.path.basename(pml))[0] + '.html'
                    html_path = os.path.join(os.getcwd(), html_name)

                    pages.append(html_name)
                    log.debug('Processing PML item %s...' % pml)
                    ttoc = self.process_pml(pml, html_path)
                    toc += ttoc
                images = self.get_images(stream, tdir, True)
        else:
            toc = self.process_pml(stream, 'index.html')
            pages.append('index.html')

            if hasattr(stream, 'name'):
                images = self.get_images(
                    stream, os.path.abspath(os.path.dirname(stream.name)))

        # We want pages to be ordered alphabetically.
        pages.sort()

        manifest_items = []
        for item in pages + images:
            manifest_items.append((item, None))

        from calibre.ebooks.metadata.meta import get_metadata
        log.debug('Reading metadata from input file...')
        mi = get_metadata(stream, 'pml')
        if 'images/cover.png' in images:
            mi.cover = 'images/cover.png'
        opf = OPFCreator(os.getcwd(), mi)
        log.debug('Generating manifest...')
        opf.create_manifest(manifest_items)
        opf.create_spine(pages)
        opf.set_toc(toc)
        with lopen('metadata.opf', 'wb') as opffile:
            with lopen('toc.ncx', 'wb') as tocfile:
                opf.render(opffile, tocfile, 'toc.ncx')

        return os.path.join(os.getcwd(), 'metadata.opf')
Beispiel #34
0
    def convert(self, stream, options, file_ext, log,
                accelerators):
        from calibre.ebooks.metadata.toc import TOC
        from calibre.ebooks.metadata.opf2 import OPFCreator
        from calibre.utils.zipfile import ZipFile

        self.options = options
        self.log = log
        pages, images = [], []
        toc = TOC()

        if file_ext == 'pmlz':
            log.debug('De-compressing content to temporary directory...')
            with TemporaryDirectory('_unpmlz') as tdir:
                zf = ZipFile(stream)
                zf.extractall(tdir)

                pmls = glob.glob(os.path.join(tdir, '*.pml'))
                for pml in pmls:
                    html_name = os.path.splitext(os.path.basename(pml))[0]+'.html'
                    html_path = os.path.join(getcwd(), html_name)

                    pages.append(html_name)
                    log.debug('Processing PML item %s...' % pml)
                    ttoc = self.process_pml(pml, html_path)
                    toc += ttoc
                images = self.get_images(stream, tdir, True)
        else:
            toc = self.process_pml(stream, 'index.html')
            pages.append('index.html')

            if hasattr(stream, 'name'):
                images = self.get_images(stream, os.path.abspath(os.path.dirname(stream.name)))

        # We want pages to be orded alphabetically.
        pages.sort()

        manifest_items = []
        for item in pages+images:
            manifest_items.append((item, None))

        from calibre.ebooks.metadata.meta import get_metadata
        log.debug('Reading metadata from input file...')
        mi = get_metadata(stream, 'pml')
        if 'images/cover.png' in images:
            mi.cover = 'images/cover.png'
        opf = OPFCreator(getcwd(), mi)
        log.debug('Generating manifest...')
        opf.create_manifest(manifest_items)
        opf.create_spine(pages)
        opf.set_toc(toc)
        with lopen('metadata.opf', 'wb') as opffile:
            with lopen('toc.ncx', 'wb') as tocfile:
                opf.render(opffile, tocfile, 'toc.ncx')

        return os.path.join(getcwd(), 'metadata.opf')
Beispiel #35
0
    def run(self, path_to_ebook):
        from calibre.ebooks.metadata.meta import get_metadata, set_metadata
        file = open(path_to_ebook, 'r+b')
        ext = os.path.splitext(path_to_ebook)[-1][1:].lower()
        mi = get_metadata(file, ext)

        outfile = run_on_file(path_to_ebook)

        set_metadata(outfile, mi, 'mp3')
        return path_to_ebook
Beispiel #36
0
def get_metadata(stream):
    from calibre.ebooks.metadata.archive import is_comic
    from calibre.ebooks.metadata.meta import get_metadata

    file_names = list(names(stream))
    if is_comic(file_names):
        return get_metadata(stream, 'cbr')
    for f in file_names:
        stream_type = os.path.splitext(f)[1].lower()
        if stream_type:
            stream_type = stream_type[1:]
            if stream_type in {'lit', 'opf', 'prc', 'mobi', 'fb2', 'epub',
                               'rb', 'imp', 'pdf', 'lrf', 'azw', 'azw1',
                               'azw3'}:
                name, data = extract_member(stream, match=None, name=f)
                stream = BytesIO(data)
                stream.name = os.path.basename(name)
                return get_metadata(stream, stream_type)
    raise ValueError('No ebook found in RAR archive')
Beispiel #37
0
 def set_cover_from_format(self, book_id, fmt):
     from calibre.ebooks.metadata.meta import get_metadata
     from calibre.utils.config import prefs
     fmt = fmt.lower()
     cdata = None
     db = self.gui.current_db.new_api
     if fmt == 'pdf':
         pdfpath = db.format_abspath(book_id, fmt)
         if pdfpath is None:
             return error_dialog(self.gui, _('Format file missing'), _(
                 'Cannot read cover as the %s file is missing from this book') % 'PDF', show=True)
         from calibre.gui2.metadata.pdf_covers import PDFCovers
         d = PDFCovers(pdfpath, parent=self.gui)
         ret = d.exec_()
         if ret == QDialog.DialogCode.Accepted:
             cpath = d.cover_path
             if cpath:
                 with open(cpath, 'rb') as f:
                     cdata = f.read()
         d.cleanup()
         if ret != QDialog.DialogCode.Accepted:
             return
     else:
         stream = BytesIO()
         try:
             db.copy_format_to(book_id, fmt, stream)
         except NoSuchFormat:
             return error_dialog(self.gui, _('Format file missing'), _(
                 'Cannot read cover as the %s file is missing from this book') % fmt.upper(), show=True)
         old = prefs['read_file_metadata']
         if not old:
             prefs['read_file_metadata'] = True
         try:
             stream.seek(0)
             mi = get_metadata(stream, fmt)
         except Exception:
             import traceback
             return error_dialog(self.gui, _('Could not read metadata'),
                         _('Could not read metadata from %s format')%fmt.upper(),
                          det_msg=traceback.format_exc(), show=True)
         finally:
             if old != prefs['read_file_metadata']:
                 prefs['read_file_metadata'] = old
         if mi.cover and os.access(mi.cover, os.R_OK):
             with open(mi.cover, 'rb') as f:
                 cdata = f.read()
         elif mi.cover_data[1] is not None:
             cdata = mi.cover_data[1]
         if cdata is None:
             return error_dialog(self.gui, _('Could not read cover'),
                         _('Could not read cover from %s format')%fmt.upper(), show=True)
     db.set_cover({book_id:cdata})
     current_idx = self.gui.library_view.currentIndex()
     self.gui.library_view.model().current_changed(current_idx, current_idx)
     self.gui.refresh_cover_browser()
Beispiel #38
0
 def set_cover_from_format(self, book_id, fmt):
     from calibre.utils.config import prefs
     from calibre.ebooks.metadata.meta import get_metadata
     fmt = fmt.lower()
     cdata = None
     db = self.gui.current_db.new_api
     if fmt == 'pdf':
         pdfpath = db.format_abspath(book_id, fmt)
         if pdfpath is None:
             return error_dialog(self.gui, _('Format file missing'), _(
                 'Cannot read cover as the %s file is missing from this book') % 'PDF', show=True)
         from calibre.gui2.metadata.pdf_covers import PDFCovers
         d = PDFCovers(pdfpath, parent=self.gui)
         ret = d.exec_()
         if ret == d.Accepted:
             cpath = d.cover_path
             if cpath:
                 with open(cpath, 'rb') as f:
                     cdata = f.read()
         d.cleanup()
         if ret != d.Accepted:
             return
     else:
         stream = BytesIO()
         try:
             db.copy_format_to(book_id, fmt, stream)
         except NoSuchFormat:
             return error_dialog(self.gui, _('Format file missing'), _(
                 'Cannot read cover as the %s file is missing from this book') % fmt.upper(), show=True)
         old = prefs['read_file_metadata']
         if not old:
             prefs['read_file_metadata'] = True
         try:
             stream.seek(0)
             mi = get_metadata(stream, fmt)
         except Exception:
             import traceback
             return error_dialog(self.gui, _('Could not read metadata'),
                         _('Could not read metadata from %s format')%fmt.upper(),
                          det_msg=traceback.format_exc(), show=True)
         finally:
             if old != prefs['read_file_metadata']:
                 prefs['read_file_metadata'] = old
         if mi.cover and os.access(mi.cover, os.R_OK):
             cdata = open(mi.cover).read()
         elif mi.cover_data[1] is not None:
             cdata = mi.cover_data[1]
         if cdata is None:
             return error_dialog(self.gui, _('Could not read cover'),
                         _('Could not read cover from %s format')%fmt.upper(), show=True)
     db.set_cover({book_id:cdata})
     current_idx = self.gui.library_view.currentIndex()
     self.gui.library_view.model().current_changed(current_idx, current_idx)
     self.gui.refresh_cover_browser()
Beispiel #39
0
def get_metadata(stream):
    from calibre.ebooks.metadata.archive import is_comic
    from calibre.ebooks.metadata.meta import get_metadata

    path = getattr(stream, "name", False)
    if not path:
        pt = PersistentTemporaryFile("_rar-meta.rar")
        pt.write(stream.read())
        pt.close()
        path = pt.name
    path = os.path.abspath(path)
    file_names = list(names(path))
    if is_comic(file_names):
        return get_metadata(stream, "cbr")
    for f in file_names:
        stream_type = os.path.splitext(f)[1].lower()
        if stream_type:
            stream_type = stream_type[1:]
            if stream_type in (
                "lit",
                "opf",
                "prc",
                "mobi",
                "fb2",
                "epub",
                "rb",
                "imp",
                "pdf",
                "lrf",
                "azw",
                "azw1",
                "azw3",
            ):
                with TemporaryDirectory() as tdir:
                    with CurrentDir(tdir):
                        stream = extract_member(path, match=None, name=f, as_file=True)[1]
                return get_metadata(stream, stream_type)
    raise ValueError("No ebook found in RAR archive")
Beispiel #40
0
    def run(self, path_to_ebook):

        from calibre.ebooks.metadata.meta import get_metadata, set_metadata
        file = open(path_to_ebook, 'r+b')
        ext = os.path.splitext(path_to_ebook)[-1][1:].lower()
        mi = get_metadata(file, ext)
        genresonbook = [element.lower() for element in mi.tags]
        mi.tags = self.new_genre_list(genresonbook)

        set_metadata(file, mi, ext)

        print(mi)
        print(genresonbook)

        return path_to_ebook
Beispiel #41
0
    def run(self, path_to_ebook):

        from calibre.ebooks.metadata.meta import get_metadata, set_metadata
        file = open(path_to_ebook, 'r+b')
        ext  = os.path.splitext(path_to_ebook)[-1][1:].lower()
        mi = get_metadata(file, ext)
        genresonbook = [element.lower() for element in mi.tags]
        mi.tags = self.new_genre_list(genresonbook)

        set_metadata(file, mi, ext)

        print(mi)
        print(genresonbook)

        return path_to_ebook
Beispiel #42
0
    def _add(self, filename, gui, add_to_lib, tags):
        if not add_to_lib or not filename:
            return
        ext = os.path.splitext(filename)[1][1:].lower()
        if ext not in BOOK_EXTENSIONS:
            raise Exception(_('Not a support e-book format.'))

        from calibre.ebooks.metadata.meta import get_metadata
        with open(filename, 'rb') as f:
            mi = get_metadata(f, ext, force_read_metadata=True)
        mi.tags.extend(tags)

        id = gui.library_view.model().db.create_book_entry(mi)
        gui.library_view.model().db.add_format_with_hooks(id, ext.upper(), filename, index_is_id=True)
        gui.library_view.model().books_added(1)
        gui.library_view.model().count_changed()
Beispiel #43
0
    def _add(self, filename, gui, add_to_lib, tags):
        if not add_to_lib or not filename:
            return
        ext = os.path.splitext(filename)[1][1:].lower()
        if ext not in BOOK_EXTENSIONS:
            raise Exception(_('Not a support ebook format.'))

        from calibre.ebooks.metadata.meta import get_metadata
        with open(filename, 'rb') as f:
            mi = get_metadata(f, ext, force_read_metadata=True)
        mi.tags.extend(tags)

        id = gui.library_view.model().db.create_book_entry(mi)
        gui.library_view.model().db.add_format_with_hooks(id, ext.upper(), filename, index_is_id=True)
        gui.library_view.model().books_added(1)
        gui.library_view.model().count_changed()
Beispiel #44
0
def book(db, notify_changes, is_remote, args):
    data, fname, fmt, add_duplicates, otitle, oauthors, oisbn, otags, oseries, oseries_index, ocover, oidentifiers, olanguages = args
    with add_ctx(), TemporaryDirectory(
            'add-single') as tdir, run_import_plugins_before_metadata(tdir):
        if is_remote:
            with lopen(os.path.join(tdir, fname), 'wb') as f:
                f.write(data[1])
            path = f.name
        else:
            path = data
        path = run_import_plugins([path])[0]
        fmt = os.path.splitext(path)[1]
        fmt = (fmt[1:] if fmt else None) or 'unknown'
        with lopen(path, 'rb') as stream:
            mi = get_metadata(stream,
                              stream_type=fmt,
                              use_libprs_metadata=True)
        if not mi.title:
            mi.title = os.path.splitext(os.path.basename(path))[0]
        if not mi.authors:
            mi.authors = [_('Unknown')]
        if oidentifiers:
            ids = mi.get_identifiers()
            ids.update(oidentifiers)
            mi.set_identifiers(ids)
        for x in ('title', 'authors', 'isbn', 'tags', 'series', 'languages'):
            val = locals()['o' + x]
            if val:
                setattr(mi, x, val)
        if oseries:
            mi.series_index = oseries_index
        if ocover:
            mi.cover = None
            mi.cover_data = ocover

        ids, duplicates = db.add_books([(mi, {
            fmt: path
        })],
                                       add_duplicates=add_duplicates,
                                       run_hooks=False)

    if is_remote:
        notify_changes(books_added(ids))
    db.dump_metadata()
    return ids, bool(duplicates), mi.title
 def run(self, path_to_ebook):
     from calibre.ebooks.metadata.meta import get_metadata
     from calibre.library import db
     import time
     file = open(path_to_ebook, 'r+b')
     ext = os.path.splitext(path_to_ebook)[-1][1:].lower()
     mi = get_metadata(file, ext)
     db = db('C:/Users/jmoor/Docs/eBooks/Calibre').new_api
     title = mi.title
     author = mi.authors[0]
     ids = list(db.search('title:' + title + ' author:' + author))
     db.remove_formats({ids[0]: ['ORIGINAL_MOBI', 'epub', 'azw3']})
     searchResults = db.search('formats:"=ORIGINAL_MOBI"')
     for bookId in searchResults:
         try:
             db.remove_formats({bookId: ['original_mobi']})
         except:
             pass
Beispiel #46
0
 def get_decrypted_kobo_books(self, book):
     '''
     This method is a call-back function used by DecryptAddProgressDialog in dialogs.py to decrypt Kobo books
     
     :param book: A KoboBook object that is to be decrypted.
     '''
     print (_('{0} - Decrypting {1}').format(PLUGIN_NAME + ' v' + PLUGIN_VERSION, book.title))
     decrypted = self.decryptBook(book)
     if decrypted['success']:
         # Build a list of calibre "book maps" for calibre's add_book function.
         mi = get_metadata(decrypted['fileobj'], 'epub')
         bookmap = {'EPUB':decrypted['fileobj'].name}
         self.books_to_add.append((mi, bookmap))
     else:
         # Book is probably still encrypted.
         print (_('{0} - Couldn\'t decrypt {1}').format(PLUGIN_NAME + ' v' + PLUGIN_VERSION, book.title))
         self.decryption_errors.append((book.title, _('decryption errors')))
         return False
     return True
Beispiel #47
0
 def get_decrypted_kobo_books(self, book):
     '''
     This method is a call-back function used by DecryptAddProgressDialog in dialogs.py to decrypt Kobo books
     
     :param book: A KoboBook object that is to be decrypted.
     '''
     print (_('{0} - Decrypting {1}').format(PLUGIN_NAME + ' v' + PLUGIN_VERSION, book.title))
     decrypted = self.decryptBook(book)
     if decrypted['success']:
         # Build a list of calibre "book maps" for calibre's add_book function.
         mi = get_metadata(decrypted['fileobj'], 'epub')
         bookmap = {'EPUB':decrypted['fileobj'].name}
         self.books_to_add.append((mi, bookmap))
     else:
         # Book is probably still encrypted.
         print (_('{0} - Couldn\'t decrypt {1}').format(PLUGIN_NAME + ' v' + PLUGIN_VERSION, book.title))
         self.decryption_errors.append((book.title, _('decryption errors')))
         return False
     return True
Beispiel #48
0
def book(db, notify_changes, is_remote, args):
    data, fname, fmt, add_duplicates, otitle, oauthors, oisbn, otags, oseries, oseries_index, ocover, oidentifiers, olanguages = args
    with add_ctx(), TemporaryDirectory('add-single') as tdir, run_import_plugins_before_metadata(tdir):
        if is_remote:
            with lopen(os.path.join(tdir, fname), 'wb') as f:
                f.write(data[1])
            path = f.name
        else:
            path = data
        path = run_import_plugins([path])[0]
        fmt = os.path.splitext(path)[1]
        fmt = (fmt[1:] if fmt else None) or 'unknown'
        with lopen(path, 'rb') as stream:
            mi = get_metadata(stream, stream_type=fmt, use_libprs_metadata=True)
        if not mi.title:
            mi.title = os.path.splitext(os.path.basename(path))[0]
        if not mi.authors:
            mi.authors = [_('Unknown')]
        if oidentifiers:
            ids = mi.get_identifiers()
            ids.update(oidentifiers)
            mi.set_identifiers(ids)
        for x in ('title', 'authors', 'isbn', 'tags', 'series', 'languages'):
            val = locals()['o' + x]
            if val:
                setattr(mi, x, val)
        if oseries:
            mi.series_index = oseries_index
        if ocover:
            mi.cover = None
            mi.cover_data = ocover

        ids, duplicates = db.add_books(
            [(mi, {fmt: path})], add_duplicates=add_duplicates, run_hooks=False)

    if is_remote:
        notify_changes(books_added(ids))
    db.dump_metadata()
    return ids, bool(duplicates), mi.title
Beispiel #49
0
    def convert(self, stream, options, file_ext, log, accelerators):
        from calibre.ebooks.metadata.opf2 import OPFCreator
        from calibre.ebooks.pdf.pdftohtml import pdftohtml

        log.debug('Converting file to html...')
        # The main html file will be named index.html
        self.opts, self.log = options, log
        if options.new_pdf_engine:
            return self.convert_new(stream, accelerators)
        pdftohtml(os.getcwd(), stream.name, options.no_images)

        from calibre.ebooks.metadata.meta import get_metadata
        log.debug('Retrieving document metadata...')
        mi = get_metadata(stream, 'pdf')
        opf = OPFCreator(os.getcwd(), mi)

        manifest = [('index.html', None)]

        images = os.listdir(os.getcwd())
        images.remove('index.html')
        for i in images:
            manifest.append((i, None))
        log.debug('Generating manifest...')
        opf.create_manifest(manifest)

        opf.create_spine(['index.html'])
        log.debug('Rendering manifest...')
        with lopen('metadata.opf', 'wb') as opffile:
            opf.render(opffile)
        if os.path.exists('toc.ncx'):
            ncxid = opf.manifest.id_for_path('toc.ncx')
            if ncxid:
                with lopen('metadata.opf', 'r+b') as f:
                    raw = f.read().replace(
                        b'<spine', b'<spine toc="%s"' % as_bytes(ncxid))
                    f.seek(0)
                    f.write(raw)

        return os.path.join(os.getcwd(), 'metadata.opf')
Beispiel #50
0
    def convert(self, stream, options, file_ext, log,
                accelerators):
        from calibre.ebooks.metadata.opf2 import OPFCreator
        from calibre.ebooks.pdf.pdftohtml import pdftohtml

        log.debug('Converting file to html...')
        # The main html file will be named index.html
        self.opts, self.log = options, log
        if options.new_pdf_engine:
            return self.convert_new(stream, accelerators)
        pdftohtml(getcwd(), stream.name, options.no_images)

        from calibre.ebooks.metadata.meta import get_metadata
        log.debug('Retrieving document metadata...')
        mi = get_metadata(stream, 'pdf')
        opf = OPFCreator(getcwd(), mi)

        manifest = [('index.html', None)]

        images = os.listdir(getcwd())
        images.remove('index.html')
        for i in images:
            manifest.append((i, None))
        log.debug('Generating manifest...')
        opf.create_manifest(manifest)

        opf.create_spine(['index.html'])
        log.debug('Rendering manifest...')
        with lopen('metadata.opf', 'wb') as opffile:
            opf.render(opffile)
        if os.path.exists('toc.ncx'):
            ncxid = opf.manifest.id_for_path('toc.ncx')
            if ncxid:
                with lopen('metadata.opf', 'r+b') as f:
                    raw = f.read().replace(b'<spine', b'<spine toc="%s"' % as_bytes(ncxid))
                    f.seek(0)
                    f.write(raw)

        return os.path.join(getcwd(), 'metadata.opf')
Beispiel #51
0
    def __call__(self, stream, odir, log):
        from calibre.utils.zipfile import ZipFile
        from calibre.ebooks.metadata.meta import get_metadata
        from calibre.ebooks.metadata.opf2 import OPFCreator


        if not os.path.exists(odir):
            os.makedirs(odir)
        with CurrentDir(odir):
            log('Extracting ODT file...')
            html = self.odf2xhtml(stream)
            # A blanket img specification like this causes problems
            # with EPUB output as the containing element often has
            # an absolute height and width set that is larger than
            # the available screen real estate
            html = html.replace('img { width: 100%; height: 100%; }', '')
            try:
                html = self.fix_markup(html, log)
            except:
                log.exception('Failed to filter CSS, conversion may be slow')
            with open('index.xhtml', 'wb') as f:
                f.write(html.encode('utf-8'))
            zf = ZipFile(stream, 'r')
            self.extract_pictures(zf)
            stream.seek(0)
            mi = get_metadata(stream, 'odt')
            if not mi.title:
                mi.title = _('Unknown')
            if not mi.authors:
                mi.authors = [_('Unknown')]
            opf = OPFCreator(os.path.abspath(os.getcwdu()), mi)
            opf.create_manifest([(os.path.abspath(f), None) for f in
                walk(os.getcwdu())])
            opf.create_spine([os.path.abspath('index.xhtml')])
            with open('metadata.opf', 'wb') as f:
                opf.render(f)
            return os.path.abspath('metadata.opf')
Beispiel #52
0
    def book_upload(self, ebook_file=None, generate_fmt=False):
        from calibre.ebooks.metadata import MetaInformation
        cherrypy.response.timeout = 3600

        name = ebook_file.filename
        fmt = os.path.splitext(name)[1]
        fmt = fmt[1:] if fmt else None
        if not fmt:
            return "bad file name: %s" % name
        fmt = fmt.lower()

        # save file
        data = ''
        while True:
            d = ebook_file.file.read(8192)
            data += d
            if not d: break

        fpath = "/tmp/" + name
        open(fpath, "wb").write(data)

        # read ebook meta
        stream = open(fpath, 'rb')
        mi = get_metadata(stream, stream_type=fmt, use_libprs_metadata=True)
        books = self.db.books_with_same_title(mi)
        if books:
            book_id = books.pop()
            raise cherrypy.HTTPRedirect('/book/%d' % book_id)

        fpaths = [fpath]
        self.generate_books(mi, fpath, fmt)
        book_id = self.db.import_book(mi, fpaths)
        messages.append({
            'status': 'success',
            'msg': _("import books success")
        })
        raise cherrypy.HTTPRedirect('/book/%d' % book_id)
Beispiel #53
0
def get_cover_data(stream, ext):  # {{{
    from calibre.ebooks.metadata.meta import get_metadata
    old = prefs['read_file_metadata']
    if not old:
        prefs['read_file_metadata'] = True
    cdata = area = None

    try:
        with stream:
            mi = get_metadata(stream, ext)
        if mi.cover and os.access(mi.cover, os.R_OK):
            cdata = open(mi.cover).read()
        elif mi.cover_data[1] is not None:
            cdata = mi.cover_data[1]
        if cdata:
            width, height, fmt = identify_data(cdata)
            area = width*height
    except:
        cdata = area = None

    if old != prefs['read_file_metadata']:
        prefs['read_file_metadata'] = old

    return cdata, area
Beispiel #54
0
    def __call__(self, stream, odir, log):
        from calibre.utils.zipfile import ZipFile
        from calibre.ebooks.metadata.meta import get_metadata
        from calibre.ebooks.metadata.opf2 import OPFCreator

        if not os.path.exists(odir):
            os.makedirs(odir)
        with CurrentDir(odir):
            log('Extracting ODT file...')
            html = self.odf2xhtml(stream)
            # A blanket img specification like this causes problems
            # with EPUB output as the containing element often has
            # an absolute height and width set that is larger than
            # the available screen real estate
            html = html.replace('img { width: 100%; height: 100%; }', '')
            try:
                html = self.fix_markup(html, log)
            except:
                log.exception('Failed to filter CSS, conversion may be slow')
            with open('index.xhtml', 'wb') as f:
                f.write(html.encode('utf-8'))
            zf = ZipFile(stream, 'r')
            self.extract_pictures(zf)
            stream.seek(0)
            mi = get_metadata(stream, 'odt')
            if not mi.title:
                mi.title = _('Unknown')
            if not mi.authors:
                mi.authors = [_('Unknown')]
            opf = OPFCreator(os.path.abspath(os.getcwdu()), mi)
            opf.create_manifest([(os.path.abspath(f), None)
                                 for f in walk(os.getcwdu())])
            opf.create_spine([os.path.abspath('index.xhtml')])
            with open('metadata.opf', 'wb') as f:
                opf.render(f)
            return os.path.abspath('metadata.opf')
Beispiel #55
0
def do_add(
    dbctx, paths, one_book_per_directory, recurse, add_duplicates, otitle, oauthors,
    oisbn, otags, oseries, oseries_index, ocover, oidentifiers, olanguages,
    compiled_rules
):
    with add_ctx():
        files, dirs = [], []
        for path in paths:
            path = os.path.abspath(path)
            if os.path.isdir(path):
                dirs.append(path)
            else:
                if os.path.exists(path):
                    files.append(path)
                else:
                    prints(path, 'not found')

        file_duplicates, added_ids = [], set()
        for book in files:
            fmt = os.path.splitext(book)[1]
            fmt = fmt[1:] if fmt else None
            if not fmt:
                continue
            ids, dups, book_title = dbctx.run(
                'add', 'book', dbctx.path(book), os.path.basename(book), fmt, add_duplicates,
                otitle, oauthors, oisbn, otags, oseries, oseries_index, serialize_cover(ocover) if ocover else None,
                oidentifiers, olanguages
            )
            added_ids |= set(ids)
            if dups:
                file_duplicates.append((book_title, book))

        dir_dups = []
        scanner = cdb_recursive_find if recurse else cdb_find_in_dir
        for dpath in dirs:
            for formats in scanner(dpath, one_book_per_directory, compiled_rules):
                cover_data = None
                for fmt in formats:
                    if fmt.lower().endswith('.opf'):
                        with lopen(fmt, 'rb') as f:
                            mi = get_metadata(f, stream_type='opf')
                            if mi.cover_data and mi.cover_data[1]:
                                cover_data = mi.cover_data[1]
                            elif mi.cover:
                                try:
                                    with lopen(mi.cover, 'rb') as f:
                                        cover_data = f.read()
                                except EnvironmentError:
                                    pass

                book_title, ids, dups = dbctx.run(
                        'add', 'format_group', tuple(map(dbctx.path, formats)), add_duplicates, cover_data)
                if book_title is not None:
                    added_ids |= set(ids)
                    if dups:
                        dir_dups.append((book_title, formats))

        sys.stdout = sys.__stdout__

        if dir_dups or file_duplicates:
            prints(
                _(
                    'The following books were not added as '
                    'they already exist in the database '
                    '(see --duplicates option):'
                ),
                file=sys.stderr
            )
            for title, formats in dir_dups:
                prints(' ', title, file=sys.stderr)
                for path in formats:
                    prints('   ', path)
            if file_duplicates:
                for title, path in file_duplicates:
                    prints(' ', title, file=sys.stderr)
                    prints('   ', path)

        if added_ids:
            prints(_('Added book ids: %s') % (', '.join(map(unicode_type, added_ids))))
Beispiel #56
0
    def convert(self, stream, options, file_ext, log,
                accelerators):
        from lxml import etree
        from calibre.ebooks.metadata.meta import get_metadata
        from calibre.ebooks.metadata.opf2 import OPFCreator
        from calibre.ebooks.rtf2xml.ParseRtf import RtfInvalidCodeException
        from calibre.ebooks.rtf.input import InlineClass
        self.opts = options
        self.log = log
        self.log('Converting RTF to XML...')
        try:
            xml = self.generate_xml(stream.name)
        except RtfInvalidCodeException as e:
            raise ValueError(_('This RTF file has a feature calibre does not '
            'support. Convert it to HTML first and then try it.\n%s')%e)

        d = glob.glob(os.path.join('*_rtf_pict_dir', 'picts.rtf'))
        if d:
            imap = {}
            try:
                imap = self.extract_images(d[0])
            except:
                self.log.exception('Failed to extract images...')

        self.log('Parsing XML...')
        parser = etree.XMLParser(recover=True, no_network=True)
        doc = etree.fromstring(xml, parser=parser)
        border_styles = self.convert_borders(doc)
        for pict in doc.xpath('//rtf:pict[@num]',
                namespaces={'rtf':'http://rtf2xml.sourceforge.net/'}):
            num = int(pict.get('num'))
            name = imap.get(num, None)
            if name is not None:
                pict.set('num', name)

        self.log('Converting XML to HTML...')
        inline_class = InlineClass(self.log)
        styledoc = etree.fromstring(P('templates/rtf.xsl', data=True))
        extensions = { ('calibre', 'inline-class') : inline_class }
        transform = etree.XSLT(styledoc, extensions=extensions)
        result = transform(doc)
        html = u'index.xhtml'
        with open(html, 'wb') as f:
            res = transform.tostring(result)
            # res = res[:100].replace('xmlns:html', 'xmlns') + res[100:]
            #clean multiple \n
            res = re.sub('\n+', '\n', res)
            # Replace newlines inserted by the 'empty_paragraphs' option in rtf2xml with html blank lines
            # res = re.sub('\s*<body>', '<body>', res)
            # res = re.sub('(?<=\n)\n{2}',
                    # u'<p>\u00a0</p>\n'.encode('utf-8'), res)
            f.write(res)
        self.write_inline_css(inline_class, border_styles)
        stream.seek(0)
        mi = get_metadata(stream, 'rtf')
        if not mi.title:
            mi.title = _('Unknown')
        if not mi.authors:
            mi.authors = [_('Unknown')]
        opf = OPFCreator(os.getcwdu(), mi)
        opf.create_manifest([(u'index.xhtml', None)])
        opf.create_spine([u'index.xhtml'])
        opf.render(open(u'metadata.opf', 'wb'))
        return os.path.abspath(u'metadata.opf')
Beispiel #57
0
    def initialize(self, library_path, db, listener, actions, show_gui=True):
        opts = self.opts
        self.preferences_action, self.quit_action = actions
        self.library_path = library_path
        self.content_server = None
        self.spare_servers = []
        self.must_restart_before_config = False
        self.listener = Listener(listener)
        self.check_messages_timer = QTimer()
        self.connect(self.check_messages_timer, SIGNAL('timeout()'),
                self.another_instance_wants_to_talk)
        self.check_messages_timer.start(1000)

        for ac in self.iactions.values():
            ac.do_genesis()
        self.donate_action = QAction(QIcon(I('donate.png')),
                _('&Donate to support calibre'), self)
        for st in self.istores.values():
            st.do_genesis()
        MainWindowMixin.__init__(self, db)

        # Jobs Button {{{
        self.job_manager = JobManager()
        self.jobs_dialog = JobsDialog(self, self.job_manager)
        self.jobs_button = JobsButton(horizontal=True, parent=self)
        self.jobs_button.initialize(self.jobs_dialog, self.job_manager)
        # }}}

        LayoutMixin.__init__(self)
        EmailMixin.__init__(self)
        EbookDownloadMixin.__init__(self)
        DeviceMixin.__init__(self)

        self.progress_indicator = ProgressIndicator(self)
        self.progress_indicator.pos = (0, 20)
        self.verbose = opts.verbose
        self.get_metadata = GetMetadata()
        self.upload_memory = {}
        self.metadata_dialogs = []
        self.default_thumbnail = None
        self.tb_wrapper = textwrap.TextWrapper(width=40)
        self.viewers = collections.deque()
        self.system_tray_icon = SystemTrayIcon(QIcon(I('lt.png')), self)
        self.system_tray_icon.setToolTip('calibre')
        self.system_tray_icon.tooltip_requested.connect(
                self.job_manager.show_tooltip)
        if not config['systray_icon']:
            self.system_tray_icon.hide()
        else:
            self.system_tray_icon.show()
        self.system_tray_menu = QMenu(self)
        self.restore_action = self.system_tray_menu.addAction(
                QIcon(I('page.png')), _('&Restore'))
        self.system_tray_menu.addAction(self.donate_action)
        self.donate_button.setDefaultAction(self.donate_action)
        self.donate_button.setStatusTip(self.donate_button.toolTip())
        self.eject_action = self.system_tray_menu.addAction(
                QIcon(I('eject.png')), _('&Eject connected device'))
        self.eject_action.setEnabled(False)
        self.addAction(self.quit_action)
        self.system_tray_menu.addAction(self.quit_action)
        self.keyboard.register_shortcut('quit calibre', _('Quit calibre'),
                default_keys=('Ctrl+Q',), action=self.quit_action)
        self.system_tray_icon.setContextMenu(self.system_tray_menu)
        self.connect(self.quit_action, SIGNAL('triggered(bool)'), self.quit)
        self.connect(self.donate_action, SIGNAL('triggered(bool)'), self.donate)
        self.connect(self.restore_action, SIGNAL('triggered()'),
                        self.show_windows)
        self.system_tray_icon.activated.connect(
            self.system_tray_icon_activated)

        self.esc_action = QAction(self)
        self.addAction(self.esc_action)
        self.keyboard.register_shortcut('clear current search',
                _('Clear the current search'), default_keys=('Esc',),
                action=self.esc_action)
        self.esc_action.triggered.connect(self.esc)

        ####################### Start spare job server ########################
        QTimer.singleShot(1000, self.add_spare_server)

        ####################### Location Manager ########################
        self.location_manager.location_selected.connect(self.location_selected)
        self.location_manager.unmount_device.connect(self.device_manager.umount_device)
        self.location_manager.configure_device.connect(self.configure_connected_device)
        self.eject_action.triggered.connect(self.device_manager.umount_device)

        #################### Update notification ###################
        UpdateMixin.__init__(self, opts)

        ####################### Search boxes ########################
        SavedSearchBoxMixin.__init__(self)
        SearchBoxMixin.__init__(self)

        ####################### Library view ########################
        LibraryViewMixin.__init__(self, db)

        if show_gui:
            self.show()

        if self.system_tray_icon.isVisible() and opts.start_in_tray:
            self.hide_windows()
        self.library_view.model().count_changed_signal.connect(
                self.iactions['Choose Library'].count_changed)
        if not gprefs.get('quick_start_guide_added', False):
            from calibre.ebooks.metadata.meta import get_metadata
            mi = get_metadata(open(P('quick_start.epub'), 'rb'), 'epub')
            self.library_view.model().add_books([P('quick_start.epub')], ['epub'],
                    [mi])
            gprefs['quick_start_guide_added'] = True
            self.library_view.model().books_added(1)
            if hasattr(self, 'db_images'):
                self.db_images.reset()
            if self.library_view.model().rowCount(None) < 3:
                self.library_view.resizeColumnsToContents()

        self.library_view.model().count_changed()
        self.bars_manager.database_changed(self.library_view.model().db)
        self.library_view.model().database_changed.connect(self.bars_manager.database_changed,
                type=Qt.QueuedConnection)

        ########################### Tags Browser ##############################
        TagBrowserMixin.__init__(self, db)

        ######################### Search Restriction ##########################
        SearchRestrictionMixin.__init__(self)
        if db.prefs['gui_restriction']:
            self.apply_named_search_restriction(db.prefs['gui_restriction'])

        ########################### Cover Flow ################################

        CoverFlowMixin.__init__(self)

        self._calculated_available_height = min(max_available_height()-15,
                self.height())
        self.resize(self.width(), self._calculated_available_height)

        self.build_context_menus()

        for ac in self.iactions.values():
            try:
                ac.gui_layout_complete()
            except:
                import traceback
                traceback.print_exc()
                if ac.plugin_path is None:
                    raise

        if config['autolaunch_server']:
            self.start_content_server()


        self.keyboard_interrupt.connect(self.quit, type=Qt.QueuedConnection)

        self.read_settings()
        self.finalize_layout()
        if self.bars_manager.showing_donate:
            self.donate_button.start_animation()
        self.set_window_title()

        for ac in self.iactions.values():
            try:
                ac.initialization_complete()
            except:
                import traceback
                traceback.print_exc()
                if ac.plugin_path is None:
                    raise
        self.device_manager.set_current_library_uuid(db.library_id)

        self.keyboard.finalize()
        self.auto_adder = AutoAdder(gprefs['auto_add_path'], self)

        self.save_layout_state()

        # Collect cycles now
        gc.collect()

        if show_gui and self.gui_debug is not None:
            info_dialog(self, _('Debug mode'), '<p>' +
                    _('You have started calibre in debug mode. After you '
                        'quit calibre, the debug log will be available in '
                        'the file: %s<p>The '
                        'log will be displayed automatically.')%self.gui_debug, show=True)

        self.iactions['Connect Share'].check_smartdevice_menus()
        QTimer.singleShot(1, self.start_smartdevice)