コード例 #1
0
def ensure_single_instance(args, open_at):
    try:
        from calibre.utils.lock import singleinstance
        si = singleinstance(singleinstance_name)
    except Exception:
        import traceback
        error_dialog(None, _('Cannot start viewer'), _(
            'Failed to start viewer, could not insure only a single instance of the viewer is running. Click "Show Details" for more information'),
                    det_msg=traceback.format_exc(), show=True)
        raise SystemExit(1)
    if not si:
        if len(args) > 1:
            t = RC(print_error=True, socket_address=viewer_socket_address())
            t.start()
            t.join(3.0)
            if t.is_alive() or t.conn is None:
                error_dialog(None, _('Connect to viewer failed'), _(
                    'Unable to connect to existing viewer window, try restarting the viewer.'), show=True)
                raise SystemExit(1)
            t.conn.send((os.path.abspath(args[1]), open_at))
            t.conn.close()
            prints('Opened book in existing viewer instance')
        raise SystemExit(0)
    listener = create_listener()
    return listener
コード例 #2
0
ファイル: save.py プロジェクト: kba/calibre
def send_message(msg=''):
    if msg:
        t = RC(print_error=False)
        t.start()
        t.join(3)
        if t.done:
            t.conn.send('bookedited:' + msg)
            t.conn.close()
コード例 #3
0
def build_pipe(print_error=True):
    t = RC(print_error=print_error)
    t.start()
    t.join(3.0)
    if t.is_alive():
        cant_start()
        raise SystemExit(1)
    return t
コード例 #4
0
ファイル: main.py プロジェクト: PERCE-NEIGE/Calibribook
def send_message(msg=''):
    prints('Notifying calibre of the change')
    from calibre.utils.ipc import RC
    t = RC(print_error=False)
    t.start()
    t.join(3)
    if t.done:
        t.conn.send('refreshdb:' + msg)
        t.conn.close()
コード例 #5
0
ファイル: lc_cli.py プロジェクト: XVicarious/library-codes
def send_rc_message(msg):

    from calibre.utils.ipc import RC
    t = RC(print_error=False)
    t.start()
    t.join(3)
    if t.done:
        t.conn.send('refreshdb:' + msg)
        t.conn.close()

    if DEBUG: print('Calibre has been notified of the change...')
コード例 #6
0
def build_pipe(print_error=True):
    t = RC(print_error=print_error)
    t.start()
    t.join(3.0)
    if t.is_alive():
        if iswindows:
            cant_start()
        else:
            f = os.path.expanduser('~/.calibre_calibre GUI.lock')
            cant_start(what=_('try deleting the file') + ': ' + f)
        raise SystemExit(1)
    return t
コード例 #7
0
def updateCalibreGUIView():
    '''
    Refresh the GUI view
    '''
    t = RC(print_error=False)
    t.start()
    sleep(0.5)
    while True:
        if t.done:
            t.conn.send('refreshdb:')
            t.conn.close()
            break
        sleep(0.5)
コード例 #8
0
    def download_finished(self, download_id):
        self.central.download_progress.remove_item(download_id)
        download_item = self.download_data.pop(download_id)
        path = download_item.path()
        fname = os.path.basename(path)
        if download_item.state() == download_item.DownloadInterrupted:
            error_dialog(self, _('Download failed'), _(
                'Download of {0} failed with error: {1}').format(fname, download_item.interruptReasonString()), show=True)
            return
        ext = fname.rpartition('.')[-1].lower()
        if ext not in BOOK_EXTENSIONS:
            if ext == 'acsm':
                if not confirm('<p>' + _(
                    'This e-book is a DRMed EPUB file.  '
                    'You will be prompted to save this file to your '
                    'computer. Once it is saved, open it with '
                    '<a href="https://www.adobe.com/solutions/ebook/digital-editions.html">'
                    'Adobe Digital Editions</a> (ADE).<p>ADE, in turn '
                    'will download the actual e-book, which will be a '
                    '.epub file. You can add this book to calibre '
                    'using "Add Books" and selecting the file from '
                    'the ADE library folder.'),
                    'acsm_download', self):
                    return
            name = choose_save_file(self, 'web-store-download-unknown', _(
                'File is not a supported e-book type. Save to disk?'), initial_filename=fname)
            if name:
                shutil.copyfile(path, name)
                os.remove(path)
            return
        t = RC(print_error=False)
        t.start()
        t.join(3.0)
        if t.conn is None:
            error_dialog(self, _('No running calibre'), _(
                'No running calibre instance found. Please start calibre before trying to'
                ' download books.'), show=True)
            return
        tags = self.data['tags']
        if isinstance(tags, string_or_bytes):
            tags = list(filter(None, [x.strip() for x in tags.split(',')]))
        data = json.dumps({'path': path, 'tags': tags})
        if not isinstance(data, bytes):
            data = data.encode('utf-8')
        t.conn.send(b'web-store:' + data)
        t.conn.close()

        info_dialog(self, _('Download completed'), _(
            'Download of {0} has been completed, the book was added to'
            ' your calibre library').format(fname), show=True)
コード例 #9
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))