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 12-20-2020, 06:19 PM   #151
capink
Wizard
capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.
 
Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
@chaley: I have implemented the changes, and they are working OK. The modifications you made to templates have simplified things for me, and the global variables opened up some new possibilities as well.

I am getting a lit bit greedy here, but after implementing the conditional execution for actions, I am now thinking about a similar thing but for the whole chain, since I can pass some state variables (number of selected books ... etc), and if conditions are not met, the chain action and menu entry would be disabled.

I started building a simple widget based on your template tester, with some extra things like datatype and comparison operator. Then, I started to wonder if I can leverage the template tab (in the search dialog), since it already contains similar functionality. If this tab can not be used, can I at least return a string like:

Code:
template:"program: globals(selection_count)#@#:n:>1"
and pass a mi object along with the above string to some function in calibre that would return True/False, or do I have to re-implement this myself (I might end up using this for conditional execution of actions and scrap the two column solution I've already implemented).

I did have a look and I found a create_template_tab function, which might be useful for building the widget, but I don't know what to do beyond that.

Last edited by capink; 12-20-2020 at 06:33 PM. Reason: typos
capink is offline   Reply With Quote
Old 12-20-2020, 07:12 PM   #152
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: 12,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by capink View Post
@chaley: I have implemented the changes, and they are working OK. The modifications you made to templates have simplified things for me, and the global variables opened up some new possibilities as well.
Sorry, but I am not sure what you want to do. Guessing ...
  • There isn't an easy way to reuse the template search mechanism. It is built into search. That said, you can of course pass template searches into calibre.db.search and get a list of book ids that match. However, there isn't any way to pass the globals dict into search because it uses its own copy of the formatter.
  • If you want to use a template to control a chain then you can define its behavior. You would invoke a template with the appropriate globals dict and run the chain if it returned an acceptable value. If possible I would avoid using datatypes, instead asking for a string value. This wasn't really practical for searches because the search language already had typed expressions. If you want to implement typed expressions then you will need to do it yourself.

    The big question for controlling a chain is whether the selected books have a role. This avoids needing the mechanism to specify the type of the response.
  • It might be that you want to execute a template without having a book. You should be able to do this by passing Metadata() as mi along with the globals dict. The globals dict would have been filled in with the values related to the chain.
  • It might be that you want to be able to pass a globals dict to the existing template tester. After a quick glance at the code I think I could do that.
What are you looking for?
chaley is offline   Reply With Quote
Old 12-20-2020, 07:30 PM   #153
capink
Wizard
capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.
 
Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
Thanks for your answer. It more like number 2 (similar request here, but covers multiple scenarios). It is not a lot of work to do, but I thought If similar code exists in calibre and is easily re-usable it would be a better quality than writing it myself. According to your first bullet point, it is not re-usable so I will write it myself.
capink is offline   Reply With Quote
Old 12-21-2020, 03:59 AM   #154
ownedbycats
Custom User Title
ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.
 
ownedbycats's Avatar
 
Posts: 10,994
Karma: 75337983
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
Question: How would I write a module to open up the item editor for the tags directly?

Click image for larger version

Name:	2020-12-21 04_58_32-calibre.png
Views:	2846
Size:	5.6 KB
ID:	184161
ownedbycats is online now   Reply With Quote
Old 12-21-2020, 07:14 AM   #155
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: 12,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by capink View Post
Thanks for your answer. It more like number 2 (similar request here, but covers multiple scenarios). It is not a lot of work to do, but I thought If similar code exists in calibre and is easily re-usable it would be a better quality than writing it myself. According to your first bullet point, it is not re-usable so I will write it myself.
I added the ability to pass the globals dict into the template editor/tester. If you give it your dict then the user can see actual results while writing the template. The change is in calibre source.
chaley is offline   Reply With Quote
Old 12-21-2020, 07:51 AM   #156
capink
Wizard
capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.
 
Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
Quote:
Originally Posted by chaley View Post
I added the ability to pass the globals dict into the template editor/tester. If you give it your dict then the user can see actual results while writing the template. The change is in calibre source.
Thanks
capink is offline   Reply With Quote
Old 12-21-2020, 10:13 AM   #157
capink
Wizard
capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.
 
Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
Quote:
Originally Posted by ownedbycats View Post
Question: How would I write a module to open up the item editor for the tags directly?

Attachment 184161
What exactly are you trying to achieve?
capink is offline   Reply With Quote
Old 12-21-2020, 12:52 PM   #158
ownedbycats
Custom User Title
ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.
 
ownedbycats's Avatar
 
Posts: 10,994
Karma: 75337983
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
I can already edit the tags themselves in the book list. I'd like to make a keyboard shortcut to this window without the step click of "Open tags prompt > click button."
Attached Thumbnails
Click image for larger version

Name:	2020-12-21 13_50_57-Manage items_ Tags.png
Views:	1482
Size:	13.1 KB
ID:	184167  
ownedbycats is online now   Reply With Quote
Old 12-21-2020, 03:02 PM   #159
capink
Wizard
capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.
 
Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
Here is the action you asked for. It is mostly a copy/paste from single field edit.

Code:
from PyQt5.Qt import (QApplication, Qt, QWidget, QVBoxLayout, QHBoxLayout,
                      QGroupBox, QComboBox, QPushButton, QRadioButton)

from calibre.gui2.dialogs.tag_editor import TagEditor

from calibre_plugins.action_chains.actions.base import ChainAction
from calibre_plugins.action_chains.templates import check_template, TEMPLATE_ERROR
from calibre_plugins.action_chains.templates.dialogs import TemplateBox

def get_possible_cols(db):
    fm = db.field_metadata.custom_field_metadata()
    cols = [ col for col, cmeta in fm.items() if cmeta['is_multiple'] ]
    cols = [ col for col in cols if fm[col]['datatype'] not in ['composite',None] ]
    cols.insert(0, 'tags')
    return cols

class ItemEditorConfig(QWidget):
    def __init__(self, plugin_action):
        QWidget.__init__(self)
        self.plugin_action = plugin_action
        self.gui = plugin_action.gui
        self.db = self.gui.current_db
        self.possible_cols = self.get_possible_cols()
        self.template = ''
        self._init_controls()

    def _init_controls(self):
        self.blockSignals(True)
        l = self.l = QVBoxLayout()
        self.setLayout(l)

        col_box = QGroupBox(_('Choose column:'))
        l.addWidget(col_box)
        col_box_layout = QVBoxLayout()
        col_box.setLayout(col_box_layout)

        name_layout = QHBoxLayout()
        col_box_layout.addLayout(name_layout)     
        name_opt = self.name_opt = QRadioButton(_('By column name'))
        name_layout.addWidget(name_opt)
        name_opt.setChecked(True)
        
        self.col_combobox = QComboBox()
        self.col_combobox.addItems(self.possible_cols)
        self.col_combobox.setCurrentText('tags')
        name_layout.addWidget(self.col_combobox)

        highlighted_opt = self.highlighted_opt = QRadioButton(_('Currently highlighted column'))
        col_box_layout.addWidget(highlighted_opt)

        template_layout = QHBoxLayout()
        col_box_layout.addLayout(template_layout)     
        template_opt = self.template_opt = QRadioButton(_('By template'))
        template_layout.addWidget(template_opt)
        
        self.template_button = QPushButton(_('Add template'))
        self.template_button.clicked.connect(self._on_template_button_clicked)
        template_layout.addWidget(self.template_button)

        l.addStretch(1)
        self.setMinimumSize(400,200)
        self.blockSignals(False)

    def get_possible_cols(self):
        return get_possible_cols(self.db)

    def _on_template_button_clicked(self):
        d = TemplateBox(self, self.plugin_action, template_text=self.template)
        if d.exec_() == d.Accepted:
            self.template = d.template
            self.template_button.setText(_('Edit template'))

    def load_settings(self, settings):
        if settings:
            if settings['col_opt'] == 'name':
                self.name_opt.setChecked(True)
                self.col_combobox.setCurrentText(settings['col_name'])
            elif settings['col_opt'] == 'highlighted':
                self.highlighted_opt.setChecked(True)
            elif settings['col_opt'] == 'template':
                self.template_opt.setChecked(True)
                self.template = settings['template']
                if self.template:
                    self.template_button.setText('Edit template')

    def save_settings(self):
        settings = {}
        if self.name_opt.isChecked():
            settings['col_opt'] = 'name'
            settings['col_name'] = self.col_combobox.currentText()
        elif self.highlighted_opt.isChecked():
            settings['col_opt'] = 'highlighted'
        else:
            settings['col_opt'] = 'template'
            settings['template'] = self.template
        return settings

class ItemEditorAction(ChainAction):

    name = 'Item Editor'

    def run(self, gui, settings, chain):
        db = gui.current_db
        rows = gui.current_view().selectionModel().selectedRows()
        book_ids = [ gui.library_view.model().db.id(row.row()) for row in rows ]

        if settings['col_opt'] == 'name':
            col_name = settings['col_name']
        elif settings['col_opt'] == 'highlighted':
            index = gui.library_view.currentIndex()
            column_map = gui.library_view.model().column_map
            col_name = column_map[index.column()]
        else:
            col_name = chain.evaluate_template(settings['template'])

        if col_name not in get_possible_cols(db):
            return

        if col_name == 'tags':
            key = None
        else:
            key = col_name
        
        if len(book_ids) == 0:
            return
        elif len(book_ids) == 1:
            book_id = book_ids[0]
        else:
            book_id = None

        d = TagEditor(gui, db, book_id, key)
        QApplication.setOverrideCursor(Qt.ArrowCursor)
        try:
            d.exec_()
        finally:
            QApplication.restoreOverrideCursor()
        if d.result() == d.Accepted:
            val = d.tags
            id_map = {book_id: val for book_id in book_ids}
            db.new_api.set_field(col_name, id_map)

        del d

    def config_widget(self):
        return ItemEditorConfig

    def validate(self, settings):
        gui = self.plugin_action.gui
        db = gui.current_db
        if not settings:
            return (_('Settings Error'), _('You must configure this action before running it'))
        if settings['col_opt'] == 'name':
            col_name = settings['col_name']
            if not col_name in get_possible_cols(db):
                return (_('Column Error'), _('Cannot find a column with name "{}" in current library'.format(col_name)))
        elif settings['col_opt'] == 'template':
            if not settings.get('template'):
                return (_('Empty Template Error'), _('Template for column name cannot be empty'))
            is_template_valid = check_template(settings['template'], self.plugin_action, print_error=False)
            if is_template_valid is not True:
                return is_template_valid
        return True
Warning: If you apply this action on multiple selected books, you will lose all preexisting tags on these books, as they will be overwritten by the new ones.

Edit: you will need to configure this action before running it to choose the column.

Edit2: This is not tested. Use at your own risk.

Last edited by capink; 05-08-2021 at 12:14 PM. Reason: remove wait cursor while dialog is on
capink is offline   Reply With Quote
Old 12-21-2020, 03:40 PM   #160
ownedbycats
Custom User Title
ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.
 
ownedbycats's Avatar
 
Posts: 10,994
Karma: 75337983
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
I tested it. It worked as expected.

I wonder if there might be a way to set a chain so that it appears greyed-out in the menu if multiple books are selected. Some actions don't work well on multiple books and it would prevent misclicks.
ownedbycats is online now   Reply With Quote
Old 12-21-2020, 03:45 PM   #161
capink
Wizard
capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.
 
Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
Quote:
Originally Posted by ownedbycats View Post
I tested it. It worked as expected.

I wonder if there might be a way to set a chain so that it appears greyed-out in the menu if multiple books are selected. Some actions don't work well on multiple books and it would prevent misclicks.
Coming in the next release, will be template based solution to enable/disable chains. Will also solve your problem about device not connected. See discussion below.

Quote:
Originally Posted by capink View Post
@chaley: I have implemented the changes, and they are working OK. The modifications you made to templates have simplified things for me, and the global variables opened up some new possibilities as well.

I am getting a lit bit greedy here, but after implementing the conditional execution for actions, I am now thinking about a similar thing but for the whole chain, since I can pass some state variables (number of selected books ... etc), and if conditions are not met, the chain action and menu entry would be disabled.

I started building a simple widget based on your template tester, with some extra things like datatype and comparison operator. Then, I started to wonder if I can leverage the template tab (in the search dialog), since it already contains similar functionality. If this tab can not be used, can I at least return a string like:

Code:
template:"program: globals(selection_count)#@#:n:>1"
and pass a mi object along with the above string to some function in calibre that would return True/False, or do I have to re-implement this myself (I might end up using this for conditional execution of actions and scrap the two column solution I've already implemented).

I did have a look and I found a create_template_tab function, which might be useful for building the widget, but I don't know what to do beyond that.
capink is offline   Reply With Quote
Old 12-21-2020, 05:40 PM   #162
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: 12,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by ownedbycats View Post
I can already edit the tags themselves in the book list. I'd like to make a keyboard shortcut to this window without the step click of "Open tags prompt > click button."
I am not sure what problem you are solving, but if what you want to do is open the tags editor from the booklist then SHIFT-F2 does that.
chaley is offline   Reply With Quote
Old 12-21-2020, 05:45 PM   #163
ownedbycats
Custom User Title
ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.
 
ownedbycats's Avatar
 
Posts: 10,994
Karma: 75337983
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
I didn't know that before! Is there a way to reassign it? It's hard to use it one-handed.
ownedbycats is online now   Reply With Quote
Old 12-21-2020, 05:56 PM   #164
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: 12,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by ownedbycats View Post
I didn't know that before! Is there a way to reassign it? It's hard to use it one-handed.
There isn't any way to change it. It is hard coded as SHIFT+Platform-Edit-Key.

As for one handed, although it doesn't matter in the least I don't see the problem. The shift key is on the left as is F2. Left little finger on shift and middle on F2 is easy for me. Perhaps my hands are larger than yours. Or who-knows-what. What I experience has no bearing on what you experience.
chaley is offline   Reply With Quote
Old 12-21-2020, 06:20 PM   #165
ownedbycats
Custom User Title
ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.
 
ownedbycats's Avatar
 
Posts: 10,994
Karma: 75337983
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
In my case it's more of a physical problem - I can't straighten the fingers in my left hand all the way because of muscle contractions (one of the fun effects of young-onset Parkinson's disease). Because of this, my style of typing is something of a weird hybrid between hunt-and-peck and the proper way.

Last edited by ownedbycats; 12-21-2020 at 06:25 PM.
ownedbycats is online now   Reply With Quote
Reply


Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
[Editor Plugin] Editor Chains capink Plugins 106 06-17-2025 05:36 PM
Action Chains Resources capink Plugins 77 06-16-2025 12:45 PM
[GUI Plugin] Noosfere_util, a companion plugin to noosfere DB lrpirlet Plugins 2 08-18-2022 03:15 PM
[GUI Plugin] Save Virtual Libraries To Column (GUI) chaley Plugins 14 04-04-2021 05:25 AM


All times are GMT -4. The time now is 06:26 PM.


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