← Back to team overview

gtg-user team mailing list archive

Re: First Steps on a plugin

 

Hi Germán,

Am 10.11.2011 01:44, schrieb Germán Gutiérrez:
Izidor, looks like you are the master in this, any helloworld.py
equivalent in backend world?

Unfortunately, there is no well-written documentation or any helloworld. (The feature was still not released).

I recommend you to get

bzr branch lp:~gtg-contributors/gtg/google_tasks

and look at backends for launchpad and google tasks. They are in general very similar although they do different things. (Google Tasks synchronize your tasks, launchpad only imports tasks)

Luca: I was thinking about lowering the barrier for writing a new backend. There is a lot of redundant code for every backend (they are pretty much the same). What about making more high level interface so "user programmer" just provides the minimum of information (authenticate yourself, this is list of remote tasks, add to GTG tasks which you do not have, give me tasks, that has changed or were deleted so I can update them on server) I think it is sufficient to specify only those 3 things and details can be solved by internal, high-level interface. The goal might be to write a brand new, simple backend under 99 lines of code. What do you say? Do you want to work on it at the hackathon on 26th?

A try to make a simple tutorial:

1, create file GTG/backends/backend_yourname.py
2, (optional) put icon of for your backend as data/icons/hicolor/scalable/apps/backend_yourname.png 3, open GTG/backends/backend_yourname.py and some other backend for inspiration 4, You have to include a lot of GTG import statements to get all things you need. 5, Put external library you need. (There might be already python bindings for your service or protocol)
6, Create a new class called Backend, extend PeriodicImportBackend
7, Put description for your backend, e.g.:
    _general_description = {
        GenericBackend.BACKEND_NAME: "backend_gtask",
        GenericBackend.BACKEND_HUMAN_NAME: _("Google Tasks"),
GenericBackend.BACKEND_AUTHORS: ["Madhumitha Viswanathan", "Izidor Matušov"],
        GenericBackend.BACKEND_TYPE: GenericBackend.TYPE_READWRITE,
        GenericBackend.BACKEND_DESCRIPTION:
            _("This backend synchronizes your tasks with the web service "
              "Google Tasks\n\n"
              "Note: This product uses the Google Tasks API but is not "
              "endorsed or certified by Google Tasks"),\
        }

8, Put parameters for your backend (e.g. username, other parameters):
    _static_parameters = {
        "username": { \
            GenericBackend.PARAM_TYPE: GenericBackend.TYPE_STRING, \
GenericBackend.PARAM_DEFAULT_VALUE: "insert your username here"}, \
        "period": { \
            GenericBackend.PARAM_TYPE: GenericBackend.TYPE_INT, \
            GenericBackend.PARAM_DEFAULT_VALUE: 2, },
        "import-bug-tags": { \
            GenericBackend.PARAM_TYPE: GenericBackend.TYPE_BOOL, \
            GenericBackend.PARAM_DEFAULT_VALUE: False}, \
        "tag-with-project-name": { \
            GenericBackend.PARAM_TYPE: GenericBackend.TYPE_BOOL, \
            GenericBackend.PARAM_DEFAULT_VALUE: True}, \
        }

9, in the constructor, call parent's constructor, initilialize pickle file (pickle is used for serialization of data) for sync_engine which keeps relation between local and remote tasks. Initialize internal variables:

    def __init__(self, parameters):
        '''
        See GenericBackend for an explanation of this function.
        Re-loads the saved state of the synchronization
        '''
        super(Backend, self).__init__(parameters)
        #loading the saved state of the synchronization, if any
        self.data_path = os.path.join('backends/launchpad/', \
                                      "sync_engine-" + self.get_id())
        self.sync_engine = self._load_pickled_file(self.data_path, \
                                                   SyncEngine())

10, When an instance of your backend is created and enabled (the user has added new backend, set parameters like username and clicked on "Enable syncing"), initialize() method is called. You can use it to start your authentication.

There is code for storing password in GNOME keyring (if it is not accessible, GTG will forget password after restart) or use authentication procedure of your webservice. (Look at other backends for inspiration)


(hardcore begins)
11, do_periodic_import(): once in while is this function called. Firstly, you fetch all tasks on the remote side. Then you put that task into sync_engine. It automagicaly tells youwhether you should add this task to local GTG, remove it or update it.

Later you ask for a difference between list of your local tasks and list of your remote tasks, and those tasks should be deleted..

12, Test it and polish it :-)

Around this state, you should have about 500 lines of code and a prototype of your backend.

If you want, you can join us on Saturday, November 26 at online hackathon and your questions will be answered in the real time :-)

Please, write down questions you have. We can from our communication put together very first version of how to write your first backend in 13 steps :-)

Izidor


Follow ups

References