示例#1
0
    def cli_main(self,argv):

        with self: # so the sys.path was modified appropriately
            # I believe there's no performance hit loading these here when
            # CLI--it would load everytime anyway.
            from StringIO import StringIO
            from calibre.library import db
            from calibre_plugins.fanficfare_plugin.fanficfare.cli import main as fff_main
            from calibre_plugins.fanficfare_plugin.prefs import PrefsFacade
            from calibre.utils.config import prefs as calibre_prefs
            from optparse import OptionParser      
    
            parser = OptionParser('%prog --run-plugin '+self.name+' -- [options] <storyurl>')
            parser.add_option('--library-path', '--with-library', default=None, help=_('Path to the calibre library. Default is to use the path stored in the settings.'))
            # parser.add_option('--dont-notify-gui', default=False, action='store_true',
            #               help=_('Do not notify the running calibre GUI (if any) that the database has'
            #                      ' changed. Use with care, as it can lead to database corruption!'))
    
            pargs = [x for x in argv if x.startswith('--with-library') or x.startswith('--library-path')
                     or not x.startswith('-')]
            opts, args = parser.parse_args(pargs)
    
            fff_prefs = PrefsFacade(db(path=opts.library_path,
                                        read_only=True))

            fff_main(argv[1:],
                      parser=parser,
                      passed_defaultsini=StringIO(get_resources("fanficfare/defaults.ini")),
                      passed_personalini=StringIO(fff_prefs["personal.ini"]))
示例#2
0
    def cli_main(self,argv):

        with self: # so the sys.path was modified appropriately
            # I believe there's no performance hit loading these here when
            # CLI--it would load everytime anyway.
            from StringIO import StringIO
            from calibre.library import db
            from calibre_plugins.fanficfare_plugin.fanficfare.cli import main as fff_main
            from calibre_plugins.fanficfare_plugin.prefs import PrefsFacade
            from calibre.utils.config import prefs as calibre_prefs
            from optparse import OptionParser

            parser = OptionParser('%prog --run-plugin '+self.name+' -- [options] <storyurl>')
            parser.add_option('--library-path', '--with-library', default=None, help=_('Path to the calibre library. Default is to use the path stored in the settings.'))
            # parser.add_option('--dont-notify-gui', default=False, action='store_true',
            #               help=_('Do not notify the running calibre GUI (if any) that the database has'
            #                      ' changed. Use with care, as it can lead to database corruption!'))

            pargs = [x for x in argv if x.startswith('--with-library') or x.startswith('--library-path')
                     or not x.startswith('-')]
            opts, args = parser.parse_args(pargs)

            fff_prefs = PrefsFacade(db(path=opts.library_path,
                                        read_only=True))

            fff_main(argv[1:],
                     parser=parser,
                     passed_defaultsini=StringIO(get_resources("fanficfare/defaults.ini")),
                     passed_personalini=StringIO(fff_prefs["personal.ini"]),
                     )
示例#3
0
def test_tag_browser(library_path=None):
    ' Compare output of server and GUI tag browsers '
    from calibre.library import db
    olddb = db(library_path)
    db = olddb.new_api
    opts = categories_settings({}, db)
    # opts = opts._replace(hidden_categories={'publisher'})
    opts = opts._replace(hide_empty_categories=True)
    category_data = db.get_categories(sort=opts.sort_by, first_letter_sort=opts.collapse_model == 'first letter')
    data = render_categories(opts, db, category_data)
    srv_data = dump_categories_tree(data)
    from calibre.gui2 import Application, gprefs
    from calibre.gui2.tag_browser.model import TagsModel
    prefs = {
        'tags_browser_category_icons':gprefs['tags_browser_category_icons'],
        'tags_browser_collapse_at':opts.collapse_at,
        'tags_browser_partition_method': opts.collapse_model,
        'tag_browser_dont_collapse': opts.dont_collapse,
        'tag_browser_hide_empty_categories': opts.hide_empty_categories,
    }
    app = Application([])
    m = TagsModel(None, prefs)
    m.set_database(olddb, opts.hidden_categories)
    m_data = dump_tags_model(m)
    if m_data == srv_data:
        print('No differences found in the two Tag Browser implementations')
        raise SystemExit(0)
    from calibre.gui2.tweak_book.diff.main import Diff
    d = Diff(show_as_window=True)
    d.string_diff(m_data, srv_data, left_name='GUI', right_name='server')
    d.exec_()
    del app
示例#4
0
def run_variation_algorithm(match_type, item_type):
    from calibre.library import db
    alg = VariationAlgorithm(db())
    dm, cm, im = alg.run_variation_check(match_type, item_type)
    print('---')
    print('%s %s Duplicate Results:'%(match_type, item_type))
    for k, matches in im.iteritems():
        texts = ['%s (%d)'%(dm[i],cm[i]) for i in matches]
        print('  %s (%d) => {%s}'%(dm[k], cm[k], ', '.join(texts)))
示例#5
0
文件: main.py 项目: Eksmo/calibre
def create_wsgi_app(path_to_library=None, prefix=''):
    'WSGI entry point'
    from calibre.library import db
    cherrypy.config.update({'environment': 'embedded'})
    db = db(path_to_library)
    parser = option_parser()
    opts, args = parser.parse_args(['calibre-server'])
    opts.url_prefix = prefix
    server = LibraryServer(db, opts, wsgi=True, show_tracebacks=True)
    return cherrypy.Application(server, script_name=None, config=server.config)
示例#6
0
def create_wsgi_app(path_to_library=None, prefix=''):
    'WSGI entry point'
    from calibre.library import db
    cherrypy.config.update({'environment': 'embedded'})
    db = db(path_to_library)
    parser = option_parser()
    opts, args = parser.parse_args(['calibre-server'])
    opts.url_prefix = prefix
    server = LibraryServer(db, opts, wsgi=True, show_tracebacks=True)
    return cherrypy.Application(server, script_name=None, config=server.config)
def do_obtain_new_books(cpus, account, notification=lambda x, y:x):
    print "do_obtain_new_books in jobs.py"

    print "Account is: %s" % (account)

    # This server is an arbitrary_n job, so there is a notifier available.
    # Set the % complete to a small number to avoid the 'unavailable' indicator
    notification(0.01, "Starting up...")

    from calibre.library import db
    from calibre.utils.config import prefs
    prefs.refresh()
    db = db(read_only=False)

    print "DB is: %s" % (db)

    prefs = PrefsFacade(db)
    print "Prefs are: %s" % (prefs)
    print "Library id is (%s)" % (prefs.get_library_uuid())

    reporter = ConsoleReporter()
    downloader = BeamEbooksDownloader(prefs, caller = reporter)
    print "-- LALA -- Downloader is: %s" % (downloader)

    if account[prefs.ENABLED]:
        downloader.login(account)

        if downloader.successful_login == False:
            notification(1.00, "Failed to log in...")
        else:
            notification(0.05, "Parsing document tree now...")
            downloadable_ebooks = downloader.recursive_descent(norms(prefs[prefs.URLBASE]))
            notification(0.50, "Loaded OPDS pages")
            reporter.notify(downloadable_ebooks)
            #
            # Now, download the obtained ebooks...

    notification(1.00, "Done...")

    adder = EBookAdder(prefs, "beam-ebooks")

    adder.load_books()

    new_ebooks = []

    for entry in downloadable_ebooks:
        beamebooks_id = entry['id']

        book = adder.books_of_this_shop.get(beamebooks_id)
        if book is None:
            new_ebooks.append(entry)

    result = (new_ebooks)

    return result
示例#8
0
    def cli_convert(self, args):
        #NODOC
        printsd(args)
        if args.all:
            # `calibre-debug -r djvumaker -- convert --all`
            printsd('in cli convert_all')
            # TODO: make work `djvumaker -- convert --all`
            # raise NotImplementedError('Convert all is not implemented.')

            user_input = ask_yesno_input(
                'Do you wany to copy-convert all PDFs to DJVU?')
            if not user_input:
                return None

            from calibre.library import db
            from calibre.customize.ui import run_plugins_on_postimport
            db = db()  # initialize calibre library database
            for book_id in list(db.all_ids()):
                if db.has_format(book_id, 'DJVU', index_is_id=True):
                    continue
                # TODO: shouldn't work with this code, db has not atributte run_plugins_on_postimport
                #       https://github.com/kovidgoyal/calibre/blob/master/src/calibre/customize/ui.py
                if db.has_format(book_id, 'PDF', index_is_id=True):
                    run_plugins_on_postimport(db, book_id, 'pdf')
                    continue
        elif args.path is not None:
            # `calibre-debug -r djvumaker -- convert -p test.pdf` -> tempfile(test.djvu)
            printsd('in path')
            if is_rasterbook(args.path):
                djvu = self.run_backend(args.path, log=self.prints.func)
                if djvu:
                    input_filename, _ = os.path.splitext(args.path)
                    shutil.copy2(djvu, input_filename + '.djvu')
                    prints("Finished DJVU outputed to: {}.".format(
                        input_filename + '.djvu'))

                    user_input = ask_yesno_input(
                        'Do you want to open djvused in subshell?'
                        ' (may not work on not macOS)')
                    if not user_input:
                        return None
                    # de-munge the tty
                    sys.stdin = sys.__stdin__
                    sys.stdout = sys.__stdout__
                    sys.stderr = sys.__stderr__
                    os.system("stat '%s'" % djvu)
                    # TODO: doesn't work on Windows, why is it here?
                    os.system("djvused -e dump '%s'" % djvu)
                    os.system("djvused -v '%s'" % djvu)

        elif args.id is not None:
            # `calibre-debug -r djvumaker -- convert -i 123 #id(123).pdf` -> tempfile(id(123).djvu)
            printsd('in convert by id')
            self._postimport(args.id)
示例#9
0
def init_gui():
    from calibre.gui2.ui import Main
    from calibre.gui2.main import option_parser
    from calibre.library import db
    parser = option_parser()
    opts, args = parser.parse_args([])
    actions = tuple(Main.create_application_menubar())
    db = db()
    gui = Main(opts)
    gui.initialize(db.library_path, db, None, actions, show_gui=False)
    return gui
示例#10
0
def init_gui():
    from calibre.gui2.ui import Main
    from calibre.gui2.main import option_parser
    from calibre.library import db
    parser = option_parser()
    opts, args = parser.parse_args([])
    actions = tuple(Main.create_application_menubar())
    db = db()
    gui = Main(opts)
    gui.initialize(db.library_path, db, actions, show_gui=False)
    return gui
示例#11
0
def get_current_db():
    '''
    This method will try to return the current database in use by the user as
    efficiently as possible, i.e. without constructing duplicate
    LibraryDatabase objects.
    '''
    from calibre.gui2.ui import get_gui
    gui = get_gui()
    if gui is not None and gui.current_db is not None:
        return gui.current_db
    from calibre.library import db
    return db()
示例#12
0
def get_current_db():
    '''
    This method will try to return the current database in use by the user as
    efficiently as possible, i.e. without constructing duplicate
    LibraryDatabase objects.
    '''
    from calibre.gui2.ui import get_gui
    gui = get_gui()
    if gui is not None and gui.current_db is not None:
        return gui.current_db
    from calibre.library import db
    return db()
示例#13
0
文件: test.py 项目: xxyzz/WordDumb
    def setUpClass(cls):
        lib_db = db('~/Calibre Library').new_api
        book_1984_id = 0
        for book_id in lib_db.all_book_ids():
            mi = lib_db.get_metadata(book_id)
            if mi.get('title') == '1984':
                book_1984_id = book_id
                break

        data = check_metadata(lib_db, book_1984_id)
        (_, cls.fmt, cls.asin, cls.book_path, _, _) = data
        create_x = False if platform.system() == 'Darwin' else True
        do_job(data, create_x=create_x)
示例#14
0
    def cli_convert(self, args):
        #NODOC
        printsd(args)
        if args.all:
            # `calibre-debug -r djvumaker -- convert --all`
            printsd('in cli convert_all')
            # TODO: make work `djvumaker -- convert --all`
            # raise NotImplementedError('Convert all is not implemented.')

            user_input = ask_yesno_input('Do you wany to copy-convert all PDFs to DJVU?')
            if not user_input:
                return None

            from calibre.library import db
            from calibre.customize.ui import run_plugins_on_postimport
            db = db() # initialize calibre library database
            for book_id in list(db.all_ids()):
                if db.has_format(book_id, 'DJVU', index_is_id=True):
                    continue
                # TODO: shouldn't work with this code, db has not atributte run_plugins_on_postimport
                #       https://github.com/kovidgoyal/calibre/blob/master/src/calibre/customize/ui.py
                if db.has_format(book_id, 'PDF', index_is_id=True):
                    run_plugins_on_postimport(db, book_id, 'pdf')
                    continue
        elif args.path is not None:
            # `calibre-debug -r djvumaker -- convert -p test.pdf` -> tempfile(test.djvu)
            printsd('in path')
            if is_rasterbook(args.path):
                djvu = self.run_backend(args.path, log=self.prints.func)
                if djvu:
                    input_filename, _ = os.path.splitext(args.path)
                    shutil.copy2(djvu, input_filename + '.djvu')
                    prints("Finished DJVU outputed to: {}.".format(input_filename + '.djvu'))

                    user_input = ask_yesno_input('Do you want to open djvused in subshell?'
                                                 ' (may not work on not macOS)')
                    if not user_input:
                        return None
                    # de-munge the tty
                    sys.stdin = sys.__stdin__
                    sys.stdout = sys.__stdout__
                    sys.stderr = sys.__stderr__
                    os.system("stat '%s'" % djvu)
                    # TODO: doesn't work on Windows, why is it here?
                    os.system("djvused -e dump '%s'" % djvu)
                    os.system("djvused -v '%s'" % djvu)

        elif args.id is not None:
            # `calibre-debug -r djvumaker -- convert -i 123 #id(123).pdf` -> tempfile(id(123).djvu)
            printsd('in convert by id')
            self._postimport(args.id, fork_job=False)
示例#15
0
文件: test.py 项目: amirhxe/WordDumb
    def setUpClass(cls):
        lib_db = db('~/Calibre Library').new_api
        book_1984_id = 0
        for book_id in lib_db.all_book_ids():
            mi = lib_db.get_metadata(book_id)
            if mi.get('title') == '1984':
                book_1984_id = book_id
                break

        data = check_metadata(lib_db, book_1984_id)
        (_, cls.fmt, cls.asin, cls.book_path, _) = data
        install_libs()
        start_time = time.time()
        do_job(data, load_json('data/lemmas.json'))
        print(f'{time.time() - start_time} seconds')
示例#16
0
def gui_catalog(fmt,
                title,
                dbspec,
                ids,
                out_file_name,
                sync,
                fmt_options,
                connected_device,
                notification=DummyReporter(),
                log=None):
    if log is None:
        log = Log()
    from calibre.library import db
    from calibre.utils.config import prefs
    prefs.refresh()
    db = db(read_only=True)
    db.catalog_plugin_on_device_temp_mapping = dbspec

    # Create a minimal OptionParser that we can append to
    parser = OptionParser()
    args = []
    parser.add_option("--verbose",
                      action="store_true",
                      dest="verbose",
                      default=True)
    opts, args = parser.parse_args()

    # Populate opts
    # opts.gui_search_text = something
    opts.catalog_title = title
    opts.connected_device = connected_device
    opts.ids = ids
    opts.search_text = None
    opts.sort_by = None
    opts.sync = sync

    # Extract the option dictionary to comma-separated lists
    for option in fmt_options:
        if isinstance(fmt_options[option], list):
            setattr(opts, option, ','.join(fmt_options[option]))
        else:
            setattr(opts, option, fmt_options[option])

    # Fetch and run the plugin for fmt
    # Returns 0 if successful, 1 if no catalog built
    plugin = plugin_for_catalog_format(fmt)
    return plugin.run(out_file_name, opts, db, notification=notification)
示例#17
0
    def config_widget(self):
        '''
        Implement this method and :meth:`save_settings` in your plugin to
        use a custom configuration dialog.

        This method, if implemented, must return a QWidget. The widget can have
        an optional method validate() that takes no arguments and is called
        immediately after the user clicks OK. Changes are applied if and only
        if the method returns True.
        '''
        if self.actual_plugin_:
            from calibre_plugins.beam_ebooks_downloader.config import ConfigWidget
            from calibre_plugins.beam_ebooks_downloader.prefs import PrefsFacade

            my_db = db(path=None, read_only=True)
            prefs = PrefsFacade(my_db)
            return ConfigWidget(self.actual_plugin_, prefs)
示例#18
0
 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
示例#19
0
    def cli_main(self, argv):
        from calibre.utils.config import prefs as calibre_prefs
        from optparse import OptionParser

        from calibre_plugins.beam_ebooks_downloader.prefs import PrefsFacade

        my_db = db(path=None, read_only=False)

        # print 'Database is (%s)' % (prefs._get_db())
        print 'Database is (%s)' % (my_db)

        prefs = PrefsFacade(my_db)

        print 'My Prefs are (%s)' % (prefs)
        print '    methods are (%s)' % (dir(prefs))
        print '    library id is (%s)' % (prefs.get_library_uuid())

        print 'Calibre Prefs are (%s)' % (calibre_prefs)
        print '    methods are (%s)' % (dir(calibre_prefs))

        downloader = BeamEbooksDownloader(prefs, self.version, caller=self)

        # Loop over all accounts until we have support for selection
        for account_id in prefs[prefs.ACCOUNTS]:
            account = prefs[prefs.ACCOUNTS][account_id]
            account[prefs.ACCOUNT_ID] = account_id
            print "Account: '%s'" % account

            if account[prefs.ENABLED]:
                downloader.login(account)

                if downloader.successful_login == False:
                    print "Failed to log in..."
                else:
                    print "Parsing document tree now..."
                    # Temporarily...
                    # downloader.recursive_descent(prefs[prefs.URLBASE] + "/aldiko/bibuebersicht.php5?user="******"/aldiko/pakete.php5?user="******"/kunden/abos.php5")
                    downloader.download_ebooks()

        pass
示例#20
0
    def remove_books_from_metadata(self, paths, booklists):
        # log.debug("{}".format((paths, booklists)))
        # if self.can_set_as_read:
        #    calibre_db = db(prefs['library_path']).new_api
        changed = set()


        for i, path in enumerate(paths):
            self.report_progress((i+1) / float(len(paths)), _('Updating fields for deleted books...'))
            for bl in booklists:
                for book in bl:
                    # log.debug("Compare {} and {}".format(path, book.path))
                    if path.endswith(book.path):
                        log.debug("We'll try to update {}".format(book))
                        log.debug("Here are the original values for {}: {}".format(book.application_id, db().new_api.get_metadata(book.application_id)))

                        try:
                            log.debug("Unset, field {}: {}".format(self.set_as_read_fields[0], (book.application_id, str(book))))
                            changed |= db().new_api.set_field(self.set_as_read_fields[0], {book.application_id: None})
                        except Exception, e:
                            log.error(e)
                        log.debug("Here are the values for {} after settings: {}".format(book.application_id, db().new_api.get_metadata(book.application_id)))
示例#21
0
def gui_catalog(fmt, title, dbspec, ids, out_file_name, sync, fmt_options, connected_device,
        notification=DummyReporter(), log=None):
    if log is None:
        log = Log()
    from calibre.library import db
    from calibre.utils.config import prefs
    prefs.refresh()
    db = db(read_only=True)
    db.catalog_plugin_on_device_temp_mapping = dbspec

    # Create a minimal OptionParser that we can append to
    parser = OptionParser()
    args = []
    parser.add_option("--verbose", action="store_true", dest="verbose", default=True)
    opts, args = parser.parse_args()

    # Populate opts
    # opts.gui_search_text = something
    opts.catalog_title = title
    opts.connected_device = connected_device
    opts.ids = ids
    opts.search_text = None
    opts.sort_by = None
    opts.sync = sync

    # Extract the option dictionary to comma-separated lists
    for option in fmt_options:
        if isinstance(fmt_options[option],list):
            setattr(opts,option, ','.join(fmt_options[option]))
        else:
            setattr(opts,option, fmt_options[option])

    # Fetch and run the plugin for fmt
    # Returns 0 if successful, 1 if no catalog built
    plugin = plugin_for_catalog_format(fmt)
    return plugin.run(out_file_name, opts, db, notification=notification)
示例#22
0
        self.current_row = row
        self.setWindowTitle(mi.title)
        self.cover_pixmap = QPixmap.fromImage(mi.cover_data[1])
        try:
            dpr = self.devicePixelRatioF()
        except AttributeError:
            dpr = self.devicePixelRatio()
        self.cover_pixmap.setDevicePixelRatio(dpr)
        self.resize_cover()
        html = render_html(mi,
                           True,
                           self,
                           pref_name='popup_book_display_fields')
        set_html(mi, html, self.details)
        self.marked = mi.marked
        self.cover.setBackgroundBrush(
            self.marked_brush if mi.marked else self.normal_brush)
        self.update_cover_tooltip()


if __name__ == '__main__':
    from calibre.gui2 import Application
    from calibre.library import db
    app = Application([])
    app.current_db = db()
    get_gui.ans = app
    d = Configure(app.current_db)
    d.exec_()
    del d
    del app
示例#23
0
                annot['notes'] = notes.strip()
            else:
                annot.pop('notes', None)
            db = current_db()
            db.update_annotations({annot_id: annot})
            self.details_panel.update_notes(annot)

    def show_dialog(self):
        if self.parent() is None:
            self.browse_panel.effective_query_changed()
            self.exec_()
        else:
            self.reinitialize()
            self.show()
            self.raise_()
            QTimer.singleShot(80, self.browse_panel.effective_query_changed)

    def reinitialize(self):
        self.browse_panel.re_initialize()


if __name__ == '__main__':
    from calibre.library import db
    app = Application([])
    current_db.ans = db(os.path.expanduser('~/test library'))
    br = AnnotationsBrowser()
    br.reinitialize()
    br.show_dialog()
    del br
    del app
示例#24
0
            for book_id in matching_books:
                aut = [a.replace('|', ',') for a in (db.authors(book_id,
                    index_is_id=True) or '').split(',')]
                add_child(ta%dict(
                    title=db.title(book_id, index_is_id=True),
                    author=authors_to_string(aut),
                    formats=db.formats(book_id, index_is_id=True,
                                       verify_formats=False)))
            add_child('')

            yield item

    @property
    def duplicates(self):
        for i in xrange(self.dup_list.topLevelItemCount()):
            x = self.dup_list.topLevelItem(i)
            if x.checkState(0) == Qt.Checked:
                yield x.data(0, Qt.UserRole).toPyObject()

if __name__ == '__main__':
    from PyQt4.Qt import QApplication
    from calibre.ebooks.metadata.book.base import Metadata as M
    from calibre.library import db

    app = QApplication([])
    db = db()
    d = DuplicatesQuestion(db, [(M('Life of Pi', ['Yann Martel']), None, None),
                            (M('Heirs of the blade', ['Adrian Tchaikovsky']), None, None)])
    print (tuple(d.duplicates))

示例#25
0
    def fix_extra_covers(self):
        tl = self.top_level_items['extra_covers']
        child_count = tl.childCount()
        for i in range(0, child_count):
            item = tl.child(i)
            id = int(item.data(0, Qt.UserRole))
            self.db.set_has_cover(id, True)

    def fix_items(self):
        for check in CHECKS:
            attr = check[0]
            fixable = check[3]
            tl = self.top_level_items[attr]
            if fixable and tl.checkState(1):
                func = getattr(self, 'fix_' + attr, None)
                if func is not None and callable(func):
                    func()
        self.run_the_check()

    def copy_to_clipboard(self):
        QApplication.clipboard().setText(self.text_results)


if __name__ == '__main__':
    app = QApplication([])
    from calibre.library import db
    d = CheckLibraryDialog(None, db())
    d.exec_()

示例#26
0
    def iteritems(self):
        cl = self.column_list
        return (cl.item(i) for i in range(cl.count()))

    def apply_spec(self, spec):
        self.clear()
        cl = self.column_list
        imap = {
            item.data(Qt.ItemDataRole.UserRole): item
            for item in self.iteritems()
        }
        for key, ascending in reversed(spec):
            item = imap.get(key)
            if item is not None:
                item = cl.takeItem(cl.row(item))
                cl.insertItem(0, item)
                self.sort_order_map[key] = ascending
                item.setCheckState(Qt.CheckState.Checked)


if __name__ == '__main__':
    from calibre.gui2 import Application
    app = Application([])
    from calibre.library import db
    d = ChooseMultiSort(db())
    d.exec_()
    print(d.current_sort_spec)
    del d
    del app
示例#27
0
    def _postimport(self,
                    book_id,
                    book_format=None,
                    db=None,
                    log=None,
                    fork_job=True,
                    abort=None,
                    notifications=None):
        #NODOC IMPORTANT
        # TODO: make general overhaul of starting conversion logic
        if log:  # divert our printing to the caller's logger
            prints = log  # Log object has __call__ dunder method with INFO level
            prints = partial(prints, '{}:'.format(PLUGINNAME))
        else:
            log = self.prints.func
        try:
            prints
        except NameError:
            prints = self.prints

        if sys.__stdin__.isatty():
            # if run by cli, i.e.:
            #    calibredb add
            #    calibredebug -r djvumaker -- convert -i #id
            # runs also for GUI if run trough `calibredebug -g`
            fork_job = False  # DEBUG UNCOMMENT
            rpc_refresh = True  # use the calibre RPC to signal a GUI refresh

        if db is None:
            from calibre.library import db  # TODO: probably legacy db import, change for new_api
            db = db()  # initialize calibre library database

        if book_format == None:
            if not db.has_format(book_id, 'PDF', index_is_id=True):
                raise Exception(
                    'Book with id #{} has not a PDF format.'.format(book_id))
            else:
                book_format = 'pdf'

        if db.has_format(book_id, 'DJVU', index_is_id=True):
            prints(
                "already have 'DJVU' format document for book ID #{}".format(
                    book_id))
            return None  # don't auto convert, we already have a DJVU for this document

        path_to_ebook = db.format_abspath(book_id,
                                          book_format,
                                          index_is_id=True)
        if book_format == 'pdf':
            is_rasterbook_val, pages, images = is_rasterbook(
                path_to_ebook, basic_return=False)
            if is_rasterbook_val:
                pass  # TODO: should add a 'scanned' or 'djvumaker' tag
            else:
                # this is a marked-up/vector-based pdf,
                # no advantages to having another copy in DJVU format
                prints((
                    "{} document from book ID #{} determined to be a markup-based ebook,"
                    " not converting to DJVU").format(book_format, book_id))
                return None  #no-error in job panel
            # TODO: test the DPI to determine if a document is from a broad-sheeted book.
            #       if so, queue up k2pdfopt to try and chunk the content appropriately to letter size

            prints((
                "scheduling new {} document from book ID #{} for post-import DJVU"
                " conversion: {}").format(book_format, book_id, path_to_ebook))

        if fork_job:
            #useful for not blocking calibre GUI when large PDFs
            # are dropped into the automatic-import-folder
            try:
                # https://github.com/kovidgoyal/calibre/blob/master/src/calibre/utils/ipc/simple_worker.py
                # dispatch API for Worker()
                # src/calibre/utils/ipc/launch.py
                # Worker() uses sbp.Popen to
                # run a second Python to a logfile
                # note that Calibre bungs the python loader to check the plugin directory when
                # modules with calibre_plugin. prefixed are passed
                # https://github.com/kovidgoyal/calibre/blob/master/src/calibre/customize/zipplugin.py#L192
                func_name = self.plugin_prefs['use_backend']
                args = [
                    path_to_ebook, log, abort, notifications, pages, images
                ]
                jobret = worker_fork_job(
                    'calibre_plugins.{}'.format(PLUGINNAME),
                    func_name,
                    args=args,
                    kwargs={'preferences': self.plugin_prefs},
                    env={'PATH': os.environ['PATH'] + ':/usr/local/bin'},
                    # djvu and poppler-utils on osx
                    timeout=600)
                # TODO: determine a resonable timeout= based on filesize or
                # make a heartbeat= check
                # TODO: doesn't work for pdf2djvu, why?

            except WorkerError as e:
                prints('djvudigital background conversion failed: \n{}'.format(
                    force_unicode(e.orig_tb)))
                raise  # ConversionError
            except:
                prints(traceback.format_exc())
                raise

        # dump djvudigital output logged in file by the Worker to
        # calibre proc's (gui or console) log/stdout
            with open(jobret['stdout_stderr'], 'rb') as f:
                raw = f.read().strip()
                prints(raw)

            if jobret['result']:
                djvu = jobret['result']
            else:
                WorkerError("djvu conversion error: %s" % jobret['result'])
        # elif hasattr(self, gui): #if we have the calibre gui running,
        # we can give it a threadedjob and not use fork_job
        else:  #!fork_job & !gui
            prints("Starts backend")
            djvu = self.run_backend(path_to_ebook, log, abort, notifications,
                                    pages, images)

        if djvu:
            db.new_api.add_format(book_id, 'DJVU', djvu, run_hooks=True)
            prints("added new 'DJVU' document to book ID #{}".format(book_id))
            if sys.__stdin__.isatty():
                # update calibre gui Out-Of-Band. Like if we were run as a command-line scripted import
                # this resets current gui views/selections, no cleaner way to do it :-(
                from calibre.utils.ipc import RC
                t = RC(print_error=False)
                t.start()
                t.join(3)
                if t.done:  # GUI is running
                    t.conn.send('refreshdb:')
                    t.conn.close()
                    prints("signalled Calibre GUI refresh")
        else:
            # TODO: normal Exception propagation instead of passing errors as return values
            raise Exception('ConversionError, djvu: {}'.format(djvu))
示例#28
0
def clean_story_link(link):
    # works for FFNet and AO3
    strings = link.split("/")
    for i, s in enumerate(strings):
        if s.isnumeric():
            return "/".join(strings[:i + 1])
    log.warn(
        f"{link} is not a parsable or valid story link, this may cause issues."
    )
    return link


# perform work in temporary directory
tempdir = tempfile.gettempdir()
log.debug(f"Using temporary directory: {tempdir}")
db = db(calibre_path).new_api

# import retry links
story_urls = []
if os.path.isfile(RETRY_FILE):
    log.info("Searching for previously failed updates...")
    with open(RETRY_FILE) as file:
        story_urls += file.read().splitlines()
    os.remove(RETRY_FILE)

log.info("Searching email for updated stories...")
try:
    story_urls += list(
        map(
            clean_story_link,
            geturls.get_urls_from_imap(imap_server, imap_email, imap_password,
示例#29
0
        changed = set()


        for i, path in enumerate(paths):
            self.report_progress((i+1) / float(len(paths)), _('Updating fields for deleted books...'))
            for bl in booklists:
                for book in bl:
                    # log.debug("Compare {} and {}".format(path, book.path))
                    if path.endswith(book.path):
                        log.debug("We'll try to update {}".format(book))
                        log.debug("Here are the original values for {}: {}".format(book.application_id, db().new_api.get_metadata(book.application_id)))

                        try:
                            log.debug("Unset, field {}: {}".format(self.set_as_read_fields[0], (book.application_id, str(book))))
                            changed |= db().new_api.set_field(self.set_as_read_fields[0], {book.application_id: None})
                        except Exception, e:
                            log.error(e)
                        log.debug("Here are the values for {} after settings: {}".format(book.application_id, db().new_api.get_metadata(book.application_id)))

        log.debug(changed)
        log.debug('Finished updating fields for %d books'%(len(paths)))
        db().new_api.commit_dirty_cache()
        from calibre.gui2.ui import get_gui

        if get_gui():
            log.debug("Got GUI!  Refreshing view for {} ({})".format(changed, db().new_api.all_field_for(self.set_as_read_fields[0], changed)))
            get_gui().library_view.model().db.refresh()
            get_gui().library_view.model().refresh_ids(changed)
        super(MUSE, self).remove_books_from_metadata(paths, booklists)

示例#30
0
        fmts = set()
        for path in files:
            fmt = path.rpartition('.')[-1].upper()
            if tweaks['save_original_format_when_polishing'] and not is_orig[fmt]:
                fmts.add(fmt)
                db.save_original_format(book_id, fmt, notify=False)
            with open(path, 'rb') as f:
                db.add_format(book_id, fmt, f, index_is_id=True)
        self.gui.status_bar.show_message(job.description + _(' completed'), 2000)
        try:
            shutil.rmtree(base)
            parent = os.path.dirname(base)
            os.rmdir(parent)
        except:
            pass
        self.gui.tags_view.recount()
        if self.gui.current_view() is self.gui.library_view:
            current = self.gui.library_view.currentIndex()
            if current.isValid():
                self.gui.library_view.model().current_changed(current, QModelIndex())
        if show_reports:
            self.report(db.title(book_id, index_is_id=True), book_id, fmts, job, job.result)


if __name__ == '__main__':
    app = QApplication([])
    app
    from calibre.library import db
    d = Polish(db(), {1:{'EPUB'}, 2:{'AZW3'}})
    d.exec_()
示例#31
0
        fmts = set()
        for path in files:
            fmt = path.rpartition('.')[-1].upper()
            if tweaks['save_original_format_when_polishing'] and not is_orig[fmt]:
                fmts.add(fmt)
                db.save_original_format(book_id, fmt, notify=False)
            with open(path, 'rb') as f:
                db.add_format(book_id, fmt, f, index_is_id=True)
        self.gui.status_bar.show_message(job.description + _(' completed'), 2000)
        try:
            shutil.rmtree(base)
            parent = os.path.dirname(base)
            os.rmdir(parent)
        except:
            pass
        self.gui.tags_view.recount()
        if self.gui.current_view() is self.gui.library_view:
            current = self.gui.library_view.currentIndex()
            if current.isValid():
                self.gui.library_view.model().current_changed(current, QModelIndex())
        if show_reports:
            self.report(db.title(book_id, index_is_id=True), book_id, fmts, job, job.result)

if __name__ == '__main__':
    app = QApplication([])
    app
    from calibre.library import db
    d = Polish(db(), {1:{'EPUB'}, 2:{'AZW3'}})
    d.exec_()

示例#32
0
        QWizard.__init__(self, parent)
        self.setModal(True)
        self.setWindowTitle(_('Add books to calibre'))
        self.setWindowIcon(QIcon(I('add_book.png')))
        self.setPixmap(
            self.LogoPixmap,
            QPixmap(P('content_server/calibre.png')).scaledToHeight(
                80, Qt.SmoothTransformation))
        self.setPixmap(self.WatermarkPixmap, QPixmap(I('welcome_wizard.png')))

        self.register = {}

        for attr, cls in [
            ('welcome_page', WelcomePage),
            ('scan_page', ScanPage),
        ]:
            setattr(self, attr, cls(db, self))
            self.setPage(getattr(cls, 'ID'), getattr(self, attr))


# }}}

# Test Wizard {{{
if __name__ == '__main__':
    from PyQt4.Qt import QApplication
    from calibre.library import db
    app = QApplication([])
    w = Wizard(db())
    w.exec_()
# }}}
示例#33
0
    def __init__(self):
        from calibre.library import current_library_name

        QWidget.__init__(self)

        actual_plugin = 'calibre_plugins.getfilename.action:GetFileNameAction'
        self.plugin_action = actual_plugin

        # get the prefs
        self.prefs = prefs_a.GetFileName_Prefs(current_library_name())
        if (self.prefs['configured'] == False):
            try:
                from calibre.gui2.ui import get_gui
                db = get_gui().current_db
                self.prefs = get_library_config(db)
            except:
                try:
                    from calibre.library import db

                    self.prefs = get_library_config(db())
                except:
                    self.prefs = prefs_a.GetFileName_Prefs(
                        current_library_name())
                    for key, col in six.iteritems(DEFAULT_MIGRATION):
                        self.prefs.set(col, DEFAULT_LIBRARY_VALUES[key])
                    self.prefs.set('OPC_PREF', 'name')

                    self.prefs.set('configured', True)
                    self.prefs.set(KEY_SCHEMA_VERSION, DEFAULT_SCHEMA_VERSION)

                    self.prefs.writeprefs()

        self.filename_col = self.prefs[NAME_PREF]
        self.extension_col = self.prefs[EXT_PREF]
        self.path_col = self.prefs[PATH_PREF]
        self.date_col = self.prefs[DATE_PREF]
        self.option_name = self.prefs[OPC_PREF]

        # Start Qt Gui dialog layout
        layout = QVBoxLayout(self)
        self.setLayout(layout)

        # -- Options -- #

        # --- File ---

        avail_columns_text = self.get_custom_columns_text()
        avail_columns_date = self.get_custom_columns_date()

        filename_group_box = QGroupBox(_('File name options:'), self)
        layout.addWidget(filename_group_box)
        filename_group_box_layout = QGridLayout()
        filename_group_box.setLayout(filename_group_box_layout)

        pos = 0

        self.path_checkbox = QCheckBox(_("Include folder"), self)
        self.path_checkbox.setTristate(False)
        self.path_checkbox.setToolTip(
            _("It indicates it stores the folder with the filename."))
        self.path_checkbox.stateChanged.connect(self.path_checkbox_clicked)
        filename_group_box_layout.addWidget(self.path_checkbox, pos, 0, 1, 1)

        pos = pos + 1

        fname_column_label = QLabel(_('&File name:'), self)
        fname_column_label.setToolTip(
            _('Custom text column for storing the filename and folder if included'
              ))
        fname_col = self.filename_col
        self.fname_column_combo = CustomColumnComboBox(self,
                                                       avail_columns_text,
                                                       fname_col)
        fname_column_label.setBuddy(self.fname_column_combo)
        filename_group_box_layout.addWidget(fname_column_label, pos, 0, 1, 1)
        filename_group_box_layout.addWidget(self.fname_column_combo, pos, 1, 1,
                                            2)
        self.fname_column_combo.currentIndexChanged.connect(
            self.filename_changed)

        pos = pos + 1

        fexten_column_label = QLabel(_('File &Extension:'), self)
        fexten_column_label.setToolTip(
            _('Custom text column for storing the extension (if empty the filename is not splited). Not used if file name column is empty'
              ))
        fexten_col = self.extension_col
        self.fexten_column_combo = CustomColumnComboBox(
            self, avail_columns_text, fexten_col)
        fexten_column_label.setBuddy(self.fexten_column_combo)
        filename_group_box_layout.addWidget(fexten_column_label, pos, 0, 1, 1)
        filename_group_box_layout.addWidget(self.fexten_column_combo, pos, 1,
                                            1, 2)
        if (self.filename_col == ""):
            self.fexten_column_combo.setEnabled(False)
        else:
            self.fexten_column_combo.setEnabled(True)

        pos = pos + 1

        fpath_column_label = QLabel(_('File &Folder:'), self)
        fpath_column_label.setToolTip(
            _('Custom text column for storing the folder (if empty the filename is not splited). Not used if file name column is empty'
              ))
        fpath_col = self.path_col
        self.fpath_column_combo = CustomColumnComboBox(self,
                                                       avail_columns_text,
                                                       fpath_col)
        fpath_column_label.setBuddy(self.fpath_column_combo)
        filename_group_box_layout.addWidget(fpath_column_label, pos, 0, 1, 1)
        filename_group_box_layout.addWidget(self.fpath_column_combo, pos, 1, 1,
                                            2)

        date_column_group = QGroupBox(self)
        layout.addWidget(date_column_group)
        date_layout = QGridLayout()
        date_column_group.setLayout(date_layout)

        fdate_column_label = QLabel(_('File &Date:'), self)
        fdate_column_label.setToolTip(
            _('Custom date column for storing the last modified date (if empty the date is not stored)'
              ))
        fdate_col = self.date_col
        self.fdate_column_combo = CustomColumnComboBox(self,
                                                       avail_columns_date,
                                                       fdate_col)
        fdate_column_label.setBuddy(self.fdate_column_combo)

        date_layout.addWidget(fdate_column_label, 2, 0, 1, 1)
        date_layout.addWidget(self.fdate_column_combo, 2, 1, 1, 2)

        if (self.option_name == 'path'):
            self.path_checkbox.setChecked(True)
            if (self.fname_column_combo.currentIndex() == 0):
                self.fpath_column_combo.setEnabled(False)
            else:
                self.fpath_column_combo.setEnabled(True)
        else:
            self.path_checkbox.setChecked(False)
            self.fpath_column_combo.setEnabled(False)

        layout.addStretch(1)
示例#34
0
    def _postimport(self, book_id, book_format=None, db=None, log=None, fork_job=True, abort=None,
                   notifications=None):
        #NODOC IMPORTANT
        # TODO: make general overhaul of starting conversion logic
        if log: # divert our printing to the caller's logger
            prints = log # Log object has __call__ dunder method with INFO level
            prints = partial(prints, '{}:'.format(PLUGINNAME))
        else:
            log = self.prints.func
        try:
            prints
        except NameError:
            prints = self.prints

        if sys.__stdin__.isatty():
            # if run by cli, i.e.:
            #    calibredb add
            #    calibredebug -r djvumaker -- convert -i #id
            # runs also for GUI if run trough `calibredebug -g`
            fork_job = False # DEBUG UNCOMMENT
            rpc_refresh = True # use the calibre RPC to signal a GUI refresh

        if db is None:
            from calibre.library import db # TODO: probably legacy db import, change for new_api
            db = db() # initialize calibre library database

        if book_format == None:
            if not db.has_format(book_id, 'PDF', index_is_id=True):
                raise Exception('Book with id #{} has not a PDF format.'.format(book_id))
            else:
                book_format='pdf'

        if db.has_format(book_id, 'DJVU', index_is_id=True):
            prints("already have 'DJVU' format document for book ID #{}".format(book_id))
            return None # don't auto convert, we already have a DJVU for this document

        path_to_ebook = db.format_abspath(book_id, book_format, index_is_id=True)
        if book_format == 'pdf':
            is_rasterbook_val, pages, images = is_rasterbook(path_to_ebook, basic_return=False)
            if is_rasterbook_val:
                pass # TODO: should add a 'scanned' or 'djvumaker' tag
            else:
            # this is a marked-up/vector-based pdf,
            # no advantages to having another copy in DJVU format
                prints(("{} document from book ID #{} determined to be a markup-based ebook,"
                        " not converting to DJVU").format(book_format, book_id))
                return None #no-error in job panel
            # TODO: test the DPI to determine if a document is from a broad-sheeted book.
            #       if so, queue up k2pdfopt to try and chunk the content appropriately to letter size

            prints(("scheduling new {} document from book ID #{} for post-import DJVU"
                    " conversion: {}").format(book_format, book_id, path_to_ebook))

        if fork_job:
            #useful for not blocking calibre GUI when large PDFs
            # are dropped into the automatic-import-folder
            try:
            # https://github.com/kovidgoyal/calibre/blob/master/src/calibre/utils/ipc/simple_worker.py
            # dispatch API for Worker()
            # src/calibre/utils/ipc/launch.py
            # Worker() uses sbp.Popen to
            # run a second Python to a logfile
            # note that Calibre bungs the python loader to check the plugin directory when
            # modules with calibre_plugin. prefixed are passed
            # https://github.com/kovidgoyal/calibre/blob/master/src/calibre/customize/zipplugin.py#L192
                func_name = self.plugin_prefs['use_backend']
                args = [path_to_ebook, log, abort, notifications, pages, images]
                jobret = worker_fork_job('calibre_plugins.{}'.format(PLUGINNAME), func_name,
                            args= args,
                            kwargs={'preferences' : self.plugin_prefs},
                            env={'PATH': os.environ['PATH'] + ':/usr/local/bin'},
                            # djvu and poppler-utils on osx
                            timeout=600)
                            # TODO: determine a resonable timeout= based on filesize or
                            # make a heartbeat= check
                            # TODO: doesn't work for pdf2djvu, why?

            except WorkerError as e:
                prints('djvudigital background conversion failed: \n{}'.format(force_unicode(e.orig_tb)))
                raise # ConversionError
            except:
                prints(traceback.format_exc())
                raise

        # dump djvudigital output logged in file by the Worker to
        # calibre proc's (gui or console) log/stdout
            with open(jobret['stdout_stderr'], 'rb') as f:
                raw = f.read().strip()
                prints(raw)

            if jobret['result']:
                djvu = jobret['result']
            else:
                WorkerError("djvu conversion error: %s" % jobret['result'])
        # elif hasattr(self, gui): #if we have the calibre gui running,
        # we can give it a threadedjob and not use fork_job
        else: #!fork_job & !gui
            prints("Starts backend")
            djvu = self.run_backend(path_to_ebook, log, abort, notifications, pages,
                                    images)

        if djvu:
            db.new_api.add_format(book_id, 'DJVU', djvu, run_hooks=True)
            prints("added new 'DJVU' document to book ID #{}".format(book_id))
            if sys.__stdin__.isatty():
            # update calibre gui Out-Of-Band. Like if we were run as a command-line scripted import
            # this resets current gui views/selections, no cleaner way to do it :-(
                from calibre.utils.ipc import RC
                t = RC(print_error=False)
                t.start()
                t.join(3)
                if t.done: # GUI is running
                    t.conn.send('refreshdb:')
                    t.conn.close()
                    prints("signalled Calibre GUI refresh")
        else:
            # TODO: normal Exception propagation instead of passing errors as return values
            raise Exception(('ConversionError, djvu: {}. Did you install any backend according to the'
                             ' documentation?').format(djvu))
示例#35
0
        collection = getattr(self, which)
        q = icu_lower(unicode(filter_value))
        for i in xrange(collection.count()):  # on every available tag
            item = collection.item(i)
            item.setHidden(
                bool(q and not primary_contains(q, unicode(item.text()))))

    def accept(self):
        self.tags = self._get_applied_tags_box_contents()
        self.save_state()
        return QDialog.accept(self)

    def reject(self):
        self.save_state()
        return QDialog.reject(self)

    def save_state(self):
        gprefs['tag_editor_geometry'] = bytearray(self.saveGeometry())


if __name__ == '__main__':
    from calibre.gui2 import Application
    from calibre.library import db
    db = db()
    app = Application([])
    d = TagEditor(None,
                  db,
                  key='#authors',
                  id_=tuple(db.new_api.all_book_ids())[0])
    d.exec_()
示例#36
0
from calibre.library import db
from calibre.utils.logging import Log
import json

log = Log()
mydb = db('~/Archive/CalTest/').new_api

from calibre_plugins.crossref_doi_download import DoiMeta
from calibre.ebooks.metadata.book.base import Metadata
from calibre_plugins.crossref_doi_download.doi_reader import DoiReader

dm = DoiMeta('./plugin/')

# url = 'https://api.crossref.org/works/10.1002/bmc.835'
url = 'https://api.crossref.org/works/10.1109/tpami.2013.50'
# output = urlopen(url).read()
qurl = 'https://api.crossref.org/works?query.author=Bogus%C5%82aw+Buszewski&query.bibliographic=Human+exhaled+air+analytics%3A+biomarkers+of+diseases'
br = dm.browser
# cdata = br.open_novisit(qurl).read()
# d2 =  json.loads(cdata)
# message = d2['message']
# results = message['items']

reader = DoiReader(log)

from calibre import ipython

ipython(locals())
示例#37
0
    def __init__(self, db, parent=None):
        QWizard.__init__(self, parent)
        self.setModal(True)
        self.setWindowTitle(_('Add books to calibre'))
        self.setWindowIcon(QIcon(I('add_book.png')))
        self.setPixmap(self.LogoPixmap, QPixmap(P('content_server/calibre.png')).scaledToHeight(80,
            Qt.SmoothTransformation))
        self.setPixmap(self.WatermarkPixmap,
            QPixmap(I('welcome_wizard.png')))

        self.register = {}

        for attr, cls in [
                ('welcome_page', WelcomePage),
                ('scan_page', ScanPage),
                ]:
            setattr(self, attr, cls(db, self))
            self.setPage(getattr(cls, 'ID'), getattr(self, attr))

# }}}

# Test Wizard {{{
if __name__ == '__main__':
    from PyQt4.Qt import QApplication
    from calibre.library import db
    app = QApplication([])
    w = Wizard(db())
    w.exec_()
# }}}

示例#38
0
            return

        self.previous_button.setEnabled(False if row == 0 else True)
        self.next_button.setEnabled(False if row == self.view.model().rowCount(QModelIndex())-1 else True)
        self.current_row = row
        self.setWindowTitle(mi.title)
        self.cover_pixmap = QPixmap.fromImage(mi.cover_data[1])
        try:
            dpr = self.devicePixelRatioF()
        except AttributeError:
            dpr = self.devicePixelRatio()
        self.cover_pixmap.setDevicePixelRatio(dpr)
        self.resize_cover()
        html = render_html(mi, self.css, True, self, pref_name='popup_book_display_fields')
        set_html(mi, html, self.details)
        self.marked = mi.marked
        self.cover.setBackgroundBrush(self.marked_brush if mi.marked else self.normal_brush)
        self.update_cover_tooltip()


if __name__ == '__main__':
    from calibre.gui2 import Application
    from calibre.library import db
    app = Application([])
    app.current_db = db()
    get_gui.ans = app
    d = Configure(app.current_db)
    d.exec_()
    del d
    del app