========================= Mitter Hacking Guidelines ========================= First of all, Mitter is a Python project and it tries to follow PEP8_ as close as possible. Sometimes we fail, but we try to adhere to it as much as possible. The Google Guidelines_ for Python are a good summary about it, although we don't follow all their recommendations: - We use PyFlakes instead of Pychecker. PyFlakes seems to be better in finding unused imports. As usual, some files don't adhere to it, mostly helper tools (Sphinx and the helper PEP8 checker, for example.) - Exceptions do not start with an Error class. Each module should have its own Exception, e.g. NetworkError and all other exceptions should use that as base, e.g. :: class UnreachableNetworkError(NetworkError): - Function parameters do not need to follow the break lines pointed, but must follow the 80 columns rule. Also, other rules we follow: - All string formating must have the variables in parenthesis. In this case, this is wrong:: text = '%d characters' % count this is right:: text = '%d characters' % (count) - Unless it's a work in progress, do not leave code commented (or, worse yet, inside a ``if 0:`` block.) If it's a WIP, be sure to comment what it is (e.g. "Working on issue #X" or "Trying to make the field count properly".) Documentation ============= All documentation (including this file!) follows the Sphinx_ format (ReSTructured_ format). This includes docstrings and external files. Creating Interfaces =================== There is a couple of things you should take care when creating your own interface. Naming and Location ------------------- Your file must have the prefix "ui\_". It must be installed in the ``mitterlib/ui`` directory. class Interface --------------- Inside your module, there should be at least one class called ``Interface``. It may inherit any other class (or ``object`` in case you don't need anything). __init__(self, connection, options) ----------------------------------- The initialization will receive two parameters: - connection: the network connection. Your interface will request any network data with that object. You can check the ``Networks`` object in the ``mitterlib/network/__init__.py`` for methods there (or read the Sphinx documentation generated about it.) - options: It's a ConfigOpt_ object, with all your interface options. Use it for EVERTYHING that you'd hardcode. __call__(self) -------------- Once Mitter have everything set up, it will call your interface. ``__call__`` is to interfaces as ``run()`` is to threads. options(self, options) ---------------------- ``options`` is a ``@classmethod`` called by Mitter on the setting up phase to populate the interface options. To add an option, use the ``add_option``; if your interface don't have any options, simply return. Again, refer to the ConfigOpt_ documentation on how to use it. NAMESPACE --------- The namespace is a class variable used to identify the name of the network. It should also be used in the config as the group name. Creating Networks ================= Naming and Location ------------------- Network reside in the ``mitterlib/network`` directory. Contrary to interfaces, it doesn't require any special prefixes. Base Class ---------- All networks must inherit from the :class:`NetworkBase` object, in the module ``networkbase``. There is a couple of method you should implement in case you want it to return any data. If the network doesn't support some functionality (e.g. reposts), simply don't declare the function. :class:`NetworkBase` offers good defaults to all functions (basically, returning nothing.) class Connection ---------------- Inside your module, you should have at least once class called ``Connection``. As pointed before, it should inherit from the :class:`NetworkBase` clas. Base Return Object ------------------ Most functions will return a :class:`NetworkData` object. It offers an unified data format for every interface, so they don't need to worry about each network data. It is wise to create your own :class:`NetworkData`, inheriting from it, with its own ``__init__`` and setting the properties. Proxy support ------------- Mitter supports proxies. Its value is in the configuration manager, in the ``NetworkManager`` section, ``proxy`` value. The network manager itself will install a urllib2 proxy handler, so you don't need to worry about manually installing a handler yourself if you use urllib2. NAMESPACE --------- The namespace is a class variable used to name the interface. It's also used in the ``--interface`` so the user can name the interfaces they want. PRIORITY -------- Interface priority, as a class variable. It's used by the interface manager to select an interface in case the user doesn't have one. The higher this value, the higher the priority. Be sure to put interfaces with more dependencies with higher priorities, as those should be, in theory, more full featured. Mixing It All ============= Creating New Elements --------------------- In case you want to display/add a new element on your interface, you need to add the element in :class:`NetworkData` with a default that represents it better (for boolean values, set it to False; strings to ''; numbers to 0 or 0.0). Once your element is there, you can add it in the networks (do not ignore other networks that may use that information!) and then, finally, use it on your interface. Creating New Request -------------------- If you want to add a new functionality in the interfaces, you need do to a couple of steps: - First of all, you need to add the method in the :class:`Networks`. Remember that this is the class that the interfaces receive to do all the other calls. If the function doesn't exist there, it won't be call it at all. - Once the function is available to be called, you need to make it available to the networks. For this, add the function in :class:`NetworkBase` module, so calling it on networks that don't have that method defined yet will still work. In this point, it should return some sort of empty value (empty list, None). - Finally, add the function on your network. Follow the same name in the :class:`NetworkBase` and you should be fine. Developer Discussion ==================== Mitter have an open developer discussion maillist. Join us on Mitter-Dev_ if you have any suggestions/patches/questions. (We had a massive problem with spammers in the recent days, so the list is currently moderated. Your first message needs to be approved and, after that, everything should be fine.) Souce Code Repository ===================== Mitter uses Git for SCM and Gitorious to host it. You can check the Mitter_ project there, clone it and hack away! ;) .. _PEP8: http://www.python.org/dev/peps/pep-0008/ .. _Guidelines: http://google-styleguide.googlecode.com/svn/trunk/pyguide.html .. _Sphinx: http://sphinx.pocoo.org/ .. _ReSTRuctured: http://docutils.sourceforge.net/docs/user/rst/quickref.html .. _ConfigOpt: http://deadbraincells.org/configopt/docs/configopt.html .. _Mitter-Dev: http://groups.google.com/group/mitter-dev/ .. _Mitter: http://gitorious.org/projects/mitter