Register Guidelines E-Books Search Today's Posts Mark Forums Read

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

Notices

Reply
 
Thread Tools Search this Thread
Old 12-08-2012, 02:22 PM   #1
GaryJonston
Junior Member
GaryJonston began at the beginning.
 
Posts: 2
Karma: 10
Join Date: Oct 2012
Device: Onyx boox A60
Help with plugin dev - get_resources() works funny

Hi

First let me say I'm rather new developer in python so I may not know all the tricks and probably this is the reason I write this post.
Ok. So my problem is like that.
I'm trying to write some plugin for calibre that embeds font in the epub. (in attachment)
I know that:
1. there already are such plugins,
2. There is a feature in the calibre that does that, but nevertheless I wanted to experiment.
Basically what I wanted to do was to have font file inside the plugin apart of python code.
So my plugin (zip file) has content like that:

Code:
__init__.py
font.otf

Now, my intent was to copy font file from the plugin into the epub and modify css file in the process.
I've found some plugin that did pretty much the same apart from fact that fonts were external to the plugin file.
I want them to be embedded into plugin because I use linux and windows interchangeably and those external paths
were always incomaptibile with one of the system. Embedding them will make no trouble for calibre to correctly know their location.
What is more, I do not want to install them system wide
Anyway
I've read that I needed to access such resource from within the plugin. The correct way to do that was to use
get_resources() function.
Now the funny part begins.
According to the calibre documentation (http://manual.calibre-ebook.com/crea...lugin-zip-file)
I need to pass a resource_name or list_of_resource_names to the function and in return I should get a byte_object or dictionary_of_bytes_objects
Ok, I've created some debug version of plugin to see if this works:

Code:
from calibre.customize import FileTypePlugin


class DebugPlugin(FileTypePlugin):
    name = 'Debug plugin' # Name of the plugin
    description = "Debug plugin"
                    
    supported_platforms = [ 'windows', 'linux' ] # Platforms this plugin will run on
    author = 'Author' # The author of this plugin
    version = (1, 0, 2)   # The version number of this plugin
    file_types = set(['epub']) 
    on_postprocess = True
    priority = 100
    
    def run(self, path_to_ebook):
        print( "Debug_plugin: run..., path to ebook (arg) '" + str( path_to_ebook ) + "'" )
           
        fontFamilyName = "Font"
        fontRegularName = fontFamilyName + '.otf'
        
        res = get_resources( fontRegularName )
        if res is None:
            print( "Debug_plugin: Could not get resource '" + fontRegularName + "'")
        else:
            print( "Debug_plugin: get_resources for '" + fontRegularName + "' returned: class: " + str( res.__class__ ) + ", name: " + str( res.__class__.__name__ ) + ", len:" + str( len( res ) ) ) 
    
        return path_to_ebook
When i look into the log file in calibre debug mode I see output like:

Code:
Debug_plugin: run..., path to ebook (arg) 'C:\TEMP\calibre_0.9.9_tmp_nbujxt\3aktb6.epub'
Debug_plugin: get_resources for 'Font.otf' returned: class: <type 'str'>, name: str, len:48976
It looks like instead of bytes object I got string. Hm.. Decoding it into bytes is pointless since there always be some byte that does not conform to
encoding page. I expected 'pure' bytes not string.
So i decided to get to know how this function works. I've downloaded Calibre source code from (sourceforge.net/projects/calibre/files/0.9.9/calibre-0.9.9.tar.xz) and I found that function
get_resources is defined in ...\calibre-0.9.9\calibre\src\calibre\customize\zipplugin.py

From what I can tell get_resources() really should return bytes object or dictionary (at least according to Python 2.7.3 ZipFile.read() documentation)
but, what surprised me, get_resources() accept two parameters , while in calibre manual it says that only one is needed.
I've checked that and indeed when I gave two arguments to the function:

e.g.
Code:
get_resources( fontRegularName, 'foobar' )
I got an error
Code:
TypeError: get_resources() takes exactly 2 arguments (3 given)
So I have two questions:
1. How is it possible that get_resources() accepts exactly 2 arguments, but I can only provide one (second), while first one is 'hidden' ? Could anyone could direct me to the site where such python feature is described.
( arguments are not default, function is not a class mentod, so it is not the case where first 'self' arg is passed implicitely)
2. Why does get_resources() return string object instead of bytes. Is there some decorator function involved ? Where is this in the calibre code ?
If someone could point me to it I would be very gratefull.

Please forgive me for long and spam-like post. I know I need to learn a lot about python but at least for now I don't know how to solve the issue.

Update:
Ok, I've looked into python documentation (2.7.4) and it says:

Quote:
ZipFile.read(name[, pwd])

Return the bytes of the file name in the archive. name is the name of the file in the archive, or a ZipInfo object.
So.. it does not explictly says it returns a bytes() object... it only says 'bytes', but would anyone interpret this that it returns a string ?
Attached Files
File Type: zip debug_plugin.zip (27.6 KB, 31 views)

Last edited by GaryJonston; 12-08-2012 at 06:04 PM.
GaryJonston is offline   Reply With Quote
Old 12-08-2012, 10:48 PM   #2
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: 25,400
Karma: 4961459
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
In python 2.x a str is a bytes object. A string is a unicode object.
kovidgoyal is offline   Reply With Quote
Old 12-09-2012, 04:23 AM   #3
GaryJonston
Junior Member
GaryJonston began at the beginning.
 
Posts: 2
Karma: 10
Join Date: Oct 2012
Device: Onyx boox A60
Ok.
So this would probably mean I could use function ZipFile.writestr() to copy files from one zip file (plugin) to another (epub)
But if i try to do this in result I got a epub that cannot be opened. The zip file is 'invalid'. Not sure why it happenes.

I still don't know how the 'hidden argument' to a function thing is achieved in python.
GaryJonston is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Modify ePub plugin dev thread kiwidude Development 346 09-02-2013 05:14 PM
Help with plugin dev. Buzzy Development 2 10-26-2012 03:22 PM
Einfacher Feature-Request: /dev/ptmx und /dev/ttyUSB2 modes Seneca PocketBook 2 12-05-2011 04:41 PM
Another plugin dev question DiapDealer Plugins 2 12-11-2010 01:46 PM
Epub plugin dev DiapDealer Plugins 15 11-12-2010 09:36 AM


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


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