[totem] Added (disabled) support for radio channels



commit 5b3ae2f682d8ea88bdcf8e6a5992613030d44e5b
Author: Philip Withnall <philip tecnocode co uk>
Date:   Sun Apr 26 16:06:23 2009 +0100

    Added (disabled) support for radio channels
    
    Full radio support is there, but commented out for two reasons:
    * Does radio really belong in Totem, a movie player?
    * With radio and TV channels being queried concurrently at startup, bad
    things happen, which will require extra code to fix.
---
 po/POTFILES.in                  |    1 +
 src/plugins/iplayer/iplayer.py  |  100 +++++++++++++++++++++++++--------------
 src/plugins/iplayer/iplayer.ui  |   71 ++++++++++++++++++++++-----
 src/plugins/iplayer/iplayer2.py |   10 +----
 4 files changed, 125 insertions(+), 57 deletions(-)

diff --git a/po/POTFILES.in b/po/POTFILES.in
index cd9959c..ae6af5a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -52,6 +52,7 @@ src/plugins/gromit/totem-gromit.c
 [type: gettext/ini]src/plugins/iplayer/iplayer.totem-plugin.in
 src/plugins/iplayer/iplayer.py
 src/plugins/iplayer/iplayer2.py
+[type: gettext/glade]src/plugins/iplayer/iplayer.ui
 [type: gettext/glade]src/plugins/jamendo/jamendo.ui
 [type: gettext/ini]src/plugins/jamendo/jamendo.totem-plugin.in
 src/plugins/jamendo/jamendo.py
diff --git a/src/plugins/iplayer/iplayer.py b/src/plugins/iplayer/iplayer.py
index fe30d3c..afac9e3 100644
--- a/src/plugins/iplayer/iplayer.py
+++ b/src/plugins/iplayer/iplayer.py
@@ -17,8 +17,12 @@ class IplayerPlugin (totem.Plugin):
 		# Build the interface
 		builder = self.load_interface ("iplayer.ui", True, totem_object.get_main_window (), self)
 		container = builder.get_object ('iplayer_vbox')
-		self.tree_store = builder.get_object ('iplayer_programme_store')
+
+		self.tv_tree_store = builder.get_object ('iplayer_programme_store')
+		#self.radio_tree_store = builder.get_object ('iplayer_radio_programme_store')
+		#for object_id in ('iplayer_programme_list', 'iplayer_radio_programme_list')
 		programme_list = builder.get_object ('iplayer_programme_list')
+		#	programme_list.set_data ('id', object_id)
 		programme_list.connect ('row-expanded', self._row_expanded_cb)
 		programme_list.connect ('row-activated', self._row_activated_cb)
 
@@ -26,38 +30,44 @@ class IplayerPlugin (totem.Plugin):
 		container.show_all ()
 
 		self.tv = iplayer2.feed ('tv')
-		# TODO: Radio support
-		#self.radio = feed ('radio')
+		#self.radio = iplayer2.feed ('radio')
 
+		# Add the interface to Totem's sidebar
 		self.totem.add_sidebar_page ("iplayer", _("BBC iPlayer"), container)
 
-		self.populate_channel_list ()
+		# Get the channel category listings
+		self.populate_channel_list (self.tv, self.tv_tree_store)
+		#self.populate_channel_list (self.radio, self.radio_tree_store)
 
 	def deactivate (self, totem_object):
 		totem_object.remove_sidebar_page ("iplayer")
 
-	def populate_channel_list (self):
+	def populate_channel_list (self, feed, tree_store):
 		if self.debug:
 			print "Populating channel listâ?¦"
 
 		# Add all the channels as top-level rows in the tree store
-		channels = self.tv.channels ()
+		channels = feed.channels ()
 		for channel_id, title in channels.items ():
-			parent_iter = self.tree_store.append (None, [title, channel_id, None])
+			parent_iter = 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.tv, self.tree_store)
+		parent_path = tree_store.get_path (parent_iter)
+		thread = PopulateChannelsThread (self, parent_path, feed, tree_store)
         	thread.start ()
 
-	def _populate_channel_list_cb (self, parent_path, values):
+	def _populate_channel_list_cb (self, tree_store, parent_path, values):
 		# Callback from PopulateChannelsThread to add stuff to the tree store
-		parent_iter = self.tree_store.get_iter (parent_path)
-		category_iter = self.tree_store.append (parent_iter, values)
+		if values == None:
+			self.totem.action_error (_('Error Listing Channel Categories'), 'TODO')
+			return False
+
+		parent_iter = tree_store.get_iter (parent_path)
+		category_iter = tree_store.append (parent_iter, values)
 
 		# Append a dummy child row so that the expander's visible; we can
 		# then queue off the expander to load the programme listing for this category
-		self.tree_store.append (category_iter, [_('Loadingâ?¦'), None, None])
+		tree_store.append (category_iter, [_('Loadingâ?¦'), None, None])
 
 		return False
 
@@ -73,36 +83,46 @@ class IplayerPlugin (totem.Plugin):
 			return
 
 		# Populate it with programmes asynchronously
-		self.populate_programme_list (row_iter)
+		#if tree_view.get_data ('id') == 'iplayer_programme_store':
+		feed = self.tv
+		#else:
+		#	feed = self.radio
+
+		self.populate_programme_list (feed, tree_model, row_iter)
 
 	def _row_activated_cb (self, tree_view, path, view_column):
-		tree_iter = self.tree_store.get_iter (path)
-		mrl = self.tree_store.get_value (tree_iter, 2)
+		tree_store = tree_view.get_model ()
+		tree_iter = tree_store.get_iter (path)
+		mrl = tree_store.get_value (tree_iter, 2)
 
 		# Only allow programme rows to be activated, not channel or category rows
 		if mrl == None:
 			return
 
 		# Add the programme to the playlist and play it
-		self.totem.add_to_playlist_and_play (mrl, self.tree_store.get_value (tree_iter, 0), True)
+		self.totem.add_to_playlist_and_play (mrl, tree_store.get_value (tree_iter, 0), True)
 
-	def populate_programme_list (self, category_iter):
+	def populate_programme_list (self, feed, tree_store, category_iter):
 		if self.debug:
 			print "Populating programme listâ?¦"
 
-		category_path = self.tree_store.get_path (category_iter)
-		thread = PopulateProgrammesThread (self, self.tv, self.tree_store, category_path)
+		category_path = tree_store.get_path (category_iter)
+		thread = PopulateProgrammesThread (self, feed, tree_store, category_path)
 		thread.start ()
 
-	def _populate_programme_list_cb (self, category_path, values, remove_placeholder):
+	def _populate_programme_list_cb (self, tree_store, category_path, values, remove_placeholder):
 		# Callback from PopulateProgrammesThread to add stuff to the tree store
-		category_iter = self.tree_store.get_iter (category_path)
+		if values == None:
+			totem.action_error (_('Error getting programme feed'), _('There was an unknown error getting the list of programmes for this channel and category combination.'))
+			return False
+
+		category_iter = tree_store.get_iter (category_path)
 
-		self.tree_store.append (category_iter, values)
+		tree_store.append (category_iter, values)
 
 		# Remove the placeholder row
 		if remove_placeholder:
-			self.tree_store.remove (self.tree_store.iter_children (category_iter))
+			tree_store.remove (tree_store.iter_children (category_iter))
 
 		return False
 
@@ -130,12 +150,15 @@ class PopulateChannelsThread (threading.Thread):
 			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, count in self.feed.get (channel_id).categories ():
-				category_id = category_name_to_id (name)
-				gobject.idle_add (self.plugin._populate_channel_list_cb, parent_path, [name, category_id, None])
+			try:
+				# 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, count in self.feed.get (channel_id).categories ():
+					category_id = category_name_to_id (name)
+					gobject.idle_add (self.plugin._populate_channel_list_cb, self.tree_model, parent_path, [name, category_id, None])
+			except:
+				gobject.idle_add (self.plugin._populate_channel_list_cb, self.tree_model, parent_path, None)
 
 			tree_iter = self.tree_model.iter_next (tree_iter)
 
@@ -158,13 +181,19 @@ class PopulateProgrammesThread (threading.Thread):
 		# Retrieve the programmes and return them
 		feed = self.feed.get (channel_id).get (category_id)
 		if feed == None:
-			totem.action_error (_('Error getting programme feed'), _('There was an unknown error getting the list of programmes for this channel and category combination.'))
-			gobject.idle_add (self.plugin._populate_programme_list_cb, self.category_path, None)
+			gobject.idle_add (self.plugin._populate_programme_list_cb, self.tree_model, self.category_path, None)
+			self.plugin.programme_download_lock.release ()
+			return
+
+		# Get the programmes
+		try:
+			programmes = feed.list ()
+		except:
+			gobject.idle_add (self.plugin._populate_programme_list_cb, self.tree_model, self.category_path, None)
 			self.plugin.programme_download_lock.release ()
 			return
 
-		# Get the programmes and add them to the tree store
-		programmes = feed.list ()
+		# Add the programmes to the tree store
 		remove_placeholder = True
 		for programme in programmes:
 			programme_item = programme.programme
@@ -174,10 +203,11 @@ class PopulateProgrammesThread (threading.Thread):
 			# which isn't currently supported by GStreamer or xine
 			media = programme_item.get_media_for ('mobile')
 			if media == None:
+				# Not worth displaying an error in the interface for this
 				print "Programme has no HTTP streams"
 				continue
 
-			gobject.idle_add (self.plugin._populate_programme_list_cb, self.category_path,
+			gobject.idle_add (self.plugin._populate_programme_list_cb, self.tree_model, self.category_path,
 					  [programme.get_title (), programme.get_summary (), media.url], remove_placeholder)
 			remove_placeholder = False
 
diff --git a/src/plugins/iplayer/iplayer.ui b/src/plugins/iplayer/iplayer.ui
index 8d858a6..084f2bf 100644
--- a/src/plugins/iplayer/iplayer.ui
+++ b/src/plugins/iplayer/iplayer.ui
@@ -9,32 +9,77 @@
 	</columns>
 </object>
 
+<!--<object class="GtkTreeStore" id="iplayer_radio_programme_store">
+	<columns>
+		<column type="gchararray"/><!-Title->
+		<column type="gchararray"/><!-Summary->
+		<column type="gchararray"/><!-MRL->
+	</columns>
+</object>-->
+
 <object class="GtkVBox" id="iplayer_vbox">
 	<property name="border-width">5</property>
 	<property name="homogeneous">False</property>
 	<property name="spacing">6</property>
 	<child>
-		<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="GtkNotebook" id="iplayer_notebook">
+			<child>-->
+				<object class="GtkScrolledWindow" id="iplayer_scrolled_window">
+					<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
+					<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
+					<child>
+						<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>
+							<child>
+								<object class="GtkTreeViewColumn" id="iplayer_title_column">
+									<child>
+										<object class="GtkCellRendererText" id="iplayer_title_cell_renderer"/>
+										<attributes>
+											<attribute name="text">0</attribute>
+										</attributes>
+									</child>
+								</object>
+							</child>
+						</object>
+					</child>
+				</object>
+			<!--</child>
+			<child type="tab">
+				<object class="GtkLabel" id="iplayer_tv_tab">
+					<property name="label" translatable="yes">Television</property>
+				</object>
+			</child>
 			<child>
-				<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="GtkScrolledWindow" id="iplayer_radio_scrolled_window">
+					<property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
+					<property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
 					<child>
-						<object class="GtkTreeViewColumn" id="iplayer_title_column">
+						<object class="GtkTreeView" id="iplayer_radio_programme_list">
+							<property name="model">iplayer_radio_programme_store</property>
+							<property name="expander-column">iplayer_radio_title_column</property>
+							<property name="headers-visible">False</property>
 							<child>
-								<object class="GtkCellRendererText" id="iplayer_title_cell_renderer"/>
-								<attributes>
-									<attribute name="text">0</attribute>
-								</attributes>
+								<object class="GtkTreeViewColumn" id="iplayer_radio_title_column">
+									<child>
+										<object class="GtkCellRendererText" id="iplayer_radio_title_cell_renderer"/>
+										<attributes>
+											<attribute name="text">0</attribute>
+										</attributes>
+									</child>
+								</object>
 							</child>
 						</object>
 					</child>
 				</object>
 			</child>
-		</object>
+			<child type="tab">
+				<object class="GtkLabel" id="iplayer_radio_tab">
+					<property name="label" translatable="yes">Radio</property>
+				</object>
+			</child>
+		</object>-->
 	</child>
 </object>
 </interface>
diff --git a/src/plugins/iplayer/iplayer2.py b/src/plugins/iplayer/iplayer2.py
index 363602a..4ece97f 100644
--- a/src/plugins/iplayer/iplayer2.py
+++ b/src/plugins/iplayer/iplayer2.py
@@ -318,15 +318,7 @@ def httpretrieve(url, filename):
     f.close() 
 
 def httpget(url):
-    resp = ''
-    data = ''
-    try:
-        resp, data = http.request(url, 'GET')
-    except:
-        #print "Response for status %s for %s" % (resp.status, data)
-        totem.action_error (_('Network Error'), _('Failed to fetch URI: %s') % url)
-        raise
-    
+    resp, data = http.request(url, 'GET')
     return data
 
 def parse_entry_id(entry_id):



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]