![]() |
#1 |
Enthusiast
![]() 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): 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 |
![]() |
![]() |
![]() |
#2 |
Calibre Plugins Developer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 4,712
Karma: 2197768
Join Date: Oct 2010
Location: Australia
Device: Kindle Oasis
|
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... |
![]() |
![]() |
Advert | |
|
![]() |
#3 |
Sigil & calibre developer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 2,487
Karma: 1063785
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.
|
![]() |
![]() |
![]() |
#4 |
Sigil & calibre developer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 2,487
Karma: 1063785
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.
|
![]() |
![]() |
![]() |
#5 |
Enthusiast
![]() 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 05:11 PM. |
![]() |
![]() |
Advert | |
|
![]() |
#6 |
Enthusiast
![]() 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? |
![]() |
![]() |
![]() |
#7 |
Sigil & calibre developer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 2,487
Karma: 1063785
Join Date: Jan 2009
Location: Florida, USA
Device: Nook STR
|
Here is an skeleton example of a store packaged as a plugin.
|
![]() |
![]() |
![]() |
#8 |
Enthusiast
![]() Posts: 38
Karma: 10
Join Date: Nov 2009
Location: Poland
Device: kindle 1st gen, kindle dxg, kindle paperwhite2
|
|
![]() |
![]() |
![]() |
#9 |
Enthusiast
![]() 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 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 |
![]() |
![]() |
![]() |
#10 |
Sigil & calibre developer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 2,487
Karma: 1063785
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() |
![]() |
![]() |
![]() |
Thread Tools | Search this Thread |
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
[GUI Plugin] Plugin Updater **Deprecated** | kiwidude | Plugins | 159 | 06-19-2011 12:27 PM |
Removal of plugin not removing config store | meme | Plugins | 4 | 02-01-2011 04:45 PM |
New Plugin Type Idea: Library Plugin | cgranade | Plugins | 3 | 09-15-2010 12:11 PM |
I can log on to Sony Store, but I can't access the Store | Dr. Drib | Sony Reader | 3 | 04-11-2009 09:05 AM |