Hi João,

See my answers inline. You may find interesting the twisted
documentation about deferreds and callbacks:
http://twistedmatrix.com/projects/core/documentation/howto/defer.html.

Cheers,

Olivier


João Rodrigues wrote:
> Hello, I'm trying to code a plugin for elisa, and I'm trying to
> understand how the youtube plugin works, but I'm having some trouble
> understanding how the HierarchyController works.
> 
> class YoutubeController(HierarchyController):
> 
>    start_uri = MediaUri('http://gdata.youtube.com/feeds/')
> 
>    def initialize(self, videos=None, uri=start_uri):
>        deferred = super(YoutubeController, self).initialize()
>        self.uri = uri
> 
>        ## add_feeds is a callback right? why the (self)? this is a
> callback function, not a class method

This is indeed confusing: the result of the previous callback is passed
to add_feeds, and it just so happens that it's always self. Hence the
name, but it would be clearer if we renamed it "result", or
"controller", or something else.

>        def add_feeds(self):
>            # search
>            self.actions.append(SearchAction(self))
> 
>            feeds_root = 'http://gdata.youtube.com/feeds/api/standardfeeds/'
>            feeds = [(_('Top rated'), 'top_rated'),
>                     (_('Top favorites'), 'top_favorites'),
>                     (_('Most viewed'), 'most_viewed'),
>                     (_('Most popular'), 'most_popular'),
>                     (_('Most recent'), 'most_recent')]
>            feed_models = []
>            for feed in feeds:
>                feed_model = YoutubeVideoFeedModel()
>                feed_model.title = feed[0]
>                feed_model.uri = MediaUri(feeds_root + feed[1])
>                feed_models.append(feed_model)
>            self.model.extend(feed_models)
> 
>            ## and where does this return goes to? And what exactly is it
> returning?

It's just returning self, or "result" if you prefer. The return value is
passed to the next callback in the chain (see twisted documentation on
deferreds).

>            return self
> 
>        ## no (self) on this one?

No, this one is clearer. The result of the previous callback is a
resource, but we need this callback to return self for other callbacks
in the chain to work as expected.

>        def resource_loaded(resource):
>            if isinstance(resource, YoutubeVideoListModel):
>                self.model.extend(resource.videos)
>            return self
> 
>        def load_resource(self):
>            resource, get_deferred =
> application.resource_manager.get(self.uri)
>            return get_deferred
> 
>        def extend_model(self, videos):
>            self.model.extend(videos)
>            return self
> 
>        # A list of videos
>        if videos is not None:
>            deferred.addCallback(extend_model, videos)
>        elif uri == self.start_uri:
>            # List of the feeds
>            deferred.addCallback(add_feeds)
>        else:
>            # One particular feed
>            deferred.addCallback(load_resource)
>            ## shouldn't resource_loaded have 1 argument? (resource)

See the documentation, the return value of the previous callback (here
load_resource) will be passed as parameter to resource_loaded.

>            deferred.addCallback(resource_loaded)
> 
>        return deferred

Reply via email to