diff --git a/manual/creating_plugins.rst b/manual/creating_plugins.rst index c3f1202365..a5b5c8be0c 100644 --- a/manual/creating_plugins.rst +++ b/manual/creating_plugins.rst @@ -15,7 +15,7 @@ Here, we will teach you how to create your own plugins to add new features to |a :depth: 2 :local: -.. note:: This only applies to calibre releases >= 0.7.53 +.. note:: This only applies to calibre releases >= 0.8.60 Anatomy of a |app| plugin --------------------------- @@ -32,11 +32,15 @@ and enter the following Python code into it: .. literalinclude:: plugin_examples/helloworld/__init__.py :lines: 10- -That's all. To add this code to |app| as a plugin, simply create a zip file with:: +That's all. To add this code to |app| as a plugin, simply run the following in +the directory in which you created :file:`__init__.py`:: - zip plugin.zip __init__.py + calibre-customize -b . -Add this plugin to |app| via :guilabel:`Preferences->Plugins`. +.. note:: + On OS X you have to first install the |app| command line tools, by + going to :guilabel:`Preferences->Miscellaneous` and clicking the + :guilabel:`Install command line tools` button. You can download the Hello World plugin from `helloworld_plugin.zip `_. @@ -191,14 +195,12 @@ When running from the command line, debug output will be printed to the console, You can insert print statements anywhere in your plugin code, they will be output in debug mode. Remember, this is python, you really shouldn't need anything more than print statements to debug ;) I developed all of |app| using just this debugging technique. -It can get tiresome to keep re-adding a plugin to calibre to test small changes. The plugin zip files are stored in the calibre config directory in plugins/ (goto Preferences->Misc and click open config directory to see the config directory). +You can quickly test changes to your plugin by using the following command +line:: -Once you've located the zip file of your plugin you can then directly update it with your changes instead of re-adding it each time. To do so from the command line, in the directory that contains your plugin source code, use:: + calibre -s; calibre-customize -b /path/to/your/plugin/directory; calibre - calibre -s; zip -r /path/to/plugin/zip/file.zip *; calibre - -This will shutdown a running calibre. Wait for the shutdown to complete, then update your plugin files and relaunch calibre. -It relies on the freely available zip command line tool. +This will shutdown a running calibre, wait for the shutdown to complete, then update your plugin in |app| and relaunch |app|. More plugin examples ---------------------- diff --git a/recipes/onda_rock.recipe b/recipes/onda_rock.recipe index 72e93088f2..ec243a35ab 100644 --- a/recipes/onda_rock.recipe +++ b/recipes/onda_rock.recipe @@ -1,21 +1,27 @@ __license__ = 'GPL v3' +__author__ = 'faber1971' +description = 'Italian rock webzine - v1.01 (6, July 2012)' from calibre.web.feeds.news import BasicNewsRecipe - class AdvancedUserRecipe1328535130(BasicNewsRecipe): title = u'Onda Rock' __author__ = 'faber1971' description = 'Italian rock webzine' language = 'it' - - - oldest_article = 7 + oldest_article = 15 max_articles_per_feed = 100 auto_cleanup = False remove_tags = [ - dict(name='div', attrs={'id':['boxHeader','boxlinks_med','footer','boxinterviste','box_special_med','boxdiscografia_head','path']}), + dict(name='div', attrs={'id':['boxHeader','boxlinks_med','footer','boxinterviste','box_special_med','boxdiscografia_head','path','widget','menuarea','headerarea']}), dict(name='div', attrs={'align':'left'}), + dict(name='div', attrs={'class':['media','boxarticoli']}), dict(name='div', attrs={'style':'text-align: center'}), + dict(name='table', attrs={'cellpadding':'0'}), + dict(name='span', attrs={'class':'liketext'}), ] no_stylesheets = True feeds = [(u'Onda Rock', u'http://www.ondarock.it/feed.php')] - masthead_url = 'http://profile.ak.fbcdn.net/hprofile-ak-snc4/71135_45820579767_4993043_n.jpg' + masthead_url = 'http://api.ning.com/files/4ot8ampp*-rYQuwL2NoaHvVqcyu7VMyWyan12a9QMsJUWxk-q5V1-34wnD-Wj9B5qWjc1yPMLGiwQg8hZJxaySeaG2lx8hpV/2009_banner_ondarock.gif' + + extra_css = ''' + .boxtabscontain_page {border: 1px solid #E0E0E0;clear: both;font-family: "Verdana", "Arial", "Helvetica", sans-serif;font-size: 10px;line-height: 17px;margin: 0px 0px 20px;padding: 10px 10px 10px 40px;position: relative;top: -1px;width: 258px;z-index: 1;} + ''' diff --git a/src/calibre/customize/ui.py b/src/calibre/customize/ui.py index 8dd4e37bfa..9b750d2f7d 100644 --- a/src/calibre/customize/ui.py +++ b/src/calibre/customize/ui.py @@ -555,6 +555,23 @@ def initialized_plugins(): # CLI {{{ +def build_plugin(path): + from calibre import prints + from calibre.ptempfile import PersistentTemporaryFile + from calibre.utils.zipfile import ZipFile, ZIP_STORED + path = type(u'')(path) + names = frozenset(os.listdir(path)) + if u'__init__.py' not in names: + prints(path, ' is not a valid plugin') + raise SystemExit(1) + t = PersistentTemporaryFile(u'.zip') + with ZipFile(t, u'w', ZIP_STORED) as zf: + zf.add_dir(path) + t.close() + plugin = add_plugin(t.name) + os.remove(t.name) + prints(u'Plugin updated:', plugin.name, plugin.version) + def option_parser(): parser = OptionParser(usage=_('''\ %prog options @@ -563,6 +580,10 @@ def option_parser(): ''')) parser.add_option('-a', '--add-plugin', default=None, help=_('Add a plugin by specifying the path to the zip file containing it.')) + parser.add_option('-b', '--build-plugin', default=None, + help=_('For plugin developers: Path to the directory where you are' + ' developing the plugin. This command will automatically zip ' + 'up the plugin and update it in calibre.')) parser.add_option('-r', '--remove-plugin', default=None, help=_('Remove a custom plugin by name. Has no effect on builtin plugins')) parser.add_option('--customize-plugin', default=None, @@ -584,6 +605,8 @@ def main(args=sys.argv): if opts.add_plugin is not None: plugin = add_plugin(opts.add_plugin) print 'Plugin added:', plugin.name, plugin.version + if opts.build_plugin is not None: + build_plugin(opts.build_plugin) if opts.remove_plugin is not None: if remove_plugin(opts.remove_plugin): print 'Plugin removed'