This document describes Moovida’s internals and its development process. It is targeted at people interested in contributing to Moovida and writing plugins for it.
The current version of this document is available in the file elisa-core/docs/developers_guide.rst in the source tree.
Moovida needs a set of dependencies to run. If you already have it running you can skip to Getting the Source Code.
Required dependencies:
Optional dependencies:
Moovida developers use the Bazaar distributed version control system to publish and share the source code. The main line of code is hosted on Launchpad. In order to retrieve it you will need to have Bazaar installed on your system (see Bazaar download page). For more information on how to use Bazaar please refer to the official Bazaar tutorial.
On the command-line type the following to download the main development branch:
$ bzr branch lp:moovida
That will create a directory called moovida containing the latest version of the source code of Moovida. Depending on your Internet connection that might take a while; as of today this process downloads over 80MB of data.
Note
Moovida used to be called Elisa prior to June 2009. While the renaming was effective in most relevant places, some references to Elisa still remain, notably in the source code where the Python modules are still using the elisa namespaces.
Go into the directory where the source code was downloaded:
$ cd moovida
Append Moovida’s python modules to the PYTHONPATH environment variable:
$ export PYTHONPATH=$PWD/elisa-core:$PWD/elisa-plugins:$PYTHONPATH
Launch Moovida:
$ python elisa-core/bin/moovida
You should now have Moovida’s splash screen appearing and soon a fullscreen Moovida showing up. Congratulations!
To exit, press the ALT+F4 key combination, or alternatively press the ESC key and click the close button of the window.
Warning
If you have installed Moovida on your system previously, you need to uninstall it otherwise the development version will not work properly.
This is a bug that will be fixed; you can follow its progress there: https://bugs.launchpad.net/moovida/+bug/255739
Warning
This section is a work in progress. It lacks a how to download and launch the SDK. Reuse http://www.moovida.com/wiki/TipsAndTricks/HackOnWindows
The first thing to do before setting yourself to hack on Moovida is installing it on your computer. Instructions are available on the website’s download page.
Moovida’s architecture aims to make adding new features very easy. To achieve that goal, it is designed to be as modular as possible and many modules are meant to be extensible, that is, new functionalities can be added to them and distributed without being included in the core thus favoring participation external to the core developers and designers.
Moovida’s API reference is available on the website and can be built from the source tree using the script elisa-core/builddoc.py.
Moovida uses the following main technologies:
Warning
This section is a work in progress.
Moovida is divided into its core contained in elisa-core/elisa/core and its default plugins elisa-plugins/elisa/plugins. Be it the core or the plugins they all provide facilities freely accessible from any piece of code.
The elisa.core.application.Application object is the main entry point of Moovida. All the necessary components for Moovida to run are accessible from there.
To retrieve a reference to the global instance from anywhere in the code:
from elisa.core.common import application
It holds a reference to the following objects:
Warning
This section is a work in progress. It lacks explanation about:
Moovida’s user interface code design strives to make easy the following tasks:
- adding new features without the burden of writing graphical user interface code.
- writing innovative, clean and appealing graphical user interface.
- changing the appearance of existing graphical user interface (layout, icons, animations, etc.) without modifying it.
- displaying differently the information without changing the way it is generated or retrieved
- keeping a high level of visual and ergonomics consistency accross the whole interface
Moovida’s user interface is created by controller objects. A controller roughly corresponds to one screen of the user interface. It is in charge of pulling data, displaying it and reacting to user input.
The default user interface uses the Pigment toolkit for its rendering which in turn uses OpenGL taking full advantage of modern computer graphics. A library of widgets is available on top of Pigment in a Moovida plugin: elisa.plugins.pigment.widgets.
The default user interface is contained in a plugin (elisa.plugins.poblesec) and defines standard controllers that can be reused as-is thus avoiding UI code re-write and encouraging consistency which is critical to keeping the learning curve shallow for users. For example:
Note
Controllers can be decorated, that is, their behaviour, appearance and content can be altered by decorators. Decorators are Python functions that take as only parameter the controller they decorate and are called whenever their corresponding controller is instantiated. This allows a plugin to modify the user interface at will.
Warning
This section is a work in progress.
Data in Moovida can be retrieved through components called resource providers.
A resource provider provides access to resources via a REST API (GET/POST/PUT/DELETE methods, see Roy Fielding’s thesis for a detailed description of the principles of REST).
Resources are uniquely identified by their URI.
Resource providers are never used directly: they are hidden behind the resource manager that acts as a proxy. The resource manager knows of all the resource providers and is responsible for forwarding a query to the correct provider, and forwarding back the response to the client code. For the resource manager to be able to dispatch the queries, resource providers define all the types of URIs they can handle in the form of a regular expression.
The most basic query is the GET one. Given a URI, it returns a representation of the associated resource. In Moovida, resources are represented using models.
Warning
This section is a work in progress.
Please consult:
Warning
This section is a work in progress.
Warning
This section is a work in progress.
Warning
This section is a work in progress.
Warning
This section is a work in progress.
All user input in Moovida is handled received by elisa.core.components.input_provider.InputProvider objects which send these input events encapsulated into elisa.core.input_event.InputEvent instances to the input manager.
Every input provider implements a specific input protocol (e.g.: keyboard input using Pigment, remote control via LIRC, etc.).
Warning
This section is a work in progress.
Warning
This section is a work in progress.
By default all of Moovida’s code is executed in one thread referred to as the main thread. User input processing, networking are examples of operations that are dealt with in the main thread.
An essential point of Moovida is to provide a reactive user interface which never blocks and always answers the user’s requests. In order to achieve that, all method calls for which the return might not be fast enough (e.g. a long computation, retrieving data from the Internet, generating a thumbnail, etc.) have to be made non-blocking. A few techniques exist to do so:
In either case Moovida uses Twisted’s deferred object to handle delayed returns. Extensive explanation and examples explaining the concept exist at:
In short, a deferred is a promise that a function will at some point have a result.
Note
Some background threads exist that one does not need to be aware of:
Apart from direct method calls, two messaging systems are used in Moovida:
Communication to the core components should use method calls as much as possible when it’s for 1 to 1 communication. In other cases, the following rules can help choosing between a bus message and a signal:
It is important to remember that the messages on the bus are dispatched in the main thread whereas signal emissions are done in the calling thread.
Moovida provides a logging framework allowing the addition of debugging, error and informative messages. It is useful for visualizing at what is happening behind the scenes at runtime without having to modify the code.
In order to use it the class where you want to add such logging must inherit from elisa.core.log.Loggable The core classes of Moovida already inherit from it. It provides with 5 new methods corresponding to the 5 logging levels:
When launching Moovida it is then possible to filter what messages should be outputted using 2 different criteria:
This is achieved via the ELISA_DEBUG environment variable.
Logging levels are incremental: if you want to view messages from one level, say the LOG (5) level, you will also see the messages from all the levels below, in that case DEBUG (4), INFO (3), WARNING (2) and ERROR (1).
Examples:
# LOG level output (very verbose)
$ ELISA_DEBUG=5 moovida
# DEBUG level output
$ ELISA_DEBUG=4 moovida
You can filter messages by class/category as well:
# let's DEBUG the media_manager
$ ELISA_DEBUG="resource_manager:5" moovida
# let's see application INFO and config DEBUG
$ ELISA_DEBUG="application:3,config:5" moovida
As you may have guessed syntax is the following:
ELISA_DEBUG="log_category:integer[,...]"
log_category is the name of the class ‘’uncamelified’’ that is transformed to have the capital letters uncapitalized and with an ‘_’ between the words.
Example:
ResourceManager becomes 'resource_manager'
BrowserController becomes 'browser_controller'
This default can be overriden by setting a value to the class variable log_category.
integer is the logging level from 1 to 5.
Note
Messages are by default displayed on the standard error output.
Warning
This section is a work in progress.
It requires an import of the information located at http://www.moovida.com/wiki/I18nIssues
Before starting developing a plugin you should of course have Moovida running on your computer. In order to retrieve the latest development version please follow the instructions from the Getting Started section.
An example plugin has been designed to facilitate writing a new plugin. It illustrates how to implement Moovida functionalities often used in plugins, for example how to display data in a list, how to play media files, how to display informative messages, etc. Also creating a plugin requires writing a small amount of boilerplate code. As no one likes to write boilerplate code over and over, the example plugin can be used as a base by plugin writers eager to get their plugin working.
The example plugin is available as a zip file at the following URL:
http://www.moovida.com/documentation/developers_guide/moovida_example_plugin.zip
If you prefer to use the Bazaar version control system the example can also be found in the following repository:
lp:~moovida-developers/moovida/example-plugin/
Please refer to the README.txt file inside it to run it and understand its structure.
In order to personalize the example plugin to your needs you will need to change the name, description, long_description, author and author_email fields of the setup.py file.
In order to ensure a high visual quality, a high degree of usability and reliability, relevant guidelines have been crafted for plugin writers to follow.
In order to publish a plugin you will need to provide a ‘.egg’ file stored on a publicly accessible server. Advanced users can then copy that file to their $HOME/.moovida/plugins directory to use it.
The ‘.egg’ file contains everything needed for your plugin to run. To generate it from the command-line go to the example plugin’s directory and type the following:
$ python setup.py bdist_egg
That will create the ‘.egg’ file which name starts with your plugin’s name in the dist directory.
If you wish your plugin to be installable from within the user interface of Moovida ('PLUGINS' > 'Available Plugins' section) it is required to send a request via e-mail to the Moovida developers at developers-list@moovida.com Please subscribe to it prior to sending the request using the registration form. A review of the plugin will be performed and guidance provided if needed. Once accepted it will appear immediately to all Moovida users.
Note
To distribute a plugin it is recommended to create a new project in Launchpad. To do so go to the ‘Register a Project’ page. All Moovida plugins follow the same convention: their name starts with “elisa-plugin-“. For example, the plugin for browsing movie trailers is called “elisa-plugin-movie-trailers” and is located at the following address: http://launchpad.net/elisa-plugin-movie-trailers
Once done it is also recommended to register your project in the Moovida Universe on Launchpad that regroups all the Moovida plugins.
Warning
This section is a work in progress:
The following explains how to:
Go into your plugin directory and create an empty i18n python package:
cd elisa-plugins/elisa/plugins/myplugin
mkdir i18n
touch i18n/__init__.py
This package will contain:
Edit your setup.py file, in the setup() function, update (or add) the package_data parameter like shown below:
setup(name='elisa-plugin-myplugin',
...
package_data={'elisa.plugins.myplugin.i18n':
['*.po', '*/LC_MESSAGES/*.mo', '*.pot'],
},
...)
Hence, the plugin tarball will contain the .po files supplied by the translators, the .pot template and the compiled .mo files.
Go in your plugin directory and create the i18n/messages.pot file:
cd elisa-plugins/elisa/plugins/myplugin
Check that you have the setup.cfg file similar to the one in elisa/plugins/skeleton/basic and that you have updated it with your plugin name, copyright and email information and run:
PYTHONPATH=../../../../elisa-core python setup.py pot_update
That’s it! Translators can now reuse the elisa-plugin-myplugin.pot template to start new translations of the plugin. See Localising a plugin below
Every time the developer adds/updates translatable strings in their code, the .pot template should be updated, at least.
Launchpad has a great tool to allow translations of your own project called Rosetta. You can use the Moovida translation project in Rosetta to host translations for your plugin. This way users translating Moovida core will also see your project and will be able to translate it in a streamlined process. Just use the ‘upload’ feature of Rosetta to put all current files in the system.
If you don’t want to host the translations in the Moovida project, you have followed the above instructions and have a project registered on Launchpad you can easily set it up for translations and automatic imports from Bazaar branches. Rosetta will then pick up all changes to the translation templates.
Now you will only need to download new translations and commit them to your branch from time to time. Also you will have to upload the template file whenever there are new or updated strings. It is advised to only commit and use complete translations (as in 100% complete), as having a mixed-language interface is the worst case scenario. Remember - using Moovida’s core translation project will probably speed up translation of your plugin as the translators will not have to jump through hoops to find all projects available for translation.
Warning
This section is a work in progress:
The following explains how to make a new translation for the existing plugin ‘elisa-plugin-myplugin’. The language we want to translate to is French - ‘fr’ (only use xx_YY locale notation if YY is not uppercase xx, i.e. it is a certain dialect, like ‘pt_BR’ for Brazilian Portuguese). We assume the plugin has already been internationalized and has an i18n directory already.
There are currently 2 supported ways to translate a plugin:
This is the only supported approach for Moovida core plugins and also recommended for external plugins as it greatly simplifies the whole process. All of Moovida’s core is handled in Rosetta and we are trying to get as much external plugins in there as well. To start translating, simply log in to Rosetta, set your languages in your profile, select the plugin you want to translate and that’s it! We will pick up new translations as soon as possible.
This approach uses Edgewall’s Babel, integrated into Moovida’s i18n tools. It is useful if a plugin is not handled in Rosetta and the author will accept i18n patches.
Go in the plugin directory and initialize a new catalog for the locale:
$ cd elisa-plugins/elisa/plugins/myplugin
$ PYTHONPATH=../../../../elisa-core/ python setup.py init_catalog \
--output i18n/fr.po --locale fr
This will create a i18n/fr.po file. You can use a tool like poedit to translate the strings inside, or do it manually (not recommended).
Go in the plugin directory and compile the previously created catalogs:
$ cd elisa-plugins/elisa/plugins/myplugin
$ PYTHONPATH=../../../../elisa-core/ python setup.py build_po
This command will compile all the .po files it will find in the plugin’s i18n directory.
If the plugin developers add new strings to translate in their code, it is their responsability to update the po template file, usually located in i18n/elisa-plugin-myplugin.pot.
If the po template file has been updated, the po files need to be updated too, so that it’s possible to translate the new or updated strings:
$ cd elisa-plugins/elisa/plugins/myplugin
$ PYTHONPATH=../../../../elisa-core/ python setup.py update_catalog \
--output i18n/fr.po --locale fr
If the –locale argument is not supplied, Babel will update all the .po files it will be able to find in the current directory.
Once new strings have been translated, the po file can be compiled to a mo file as described in the Compile the po file to a mo file section.
Social Aspects¶
Communication Among the Community¶
If you wish to discuss ideas, ask questions, get involved or simply observe the Moovida community, a set of communication means are at your disposal:
Current Development¶
Moovida’s development is largely published via its Launchpad project page.
You will find there a list of features and items that are being thought about or worked on in the list of blueprints.
It is also the place to report bugs and problems you might encounter. Up to date instructions as how to do this can be found on Moovida’s website.
Releases¶
Warning
This section is a work in progress.
A release of Moovida is made public every month ensuring a regular stream of improvements for our users.
The release procedure is available in the file elisa-core/docs/release_procedure.rst.
Submitting Code¶
All code changes coming in to Moovida’s core are reviewed by a core contributor. Code reviews happen on the Moovida merges mailing list. If you wish to have code you wrote added to Moovida’s codebase please follow these steps:
$ bzr branch lp:moovida$ bzr diff > my_changes.patchSubscribe to the merges mailing list.
Send an e-mail to the list explaining the purpose of the change. Don’t forget to attach your patch. The subject must start with ‘[MERGE]’. See the following e-mail example:
A core contributor will get back to you with a vote. There are three possible outcomes:
Guidance and advice will be provided in all cases explaining what the next steps are to go forward.
Please detail the merge request e-mail well including:
Note
Good reviews take time. They also regularly require a solid understanding of the overall code base. In practice, this means a small number of people often have a large review burden.
Once submitted, the merge request is tracked by the Bundle Buggy system letting you know about its current status.
The following, noncomprehensive checklist can help smoothening the process by ensuring high quality code submission and reviews. Before submitting the merge request please make sure that:
Coding Style Guidelines¶
General Rules¶
Moovida’s developers stick with official Python recommendations:
Doctring format in Moovida follows the epytext markup language. This format makes the generation of pretty API documentation very easy.
A few extra rules specific to Moovida apply:
Naming Conventions¶
Licensing¶
Moovida is free software. Its core is dual-licensed under the GPLv3 and Fluendo’s proprietary license.
In order to make sure that all of our copyrights can meet the recordkeeping, in order to dual license Moovida’s code and in order to be able to enforce the licenses most effectively, it is required that each author of code shipped with Moovida provides a copyright assignment. It grants back to the author a perpetual right to use, modify, and distribute his/her code and ensures that it will always be made available under the terms of the GNU Public License.
This is common practice in many open-source projects. The Free Sofware Foundation with the GNU project, Sun Microsystems, the Apache Software Foundation among others follow this rule.
Moovida’s copyright assignment form can be downloaded from there.