Add configurable properties in the status window.
[python-gnt.git] / example / xmms / xmms_status.py
blob1c38da31871fb339eba962d93658eecd1e1ca709
1 #!/usr/bin/env python
3 """
4 xmms-status : A status widget for XMMS2.
6 Copyright (C) 2007 Sadrul Habib Chowdhury <sadrul@users.sourceforge.net>
8 This application is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
13 This application is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with this application; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301
21 USA
22 """
24 import xmmsclient
25 import xmmsclient.glib as xg
26 import xmmsclient.collections as xc
27 import gobject
28 import gnt
29 import os
30 import sys
32 import common
34 __version__ = "0.0.1alpha"
35 __author__ = "Sadrul Habib Chowdhury <sadrul@users.sourceforge.net>"
36 __copyright__ = "Copyright 2007, Sadrul Habib Chowdhury"
37 __license__ = "GPL"
39 reload(sys)
40 sys.setdefaultencoding("utf-8")
42 class XStatus(gnt.Box):
43 """A generic widget displaying the playback status of XMMS2."""
44 PROP_TITLE = 1 << 0
45 PROP_ARTIST = 1 << 1
46 PROP_ALBUM = 1 << 2
47 PROP_DURATION = 1 << 3
48 PROP_QUALITY = 1 << 4
49 PROP_URL = 1 << 5
51 def __init__(self, xmms):
52 gnt.Box.__init__(self, False, False)
53 self.set_property('vertical', True)
54 self.set_pad(0)
55 self.xmms = xmms
56 self.current = None
57 self.playtime = ""
58 self.fields = self.PROP_TITLE | self.PROP_ARTIST | self.PROP_DURATION
60 self.tv = gnt.TextView()
61 self.tv.set_flag(gnt.TEXT_VIEW_NO_SCROLL)
62 self.tv.set_flag(gnt.TEXT_VIEW_TOP_ALIGN)
64 self.tv.append_text_with_flags("Title: ", gnt.TEXT_FLAG_BOLD)
65 self.tv.append_text_with_tag("...", gnt.TEXT_FLAG_NORMAL, "title")
66 self.tv.append_text_with_flags("\nArtist: ", gnt.TEXT_FLAG_BOLD)
67 self.tv.append_text_with_tag("...", gnt.TEXT_FLAG_NORMAL, "artist")
68 self.tv.append_text_with_flags("\nDuration: ", gnt.TEXT_FLAG_BOLD)
69 self.tv.append_text_with_tag(".../...", gnt.TEXT_FLAG_NORMAL, "playtime")
70 self.tv.set_size(-1, 3)
71 gnt.unset_flag(self.tv, gnt.WIDGET_GROW_Y)
73 self.status = gnt.Label(" " * max(len("Stopped"), len("Paused"), len("Playing")))
74 # Hopefully this will make it easier when translation happens
75 self.status.set_property("text-flag", gnt.TEXT_FLAG_BOLD);
76 gnt.unset_flag(self.status, gnt.WIDGET_GROW_X)
78 self.progress = gnt.Slider(False, 1, 0)
79 gnt.unset_flag(self.progress, gnt.WIDGET_CAN_TAKE_FOCUS)
81 self.add_widget(self.tv)
82 self.add_widget(common.pack_widget(False, [self.status, self.progress]))
84 # Update playback status
85 self.xmms.broadcast_playback_status(self.update_status)
86 self.xmms.playback_status(self.update_status)
88 # Update playback time
89 self.xmms.playback_playtime(self.update_playtime)
91 # Update song information
92 self.xmms.broadcast_playback_current_id(self.update_song_info)
93 self.xmms.playback_current_id(self.update_song_info)
95 def medialib_entry_changed(result):
96 song = result.value()
97 if song == self.current['id']:
98 self.update_song_info()
99 self.xmms.broadcast_medialib_entry_changed(medialib_entry_changed)
101 def update_fields(self):
102 self.tv.clear()
103 height = 0
104 fields = ((self.PROP_TITLE, "Title", "title"),
105 (self.PROP_ARTIST, "Artist", "artist"),
106 (self.PROP_ALBUM, "Album", "album"),
107 (self.PROP_DURATION, "Duration", "playtime"),
108 (self.PROP_QUALITY, "Quality", "quality"),
109 (self.PROP_URL, "URL", "url"),
112 for field, title, attr in fields:
113 if not (self.fields & field): continue
114 if height > 0:
115 title = "\n" + title
116 self.tv.append_text_with_flags(title + ": ", gnt.TEXT_FLAG_BOLD)
117 self.tv.append_text_with_tag("...", gnt.TEXT_FLAG_NORMAL, attr)
118 height = height + 1
120 gnt.set_flag(self.tv, gnt.WIDGET_GROW_Y)
121 self.tv.set_size(-1, height)
122 gnt.unset_flag(self.tv, gnt.WIDGET_GROW_Y)
123 if self.current:
124 self.update_song_info()
126 def update_status(self, result):
127 val = result.value()
128 status = "..."
129 if val == xmmsclient.PLAYBACK_STATUS_STOP:
130 status = "Stopped"
131 elif val == xmmsclient.PLAYBACK_STATUS_PLAY:
132 status = "Playing"
133 elif val == xmmsclient.PLAYBACK_STATUS_PAUSE:
134 status = "Paused"
135 self.status.set_text(status)
137 def update_playtime(self, result):
138 val = result.value() / 1000
139 self.tv.tag_change("playtime", "%02d:%02d/%s" % (val / 60, val % 60, self.playtime), True)
140 self.tv.draw()
141 self.progress.set_value(val)
142 def restart_signal():
143 self.xmms.playback_playtime(self.update_playtime)
144 return False
145 gobject.timeout_add_seconds(1, restart_signal)
147 def update_song(self):
148 for field in ('title', 'artist', 'album', 'quality', 'url'):
149 self.tv.tag_change(field, str(self.current.get(field, ' ')), True)
150 common.debug("setting %s to %s\n" % (field, str(self.current.get(field, ' '))))
151 self.tv.draw()
153 def update_song_info(self, result = None):
154 if result:
155 val = result.value()
156 else:
157 val = self.current['id']
158 def received_song_info(result):
159 self.current = result.value()
160 if self.current is None:
161 playtime = 0
162 self.current = {'id' : -1, 'title' : '...', 'artist' : '...', 'album' : '...', 'samplerate' : 0, 'bitrate' : 0}
163 else:
164 playtime = int(self.current.get('duration', 0) / 1000)
165 self.current[('client-quality', 'quality')] = "%.1f kHz, %d kb/s" % (self.current.get('samplerate', 0) / 1000, self.current.get('bitrate', 0) / 1000)
166 self.progress.set_range(0, playtime)
167 self.playtime = "%02d:%02d" % (playtime / 60, playtime % 60)
168 self.update_song()
169 common.debug("%s\n" % self.current)
170 self.xmms.medialib_get_info(val, received_song_info)
172 def show(self):
173 win = gnt.Window()
174 win.set_pad(0)
175 win.set_title("XMMS2 Status")
176 win.add_widget(self)
177 win.show()
179 def setup_xmms():
180 xmms = xmmsclient.XMMS("pygnt-search")
181 try:
182 xmms.connect(os.getenv("XMMS_PATH"))
183 conn = xg.GLibConnector(xmms)
184 xs = XStatus(xmms)
185 xs.fields = xs.fields & ~xs.PROP_TITLE
186 xs.fields = xs.fields | xs.PROP_URL | xs.PROP_QUALITY
187 xs.update_fields()
188 xs.show()
189 except IOError, detail:
190 common.show_error("Connection failed: " + str(detail))
192 if __name__ == '__main__':
193 setup_xmms()
194 gnt.gnt_main()
195 gnt.gnt_quit()