Quote:
Originally Posted by sbenz
I am developing a 'Bad Word' plugin to scan books for words the reader would rather not encounter. Based on the plugin response, the reader can choose to keep the book or delete it. The approach is simple:
1. BWFile.txt - a plugin resource that contains a list of bad words provided by the plugin but editable by the user
2. On scanning a book the plugin generates two items: a. <bookid>_bwstats.txt - for each bad word in BWFile.txt it stores the number of times the bad word was encountered in the book b. bwstats_M_N tag - adds this tag to the book indicating the book was scanned and had M unique bad words and N total bad words (this provides the reader a way to know if the book was scanned and a summary of the results) 3. Scanning is triggered two ways: a. On adding a book (configurable) b. On demand by the user 4. Review Results: the use may filter on books with the tag and via the plugin bring up the <bookid>_bwstats.txt for review before deciding whether to keep or delete the book
|
I can't say I have need for this, but, I'll probably try it and see how "bad" some of my books are

And of course, I can see someone using it to select the book to read.
Quote:
My questions:
1. Maintaining BWFile.txt on plugin update. If the user has edited the BWFile.txt (or preferences for that matter), how is it kept from being overwritten by an update to the plugin? The plugin installation is performed by Calibre and I haven't seen any documentation on how to keep existing plugin resources for use by the updated plugin.
|
I can think of a few ways:
- Calculate the md5/crc or whatever for the files and only replace if it hasn't changed. Or prompt the user to decide.
- Use two files. One is the defaults that is always replaced. The other is the users file. The decision then is whether the use file is a complete replacement, or just extra words for that user.
- Don't replace the file, but have a way to download it from somewhere with a notification when it has changed.
Quote:
2. Storing <bookid>_bwstats.txt: a. In same folder as the book? Ideally it should be stored in the same folder as the book since the data is directly related to the book. If the book is removed from the library this file would also be removed. Is this a good practice? Perhaps it should be stored as meta-data, but at this point I don't know how I would do it. b. How do I obtain the path to the folder containing the book? 1) db.field_for('path', bookid) returns the path relative to the Calibre library, but I haven't found an environment variable or method that specifies the Calibre library path. 2) db.format_abspath(bookid, 'epub') returns the absolute path to the book but requires a specific book format. What if there isn't an epub format? Furthermore, the API warns against using this approach for thread safety.
|
As you are running this within calibre against a book in the library, you can do either of these easily. Storing the data in a custom column is easy and is done in a lot of plugins. Both of my plugins do it, plus the Count Pages (which is where I cribbed the code from), Reading List, Goodreads Sync and others. And look at Kovid's post in
https://www.mobileread.com/forums/sho...d.php?t=249522.
I haven't added a file to the library, but there should be simple way to add a format to the current book. That means you don't care about the path. You could add the file with your own extension then associate that in the OS with the text editor. Or add a "View stats" option to the plugin menu that displays the file.
Quote:
3. How do I create a dual use plugin, that is, one that acts like a FileTypePlugin (triggered when adding a book) and one that acts like a UserInterfacePlugin (triggered by user action). The core of the plugin is the same in both cases. The FileTypePlugin adds derivation from the FileTypePlugin class, has numerous 'on_...' instructions, and uses the 'def run(...)' method to be executed by Calibre. The UserInterfacePlugin derives from the InterfaceActionBase would call a different method and has added job control code. Can I combine the two into one plugin or should these be separate plugins? Are there plugin examples already doing this?
|
Kovid will probably have a better way, but, what comes to mind is two plugins. One just uses a classes and methods in the other.