diff options
Diffstat (limited to 'docs/write_addons.rst')
-rw-r--r-- | docs/write_addons.rst | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/docs/write_addons.rst b/docs/write_addons.rst new file mode 100644 index 000000000..9f4436cc5 --- /dev/null +++ b/docs/write_addons.rst @@ -0,0 +1,158 @@ +.. _write_addons: + +Addons +====== + +A Addon is a python file which is located at :file:`pyload/plugin/addon`. +The :class:`AddonManager <pyload.manager.Addon.AddonManager>` will load it automatically on startup. Only one instance exists +over the complete lifetime of pyload. Your addon can interact on various events called by the :class:`AddonManager <pyload.manager.Addon.AddonManager>`, +do something complete autonomic and has full access to the :class:`Api <pyload.api.Api>` and every detail of pyLoad. +The UpdateManager, CaptchaTrader, UnRar and many more are realised as addon. + +Addon header +----------- + +Your addon needs to subclass :class:`Addon <pyload.plugin.Addon.Addon>` and will inherit all of its method, make sure to check its documentation! + +All addons should start with something like this: :: + + from pyload.plugin.Addon import Addon + + class YourAddon(Addon): + __name = "YourAddon" + __version = "0.1" + __description = "Does really cool stuff" + __config = [ ("activated" , "bool" , "Activated" , "True" ) ] + __author_name__ = ("Me") + __author_mail__ = ("me@has-no-mail.com") + +All meta-data is defined in the header, you need at least one option at ``__config`` so the user can toggle your +addon on and off. Dont't overwrite the ``init`` method if not neccesary, use ``setup`` instead. + +Using the Config +---------------- + +We are taking a closer look at the ``__config`` parameter. +You can add more config values as desired by adding tuples of the following format to the config list: ``("name", "type", "description", "default value")``. +When everything went right you can access the config values with ``self.getConfig(name)`` and ``self.setConfig(name, value``. + + +Interacting on Events +--------------------- + +The next step is to think about where your Addon action takes places. + +The easiest way is to overwrite specific methods defined by the :class:`Addon <pyload.plugin.Addon.Addon>` base class. +The name is indicating when the function gets called. +See :class:`Addon <pyload.plugin.Addon.Addon>` page for a complete listing. + +You should be aware of the arguments the Addon is called with, whether its a :class:`PyFile <pyload.datatype.File.PyFile>` +or :class:`PyPackage <pyload.datatype.Package.PyPackage>` you should read its related documentation to know how to access her great power and manipulate them. + +A basic excerpt would look like: :: + + from pyload.plugin.Addon import Addon + + class YourAddon(Addon): + """ + Your Addon code here. + """ + + def activate(self): + print "Yay, the core is ready let's do some work." + + def downloadFinished(self, pyfile): + print "A Download just finished." + +Another and more flexible and powerful way is to use event listener. +All addon methods exists as event and very useful additional events are dispatched by the core. For a little overview look +at :class:`AddonManager <pyload.manager.Addon.AddonManager>`. Keep in mind that you can define own events and other people may listen on them. + +For your convenience it's possible to register listeners automatical via the ``event_map`` attribute. +It requires a `dict` that maps event names to function names or a `list` of function names. It's important that all names are strings :: + + from pyload.plugin.Addon import Addon + + class YourAddon(Addon): + """ + Your Addon code here. + """ + event_map = {'downloadFinished': "doSomeWork", + 'allDownloadsFnished': "someMethod", + 'activate': "initialize"} + + def initialize(self): + print "Initialized." + + def doSomeWork(self, pyfile): + print "This is equivalent to the above example." + + def someMethod(self): + print "The underlying event (allDownloadsFinished) for this method is not available through the base class" + +An advantage of the event listener is that you are able to register and remove the listeners at runtime. +Use `self.manager.addEvent("name", function)`, `self.manager.removeEvent("name", function)` and see doc for +:class:`AddonManager <pyload.manager.Addon.AddonManager>`. Contrary to ``event_map``, ``function`` has to be a reference +and **not** a `string`. + +We introduced events because it scales better if there a a huge amount of events and addons. So all future interaction will be exclusive +available as event and not accessible through overwriting addon methods. However you can safely do this, it will not be removed and is easier to implement. + + +Providing RPC services +---------------------- + +You may noticed that pyLoad has an :class:`Api <pyload.api.Api>`, which can be used internal or called by clients via RPC. +So probably clients want to be able to interact with your addon to request it's state or invoke some action. + +Sounds complicated but is very easy to do. Just use the ``Expose`` decorator: :: + + from pyload.plugin.Addon import Addon, Expose + + class YourAddon(Addon): + """ + Your Addon code here. + """ + + @Expose + def invoke(self, arg): + print "Invoked with", arg + +Thats all, it's available via the :class:`Api <pyload.api.Api>` now. If you want to use it read :ref:`access_api`. +Here is a basic example: :: + + #Assuming client is a ThriftClient or Api object + + print client.getServices() + print client.call(ServiceCall("YourAddon", "invoke", "an argument")) + +Providing status information +---------------------------- +Your addon can store information in a ``dict`` that can easily be retrievied via the :class:`Api <pyload.api.Api>`. + +Just store everything in ``self.info``. :: + + from pyload.plugin.Addon import Addon + + class YourAddon(Addon): + """ + Your Addon code here. + """ + + def setup(self): + self.info = {'running': False} + + def activate(self): + self.info['running'] = True + +Usable with: :: + + #Assuming client is a ThriftClient or Api object + + print client.getAllInfo() + +Example +------- + Sorry but you won't find an example here ;-) + + Look at :file:`pyload/plugin/addon` and you will find plenty examples there. |