totem r5819 - in trunk: . src/plugins/jamendo
- From: hadess svn gnome org
- To: svn-commits-list gnome org
- Subject: totem r5819 - in trunk: . src/plugins/jamendo
- Date: Fri, 5 Dec 2008 10:51:35 +0000 (UTC)
Author: hadess
Date: Fri Dec 5 10:51:35 2008
New Revision: 5819
URL: http://svn.gnome.org/viewvc/totem?rev=5819&view=rev
Log:
2008-12-05 Bastien Nocera <hadess hadess net>
* configure.in:
* src/plugins/jamendo/Makefile.am:
* src/plugins/jamendo/jamendo.glade:
* src/plugins/jamendo/jamendo.py:
* src/plugins/jamendo/jamendo.totem-plugin.in:
* totem.spec.in: Patch from David JEAN LOUIS <izimobil gmail com>
to add the Jamendo plugin (Closes: #561811)
Added:
trunk/src/plugins/jamendo/
trunk/src/plugins/jamendo/Makefile.am
trunk/src/plugins/jamendo/jamendo.glade
trunk/src/plugins/jamendo/jamendo.py
trunk/src/plugins/jamendo/jamendo.totem-plugin.in
Modified:
trunk/ChangeLog
trunk/configure.in
trunk/totem.spec.in
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Fri Dec 5 10:51:35 2008
@@ -50,7 +50,7 @@
AC_SUBST(TOTEM_VERSION_MICRO)
# The full list of plugins
-allowed_plugins="thumbnail screensaver ontop galago gromit lirc media-player-keys mythtv properties sidebar-test skipto sample-python sample-vala bemused youtube publish tracker pythonconsole"
+allowed_plugins="thumbnail screensaver ontop galago gromit lirc media-player-keys mythtv properties sidebar-test skipto sample-python sample-vala bemused youtube publish tracker pythonconsole jamendo"
PLUGINDIR='${libdir}/totem/plugins'
AC_SUBST(PLUGINDIR)
@@ -874,6 +874,7 @@
src/plugins/youtube/Makefile
src/plugins/pythonconsole/Makefile
src/plugins/publish/Makefile
+src/plugins/jamendo/Makefile
src/backend/Makefile
browser-plugin/Makefile
data/Makefile
Added: trunk/src/plugins/jamendo/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/plugins/jamendo/Makefile.am Fri Dec 5 10:51:35 2008
@@ -0,0 +1,14 @@
+plugindir = $(PLUGINDIR)/jamendo
+uidir = $(plugindir)
+plugin_PYTHON = jamendo.py
+plugin_in_files = jamendo.totem-plugin.in
+
+%.totem-plugin: %.totem-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+plugin_DATA = $(plugin_in_files:.totem-plugin.in=.totem-plugin)
+ui_DATA = jamendo.glade
+
+EXTRA_DIST = $(plugin_in_files) $(ui_DATA) jamendo.py
+
+CLEANFILES = $(plugin_DATA)
+DISTCLEANFILES = $(plugin_DATA)
Added: trunk/src/plugins/jamendo/jamendo.glade
==============================================================================
--- (empty file)
+++ trunk/src/plugins/jamendo/jamendo.glade Fri Dec 5 10:51:35 2008
@@ -0,0 +1,1571 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="mainwindow">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Jamendo totem plugin</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+
+ <child>
+ <widget class="GtkVBox" id="mainwindow_container">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">5</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="search_hbox">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkEntry" id="search_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">â</property>
+ <property name="activates_default">False</property>
+ <signal name="activate" handler="on_search_entry_activate"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="search_combo">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="items" translatable="yes">By artist
+By tag</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="search_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_search_button_clicked"/>
+
+ <child>
+ <widget class="GtkImage" id="track_icon">
+ <property name="visible">True</property>
+ <property name="stock">gtk-find</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkNotebook" id="notebook">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="show_tabs">True</property>
+ <property name="show_border">True</property>
+ <property name="tab_pos">GTK_POS_TOP</property>
+ <property name="scrollable">False</property>
+ <property name="enable_popup">False</property>
+ <signal name="switch_page" handler="on_notebook_switch_page"/>
+
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="results_scrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkViewport" id="viewport1">
+ <property name="visible">True</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+
+ <child>
+ <widget class="GtkVBox" id="results_vbox">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkTreeView" id="results_treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ <signal name="button_press_event" handler="on_treeview_row_clicked"/>
+ <signal name="row_activated" handler="on_treeview_row_activated"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkProgressBar" id="results_progressbar">
+ <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
+ <property name="fraction">0</property>
+ <property name="pulse_step">0.10000000149</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="results_tab_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Search results</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="popular_scrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkViewport" id="viewport2">
+ <property name="visible">True</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+
+ <child>
+ <widget class="GtkVBox" id="popular_vbox">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkTreeView" id="popular_treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ <signal name="button_press_event" handler="on_treeview_row_clicked"/>
+ <signal name="row_activated" handler="on_treeview_row_activated"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkProgressBar" id="popular_progressbar">
+ <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
+ <property name="fraction">0</property>
+ <property name="pulse_step">0.10000000149</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="popular_tab_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Popular</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="latest_scrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkViewport" id="viewport3">
+ <property name="visible">True</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+
+ <child>
+ <widget class="GtkVBox" id="latest_vbox">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkTreeView" id="latest_treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ <signal name="button_press_event" handler="on_treeview_row_clicked"/>
+ <signal name="row_activated" handler="on_treeview_row_activated"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkProgressBar" id="latest_progressbar">
+ <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
+ <property name="fraction">0</property>
+ <property name="pulse_step">0.10000000149</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="latest_tab_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Latest releases</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkButton" id="album_button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_album_button_clicked"/>
+
+ <child>
+ <widget class="GtkHBox" id="album_button_hbox">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkImage" id="album_button_image">
+ <property name="visible">True</property>
+ <property name="stock">gtk-jump-to</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="download_button_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Jamendo album page</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkButton" id="previous_button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_previous_button_clicked"/>
+
+ <child>
+ <widget class="GtkImage" id="previous_button_image">
+ <property name="visible">True</property>
+ <property name="stock">gtk-go-back</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="next_button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_next_button_clicked"/>
+
+ <child>
+ <widget class="GtkImage" id="next_button_image">
+ <property name="visible">True</property>
+ <property name="stock">gtk-go-forward</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="config_dialog">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Jamendo plugin configuration</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">False</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="config_dialog_container">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="buttons">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancel_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_cancel_button_clicked"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="ok_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_ok_button_clicked"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkTable" id="table">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">0</property>
+ <property name="column_spacing">2</property>
+
+ <child>
+ <widget class="GtkLabel" id="album_num_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Number of albums to retrieve</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkSpinButton" id="album_num_spinbutton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="climb_rate">1</property>
+ <property name="digits">0</property>
+ <property name="numeric">False</property>
+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+ <property name="snap_to_ticks">False</property>
+ <property name="wrap">False</property>
+ <property name="adjustment">10 1 100 1 0 0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="preferred_format_combo">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="items" translatable="yes">Ogg
+MP3</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="preferred_format_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Preferred audio format</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_END</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkMenu" id="popup_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="add_to_playlist">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Add to Playlist</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_add_to_playlist_activate" last_modification_time="Thu, 04 Dec 2008 14:11:09 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image4">
+ <property name="visible">True</property>
+ <property name="stock">gtk-add</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="jamendo_album_page">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Open Jamendo album page in browser</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_open_jamendo_album_page_activate" last_modification_time="Thu, 04 Dec 2008 14:11:09 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image5">
+ <property name="visible">True</property>
+ <property name="stock">gtk-jump-to</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="mainwindow">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Jamendo totem plugin</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+
+ <child>
+ <widget class="GtkVBox" id="mainwindow_container">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">5</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="search_hbox">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkEntry" id="search_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">â</property>
+ <property name="activates_default">False</property>
+ <signal name="activate" handler="on_search_entry_activate"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="search_combo">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="items" translatable="yes">By artist
+By tag</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="search_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_search_button_clicked"/>
+
+ <child>
+ <widget class="GtkImage" id="track_icon">
+ <property name="visible">True</property>
+ <property name="stock">gtk-find</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkNotebook" id="notebook">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="show_tabs">True</property>
+ <property name="show_border">True</property>
+ <property name="tab_pos">GTK_POS_TOP</property>
+ <property name="scrollable">False</property>
+ <property name="enable_popup">False</property>
+ <signal name="switch_page" handler="on_notebook_switch_page"/>
+
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="results_scrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkViewport" id="viewport1">
+ <property name="visible">True</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+
+ <child>
+ <widget class="GtkVBox" id="results_vbox">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkTreeView" id="results_treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ <signal name="button_press_event" handler="on_treeview_row_clicked"/>
+ <signal name="row_activated" handler="on_treeview_row_activated"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkProgressBar" id="results_progressbar">
+ <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
+ <property name="fraction">0</property>
+ <property name="pulse_step">0.10000000149</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="results_tab_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Search results</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="popular_scrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkViewport" id="viewport2">
+ <property name="visible">True</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+
+ <child>
+ <widget class="GtkVBox" id="popular_vbox">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkTreeView" id="popular_treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ <signal name="button_press_event" handler="on_treeview_row_clicked"/>
+ <signal name="row_activated" handler="on_treeview_row_activated"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkProgressBar" id="popular_progressbar">
+ <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
+ <property name="fraction">0</property>
+ <property name="pulse_step">0.10000000149</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="popular_tab_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Popular</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="latest_scrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkViewport" id="viewport3">
+ <property name="visible">True</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+
+ <child>
+ <widget class="GtkVBox" id="latest_vbox">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkTreeView" id="latest_treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ <signal name="button_press_event" handler="on_treeview_row_clicked"/>
+ <signal name="row_activated" handler="on_treeview_row_activated"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkProgressBar" id="latest_progressbar">
+ <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
+ <property name="fraction">0</property>
+ <property name="pulse_step">0.10000000149</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="latest_tab_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Latest releases</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkButton" id="album_button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_album_button_clicked"/>
+
+ <child>
+ <widget class="GtkHBox" id="album_button_hbox">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkImage" id="album_button_image">
+ <property name="visible">True</property>
+ <property name="stock">gtk-jump-to</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="download_button_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Jamendo album page</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkButton" id="previous_button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_previous_button_clicked"/>
+
+ <child>
+ <widget class="GtkImage" id="previous_button_image">
+ <property name="visible">True</property>
+ <property name="stock">gtk-go-back</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="next_button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_next_button_clicked"/>
+
+ <child>
+ <widget class="GtkImage" id="next_button_image">
+ <property name="visible">True</property>
+ <property name="stock">gtk-go-forward</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="config_dialog">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Jamendo plugin configuration</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">False</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="config_dialog_container">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="buttons">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancel_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_cancel_button_clicked"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="ok_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="on_ok_button_clicked"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkTable" id="table">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">0</property>
+ <property name="column_spacing">2</property>
+
+ <child>
+ <widget class="GtkLabel" id="album_num_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Number of albums to retrieve</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkSpinButton" id="album_num_spinbutton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="climb_rate">1</property>
+ <property name="digits">0</property>
+ <property name="numeric">False</property>
+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+ <property name="snap_to_ticks">False</property>
+ <property name="wrap">False</property>
+ <property name="adjustment">10 1 100 1 0 0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="preferred_format_combo">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="items" translatable="yes">Ogg
+MP3</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="preferred_format_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Preferred audio format</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_END</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
Added: trunk/src/plugins/jamendo/jamendo.py
==============================================================================
--- (empty file)
+++ trunk/src/plugins/jamendo/jamendo.py Fri Dec 5 10:51:35 2008
@@ -0,0 +1,645 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2008 David JL <izimobil gmail com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+"""
+Jamendo totem plugin (http://www.jamendo.com).
+
+TODO:
+- store thumbnails in relevant XDG directories (?)
+- cleanup the notebook code
+- interface with jamendo write API (not documented yet):
+ favorites, comments, etc...
+"""
+
+import os
+import totem
+import gettext
+import gconf
+import gobject
+import gtk
+import gtk.glade
+import pango
+import socket
+import threading
+import time
+import urllib
+import urllib2
+from xml.sax.saxutils import escape
+try:
+ import json
+except ImportError:
+ try:
+ import simplejson as json
+ except ImportError:
+ dlg = gtk.MessageDialog(
+ type=gtk.MESSAGE_ERROR,
+ buttons=gtk.BUTTONS_OK
+ )
+ dlg.set_markup(_('You need to install the python simplejson module'))
+ dlg.run()
+ dlg.destroy()
+ raise
+
+socket.setdefaulttimeout(30)
+gobject.threads_init()
+_ = gettext.gettext
+gconf_key = '/apps/totem/plugins/jamendo'
+
+
+class JamendoPlugin(totem.Plugin):
+ """
+ Jamendo totem plugin GUI.
+ """
+ SEARCH_CRITERIUM = ['artist_name', 'tag_idstr']
+ AUDIO_FORMATS = ['ogg2', 'mp31']
+ TAB_RESULTS = 0
+ TAB_POPULAR = 1
+ TAB_LATEST = 2
+
+ def __init__(self):
+ totem.Plugin.__init__(self)
+ self.debug = True
+ self.gstreamer_plugins_present = True
+ self.totem = None
+ self.gconf = gconf.client_get_default()
+ self.init_settings()
+
+ # init glade interface
+ f = os.path.join(os.path.dirname(__file__), 'jamendo.glade')
+ self.glade = gtk.glade.XML(f)
+ self.config_dialog = self.glade.get_widget('config_dialog')
+ self.window = self.glade.get_widget('mainwindow')
+ self.container = self.glade.get_widget('mainwindow_container')
+ self.notebook = self.glade.get_widget('notebook')
+ self.search_entry = self.glade.get_widget('search_entry')
+ self.search_combo = self.glade.get_widget('search_combo')
+ # XXX active property set in glade file does not work
+ self.search_combo.set_active(0)
+ self.album_button = self.glade.get_widget('album_button')
+ self.previous_button = self.glade.get_widget('previous_button')
+ self.next_button = self.glade.get_widget('next_button')
+ self.progressbars = [
+ self.glade.get_widget('results_progressbar'),
+ self.glade.get_widget('popular_progressbar'),
+ self.glade.get_widget('latest_progressbar'),
+ ]
+ self.setup_treeviews()
+
+ # connect signals to slots
+ self.glade.signal_autoconnect({
+ 'on_search_button_clicked': self.on_search_button_clicked,
+ 'on_search_entry_activate': self.on_search_entry_activate,
+ 'on_notebook_switch_page': self.on_notebook_switch_page,
+ 'on_treeview_row_activated': self.on_treeview_row_activated,
+ 'on_treeview_row_clicked': self.on_treeview_row_clicked,
+ 'on_previous_button_clicked': self.on_previous_button_clicked,
+ 'on_next_button_clicked': self.on_next_button_clicked,
+ 'on_album_button_clicked': self.on_album_button_clicked,
+ 'on_cancel_button_clicked': self.on_cancel_button_clicked,
+ 'on_ok_button_clicked': self.on_ok_button_clicked,
+ })
+
+ self.reset()
+
+ def activate(self, totem_object):
+ """
+ Plugin activation.
+ """
+ self.totem = totem_object
+ # unparent the container to embed it into totem sidebar
+ self.container.unparent()
+ self.totem.add_sidebar_page("jamendo", _("Jamendo"), self.container)
+
+ def deactivate(self, totem_object):
+ """
+ Plugin deactivation.
+ """
+ totem_object.remove_sidebar_page("jamendo")
+
+ def create_configure_dialog(self, *args):
+ """
+ Plugin config dialog.
+ """
+ format = self.gconf.get_string('%s/format' % gconf_key)
+ num_per_page = self.gconf.get_int('%s/num_per_page' % gconf_key)
+ combo = self.glade.get_widget('preferred_format_combo')
+ combo.set_active(self.AUDIO_FORMATS.index(format))
+ spinbutton = self.glade.get_widget('album_num_spinbutton')
+ spinbutton.set_value(num_per_page)
+ return self.config_dialog
+
+ def reset(self):
+ """
+ XXX this will be refactored asap.
+ """
+ self.current_page = {
+ self.TAB_RESULTS: 1,
+ self.TAB_POPULAR: 1,
+ self.TAB_LATEST : 1
+ }
+ self.pages = {
+ self.TAB_RESULTS: [],
+ self.TAB_POPULAR: [],
+ self.TAB_LATEST : []
+ }
+ self.album_count = [0, 0, 0]
+ for tv in self.treeviews:
+ tv.get_model().clear()
+ self._update_buttons_state()
+
+ def init_settings(self):
+ """
+ Initialize plugin settings.
+ """
+ format = self.gconf.get_string('%s/format' % gconf_key)
+ if not format:
+ format = 'ogg2'
+ self.gconf.set_string('%s/format' % gconf_key, format)
+ num_per_page = self.gconf.get_int('%s/num_per_page' % gconf_key)
+ if not num_per_page:
+ num_per_page = 10
+ self.gconf.set_int('%s/num_per_page' % gconf_key, num_per_page)
+ JamendoService.AUDIO_FORMAT = format
+ JamendoService.NUM_PER_PAGE = num_per_page
+
+ def setup_treeviews(self):
+ """
+ Setup the 3 treeview: result, popular and latest
+ """
+ self.treeviews = [
+ self.glade.get_widget('results_treeview'),
+ self.glade.get_widget('popular_treeview'),
+ self.glade.get_widget('latest_treeview'),
+ ]
+ self.current_treeview = self.treeviews[0]
+ for w in self.treeviews:
+
+ # build a treestore
+ model = gtk.TreeStore(
+ gobject.TYPE_PYOBJECT, # album or track dict
+ gtk.gdk.Pixbuf, # album cover or track icon
+ str, # album or track description
+ str, # album or track duration
+ str, # album or track tooltip
+ )
+ w.set_model(model)
+
+ # build pixbuf column
+ cell = gtk.CellRendererPixbuf()
+ col = gtk.TreeViewColumn()
+ col.pack_start(cell, True)
+ col.set_attributes(cell, pixbuf=1)
+ w.append_column(col)
+
+ # build description column
+ cell = gtk.CellRendererText()
+ cell.set_property('wrap-mode', pango.WRAP_WORD)
+ cell.set_property('wrap-width', 30)
+ col = gtk.TreeViewColumn()
+ col.pack_start(cell, True)
+ col.set_attributes(cell, markup=2)
+ col.set_expand(True)
+ w.append_column(col)
+ w.connect_after(
+ 'size-allocate',
+ self.on_treeview_size_allocate,
+ col,
+ cell
+ )
+
+ # duration column
+ cell = gtk.CellRendererText()
+ cell.set_property('xalign', 1.0)
+ cell.set_property('size-points', 8)
+ col = gtk.TreeViewColumn()
+ col.pack_start(cell, True)
+ col.set_attributes(cell, markup=3)
+ col.set_alignment(1.0)
+ w.append_column(col)
+
+ # configure the treeview
+ w.set_show_expanders(False) # we manage internally expand/collapse
+ w.set_tooltip_column(4) # set the tooltip column
+
+ def add_treeview_item(self, treeview, album):
+ if not isinstance(album['image'], gtk.gdk.Pixbuf):
+ # album image pixbuf is not yet built
+ try:
+ pb = gtk.gdk.pixbuf_new_from_file(album['image'])
+ os.unlink(album['image'])
+ album['image'] = pb
+ except:
+ # do not fail for this, just display a dummy pixbuf
+ album['image'] = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True,
+ 8, 1, 1)
+ # format title
+ title = '<b>%s</b>\n' % self._format_str(album['name'])
+ title += _('Artist: %s') % self._format_str(album['artist_name'])
+ # format duration
+ dur = self._format_duration(album['duration'])
+ # format tooltip
+ try:
+ release = time.strptime(album['dates']['release'][0:10], '%Y-%m-%d')
+ release = time.strftime('%x', release)
+ except:
+ release = ''
+ tip = '\n'.join([
+ '<b>%s</b>' % self._format_str(album['name']),
+ _('Artist: %s') % self._format_str(album['artist_name']),
+ _('Genre: %s') % self._format_str(album['genre']),
+ _('Released on: %s') % release,
+ _('License: %s') % self._format_str(album['license'][0]),
+ ])
+ # append album row
+ parent = treeview.get_model().append(None,
+ [album, album['image'], title, dur, tip]
+ )
+ # append track rows
+ icon = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, 1, 1)
+ for i, track in enumerate(album['tracks']):
+ # track title
+ tt = '<small>%02d. %s</small>' % \
+ (i+1, self._format_str(track['name']))
+ # track duration
+ td = self._format_duration(track['duration'])
+ # track tooltip
+ tip = '\n'.join([
+ '<b>%s</b>' % self._format_str(track['name']),
+ _('Album: %s') % self._format_str(album['name']),
+ _('Artist: %s') % self._format_str(album['artist_name']),
+ _('Duration: %s') % td,
+ ])
+ # append track
+ treeview.get_model().append(parent, [track, icon, tt, td, tip])
+ # update current album count
+ pindex = self.treeviews.index(treeview)
+ self.album_count[pindex] += 1
+
+ def fetch_albums(self, pn=1):
+ """
+ Initialize the fetch thread.
+ """
+ tab_index = self.treeviews.index(self.current_treeview)
+ if tab_index == self.TAB_POPULAR:
+ params = {'order': 'rating_desc'}
+ elif tab_index == self.TAB_LATEST:
+ params = {'order': 'date_desc'}
+ else:
+ value = self.search_entry.get_text()
+ if not value:
+ return
+ prop = self.SEARCH_CRITERIUM[self.search_combo.get_active()]
+ params = {'order': 'date_desc', prop: value}
+ params['pn'] = pn
+ self.current_treeview.get_model().clear()
+ self.previous_button.set_sensitive(False)
+ self.next_button.set_sensitive(False)
+ self.album_button.set_sensitive(False)
+ self.progressbars[tab_index].show()
+ self.progressbars[tab_index].set_fraction(0.0)
+ self.progressbars[tab_index].set_text(
+ _('Fetching albums, please wait...')
+ )
+ lcb = (self.on_fetch_albums_loop, self.current_treeview)
+ dcb = (self.on_fetch_albums_done, self.current_treeview)
+ ecb = (self.on_fetch_albums_error, self.current_treeview)
+ thread = JamendoService(params, lcb, dcb, ecb)
+ thread.start()
+
+ def on_fetch_albums_loop(self, treeview, album):
+ """
+ Add an album item and its tracks to the current treeview.
+ """
+ self.add_treeview_item(treeview, album)
+ # pulse progressbar
+ pindex = self.treeviews.index(treeview)
+ self.progressbars[pindex].set_fraction(
+ float(self.album_count[pindex]) / float(JamendoService.NUM_PER_PAGE)
+ )
+
+ def on_fetch_albums_done(self, treeview, albums, save_state=True):
+ """
+ Called when the thread finished fetching albums.
+ """
+ pindex = self.treeviews.index(treeview)
+ model = treeview.get_model()
+ if save_state and len(albums):
+ self.pages[pindex].append(albums)
+ self.current_page[pindex] = len(self.pages[pindex])
+ self._update_buttons_state()
+ self.progressbars[pindex].set_fraction(0.0)
+ self.progressbars[pindex].hide()
+ self.album_count[pindex] = 0
+
+ def on_fetch_albums_error(self, treeview, exc):
+ """
+ Called when an error occured in the thread.
+ """
+ self.reset()
+ pindex = self.treeviews.index(treeview)
+ self.progressbars[pindex].set_fraction(0.0)
+ self.progressbars[pindex].hide()
+ dlg = gtk.MessageDialog(
+ type=gtk.MESSAGE_ERROR,
+ buttons=gtk.BUTTONS_OK
+ )
+ dlg.set_markup(
+ '<b>%s</b>' % _('An error occured while fetching albums.')
+ )
+ # managing exceptions with urllib is a real PITA... :(
+ if hasattr(exc, 'reason'):
+ try:
+ reason = exc.reason[1]
+ except:
+ try:
+ reason = exc.reason[0]
+ except:
+ reason = str(exc)
+ reason = reason.capitalize()
+ msg = _('Failed to connect to jamendo server.\n%s.') % reason
+ elif hasattr(exc, 'code'):
+ msg = _('The jamendo server returned code %s') % exc.code
+ else:
+ msg = str(exc)
+ dlg.format_secondary_text(msg)
+ dlg.run()
+ dlg.destroy()
+
+ def on_search_entry_activate(self, *args):
+ """
+ Called when the user typed <enter> in the search entry.
+ """
+ return self.on_search_button_clicked()
+
+ def on_search_button_clicked(self, *args):
+ """
+ Called when the user clicked on the search button.
+ """
+ if not self.search_entry.get_text():
+ return
+ if self.current_treeview != self.treeviews[self.TAB_RESULTS]:
+ self.current_treeview = self.treeviews[self.TAB_RESULTS]
+ self.notebook.set_current_page(self.TAB_RESULTS)
+ else:
+ self.on_notebook_switch_page(new_search=True)
+
+ def on_notebook_switch_page(self, nb=None, tab=None, tab_num=0,
+ new_search=False):
+ """
+ Called when the changed a notebook page.
+ """
+ self.current_treeview = self.treeviews[int(tab_num)]
+ self._update_buttons_state()
+ model = self.current_treeview.get_model()
+ # fetch popular and latest albums once only
+ if not new_search and len(model):
+ return
+ if new_search:
+ self.current_page[self.TAB_RESULTS] = 1
+ self.pages[self.TAB_RESULTS] = []
+ self.album_count[self.TAB_RESULTS] = 0
+ self._update_buttons_state()
+ model.clear()
+ self.fetch_albums()
+
+ def on_treeview_row_activated(self, tv, path, column):
+ """
+ Called when the user double-clicked on a treeview element.
+ """
+ sel = self._get_selection_at(0)
+ try:
+ prop = (len(path) == 1) and 'album_id' or 'id'
+ url = '%s/stream/track/redirect/?%s=%s&streamencoding=%s' %\
+ (JamendoService.API_URL, prop, sel['id'],
+ JamendoService.AUDIO_FORMAT)
+ self.totem.action_set_mrl_and_play(url)
+ # update play icon
+ empty = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, 1, 1)
+ icon = self.window.render_icon(gtk.STOCK_MEDIA_PLAY,
+ gtk.ICON_SIZE_MENU)
+ for treeview in self.treeviews:
+ model = treeview.get_model()
+ for row in model:
+ if row.path == path:
+ path = (path[0], 0)
+ for subrow in row.iterchildren():
+ subrow[1] = subrow.path == path and icon or empty
+ except:
+ raise
+
+ def on_treeview_row_clicked(self, tv, evt):
+ """
+ Called when the user clicked on a treeview element.
+ """
+ try:
+ coords = evt.get_coords()
+ path, c, x, y = tv.get_path_at_pos(int(coords[0]), int(coords[1]))
+ if (len(path) == 1):
+ if tv.row_expanded(path):
+ tv.collapse_row(path)
+ else:
+ tv.expand_row(path, False)
+ self.album_button.set_sensitive(True)
+ except:
+ pass
+
+ def on_treeview_size_allocate(self, tv, allocation, col, cell):
+ """
+ Hack to autowrap text of the title colum.
+ """
+ cols = (c for c in tv.get_columns() if c != col)
+ w = allocation.width - sum(c.get_width() for c in cols)
+ if cell.props.wrap_width == w or w <= 0:
+ return
+ cell.props.wrap_width = w
+
+ def on_previous_button_clicked(self, *args):
+ """
+ Called when the user clicked the previous button.
+ """
+ try:
+ self._update_buttons_state()
+ model = self.current_treeview.get_model()
+ model.clear()
+ pindex = self.treeviews.index(self.current_treeview)
+ self.current_page[pindex] -= 1
+ albums = self.pages[pindex][self.current_page[pindex]-1]
+ for album in albums:
+ self.add_treeview_item(self.current_treeview, album)
+ self.on_fetch_albums_done(self.current_treeview, albums, False)
+ except:
+ raise
+
+ def on_next_button_clicked(self, *args):
+ """
+ Called when the user clicked the next button.
+ """
+ try:
+ self._update_buttons_state()
+ model = self.current_treeview.get_model()
+ model.clear()
+ pindex = self.treeviews.index(self.current_treeview)
+ if self.current_page[pindex] == len(self.pages[pindex]):
+ self.fetch_albums(self.current_page[pindex]+1)
+ else:
+ self.current_page[pindex] += 1
+ albums = self.pages[pindex][self.current_page[pindex]-1]
+ for album in albums:
+ self.add_treeview_item(self.current_treeview, album)
+ self.on_fetch_albums_done(self.current_treeview, albums, False)
+ except:
+ raise
+
+ def on_album_button_clicked(self, *args):
+ """
+ Called when the user clicked on the album button.
+ """
+ album_id = self._get_selection_at(0, None, True)['id']
+ os.spawnlp (os.P_NOWAIT, "xdg-open", "xdg-open", '%s/url/album/redirect/?id=%s' % (
+ (JamendoService.API_URL, album_id)))
+
+ def on_cancel_button_clicked(self, *args):
+ """
+ Called when the user clicked cancel in the config dialog.
+ """
+ self.config_dialog.hide()
+
+ def on_ok_button_clicked(self, *args):
+ """
+ Called when the user clicked ok in the config dialog.
+ """
+ combo = self.glade.get_widget('preferred_format_combo')
+ spinbutton = self.glade.get_widget('album_num_spinbutton')
+ format = self.AUDIO_FORMATS[combo.get_active()]
+ self.gconf.set_string('%s/format' % gconf_key, format)
+ num_per_page = int(spinbutton.get_value())
+ self.gconf.set_int('%s/num_per_page' % gconf_key, num_per_page)
+ self.init_settings()
+ self.config_dialog.hide()
+ try:
+ self.reset()
+ except:
+ pass
+
+ def _update_buttons_state(self):
+ """
+ Update the state of the previous and next buttons.
+ """
+ sel = self.current_treeview.get_selection()
+ model, it = sel.get_selected()
+ pindex = self.treeviews.index(self.current_treeview)
+ self.previous_button.set_sensitive(self.current_page[pindex] > 1)
+ self.next_button.set_sensitive(len(model)==JamendoService.NUM_PER_PAGE)
+ self.album_button.set_sensitive(it is not None)
+
+ def _get_selection_at(self, at=0, sel=None, root=False):
+ """
+ Shortcut method to retrieve the value of the selected item at the
+ given column.
+ """
+ if sel is None:
+ sel = self.current_treeview.get_selection()
+ model, it = sel.get_selected()
+ if root:
+ while model.iter_parent(it) is not None:
+ it = model.iter_parent(it)
+ if it is not None:
+ return model.get(it, at)[0]
+ return None
+
+ def _format_str(self, st, truncate=False):
+ """
+ Escape entities for pango markup and force the string to utf-8.
+ """
+ if not st:
+ return ''
+ try:
+ return escape(st.encode('utf8'))
+ except:
+ return st
+
+ def _format_duration(self, secs):
+ """
+ Format the given number of seconds to a human readable duration.
+ """
+ try:
+ secs = int(secs)
+ if secs >= 3600:
+ return time.strftime('%H:%M:%S', time.gmtime(secs))
+ return time.strftime('%M:%S', time.gmtime(secs))
+ except:
+ return ''
+
+
+class JamendoService(threading.Thread):
+ """
+ Class that requests the jamendo REST service.
+ """
+
+ API_URL = 'http://api.jamendo.com/get2'
+ AUDIO_FORMAT = 'ogg2'
+ NUM_PER_PAGE = 10
+
+ def __init__(self, params, loop_cb, done_cb, error_cb):
+ self.params = params
+ self.loop_cb = loop_cb
+ self.done_cb = done_cb
+ self.error_cb = error_cb
+ self.lock = threading.Lock()
+ threading.Thread.__init__(self)
+
+ def run(self):
+ url = '%s/id+name+duration+image+genre+dates+artist_id+' \
+ 'artist_name+artist_url/album/json/?n=%s&imagesize=50' % \
+ (self.API_URL, self.NUM_PER_PAGE)
+ if len(self.params):
+ url += '&%s' % urllib.urlencode(self.params)
+ try:
+ self.lock.acquire()
+ albums = json.loads(self._request(url))
+ ret = []
+ for i, album in enumerate(albums):
+ fname, headers = urllib.urlretrieve(album['image'])
+ album['image'] = fname
+ album['tracks'] = json.loads(self._request(
+ '%s/id+name+duration/track/json/?album_id=%s'\
+ '&order=numalbum_asc' % (self.API_URL, album['id'])
+ ))
+ album['license'] = json.loads(self._request(
+ '%s/name/license/json/album_license/?album_id=%s'\
+ % (self.API_URL, album['id'])
+ ))
+ gobject.idle_add(self.loop_cb[0], self.loop_cb[1], album)
+ gobject.idle_add(self.done_cb[0], self.done_cb[1], albums)
+ except Exception, exc:
+ gobject.idle_add(self.error_cb[0], self.error_cb[1], exc)
+ finally:
+ self.lock.release()
+
+ def _request(self, url):
+ opener = urllib2.build_opener()
+ opener.addheaders = [('User-agent', 'Totem Jamendo plugin')]
+ handle = opener.open(url)
+ data = handle.read()
+ handle.close()
+ return data
+
Added: trunk/src/plugins/jamendo/jamendo.totem-plugin.in
==============================================================================
--- (empty file)
+++ trunk/src/plugins/jamendo/jamendo.totem-plugin.in Fri Dec 5 10:51:35 2008
@@ -0,0 +1,9 @@
+[Totem Plugin]
+Loader=python
+Module=jamendo
+IAge=1
+_Name=Jamendo
+_Description=Listen to the large collection of Creative Commons licensed music on Jamendo.
+Authors=David Jean Louis <izimobil gmail com>
+Copyright=Copyright  2008 David Jean Louis
+Website=http://www.jamendo.com
Modified: trunk/totem.spec.in
==============================================================================
--- trunk/totem.spec.in (original)
+++ trunk/totem.spec.in Fri Dec 5 10:51:35 2008
@@ -47,9 +47,6 @@
export MOZILLA_PLUGINDIR=%{_libdir}/mozilla
%configure --enable-gstreamer=yes --enable-mozilla --enable-nvtv
-#apparently someone forgot to autogen before disting 0.99.17 :)
-#perl -pi -e 's/gstvideowidget.h//g' src/Makefile
-
make %{?_smp_mflags}
%install
@@ -58,24 +55,10 @@
make install DESTDIR=$RPM_BUILD_ROOT
# no static libs and libtool archives either
-rm -f $RPM_BUILD_ROOT%{_libdir}/*.a
-rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
-rm -f $RPM_BUILD_ROOT%{_libdir}/nautilus/extensions-1.0/*.a
-rm -f $RPM_BUILD_ROOT%{_libdir}/nautilus/extensions-1.0/*.la
-rm -f $RPM_BUILD_ROOT%{_libdir}/mozilla/plugins/*.a
-rm -f $RPM_BUILD_ROOT%{_libdir}/mozilla/plugins/*.la
-rm -f $RPM_BUILD_ROOT%{_libdir}/totem/plugins/gromit/libgromit.a
-rm -f $RPM_BUILD_ROOT%{_libdir}/totem/plugins/gromit/libgromit.la
-rm -f $RPM_BUILD_ROOT%{_libdir}/totem/plugins/ontop/libontop.a
-rm -f $RPM_BUILD_ROOT%{_libdir}/totem/plugins/ontop/libontop.la
-rm -f $RPM_BUILD_ROOT%{_libdir}/totem/plugins/screensaver/libscreensaver.a
-rm -f $RPM_BUILD_ROOT%{_libdir}/totem/plugins/screensaver/libscreensaver.la
-rm -f $RPM_BUILD_ROOT%{_libdir}/totem/plugins/skipto/libskipto.a
-rm -f $RPM_BUILD_ROOT%{_libdir}/totem/plugins/skipto/libskipto.la
-rm -f $RPM_BUILD_ROOT%{_libdir}/totem/plugins/media-player-keys/libmedia_player_keys.a
-rm -f $RPM_BUILD_ROOT%{_libdir}/totem/plugins/media-player-keys/libmedia_player_keys.la
-rm -f $RPM_BUILD_ROOT%{_libdir}/totem/plugins/properties/libmovie-properties.a
-rm -f $RPM_BUILD_ROOT%{_libdir}/totem/plugins/properties/libmovie-properties.la
+rm -f $RPM_BUILD_ROOT%{_libdir}/*.{a,la}
+rm -f $RPM_BUILD_ROOT%{_libdir}/nautilus/extensions-1.0/*.{a,la}
+rm -f $RPM_BUILD_ROOT%{_libdir}/mozilla/plugins/*.{a,la}
+rm -f $RPM_BUILD_ROOT%{_libdir}/totem/plugins/*/*.{a,la}
%clean
rm -rf $RPM_BUILD_ROOT
@@ -137,6 +120,11 @@
%{_libdir}/totem/plugins/pythonconsole/*.pyc
%{_libdir}/totem/plugins/pythonconsole/*.pyo
%{_libdir}/totem/plugins/pythonconsole/pythonconsole.totem-plugin
+%{_libdir}/totem/plugins/jamendo/*.py
+%{_libdir}/totem/plugins/jamendo/*.pyc
+%{_libdir}/totem/plugins/jamendo/*.pyo
+%{_libdir}/totem/plugins/jamendo/jamendo.totem-plugin
+%{_libdir}/totem/plugins/jamendo/jamendo.glade
%{_libexecdir}/totem/totem-bugreport.*
%files mozplugin
@@ -145,6 +133,9 @@
%{_libexecdir}/totem-plugin-viewer
%changelog
+* Tue Nov 25 2008 David JEAN LOUIS <izimobil gmail com>
+- Added jamendo python plugin
+
* Sat Mar 1 2008 Christian Schaller <christian schaller collabora co uk>
- Update for new plugins and removed pl-parser
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]