Commit 655fe75d authored by Philip Withnall's avatar Philip Withnall

Added basic support for listing channels and categories asynchronously

parent c23ad344
# -*- coding: utf-8 -*-
import totem import totem
import gobject import gobject
import gtk import gtk
import iplayer2
import threading
class IplayerPlugin (totem.Plugin): class IplayerPlugin (totem.Plugin):
def __init__(self): def __init__ (self):
totem.Plugin.__init__ (self) totem.Plugin.__init__ (self)
self.debug = True self.debug = True
self.totem = None self.totem = None
def activate (self, totem_object): def activate (self, totem_object):
# Build the interface # Build the interface
self.builder = self.load_interface ("iplayer.ui", True, totem_object.get_main_window (), self) builder = self.load_interface ("iplayer.ui", True, totem_object.get_main_window (), self)
container = self.builder.get_object ('iplayer_vbox') container = builder.get_object ('iplayer_vbox')
self.tree_store = builder.get_object ('iplayer_programme_store')
self.totem = totem_object self.totem = totem_object
container.show_all () container.show_all ()
self.totem.add_sidebar_page("iplayer", _("BBC iPlayer"), container) = iplayer2.feed ('tv')
# TODO: Radio support = feed ('radio')
self.totem.add_sidebar_page ("iplayer", _("BBC iPlayer"), container)
self.populate_channel_list ()
def deactivate (self, totem_object): def deactivate (self, totem_object):
totem_object.remove_sidebar_page ("iplayer") totem_object.remove_sidebar_page ("iplayer")
def populate_channel_list (self):
# Add all the channels as top-level rows in the tree store
channels = ()
for channel_id, title in channels.items ():
parent_iter = self.tree_store.append (None, [title, channel_id, None])
# Add the channels' categories in a thread, since they each require a network request
parent_path = self.tree_store.get_path (parent_iter)
thread = PopulateChannelsThread (self, parent_path,, self.tree_store)
thread.start ()
def _populate_channel_list_cb (self, parent_path, values):
# Callback from PopulateChannelsThread to add stuff to the tree store
parent_iter = self.tree_store.get_iter (parent_path)
self.tree_store.append (parent_iter, values)
return False
class PopulateChannelsThread (threading.Thread):
# Class to populate the channel list from the Internet
def __init__ (self, plugin, parent_path, feed, tree_model):
self.plugin = plugin
self.feed = feed
self.tree_model = tree_model
threading.Thread.__init__ (self)
def run (self):
tree_iter = self.tree_model.get_iter_first ()
while (tree_iter != None):
channel_id = self.tree_model.get_value (tree_iter, 1)
parent_path = self.tree_model.get_path (tree_iter)
# Add this channel's categories as sub-rows
# We have to pass a path because the model could theoretically be modified
# while the idle function is waiting in the queue, invalidating an iter
for name, category_id in self.feed.get (channel_id).categories ():
gobject.idle_add (self.plugin._populate_channel_list_cb, parent_path, [name, category_id, None])
tree_iter = self.tree_model.iter_next (tree_iter)
<?xml version="1.0"?> <?xml version="1.0"?>
<!--*- mode: xml -*--> <!--*- mode: xml -*-->
<interface> <interface>
<object class="GtkListStore" id="iplayer_programme_list_store"> <object class="GtkTreeStore" id="iplayer_programme_store">
<columns> <columns>
<column type="GdkPixbuf"/><!--Thumbnail-->
<column type="gchararray"/><!--Title--> <column type="gchararray"/><!--Title-->
<column type="gchararray"/><!--Summary-->
<column type="gchararray"/><!--MRL--> <column type="gchararray"/><!--MRL-->
<column type="GObject"/><!--Video entry; TODO: should be GDataYouTubeVideo, see bug #576285-->
</columns> </columns>
</object> </object>
...@@ -14,5 +13,28 @@ ...@@ -14,5 +13,28 @@
<property name="border-width">5</property> <property name="border-width">5</property>
<property name="homogeneous">False</property> <property name="homogeneous">False</property>
<property name="spacing">6</property> <property name="spacing">6</property>
<object class="GtkScrolledWindow" id="iplayer_scrolled_window">
<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
<object class="GtkTreeView" id="iplayer_programme_list">
<property name="model">iplayer_programme_store</property>
<property name="expander-column">iplayer_title_column</property>
<property name="headers-visible">False</property>
<object class="GtkTreeViewColumn" id="iplayer_title_column">
<object class="GtkCellRendererText" id="iplayer_title_cell_renderer"/>
<attribute name="text">0</attribute>
</object> </object>
</interface> </interface>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment