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