Register Guidelines E-Books Today's Posts Search

Go Back   MobileRead Forums > E-Book Software > Calibre > Plugins

Notices

Reply
 
Thread Tools Search this Thread
Old 03-09-2022, 03:58 AM   #181
lomkiri
Zealot
lomkiri ought to be getting tired of karma fortunes by now.lomkiri ought to be getting tired of karma fortunes by now.lomkiri ought to be getting tired of karma fortunes by now.lomkiri ought to be getting tired of karma fortunes by now.lomkiri ought to be getting tired of karma fortunes by now.lomkiri ought to be getting tired of karma fortunes by now.lomkiri ought to be getting tired of karma fortunes by now.lomkiri ought to be getting tired of karma fortunes by now.lomkiri ought to be getting tired of karma fortunes by now.lomkiri ought to be getting tired of karma fortunes by now.lomkiri ought to be getting tired of karma fortunes by now.
 
lomkiri's Avatar
 
Posts: 137
Karma: 1000102
Join Date: Jul 2021
Device: N/A
Quote:
Originally Posted by lomkiri View Post
Binary is ok, but running calibre-debug -t from source (calibre-5.99.7.tar.xz) gives me another exception:
Spoiler:
Code:
% calibre-debug --version
calibre-debug (calibre 5.99.7*)
% calibre-debug -t       
Failed to import PyQt module: PyQt6.QtCore with error: No module named 'PyQt6'
Traceback (most recent call last):
  File "runpy.py", line 194, in _run_module_as_main
  File "runpy.py", line 87, in _run_code
  File "site.py", line 45, in <module>
  File "site.py", line 41, in main
  File "/data/opt/calibre-source/last/src/calibre/debug.py", line 282, in main
    ebook_edit(['ebook-edit'] + args[1:])
  File "/data/opt/calibre-source/last/src/calibre/gui_launch.py", line 119, in ebook_edit
    from calibre.gui2.tweak_book.main import main
  File "/data/opt/calibre-source/last/src/calibre/gui2/__init__.py", line 13, in <module>
    from qt.core import (
ImportError: cannot import name 'QT_VERSION' from 'qt.core' (/data/opt/calibre-source/last/src/qt/core.py)
Fixed in 5.99.8, using calibre-5.99.8.tar.xz
Thank you.
lomkiri is offline   Reply With Quote
Old 03-22-2022, 05:27 AM   #182
lrpirlet
Connoisseur
lrpirlet began at the beginning.
 
Posts: 93
Karma: 40
Join Date: Mar 2020
Location: Belgium (sorry, I am from the Walloon side of the country and I speak french only)
Device: PW3, Kobo Libra H2O
Webengine_demo plugin does not show

I am currently writing a plugin based on webengine_Demo_plugin... It does work even if the configuration part is far from being optimal. (noosfere_util that work as a complement to noosfere DB a published metadata plugin )

My intention is to make it available soon so that bugs can be displayed.

When I saw this thread I thought to verify the compatibility... Well it does not work. Back to basic, try to install and use webengine demo... No luck.

I installed the portable version to not interfere with my installed version 5.39... webengine_demo does NOT SHOW anything after asking the url... A process named calibre worker process flashes to live for a very short time when I hit the ok button in the box asking the URL address...

A
Code:
calibre-debug -g
command seems to start the installed version... Frustrating... I am not sure that I have another 64 bits machine (will I need to borrow the machine of my wife??? )

The startup log follow, if usefull:

Code:
calibre Journal de débogage
calibre 5.99.8 Portable embedded-python: True
Windows-10-10.0.19044 Windows ('64bit', 'WindowsPE')
('Windows', '10', '10.0.19044')
Python 3.10.1
Windows: ('10', '10.0.19044', '', 'Multiprocessor Free')
Interface language: fr
Successfully initialized third party plugins: Gather KFX-ZIP (from KFX Input) (1, 47, 0) && Package KFX (from KFX Input) (1, 47, 0) && Find Duplicates (1, 9, 4) && KFX metadata reader (from KFX Input) (1, 47, 0) && KFX Input (1, 47, 0) && Set KFX metadata (from KFX Output) (1, 60, 0) && KFX Output (1, 60, 0) && KePub Input (3, 4, 3) && KePub Metadata Reader (3, 4, 3) && KePub Output (3, 5, 3) && Kindle Collections (1, 7, 29) && Kindle hi-res covers (0, 5, 0) && Kobo Books (1, 8, 3) && Kobo Utilities (2, 15, 1) && KoboTouchExtended (3, 5, 4) && Manage Series (1, 3, 0) && View Manager (1, 7, 0) && WebEngine Plugin Demo (1, 0, 0) && Wiki Reader (2, 2, 1) && noosfere DB (0, 9, 6) && noosfere util (0, 5, 0)
calibre 5.99.8 Portable embedded-python: True
Windows-10-10.0.19044 Windows ('64bit', 'WindowsPE')
('Windows', '10', '10.0.19044')
Python 3.10.1
Windows: ('10', '10.0.19044', '', 'Multiprocessor Free')
Interface language: fr
Successfully initialized third party plugins: Gather KFX-ZIP (from KFX Input) (1, 47, 0) && Package KFX (from KFX Input) (1, 47, 0) && Find Duplicates (1, 9, 4) && KFX metadata reader (from KFX Input) (1, 47, 0) && KFX Input (1, 47, 0) && Set KFX metadata (from KFX Output) (1, 60, 0) && KFX Output (1, 60, 0) && KePub Input (3, 4, 3) && KePub Metadata Reader (3, 4, 3) && KePub Output (3, 5, 3) && Kindle Collections (1, 7, 29) && Kindle hi-res covers (0, 5, 0) && Kobo Books (1, 8, 3) && Kobo Utilities (2, 15, 1) && KoboTouchExtended (3, 5, 4) && Manage Series (1, 3, 0) && View Manager (1, 7, 0) && WebEngine Plugin Demo (1, 0, 0) && Wiki Reader (2, 2, 1) && noosfere DB (0, 9, 6) && noosfere util (0, 5, 0)
devicePixelRatio: 1.0
logicalDpi: 96.0 x 96.0
physicalDpi: 117.58408679927668 x 117.60771704180064
Using calibre Qt style: True
[0.00] Starting up...
[0.00] Showing splash screen...
[0.19] splash screen shown
[0.19] Initializing db...
[0.19] db initialized
[0.19] Constructing main UI...
DEBUG:    0.0 Kobo Utilities Configuration - CreateNewCustomColumn is supported
DEBUG:    0.0 KoboUtilites::action.py - loading translations
DEBUG:    0.0 KoboUtilites::dialogs.py - loading translations
DEBUG:    0.0 KoboUtilites::action.py - loading translations
DEBUG:    0.6 No Kobo Touch, Glo or Mini appears to be connected
DEBUG:    0.6 rebuild_menus - self.supports_ratings=None, self.supports_tiles=None
DEBUG:    0.6 KoboUtilities:set_toolbar_button_tooltip - start: text='None'
DEBUG:    0.6 KoboUtilities:set_toolbar_button_tooltip - setting to text='Utilities to use with Kobo ereaders

Pilote : KoboTouchExtended'
[1.09] main UI initialized...
[1.09] Hiding splash screen
Starting QuickView
[6.58] splash screen hidden
[6.58] Started up in 6.58 seconds with 1 books
Worker Launch took: 0.00 seconds
lrpirlet is offline   Reply With Quote
Advert
Old 03-22-2022, 05:41 AM   #183
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 11,799
Karma: 7029971
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by lrpirlet View Post
I installed the portable version to not interfere with my installed version 5.39... webengine_demo does NOT SHOW anything after asking the url... A process named calibre worker process flashes to live for a very short time when I hit the ok button in the box asking the URL address...

A
Code:
calibre-debug -g
command seems to start the installed version... Frustrating... I am not sure that I have another 64 bits machine (will I need to borrow the machine of my wife??? )
To run the portable version in debug mode use full paths. For example, I do what you are doing, running V5 installed and V6 as portable. I start V6 using
Code:
"C:\CBH_Data\calibre.git\Calibre-Qt6\Calibre Portable\Calibre\calibre-debug.exe" -g
Of course the path up to "Calibre Portable" will be different for you.
chaley is offline   Reply With Quote
Old 03-22-2022, 09:05 AM   #184
lrpirlet
Connoisseur
lrpirlet began at the beginning.
 
Posts: 93
Karma: 40
Join Date: Mar 2020
Location: Belgium (sorry, I am from the Walloon side of the country and I speak french only)
Device: PW3, Kobo Libra H2O
Thanks chaley

I DO have a full path in a portable-debugit.bat file...

I probably was too 'square' in writting the above as path\calibre-debug --gui does indeed run calibre 5.99.8...

What I see is that it does uses all the default of the installed calibre...
Including copying the modified code to the default place of the installed calibre...
I guess this is NOT really tied with PyQt6, yet I was surprised

See my commented bat file...

Code:
rem see https://manual.calibre-ebook.com/creating_plugins.html#id14 goto Debugging plugins...
rem click runit from from the directory where the plugin is developed... 
rem this will kill any running calibre, push a new plugin.zip where appropriate and start calibre again in gui debug mode

"P:\000Calibre\Calibre Portable\Calibre\calibre-debug" -s
"P:\000Calibre\Calibre Portable\Calibre\calibre-customize" -b . 

rem calibre-customize -b . copies the plugin to C:\Users\Papa\AppData\Roaming\calibre\plugins not to P:\000Calibre\Calibre Portable\Calibre Settings\plugins

rem START calibre-debug --gui  creates a new cmd windows that executes calibre-debug --gui 
rem this allows killing a running calibre without fumbling all over the places on my too small monitor...
rem START "P:\000Calibre\Calibre Portable\Calibre\calibre-debug" --gui ... that gives windows does not find '--gui' !!! génial !!!

"P:\000Calibre\Calibre Portable\Calibre\calibre-debug" --gui 
rem that works...
But that is ok, I found an old i5-3210M that has enough disk space and W10 64 bits so I will use that... I may need a couple of days to patch it to the latest version of all the programs I use...

However, I confirm that webengine_demo works on calibre 5.39 and NOT on Calibre 5.99.8...

Last edited by lrpirlet; 03-22-2022 at 09:07 AM. Reason: missing info
lrpirlet is offline   Reply With Quote
Old 03-22-2022, 01:00 PM   #185
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 44,030
Karma: 22669822
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
The webengine demo plugin worked fine for me in 5.99.8. Although, thanks to https://github.com/kovidgoyal/calibr...5a8c71de4c3420 hopefully the need to run webengine in separate processes should go away soon.
kovidgoyal is offline   Reply With Quote
Advert
Old 03-22-2022, 04:32 PM   #186
lrpirlet
Connoisseur
lrpirlet began at the beginning.
 
Posts: 93
Karma: 40
Join Date: Mar 2020
Location: Belgium (sorry, I am from the Walloon side of the country and I speak french only)
Device: PW3, Kobo Libra H2O
Thanks kovidgoyal

I should have realized that to use a webengine_demo I got such a long time ago is not the best move...

I downloaded a new version that work for me as well as for you...

For the record I had a main.py dated 20-12-03... It was failing on the import, well before my redirected error output would be activated...

Code:
C:\Users\lrp>calibre-debug
Module readline not available.
Welcome to the interactive calibre shell!
Use exit to quit
>>> from PyQt5.QtWebEngineWidgets import QWebEngineView
Traceback (most recent call last):
  File "<console>", line 1, in <module>
ImportError: cannot import name 'QWebEngineView' from 'qt.core' (C:\Program Files\Calibre2\app\bin\python-lib.bypy.frozen\qt\core.pyc)
lrpirlet is offline   Reply With Quote
Old 03-24-2022, 12:49 PM   #187
lrpirlet
Connoisseur
lrpirlet began at the beginning.
 
Posts: 93
Karma: 40
Join Date: Mar 2020
Location: Belgium (sorry, I am from the Walloon side of the country and I speak french only)
Device: PW3, Kobo Libra H2O
type object 'QKeySequence' has no attribute 'FindNext'

Hello

I have been working on porting noosfere_util to Qt6...

I have the following:
Code:
2022-03-24 15:02:04,658:ERROR:STDERR:Traceback (most recent call last):
2022-03-24 15:02:04,658:ERROR:STDERR:  File "runpy.py", line 196, in _run_module_as_main
2022-03-24 15:02:04,659:ERROR:STDERR:  File "runpy.py", line 86, in _run_code
2022-03-24 15:02:04,659:ERROR:STDERR:  File "site.py", line 82, in <module>
2022-03-24 15:02:04,661:ERROR:STDERR:  File "site.py", line 77, in main
2022-03-24 15:02:04,661:ERROR:STDERR:  File "site.py", line 49, in run_entry_point
2022-03-24 15:02:04,662:ERROR:STDERR:  File "calibre\utils\ipc\worker.py", line 215, in main
2022-03-24 15:02:04,662:ERROR:STDERR:  File "calibre\gui_launch.py", line 98, in webengine_dialog
2022-03-24 15:02:04,662:ERROR:STDERR:  File "calibre_plugins.noosfere_util.web_main", line 453, in main
2022-03-24 15:02:04,662:ERROR:STDERR:  File "calibre_plugins.noosfere_util.web_main", line 150, in __init__
2022-03-24 15:02:04,663:ERROR:STDERR:  File "calibre_plugins.noosfere_util.web_main", line 223, in set_search_bar
2022-03-24 15:02:04,663:ERROR:STDERR:  File "calibre_plugins.noosfere_util.web_main", line 101, in __init__
2022-03-24 15:02:04,663:ERROR:STDERR:AttributeError
2022-03-24 15:02:04,663:ERROR:STDERR::
2022-03-24 15:02:04,663:ERROR:STDERR:type object 'QKeySequence' has no attribute 'FindNext'
When I comment that line, I also have it for QKeySequence.FindPrevious and for QKeySequence.Find. According to the doc, this should be ok under qt6... It is working under qt5...

short code extract

Code:
        #QShortcut(QKeySequence.FindNext, self, activated=next_btn.animateClick)
        #QShortcut(QKeySequence.FindPrevious, self, activated=prev_btn.animateClick)
        QShortcut(QKeySequence(Qt.Key_Escape), self.srch_dsp, activated=self.closed)
complete source file if needed

Spoiler:
Code:
#!/usr/bin/env python
# vim:fileencoding=utf-8

__license__   = 'GPL v3'
__copyright__ = '2022, Louis Richard Pirlet'


# from PyQt5.QtCore import pyqtSlot, QUrl, QSize, Qt, pyqtSignal, QTimer
from qt.core import (pyqtSlot, QUrl, QSize, Qt, pyqtSignal, QTimer,      # from PyQt5.QtCore import pyqtSlot, QUrl, QSize, Qt, pyqtSignal, QTimer
    QMainWindow, QToolBar, QAction, QLineEdit, QStatusBar, QProgressBar, # from PyQt5.QtWidgets import (QMainWindow, QToolBar, QAction, QLineEdit, QStatusBar, QProgressBar,
    QMessageBox, QWidget, QVBoxLayout, QHBoxLayout, QLabel,        # qApp,                                 QMessageBox, qApp, QWidget, QVBoxLayout, QHBoxLayout, QLabel,
    QPushButton, QShortcut,                                              #                                 QPushButton, QShortcut)
    QKeySequence, QIcon                                                  # from PyQt5.QtGui import QKeySequence    #, QIcon
)
# from qt.core import ()
#     QApplication, QBrush, QByteArray, QCheckBox, QColor, QColorDialog,
#     QDialog, QDialogButtonBox, QFont, QFontInfo, QFontMetrics, QFormLayout,
#     QMenu, QPalette, QPlainTextEdit,
#     QSyntaxHighlighter, QTabWidget, QTextBlockFormat, QTextCharFormat,
#     QTextCursor, QTextEdit, QTextFormat, QTextListFormat,
#     QObject, QToolButton,  QMenuBar,
#     QPropertyAnimation, QEasingCurve, pyqtProperty, QPainter,
#     QEvent, QStylePainter,
#     QSizePolicy, QSplitter, QStackedWidget, QStyle, QStyleOption,
#     QTabBar,
#     QComboBox, QCompleter, QDateTime,
#     QGridLayout, QInputDialog,
#     QListView, QModelIndex,
#     QPixmap, pyqtSlot, QUrl, QSize, Qt, pyqtSignal, QTimer,
#     QMainWindow, QToolBar, QAction, QLineEdit, QStatusBar, QProgressBar,
#     QMessageBox, QWidget, QVBoxLayout, QHBoxLayout, QLabel,            #                                 QPushButton, QShortcut)
#     QKeySequence, QIcon
# )





from qt.webengine import QWebEngineView, QWebEnginePage     # from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage

from calibre.gui2 import Application

from json import dumps
from functools import partial
import tempfile, os, sys, logging


class StreamToLogger(object):
    """
    Fake file-like stream object that redirects writes to a logger instance.
    This will help when the web browser in web_main does not pop-up (read: web_main crashes)
    """
    def __init__(self, logger, log_level=logging.INFO):
      self.logger = logger
      self.log_level = log_level
      self.linebuf = ''

    def write(self, buf):
      for line in buf.rstrip().splitlines():
         self.logger.log(self.log_level, line.rstrip())

    def flush(self):
        for handler in self.logger.handlers:
            handler.flush()

class Search_Panel(QWidget):
    searched = pyqtSignal(str, QWebEnginePage.FindFlag)
    closed = pyqtSignal()

    def __init__(self,parent=None):
        super(Search_Panel,self).__init__(parent)

        next_btn = QPushButton('Suivant')
        next_btn.setToolTip("Ce bouton recherche la prochaine occurrence dans la page")
        next_btn.clicked.connect(self.update_searching)
        if isinstance(next_btn, QPushButton): next_btn.clicked.connect(self.setFocus)

        prev_btn = QPushButton('Précédent')
        prev_btn.setToolTip("Ce bouton recherche l'occurrence précédente dans la page")
        prev_btn.clicked.connect(self.on_preview_find)
        if isinstance(prev_btn, QPushButton): prev_btn.clicked.connect(self.setFocus)

        done_btn = QPushButton("Terminé")
        done_btn.setToolTip("Ce bouton ferme la barre de recherche")
        done_btn.clicked.connect(self.closed)
        if isinstance(done_btn, QPushButton): done_btn.clicked.connect(self.setFocus)

        self.srch_dsp = QLineEdit()
        self.srch_dsp.setToolTip(" Cette boite contient le texte Ã* chercher dans la page")
        self.setFocusProxy(self.srch_dsp)
        self.srch_dsp.textChanged.connect(self.update_searching)
        self.srch_dsp.returnPressed.connect(self.update_searching)
        self.closed.connect(self.srch_dsp.clear)

        self.srch_lt = QHBoxLayout(self)
        self.srch_lt.addWidget(self.srch_dsp)
        self.srch_lt.addWidget(next_btn)
        self.srch_lt.addWidget(prev_btn)
        self.srch_lt.addWidget(done_btn)

        #QShortcut(QKeySequence.FindNext, self, activated=next_btn.animateClick)
        #QShortcut(QKeySequence.FindPrevious, self, activated=prev_btn.animateClick)
        QShortcut(QKeySequence(Qt.Key_Escape), self.srch_dsp, activated=self.closed)

    @pyqtSlot()
    def on_preview_find(self):
        self.update_searching(QWebEnginePage.FindBackward)

    @pyqtSlot()
    def update_searching(self, direction=QWebEnginePage.FindFlag(0)):
        flag = direction
        self.searched.emit(self.srch_dsp.text(), flag)

    def showEvent(self, event):
        super(Search_Panel, self).showEvent(event)
        self.setFocus(True)

class MainWindow(QMainWindow):
    """
    this process, running in the calibre environment, is detached from calibre program
    It does receive data from noofere_util, processes it, then communicates back the result and dies.
    In fact this is a WEB browser centered on www.noosfere.org to get the nsfr_id of a choosen volume.

    """

    def __init__(self, data):
        super().__init__()

      # Initialize environment..
      # note: web_main is NOT supposed to output anything over STDOUT or STDERR
        logging.basicConfig(
        level = logging.DEBUG,
        format = '%(asctime)s:%(levelname)s:%(name)s:%(message)s',
        filename = os.path.join(tempfile.gettempdir(), 'nsfr_utl-web_main.log'),
        filemode = 'a')
        stdout_logger = logging.getLogger('STDOUT')
        sl = StreamToLogger(stdout_logger, logging.INFO)
        sys.stdout = sl
        stderr_logger = logging.getLogger('STDERR')
        sl = StreamToLogger(stderr_logger, logging.ERROR)
        sys.stderr = sl

      # data = [url, isbn, auteurs, titre]
        self.isbn, self.auteurs, self.titre = data[1].replace("-",""), data[2], data[3]

        self.set_browser()
        self.set_isbn_box()
        self.set_auteurs_box()
        self.set_titre_box()
        self.set_search_bar()
        self.join_all_boxes()
        self.set_nav_and_status_bar()

      # make all that visible... I want this window on top ready to work with
        self.setWindowFlags(Qt.WindowStaysOnTopHint)
        self.show()
        self.activateWindow()

      # signals
        self.browser.urlChanged.connect(self.update_urlbar)
        self.browser.loadStarted.connect(self.loading_title)
        self.browser.loadStarted.connect(self.set_progress_bar)
        self.browser.loadProgress.connect(self.update_progress_bar)
        self.browser.loadFinished.connect(self.update_title)
        self.browser.loadFinished.connect(self.reset_progress_bar)
        self.isbn_btn.clicked.connect(partial(self.set_noosearch_page, "isbn"))
        self.auteurs_btn.clicked.connect(partial(self.set_noosearch_page, "auteurs"))
        self.titre_btn.clicked.connect(partial(self.set_noosearch_page, "titre"))

      # browser
    def set_browser(self):
        print("in set_browser")
        self.browser = QWebEngineView()
        self.browser.setUrl(QUrl("http://www.google.com"))

      # info boxes
    def set_isbn_box(self):        # info boxes isbn
        print("in set_isbn_box")
        self.isbn_btn = QPushButton(" ISBN ", self)
        self.isbn_btn.setToolTip('Action sur la page noosfere initiale: "Mots-clefs Ã* rechercher" = ISBN, coche la case "Livre".')
                                   # Action on home page: "Mots-clefs Ã* rechercher" = ISBN, set checkbox "Livre".
        self.isbn_dsp = QLineEdit()
        self.isbn_dsp.setReadOnly(True)
        self.isbn_dsp.setText(self.isbn)
        self.isbn_dsp.setToolTip(" Cette boite montre l'ISBN protégé en écriture. Du texte peut y être sélectionné pour chercher dans la page")
                                   # This box displays the ISBN write protected. Some text may be selected here to search the page.

        self.isbn_lt = QHBoxLayout()
        self.isbn_lt.addWidget(self.isbn_btn)
        self.isbn_lt.addWidget(self.isbn_dsp)

    def set_auteurs_box(self):                  # info boxes auteurs
        print("in set_auteurs_box")
        self.auteurs_btn = QPushButton("Auteur(s)", self)
        self.auteurs_btn.setToolTip('Action sur la page noosfere initiale: "Mots-clefs Ã* rechercher" = Auteur(s), coche la case "Auteurs".')
                                      # Action on home page: "Mots-clefs Ã* rechercher" = Auteur(s), set checkbox "Auteurs".
        self.auteurs_dsp = QLineEdit()
        self.auteurs_dsp.setReadOnly(True)
        self.auteurs_dsp.setText(self.auteurs)
        self.auteurs_dsp.setToolTip(" Cette boite montre le ou les Auteur(s) protégé(s) en écriture. Du texte peut être manuellement introduit pour chercher dans la page")
                                      # This box displays the Author(s) write protected. Some text may be written here to search the page.
        self.auteurs_lt = QHBoxLayout()
        self.auteurs_lt.addWidget(self.auteurs_btn)
        self.auteurs_lt.addWidget(self.auteurs_dsp)

    def set_titre_box(self):                    # info boxes titre
        print("in set_titre_box")
        self.titre_btn = QPushButton("Titre", self)
        self.titre_btn.setToolTip('Action sur la page noosfere initiale: "Mots-clefs Ã* rechercher" = Titre, coche la case "Livres".')
                                    # Action on home page: "Mots-clefs Ã* rechercher" = Titre, set checkbox "Livres".
        self.titre_dsp = QLineEdit()
        self.titre_dsp.setReadOnly(True)
        self.titre_dsp.setText(self.titre)
        self.titre_dsp.setToolTip(" Cette boite montre le Titre protégé en écriture. Tout ou partie du texte peut être sélectionné pour chercher dans la page")
                                    # This box displays the Title write protected. Some text may be selected here to search the page.
        self.titre_lt = QHBoxLayout()
        self.titre_lt.addWidget(self.titre_btn)
        self.titre_lt.addWidget(self.titre_dsp)

  # search bar hidden when inactive ready to find something (I hope :-) )
    def set_search_bar(self):
        print("in set_search_bar")
        self.search_pnl = Search_Panel()
        self.search_toolbar = QToolBar()
        self.search_toolbar.addWidget(self.search_pnl)
        self.addToolBar(Qt.BottomToolBarArea, self.search_toolbar)
        self.search_toolbar.hide()
        self.search_pnl.searched.connect(self.on_searched)
        self.search_pnl.closed.connect(self.search_toolbar.hide)

    def join_all_boxes(self):                   # put all that together, center, size and make it central widget
        print("in join_all_boxes")
        layout = QVBoxLayout()
        layout.addWidget(self.browser)
        layout.addLayout(self.isbn_lt)
        layout.addLayout(self.auteurs_lt)
        layout.addLayout(self.titre_lt)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

        self.resize(1200,1000)

      # set navigation toolbar
    def set_nav_and_status_bar(self) :
        print("in set_nav_and_status_bar")
        nav_tb = QToolBar("Navigation")
        nav_tb.setIconSize(QSize(24,24))
        self.addToolBar(nav_tb)

        back_btn = QAction(get_icons('blue_icon/back.png'), "Back", self)
        back_btn.setToolTip("On revient Ã* la page précédente")                    # Back to the previous page
        back_btn.triggered.connect(self.browser.back)
        nav_tb.addAction(back_btn)

        next_btn = QAction(get_icons('blue_icon/forward.png'), "Forward", self)
        next_btn.setToolTip("On retourne Ã* la page suivante")                     # Back to the next page
        next_btn.triggered.connect(self.browser.forward)
        nav_tb.addAction(next_btn)

        reload_btn = QAction(get_icons('blue_icon/reload.png'), "Reload", self)
        reload_btn.setToolTip("On recharge la page présente")                     # Reload the page
        reload_btn.triggered.connect(self.browser.reload)
        nav_tb.addAction(reload_btn)

        home_btn = QAction(get_icons('blue_icon/home.png'), "Home", self)
        home_btn.setToolTip("On va Ã* la recherche avancée de noosfere")           # We go to the front page of noosfere
        home_btn.triggered.connect(self.navigate_home)
        nav_tb.addAction(home_btn)

        stop_btn = QAction(get_icons('blue_icon/stop.png'), "Stop", self)
        stop_btn.setToolTip("On arrête de charger la page")                       # Stop loading the page
        stop_btn.triggered.connect(self.browser.stop)
        nav_tb.addAction(stop_btn)

        nav_tb.addSeparator()

        find_btn = QAction(get_icons('blue_icon/search.png'), "Search", self)
        find_btn.setToolTip("Ce bouton fait apparaitre la barre de recherche... Z'avez pas vu Mirza? Oh la la la la la. Où est donc passé ce chien. Je le cherche partout...  (Merci Nino Ferrer)")   # search, search...
        find_btn.triggered.connect(self.wake_search_panel)
        #find_btn.setShortcut(QKeySequence.Find)
        nav_tb.addAction(find_btn)

        self.urlbox = QLineEdit()
        self.urlbox.returnPressed.connect(self.navigate_to_url)
        self.urlbox.setToolTip("On peut même introduire une adresse, hors noosfere, mais A TES RISQUES ET PERILS... noosfere est sûr (https://), la toile par contre...")
                                # You can even enter an address, outside of noosfere, but AT YOUR OWN RISK... noosfere is safe: (https://), the web on the other side...
        nav_tb.addWidget(self.urlbox)

        abort_btn = QAction(get_icons('blue_icon/abort.png'), "Abort", self)
        abort_btn.setToolTip("On arrête, on oublie, on ne change rien au livre... au suivant")
                              # Stop everything, forget everything and change nothing... proceed to next book
        abort_btn.triggered.connect(self.abort_book)
        nav_tb.addAction(abort_btn)

        nav_tb.addSeparator()

        exit_btn = QAction(get_icons('blue_icon/exit.png'), "Select and exit", self)
        exit_btn.setToolTip("On sélectionne cet URL pour extraction de nsfr_id... au suivant")
                             # select this URL for extraction of nsfr_id, continue
        exit_btn.triggered.connect(self.select_and_exit)
        nav_tb.addAction(exit_btn)

  # set status bar
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)
  # Create page loading progress bar that is displayed in the status bar.
        self.msg_label = QLabel()
        self.page_load_label = QLabel()
        self.page_load_pb = QProgressBar()
  # Set up widgets on the statusbar
        self.statusBar().addPermanentWidget(self.msg_label, stretch=36)
        self.statusBar().addPermanentWidget(self.page_load_label, stretch=14)
        self.statusBar().addPermanentWidget(self.page_load_pb, stretch=50)

  # search action
    @pyqtSlot(str, QWebEnginePage.FindFlag)
    def on_searched(self, text, flag):
        print("in on_searched text : {}, flag : {}".format(text, flag))
        def callback(found):
            if text and not found:
                self.msg_label.setText('Désolé, {} pas trouvé...'.format(text))     # Sorry "text" not found
            else:
                self.msg_label.setText('')
        self.browser.findText(text, flag, callback)

  # info boxes actions
    @pyqtSlot()
    def set_noosearch_page(self, iam):
        print("in set_noosearch_page iam : {}".format(iam))
        if self.urlbox.text() == "https://www.noosfere.org/livres/noosearch.asp":
            if iam == "isbn": val = self.isbn
            elif iam == "auteurs": val = self.auteurs
            else: val = self.titre
            self.browser.page().runJavaScript("document.getElementsByName('Mots')[1].value =" + dumps(val))
            if iam == "auteurs":
                self.browser.page().runJavaScript("document.getElementsByName('auteurs')[0].checked = true")
                self.browser.page().runJavaScript("document.getElementsByName('livres')[0].checked = false")
            else:
                self.browser.page().runJavaScript("document.getElementsByName('livres')[0].checked = true")
                self.browser.page().runJavaScript("document.getElementsByName('auteurs')[0].checked = false")
        else:
            pass

    @pyqtSlot()
    def wake_search_panel(self):
        print("in wake_search_panel")
        self.search_toolbar.show()

  # Navigation actions
    def initial_url(self, url="http://www.google.com"):
        print("in initial_url url : {}".format(url))
        self.browser.setUrl(QUrl(url))

    def navigate_home(self):
        print("in navigate_home")
        self.browser.setUrl(QUrl("https://www.noosfere.org/livres/noosearch.asp"))

    def navigate_to_url(self):                    # Does not receive the Url, activated when url bar is manually changed
        print("in navigate_to_url")
        q = QUrl(self.urlbox.text())
        self.browser.setUrl(q)

    def update_urlbar(self, q):
        print("in update_urlbar")
        self.urlbox.setText(q.toString())
        self.urlbox.setCursorPosition(0)

    def loading_title(self):
        print("in loading_title")
      # anytime we change page we come here... let's clear and hide the search panel
        self.search_pnl.closed.emit()           # by sending a close search panel signal
      # before doubling indication that we load a page in the title
        title="En téléchargement de l'url"
        self.setWindowTitle(title)

    def update_title(self):
        print("in update_title")
        title = self.browser.page().title()
        self.setWindowTitle(title)

    def report_returned_id(self, returned_id):
        print("in report_returned_id returned_id : {}".format(returned_id))
        report_tpf=open(os.path.join(tempfile.gettempdir(),"nsfr_utl_report_returned_id"),"w")
        report_tpf.write(returned_id)
        report_tpf.close

    def set_progress_bar(self):
        print("in set_progress_bar")
        self.page_load_pb.show()
        self.page_load_label.show()

    def update_progress_bar(self, progress):
        print("in update_progress_bar progress : {}".format(progress))
        self.page_load_pb.setValue(progress)
        self.page_load_label.setText("En téléchargement de l'url... ({}/100)".format(str(progress)))

    def reset_progress_bar(self):
        print("in reset_progress_bar")
        def wait_a_minut():
            self.page_load_pb.hide()
            self.page_load_label.hide()
        QTimer.singleShot(1000, wait_a_minut)

    def select_and_exit(self):                    # sent response over report_returned_id file in temp dir
      # create a temp file with name starting with nsfr_id
        print("in select_and_exit")
        choosen_url = self.urlbox.text()
        if "numlivre=" in choosen_url:
            print('choosen_url : ',choosen_url)
            nsfr_id = "vl$"+choosen_url.split("numlivre=")[1]
            print("nsfr_id : ", nsfr_id)
            self.report_returned_id(nsfr_id)
        else:
            print('No book selected, no change will take place: unset')
            self.report_returned_id("unset")
        Application.instance().quit()     # exit application... qApp gone in PyQt6

    def abort_book(self):                         # we want to NOT change the book and proceed to the next one
        print("in abort_book")
        reply = QMessageBox.question(self, 'Certain', "Oublier ce livre et passer au suivant", QMessageBox.No | QMessageBox.Yes, QMessageBox.Yes)
        if reply == QMessageBox.Yes:
            print("WebEngineView was aborted: aborted")
            self.report_returned_id("aborted")
            Application.instance().quit()     # exit application... qApp gone in PyQt6


    def closeEvent(self, event):                  # abort hit window exit "X" button we stop processing this and all following books
        print("in closeEvent event : {}".format(event))
        reply = QMessageBox.question(self, 'Vraiment', "Quitter et ne plus rien changer", QMessageBox.No | QMessageBox.Yes, QMessageBox.Yes)
        if reply == QMessageBox.Yes:
            event.accept()
            print("WebEngineView was closed: killed")
            self.report_returned_id("killed")
            super().closeEvent(event)
        else:
            event.ignore()


def main(data):

    # create a temp file... while it exists launcher program will wait... this file will disappear with the process
    sync_tpf=tempfile.NamedTemporaryFile(prefix="nsfr_utl_sync-cal-qweb")

    # retrieve component from data
    #        data = [url, isbn, auteurs, titre]
    url, isbn, auteurs, titre = data[0], data[1], data[2], data[3],
    # Start QWebEngineView and associated widgets
    app = Application([])
    window = MainWindow(data)
    window.initial_url(url)     # supposed to be noosfere advanced search page, fixed by launcher program
    app.exec()

    # signal launcher program that we are finished
    sync_tpf.close           # close temp file


if __name__ == '__main__':
    '''
    watch out name 'get_icons' is not defined, and can't be defined easyly...
    workaround, swap it with QIcon + path to icon
    '''
    url = "https://www.noosfere.org/livres/noosearch.asp"   # jump directly to noosfere advanced search page
    isbn = "2-277-12362-5"
    auteurs = "Alfred Elton VAN VOGT"                       # forget not that auteurs may be a list of auteurs
    titre = "Le Monde des Ã"
    data = [url, isbn, auteurs, titre]
    main(data)

    tf = open(os.path.join(tempfile.gettempdir(),"nsfr_utl_report_returned_id"), "r")
    returned_id = tf.read()
    tf.close()

  # from here should modify the metadata, or not.
    if returned_id.replace("vl$","").replace("-","").isnumeric():
        nsfr_id = returned_id
        print("nfsr_id : ", nsfr_id)
    elif "unset" in returned_id:
        print('unset, no change will take place...')
    elif "killed" in returned_id:
        print('killed, no change will take place...')
    else:
        print("should not ends here... returned_id : ", returned_id)


I could not find any occurence of QKeySequence.FindNext, QKeySequence.FindPrevious or QKeySequence.Find in calibre source files...

Thanks in advance.
lrpirlet is offline   Reply With Quote
Old 03-24-2022, 12:51 PM   #188
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 44,030
Karma: 22669822
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
You need QKeySequence.StandardKey.FindNext
kovidgoyal is offline   Reply With Quote
Old 03-24-2022, 05:41 PM   #189
lrpirlet
Connoisseur
lrpirlet began at the beginning.
 
Posts: 93
Karma: 40
Join Date: Mar 2020
Location: Belgium (sorry, I am from the Walloon side of the country and I speak french only)
Device: PW3, Kobo Libra H2O
Thanks kovidgoyal

It works with StandardKey... Even better I could find a reference in QT doc (the label of the column is StandardKey so I can tie with 'key' in QKeySequence(QKeySequence::StandardKey key)

Last edited by lrpirlet; 03-24-2022 at 05:44 PM.
lrpirlet is offline   Reply With Quote
Old 04-22-2022, 06:02 AM   #190
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 11,799
Karma: 7029971
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
To all who maintain kiwidude-based plugins: There is a problem in common_utils.CheckableTableWidgetItem(). The line
Code:
        self.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled ))
should be
Code:
        self.setFlags(Qt.ItemFlag(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled ))
Qt.ItemFlags is changed to Qt.ItemFlag

Without the change and assuming you use that widget, you will get the error
Code:
AttributeError: type object 'Qt' has no attribute 'ItemFlags'
EDIT: The change worked on both the beta and 5.41.

Last edited by chaley; 04-22-2022 at 08:51 AM.
chaley is offline   Reply With Quote
Old 04-25-2022, 02:10 PM   #191
JimmXinu
Plugin Developer
JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.
 
JimmXinu's Avatar
 
Posts: 6,403
Karma: 4276871
Join Date: Dec 2011
Location: Midwest USA
Device: Kindle Paperwhite(10th)
Quote:
Originally Posted by chaley View Post
To all who maintain kiwidude-based plugins: There is a problem in common_utils.CheckableTableWidgetItem().
In the kiwidude plugins I maintain, only Reading List uses common_utils.CheckableTableWidgetItem(). This issue doesn't affect FavouritesMenu, ViewManager, GenerateCover or ManageSeries. I'll fix it in source, but I'm not going to release new versions of those.

I wouldn't be surprised if CheckableTableWidgetItem was only used in Reading List.

EDIT: FYI, changing Qt.ItemFlags to Qt.ItemFlag works back to Calibre v2.85.1 for me.
JimmXinu is offline   Reply With Quote
Old 05-08-2022, 12:03 PM   #192
JSWolf
Resident Curmudgeon
JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.JSWolf ought to be getting tired of karma fortunes by now.
 
JSWolf's Avatar
 
Posts: 74,703
Karma: 130140792
Join Date: Nov 2006
Location: Roslindale, Massachusetts
Device: Kobo Libra 2, Kobo Aura H2O, PRS-650, PRS-T1, nook STR, PW3
Quote:
Originally Posted by JimmXinu View Post
In the kiwidude plugins I maintain, only Reading List uses common_utils.CheckableTableWidgetItem(). This issue doesn't affect FavouritesMenu, ViewManager, GenerateCover or ManageSeries. I'll fix it in source, but I'm not going to release new versions of those.

I wouldn't be surprised if CheckableTableWidgetItem was only used in Reading List.

EDIT: FYI, changing Qt.ItemFlags to Qt.ItemFlag works back to Calibre v2.85.1 for me.
Thank you for helping to maintain kiwidude's plugins. I really do appreciate it.
JSWolf is offline   Reply With Quote
Old 05-08-2022, 03:15 PM   #193
theducks
Well trained by Cats
theducks ought to be getting tired of karma fortunes by now.theducks ought to be getting tired of karma fortunes by now.theducks ought to be getting tired of karma fortunes by now.theducks ought to be getting tired of karma fortunes by now.theducks ought to be getting tired of karma fortunes by now.theducks ought to be getting tired of karma fortunes by now.theducks ought to be getting tired of karma fortunes by now.theducks ought to be getting tired of karma fortunes by now.theducks ought to be getting tired of karma fortunes by now.theducks ought to be getting tired of karma fortunes by now.theducks ought to be getting tired of karma fortunes by now.
 
theducks's Avatar
 
Posts: 30,000
Karma: 57259778
Join Date: Aug 2009
Location: The Central Coast of California
Device: Kobo Libra2,Kobo Aura2v1, K4NT(Fixed: New Bat.), Galaxy Tab A
Quote:
Originally Posted by JSWolf View Post
Thank you for helping to maintain kiwidude's plugins. I really do appreciate it.

Others have added plugin (floods) over time, but Kiwidude sure made a lot that I use regularly.
Thanks for keeping them alive.
(And Thanks to you Kiwidude if you are lurking)
theducks is offline   Reply With Quote
Old 05-09-2022, 09:48 AM   #194
JimmXinu
Plugin Developer
JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.JimmXinu ought to be getting tired of karma fortunes by now.
 
JimmXinu's Avatar
 
Posts: 6,403
Karma: 4276871
Join Date: Dec 2011
Location: Midwest USA
Device: Kindle Paperwhite(10th)
I've far from the only one helping out with kiwidude's plugins, but you're welcome.

And I agree; my thanks too, to kiwidude for all the plugins and to everyone keeping them running.
JimmXinu is offline   Reply With Quote
Old 05-17-2022, 04:23 AM   #195
iamagloworm
Connoisseur
iamagloworm began at the beginning.
 
Posts: 60
Karma: 10
Join Date: Apr 2013
Device: Kindle Paperwhite 3 (Manga)
I wonder if anyone could have a look at this plugin? davidfor has updated it for python 3, and collects some metadata from FictionDB, but genre, classification and time period are not added to tags, and I want to add age-level as well, ideally to a separate column.

I really appreciate davidfor reviving this plugin and thought some extra support would be welcome.

FictionDB Plug-In thread

Thanks!
iamagloworm is offline   Reply With Quote
Reply


Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Suggestion for PI Devs BetterRed Plugins 11 09-27-2020 06:18 PM
Attn plugin devs: porting to python 3 kovidgoyal Plugins 129 06-16-2020 01:31 AM
Attention All Plugin Devs: Remove vestiges from python 2? KevinH Plugins 11 05-29-2020 03:16 PM
Plugin Devs: Should we include a License or COPYING file? KevinH Plugins 3 08-15-2017 01:09 PM
New Plugin Features in the upcoming Sigil 0.8.900 KevinH Plugins 6 09-14-2015 02:48 PM


All times are GMT -4. The time now is 09:35 PM.


MobileRead.com is a privately owned, operated and funded community.