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 05-07-2011, 01:15 PM   #1
t3d
Enthusiast
t3d began at the beginning.
 
Posts: 38
Karma: 10
Join Date: Nov 2009
Location: Poland
Device: kindle 1st gen, kindle dxg, kindle paperwhite2
store plugin

Hello,
I'm trying to write a store plugin.

It begins like that:
Code:
# -*- coding: utf-8 -*-

from __future__ import (unicode_literals, division, absolute_import, print_function)

__license__ = 'GPL 3'
__copyright__ = '2011, Tomasz Długosz <tomek3d@gmail.com>'
__docformat__ = 'restructuredtext en'

# import random
import re
import urllib2
from contextlib import closing

from lxml import html

from PyQt4.Qt import QUrl

from calibre import browser, url_slash_cleaner
from calibre.gui2 import open_url
from calibre.gui2.store import StorePlugin
#from calibre.gui2.store.basic_config import BasicStoreConfig
from calibre.gui2.store.search_result import SearchResult
#from calibre.gui2.store.web_store_dialog import WebStoreDialog
        
class Nexto(StorePlugin):
But when I try to add this plugin to calibre (Add a new plugin button), I get

calibre, version 0.8.0
ERROR: Unhandled exception: <b>InvalidPlugin</b>:No plugin class found in /home/tomek/plugin/plugin.zip:dummy3

Traceback (most recent call last):
File "/usr/lib/calibre/calibre/gui2/preferences/plugins.py", line 283, in add_plugin
plugin = add_plugin(path)
File "/usr/lib/calibre/calibre/customize/ui.py", line 322, in add_plugin
plugin = load_plugin(path_to_zip_file)
File "/usr/lib/calibre/calibre/customize/ui.py", line 54, in load_plugin
return loader.load(path_to_zip_file)
File "/usr/lib/calibre/calibre/customize/zipplugin.py", line 177, in load
as_unicode(path_to_zip_file), plugin_name))
InvalidPlugin: No plugin class found in /home/tomek/plugin/plugin.zip:dummy3
t3d is offline   Reply With Quote
Old 05-07-2011, 03:48 PM   #2
kiwidude
calibre/Sigil Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,230
Karma: 1345754
Join Date: Oct 2010
Location: London, UK
Device: Kindle Paperwhite 3G, iPad 3, iPad Air
Moderator Notice
I've moved this post into the dev forum from the plugins one.

It's a 50/50 whether posts about developing plugins sit here or in the plugins subforum. However as 95% of the other questions related to developing with Calibre have been in here I figure this is a better place. Particularly as undoubtedly this sort of topic may end up touching general Calibre development questions...
kiwidude is offline   Reply With Quote
 
Advertisement
Old 05-07-2011, 04:02 PM   #3
user_none
Sigil & calibre developer
user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.
 
user_none's Avatar
 
Posts: 2,473
Karma: 1053245
Join Date: Jan 2009
Location: Florida, USA
Device: Nook STR
See http://calibre-ebook.com/user_manual...g_plugins.html Plugins are more than putting a .py file in a zip archive. You need to setup the archive properly to be recognized.
user_none is offline   Reply With Quote
Old 05-07-2011, 04:06 PM   #4
user_none
Sigil & calibre developer
user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.
 
user_none's Avatar
 
Posts: 2,473
Karma: 1053245
Join Date: Jan 2009
Location: Florida, USA
Device: Nook STR
Also with Store's you need to use a calibre.customize.StoreBase to load the calibre.gui2.store.StorePlugin. See calibre.customize.builtins for examples of creating the StoreBase. Store's follow the same pattern as user interface plugins in the above link.
user_none is offline   Reply With Quote
Old 05-07-2011, 05:05 PM   #5
t3d
Enthusiast
t3d began at the beginning.
 
Posts: 38
Karma: 10
Join Date: Nov 2009
Location: Poland
Device: kindle 1st gen, kindle dxg, kindle paperwhite2
Thanks for noticing that the pattern is the same as in UI plugins.

Last edited by t3d; 05-07-2011 at 06:11 PM.
t3d is offline   Reply With Quote
Old 05-08-2011, 08:42 AM   #6
t3d
Enthusiast
t3d began at the beginning.
 
Posts: 38
Karma: 10
Join Date: Nov 2009
Location: Poland
Device: kindle 1st gen, kindle dxg, kindle paperwhite2
Could you please package one of your plugins as external zip for a reference?
Or maybe there is some external store plugin written up to date?
t3d is offline   Reply With Quote
Old 05-08-2011, 01:04 PM   #7
user_none
Sigil & calibre developer
user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.
 
user_none's Avatar
 
Posts: 2,473
Karma: 1053245
Join Date: Jan 2009
Location: Florida, USA
Device: Nook STR
Here is an skeleton example of a store packaged as a plugin.
Attached Files
File Type: zip fictionwise_store.zip (1.1 KB, 159 views)
user_none is offline   Reply With Quote
Old 05-08-2011, 07:14 PM   #8
t3d
Enthusiast
t3d began at the beginning.
 
Posts: 38
Karma: 10
Join Date: Nov 2009
Location: Poland
Device: kindle 1st gen, kindle dxg, kindle paperwhite2
Quote:
Originally Posted by user_none View Post
Here is an skeleton example of a store packaged as a plugin.

I was wondering what to put in ui.py till now
t3d is offline   Reply With Quote
Old 05-15-2011, 08:32 AM   #9
t3d
Enthusiast
t3d began at the beginning.
 
Posts: 38
Karma: 10
Join Date: Nov 2009
Location: Poland
Device: kindle 1st gen, kindle dxg, kindle paperwhite2
The plugin I was working on earlier is finished and working, but I have another issue with other one I want to write.

The ebook store uses html POST method instead of GET. Here is a snippet That works:
Code:
#!/usr/bin/python
# coding=iso-8859-2
# vim: set fileencoding=iso-8859-2


#import os
import urllib
import urllib2

query = 'test'

url='http://www.gandalf.com.pl/s/'
values={
    'search': query,
    'dzialx':'11'}
request=urllib2.Request(url, urllib.urlencode(values))
response=urllib2.urlopen(request, None, 60)
the_page=response.read()

print the_page
But when I try to put that into search function in plugin I get no results:
Code:
# -*- coding: utf-8 -*-

from __future__ import (unicode_literals, division, absolute_import, print_function)

__license__ = 'GPL 3'
__copyright__ = '2011, Tomasz Długosz <tomek3d@gmail.com>'
__docformat__ = 'restructuredtext en'

import re
import urllib
import urllib2
#from contextlib import closing

from lxml import html

from PyQt4.Qt import QUrl

from calibre import browser, url_slash_cleaner
from calibre.gui2 import open_url
from calibre.gui2.store import StorePlugin
from calibre.gui2.store.basic_config import BasicStoreConfig
from calibre.gui2.store.search_result import SearchResult
from calibre.gui2.store.web_store_dialog import WebStoreDialog

class GandalfStore(BasicStoreConfig, StorePlugin):

    def open(self, parent=None, detail_item=None, external=False):
        url = 'http://www.gandalf.com.pl/ebooks/'
        detail_url = None

    def search(self, query, max_results=10, timeout=60):
        url = 'http://www.gandalf.com.pl/s/'
        values={
            'search': query,
            'dzialx':'11'
            }
        request = urllib2.Request(url, urllib.urlencode(values))
        response = urllib2.urlopen(request, None, timeout)

        counter = max_results
        doc = html.fromstring(response.read())
        for data in doc.xpath('//div[@class="wyszukiwanie_podstawowe_header"]'):
            if counter <= 0:
                break

            #id = ''.join(data.xpath('.//div[@class="box"]/img/@src'))
            id = 'lala'#.join(data.xpath('.//div[@class="box"]/img/@src'))
            if not id:
                continue

            price = ''.join(data.xpath('.//h3[@class="promocja"]/text()'))

            cover_url = ''.join(data.xpath('.//img[@class="box"]/img/@src'))
            title = ''.join(data.xpath('.//div[@class="info"]/h3/a/text()'))
            formats = ''

            author = 'LALALA'
            counter -= 1

            s = SearchResult()
            s.cover_url = cover_url
            s.title = title.strip()
            s.author = author.strip()
            s.price = price
            s.detail_item = id.strip()
            s.drm = SearchResult.DRM_UNKNOWN
            s.formats = formats

            yield s
I did assign nonsense values to variables in above snippet, to check where the bug is. I guess it is something wrong with putting response content into doc.
t3d is offline   Reply With Quote
Old 05-15-2011, 09:56 AM   #10
user_none
Sigil & calibre developer
user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.user_none ought to be getting tired of karma fortunes by now.
 
user_none's Avatar
 
Posts: 2,473
Karma: 1053245
Join Date: Jan 2009
Location: Florida, USA
Device: Nook STR
First you need to use the Browser object. The Browser takes into account the users proxy settings. You can use urllib2 like you are but you will need to handle detecting and using the users proxy settings. It's easier just to use Browser as it does this for you. The Browser also sets the user agent to a Firefox to avoid issues with sites that filter or give different responses to non-browser apps.

The Browser is able to POST data. Here is an example.

Code:
# -*- coding: utf-8 -*-

import urllib
from contextlib import closing

from calibre import browser

url='http://www.gandalf.com.pl/s/'
data = {
    'search': 'Andrzej Franaszek',
    'dzialx': '11'
}

br = browser()

with closing(br.open(url, data=urllib.urlencode(data), timeout=10)) as f:
    print f.read()
As for why it's not showing any results. My guess is it has to do with your generic test values. The search dialog is smart and does additional filtering. Many stores always return results even when they have nothing to do with the users search. So the search dialog filters out all results that don't have anything to do with the query. Meaning if you search for "Franaszek" and the SearchResults objects come back with a title of "Blah" and an author of "Lalala" it will be filtered because "Franaszek" doesn't appear in either field.
user_none 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
[GUI Plugin] Plugin Updater **Deprecated** kiwidude Plugins 159 06-19-2011 01:27 PM
Removal of plugin not removing config store meme Plugins 4 02-01-2011 05:45 PM
New Plugin Type Idea: Library Plugin cgranade Plugins 3 09-15-2010 01:11 PM
I can log on to Sony Store, but I can't access the Store Dr. Drib Sony Reader 3 04-11-2009 10:05 AM


All times are GMT -4. The time now is 11:05 AM.


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