View Single Post
Old 02-01-2025, 08:58 AM   #1
Angeljo
Junior Member
Angeljo began at the beginning.
 
Posts: 1
Karma: 10
Join Date: Feb 2025
Device: Kindle Color
Help on a plugin which not appears in the Menu

Good morning. I am completely new to development in python and even more so in Calibre. I wanted, for my personal use, to prepare a small plugin that would allow me to manage the biography of an author, on several books at the same time. With the help of AI I made this plugin, which apparently integrates with Calibre because we see it in the plugin folder and also in Preferences>Plugins>User Interface Action. Unfortunately, I cannot test it, because it does not appear in the menu (despite the creation request). I searched in the different toolbars (in Preferences), in the shortcuts but without success. So maybe my code doesn't work, but I don't know because I can't test it. Sorry for my bad English: I am French speaking. And also sorry if my question is really stupid in your eyes: be lenient.
Could you tell me what I'm doing wrong?

here is the code for the 2 main files (the other 2, manifest.json and __init_.py are less important I believe):

1. ui.py

Code:
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QLabel, QComboBox, QTextEdit, QPushButton
from calibre.gui2 import info_dialog
from calibre.gui2.dialogs.message_box import MessageBox

class BioManagerUI(QDialog):
    """
    Fenêtre pour gérer les biographies des auteurs.
    L'utilisateur sélectionne un auteur et saisit/modifie sa biographie.
    """
    def __init__(self, gui, parent=None):
        super(BioManagerUI, self).__init__(parent)
        self.gui = gui
        self.setWindowTitle("Gérer les biographies des auteurs")
        self.resize(500, 400)
        layout = QVBoxLayout(self)
        
        # Label et menu déroulant pour sélectionner un auteur
        label = QLabel("Sélectionnez un auteur :")
        layout.addWidget(label)
        self.combo = QComboBox(self)
        self.combo.addItems(self.get_authors())
        layout.addWidget(self.combo)
        
        # Zone de saisie pour la biographie (support HTML)
        self.text_edit = QTextEdit(self)
        self.text_edit.setAcceptRichText(True)
        layout.addWidget(self.text_edit)
        
        # Bouton pour enregistrer
        self.save_button = QPushButton("Enregistrer", self)
        self.save_button.clicked.connect(self.save_bio)
        layout.addWidget(self.save_button)
    
    def get_authors(self):
        """
        Récupère la liste de tous les auteurs présents dans la bibliothèque.
        """
        db_instance = self.gui.current_db
        authors = set()
        for book_id in db_instance.all_book_ids():
            mi = db_instance.get_metadata(book_id, index_is_id=True)
            if mi.authors:
                authors.update(mi.authors)
        return sorted(authors)
    
    def save_bio(self):
        """
        Enregistre la biographie pour l'auteur sélectionné.
        Si une biographie existe déjà, demande si l'utilisateur souhaite la remplacer ou l'ajouter.
        """
        db_instance = self.gui.current_db
        author = self.combo.currentText()
        new_bio = self.text_edit.toHtml().strip()
        count = 0
        existing_bio = ""
        for book_id in db_instance.all_book_ids():
            mi = db_instance.get_metadata(book_id, index_is_id=True)
            if mi.authors == [author]:
                existing_bio = db_instance.get_custom(book_id, "#auteurbio") or ""
                break
        if existing_bio:
            choice = MessageBox.question(
                self.gui,
                "Biographie existante",
                f"Une biographie existe déjà pour {author}.\nVoulez-vous la remplacer ou l'ajouter ?",
                "Remplacer", "Ajouter", "Annuler"
            )
            if choice == 2:
                return
            elif choice == 1:
                new_bio = existing_bio + "\n\n" + new_bio
        for book_id in db_instance.all_book_ids():
            mi = db_instance.get_metadata(book_id, index_is_id=True)
            if mi.authors == [author]:
                db_instance.set_custom(book_id, "#auteurbio", new_bio)
                count += 1
        info_dialog(self.gui, "Succès", f"Biographie mise à jour pour {count} livre(s) de {author}.", show=True)
        self. Accept()
2. plugin.py

Code:
import csv
import os, sys, subprocess, zipfile
from functools import partial

from calibre.constants import DEBUG, numeric_version as calibre_version
from calibre.gui2 import info_dialog, question_dialog, error_dialog, Dispatcher
from calibre.gui2.actions import InterfaceAction
from calibre.customize import InterfaceActionBase

#-----------------------------------------------
class BioManagerUpdate(InterfaceAction):
    name = 'bio_manager_action'
    action_spec = ('Gérer Biographies', None, 'Gérer les biographies des auteurs', None)
    action_type = 'global'
    accepts_drops = False
    auto_repeat = False
    priority = 9
    popup_type = 1

    def genesis(self):
        # On récupère la fenêtre principale
        self.maingui = self.gui
        # Créer un sous-menu "Biographies" dans le menu "Outils"
        self.menu = self.gui.main_window.menu.addMenu("Biographies")
        # Ajout de l'action au sous-menu avec un identifiant unique (ici, "_v2" pour forcer le changement)
        self.qaction.setText("Gérer Biographies")
        self.qaction.triggered.connect(self.open_ui)
        self.menu.addAction(self.qaction)
        # Ajout de l'action dans le menu "Outils" (si disponible)
        if hasattr(self.gui.main_window, 'menu_actions') and 'tools' in self.gui.main_window.menu_actions:
            self.gui.main_window.menu_actions['tools'].addAction(self.qaction)
        print("Plugin 'Gérer Biographies' chargé (v2).")

    def apply_settings(self):
        self.gui.add_action(self)

    def open_ui(self):
        try:
            from calibre_plugins.bio_manager.ui import BioManagerUI
        except ImportError:
            from ui import BioManagerUI
        ui = BioManagerUI(self.gui)
        ui.exec_()

#-----------------------------------------------
class BioManagerPlugin(InterfaceActionBase):
    name = "BioManager"
    description = "Un plugin pour gérer les biographies des auteurs dans Calibre"
    supported_platforms = ["windows", "osx", "linux"]
    author = "ChatGPT & Joëlle"
    version = (1, 0, 0)
    minimum_calibre_version = (5, 0)

    def load_actual_plugin(self, gui):
        self.actual_plugin = BioManagerUpdate(gui)
        gui.add_action(self.actual_plugin)

    def unload_actual_plugin(self):
        self.actual_plugin = None
Angeljo is offline   Reply With Quote