![]() |
#1 |
Junior Member
![]() Posts: 7
Karma: 10
Join Date: Nov 2014
Device: None
|
Plugin Best Practices
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 bookMy 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. 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. Any guidance would be appreciated! |
![]() |
![]() |
![]() |
#2 | ||||
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 24,905
Karma: 47303824
Join Date: Jul 2011
Location: Sydney, Australia
Device: Kobo:Touch,Glo, AuraH2O, GloHD,AuraONE, ClaraHD, Libra H2O; tolinoepos
|
Quote:
![]() Quote:
- 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:
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 |
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,300
Karma: 27111240
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
1. You store persistent data, just like any other settings, in the config directory, they are not touched by install/uninstalls of plugins. See http://manual.calibre-ebook.com/crea...of-your-plugin
You wont store it as a .txt file, instead it will be stored as a string in a JSON file. 2. Dont store book specific data as a file. Store it in the database. Using db.new_api.add_custom_data and db.new_api.get_custom_data Naturally this will only work in a user interface pugin, which has access ot the db 3. Use two plugins. You can technically get fancy and have your user interface plugin install the file type plugin on initialization, but that is a hack and likely to break in the future. |
![]() |
![]() |
![]() |
#4 | ||
Junior Member
![]() Posts: 7
Karma: 10
Join Date: Nov 2014
Device: None
|
Thanks for the quick reply. Still some questions:
Quote:
Quote:
2. Using: db.new_api.add_custom_data and db.new_api.get_custom_data. I would like to learn how to use this anyway. I have seen the documentation, (add_custom_book_data(name, val_map, delete_first=False) but don't understand what a value map is. Is this just a string? And is <name> any name of my choosing? (unique of course) 3. FileTypePlugin and db. Above you stated that I would need an InterfacePlugin to get access to the db. I presume you only meant if the user was wanting to see something since the FileTypePlugin would need to db access as well and I believe that is possible from the examples I have seen. BTW - you have provided a real service with Calibre. It is a wonderful tool and I have already loaded it on multiple friends systems! I salute you. ![]() |
||
![]() |
![]() |
![]() |
#5 |
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,300
Karma: 27111240
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
You cannot store any files in the calibre library unless you are willing to give them their own extension and make them a format. And that will just confuse your users. Store your wordlist in the db, your life will be a lot simpler. If you put random files in calibre library folders they will be deleted automatically if the user chanes title or author and check library will complain about them.
Quoting the documentation: A val_map is just a python dictionary, like this: {book_id:"some value", book_id2:"other value"} Yes, I was refering to providing an interface for your users to edit the stored data, which can happen only in a user interface plugin. |
![]() |
![]() |
![]() |
#6 | |||
Junior Member
![]() Posts: 7
Karma: 10
Join Date: Nov 2014
Device: None
|
Thanks for the quick reply!
Quote:
Quote:
Quote:
|
|||
![]() |
![]() |
![]() |
#7 |
null operator (he/him)
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 21,694
Karma: 29711016
Join Date: Mar 2012
Location: Sydney Australia
Device: none
|
![]() I wonder if sbenz's Bad Words PI could leverage that feature. Assuming different Bad Word 'dictionaries' would be used for different physical libraries then only the dictionary name need be stored in the library database. Another advantage of leveraging the existing user dictionary facility might be that it is language aware. Aside : I doubt that storing the bad word list in the database would have any noticeable impact on performance. As for cluttering, one of my databases has 31 tables, 61 indices, 13 views and 46 triggers. I assume a bad_word_list would be a row in the preferences table and an update to the preferences autoindex, I can't see how that could be regarded as 'cluttering' the database. One of my user dictionaries has ~6800 words, it weighs-in at 105MB, I'm pretty certain that SQLite can handle something of that size and much larger. BR Last edited by BetterRed; 11-08-2014 at 10:18 PM. |
![]() |
![]() |
![]() |
#8 | ||
Junior Member
![]() Posts: 7
Karma: 10
Join Date: Nov 2014
Device: None
|
Quote:
Using multiple dictionaries occurred to me also for other reasons. I will explore this more after it is running. Quote:
BW_Dict = list of bad words; stored only once in preferences I really appreciate your input.BW_BookStats = dict of (bw, count) pairs where count is number of occurrences of bw in the book.
sb |
||
![]() |
![]() |
![]() |
#9 |
null operator (he/him)
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 21,694
Karma: 29711016
Join Date: Mar 2012
Location: Sydney Australia
Device: none
|
@sbenz - Gotcha - yes I can see how a 'bad-word, count' list for every book could be regarded as 'cluttering' - especially if it's short-lived.
You probably did explain it well enough, but these days my brain disengages when I see 'programmer' lingo. You can add one of any 'file type' to a book. So for example you can add an MP3 file to a book, calibre itself can't do much with an MP3 except hand it off to the OS in the hope it knows what to do with it. There's also an Open With PI that will hand off a file type to a designated program So you could write the 'bad-word, count' list for a book in calibre's current temp folder with a name of <some random string or other>.bwlist, and then add that file to the book. You would then have a BWLIST 'format' in the book, calibre will then take care of it - ie not lose it if a folder is moved or renamed - but like an MP3 it won't be able to do much with it. Some alternatives for the internal representation that spring to mind include - json, csv, serialised. BR Last edited by BetterRed; 11-10-2014 at 06:07 PM. |
![]() |
![]() |
![]() |
#10 |
Junior Member
![]() Posts: 7
Karma: 10
Join Date: Nov 2014
Device: None
|
I have carefully reviewed each option for my Bad Words List plugin and none are satisfactory.
The best solution appears to be an "Attachment" folder in each book folder that any plugin could drop files into and manage. Would it be difficult to enhance Calibre to include an "Attachment" folder in each book folder? Initially Calibre's only responsibility for this folder would be:
I don't want to write up an enhancement request unless this is relatively easy to achieve. |
![]() |
![]() |
![]() |
#11 |
null operator (he/him)
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 21,694
Karma: 29711016
Join Date: Mar 2012
Location: Sydney Australia
Device: none
|
How would you prevent a user not putting 'other' things in the Attachments folder ?
BR |
![]() |
![]() |
![]() |
#12 | |
Junior Member
![]() Posts: 7
Karma: 10
Join Date: Nov 2014
Device: None
|
Quote:
SB |
|
![]() |
![]() |
![]() |
#13 | |
null operator (he/him)
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 21,694
Karma: 29711016
Join Date: Mar 2012
Location: Sydney Australia
Device: none
|
Quote:
However, there have been several requests to have an Attachments (Extras, Supplementary) folder within the book folders into which user could put things. Kovid has declined to do that, I can't recall his rationale in detail but at the time it seemed reasonable. Might have been related in part at least to deletions, and what happens if a file in Attachments is locked by another process when there's a move to be done etc. I suggest you ask Kovid for his thoughts. My observation is that the file handling across different platforms is one of the more 'difficult' issues calibre has to address - case significance, access control, file locking, path lengths etc. Which maybe brings you full circle to either having the word list stored in the database, or as a 'pseudo_format file', or... in unmanaged space. Your main objection to the 'pseudo_format_file' was that seeing a file called 'Some Title - An Author.badwords' would confuse the user. But would that be any more confusing than pressing 'O' and seeing an Attachments folder containing a file of a similar name. Or coming to grips with the purpose of ORIGINAL_XXXX.xxxx files. Transparency is often the best way to avoid confusion. The file wouldn't come into existence unless the user ran your PI, and presumably your PI would hook up to a custom column as a place to store the bad word count. And the user could colour that column based on the count, blue if more than 50, red if more then 20 etc ![]() BR Last edited by BetterRed; 11-28-2014 at 10:37 PM. |
|
![]() |
![]() |
![]() |
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
[FileType Plugin] YVES Bible Plugin | ClashTheBunny | Plugins | 27 | 01-16-2023 01:25 AM |
Plugin not customizable: Plugin: HTML Output does not need customization | flyingfoxlee | Conversion | 2 | 02-24-2012 02:24 AM |
Apple practices...... | carpetmojo | News | 67 | 02-16-2012 05:15 AM |
[GUI Plugin] Plugin Updater **Deprecated** | kiwidude | Plugins | 159 | 06-19-2011 12:27 PM |
New Plugin Type Idea: Library Plugin | cgranade | Plugins | 3 | 09-15-2010 12:11 PM |