--- a/immsview Sun Feb 01 12:21:02 2004 -0500
+++ b/immsview Sun Feb 01 23:51:35 2004 -0500
@@ -1,6 +1,6 @@
#!/usr/bin/python
-_immsview_version = "$Id: immsview 1687 2004-02-01 17:21:02Z fabien $"
+_immsview_version = "$Id: immsview 1688 2004-02-02 04:51:35Z fabien $"
# Copyright (C) 2004 by Fabien Ninoles
@@ -38,21 +38,23 @@
# - adding, deleting, suppressing a file (including updating other
# interface).
+import pygtk
+pygtk.require('2.0')
+
import sys
import os
import sqlite
-import Tkinter
-import ScrolledText
+import gobject
+import gtk
+import gtk.glade
import gettext
import xmms.control
import time
-gettext.bindtextdomain('immsview', '/usr/share/immsview/LANG')
-gettext.textdomain('immsview')
+gtk.glade.bindtextdomain('immsview', '/usr/share/immsview/LANG')
+gtk.glade.textdomain('immsview')
_ = gettext.gettext
-_dbname = os.environ['HOME'] + '/.imms/imms.db'
-
def strtime(seconds):
secs = abs(round(seconds))
minutes = secs / 60;
@@ -89,134 +91,166 @@
return -1
def play_file(self, filename):
idx = self.find_in_playlist(filename)
- print idx
if idx == -1:
self.enqueue_and_play((filename,))
else:
self.set_playlist_pos(idx)
class IMMSDb:
+ _dbname = os.environ['HOME'] + '/.imms/imms.db'
+ # _dbname = os.environ['HOME'] + '/.imms/imms.backup.db'
+ def __init__(self):
+ self.cx = sqlite.connect(IMMSDb._dbname)
+ def commit(self):
+ self.cx.commit()
+ def _get_ratings(self, min = 0, max = 250):
+ cu = self.cx.cursor()
+ cu.execute('''SELECT Rating.uid, Rating.rating
+ FROM Rating
+ WHERE Rating.rating >= %d
+ AND Rating.rating <= %d
+ ORDER BY Rating.rating;''' % (min, max))
+ return cu.fetchall()
+ def _get_library_uid(self, uid):
+ cu = self.cx.cursor()
+ cu.execute('''SELECT Library.path
+ FROM Library
+ WHERE Library.uid = %d;''' % (uid,))
+ return cu.fetchone()
+ def _get_library_by_path(self, path):
+ cu = self.cx.cursor()
+ cu.execute('''SELECT Library.uid, Library.sid
+ FROM Library
+ WHERE Library.path = '%s';''' % (path))
+ return cu.fetchone()
+ def get_ratings_and_info(self):
+ cu = self.cx.cursor()
+ cu.execute('''SELECT Rating.uid, Rating.rating,
+ Library.path, Last.last
+ FROM Rating, Library, Last
+ WHERE Rating.uid = Library.uid AND
+ Library.sid = Last.sid
+ ORDER BY Rating.rating DESC;''')
+ # Better to fetch everything since locking can really mess
+ # things in imms plugin.
+ res = cu.fetchall()
+ self.commit()
+ results = []
+ for tune in res:
+ try:
+ tmp = {'rating' : tune[1],
+ 'path' : tune[2].decode('latin_1', 'replace'),
+ 'last' : int(tune[3])}
+ results.append(tmp)
+ except UnicodeDecodeError:
+ print tune[2]
+ return results
+
+class IMMSStore(gtk.ListStore):
+ COL_RATING = 0
+ COL_PATH = 1
+ COL_LAST_STR = 2
+ COL_LAST = 3
+ COL_SELECT = 4
+ def __init__(self, db, xmms):
+ gtk.ListStore.__init__(self,
+ gobject.TYPE_INT,
+ gobject.TYPE_STRING,
+ gobject.TYPE_STRING,
+ gobject.TYPE_INT,
+ gobject.TYPE_BOOLEAN)
+ self.db = db
+ self.xmms = xmms
+ def refresh(self):
+ curtime = time.time()
+ tunes = self.db.get_ratings_and_info()
+ self.clear()
+ for tune in tunes:
+ iter = self.append(None)
+ self.set(iter,
+ IMMSStore.COL_RATING, tune['rating'],
+ IMMSStore.COL_PATH, tune['path'],
+ IMMSStore.COL_LAST_STR, strtime(curtime-tune['last']),
+ IMMSStore.COL_LAST, tune['last'],
+ IMMSStore.COL_SELECT, gtk.FALSE)
+ def _check_song_path(self, path, giter, song):
+ self.set(giter, 4, self.get_value(giter, 1) == song)
+ def set_current_song(self):
+ self.foreach(IMMSStore._check_song_path, self.xmms.get_current_file())
+
+class IMMSView(gtk.TreeView):
+ def __init__(self, model, xmms):
+ gtk.TreeView.__init__(self, model)
+ self.create_widgets()
+ def create_widgets(self):
+ renderer = gtk.CellRendererText()
+ renderer.set_property('weight', 700)
+ # renderer.connect('double-clicked', on_clicked)
+ column = gtk.TreeViewColumn(_("Rating"), renderer,
+ weight_set = IMMSStore.COL_SELECT,
+ text = IMMSStore.COL_RATING)
+ column.set_sort_column_id(IMMSStore.COL_RATING)
+ self.append_column(column)
+ column = gtk.TreeViewColumn(_("File"), renderer,
+ weight_set = IMMSStore.COL_SELECT,
+ text = IMMSStore.COL_PATH)
+ column.set_resizable(gtk.TRUE)
+ column.set_sort_column_id(IMMSStore.COL_PATH)
+ column.set_clickable(gtk.TRUE)
+ self.append_column(column)
+ column = gtk.TreeViewColumn(_("Last"), renderer,
+ weight_set = IMMSStore.COL_SELECT,
+ text = IMMSStore.COL_LAST_STR)
+ column.set_sort_column_id(IMMSStore.COL_LAST)
+ self.append_column(column)
+ self.set_search_column(IMMSStore.COL_PATH)
+ self.set_headers_clickable(gtk.TRUE)
+ def get_selected(self):
+ model, giter = self.get_selection().get_selected()
+ return model.get_value(giter, IMMSStore.COL_PATH)
+
+class IMMSToolbar(gtk.Toolbar):
def __init__(self):
- self.cx = sqlite.connect(_dbname)
- def commit(self):
- self.cx.commit()
- def _get_ratings(self, min = 0, max = 250):
- cu = self.cx.cursor()
- cu.execute('''SELECT Rating.uid, Rating.rating
- FROM Rating
- WHERE Rating.rating >= %d
- AND Rating.rating <= %d
- ORDER BY Rating.rating;''' % (min, max))
- return cu.fetchall()
- def _get_library_uid(self, uid):
- cu = self.cx.cursor()
- cu.execute('''SELECT Library.path
- FROM Library
- WHERE Library.uid = %d;''' % (uid,))
- return cu.fetchone()
- def _get_library_by_path(self, path):
- cu = self.cx.cursor()
- cu.execute('''SELECT Library.uid, Library.sid
- FROM Library
- WHERE Library.path = '%s';''' % (path))
- def get_ratings_and_info(self):
- cu = self.cx.cursor()
- cu.execute('''SELECT Rating.uid, Rating.rating,
- Library.path, Last.last
- FROM Rating, Library, Last
- WHERE Rating.uid = Library.uid AND
- Library.sid = Last.sid
- ORDER BY Rating.rating DESC;''')
- # Better to fetch everything since locking can really mess
- # things in imms plugin.
- res = cu.fetchall()
- self.commit()
- results = []
- for tune in res:
- tmp = {'rating' : tune[1],
- 'path' : tune[2],
- 'last' : int(tune[3])}
- results.append(tmp)
- return results
-
-class IMMSView(Tkinter.Frame):
- def __init__(self, xmms, db, master = None):
- Tkinter.Frame.__init__(self, master)
- self.db = db
- self.xmms = xmms
+ gtk.Toolbar.__init__(self)
+ self.refresh_command = None
+ self.select_command = None
self.create_widgets()
def create_widgets(self):
- lf = Tkinter.Frame(self)
- lf.pack(expand = 1, fill = Tkinter.BOTH, side = Tkinter.LEFT)
- self.lb = Tkinter.Listbox(lf, relief = Tkinter.RAISED)
- self.lb.pack(expand = 1, side = Tkinter.TOP, fill = Tkinter.BOTH)
- xsb = Tkinter.Scrollbar(lf, orient = Tkinter.HORIZONTAL)
- xsb.pack({'fill' : Tkinter.X, 'side' : Tkinter.BOTTOM})
- ysb = Tkinter.Scrollbar(self)
- ysb.pack({'fill' : Tkinter.Y, 'side' : Tkinter.RIGHT})
-
- ysb['command'] = self.lb.yview
- xsb['command'] = self.lb.xview
- self.lb['yscrollcommand'] = ysb.set
- self.lb['xscrollcommand'] = xsb.set
- self.lb.bind("<Double-Button-1>", self.play_selection)
-
- self.refresh()
-
- def refresh(self):
- curtime = time.time()
- self.tunes = self.db.get_ratings_and_info()
- self.lb.delete(0,self.lb.size())
- l = []
- for tune in self.tunes:
- l.append("%4d: %s [%s]" %
- (tune['rating'], tune['path'],
- strtime(curtime - tune['last'])))
- apply(self.lb.insert, [0]+ l)
- self.select_current()
- def select_current(self):
- fn = self.xmms.get_current_file()
- tune = filter(lambda x: x['path'] == fn, self.tunes)
- if len(tune):
- idx = self.tunes.index(tune[0])
- self.lb.see(idx)
- self.lb.select_set(idx)
- def play_selection(self, event):
- sel = self.lb.curselection()
- if len(sel) > 0:
- fn = self.tunes[int(sel[0])]['path']
- self.xmms.play_file(fn)
-
-class IMMSToolbar(Tkinter.Frame):
- def __init__(self, master = None):
- Tkinter.Frame.__init__(self, master)
- self.refresh_command = None
- self.create_widgets()
- def create_widgets(self):
- button = Tkinter.Button(self, text = _('Refresh'),
- command = self.do_refresh)
- button.pack(side = Tkinter.LEFT)
- button = Tkinter.Button(self, text = _('Plot'),
- command = self.plot)
- button.pack(side = Tkinter.LEFT)
- button = Tkinter.Button(self, text = _('Current'),
- command = self.do_get_current)
- button.pack(side = Tkinter.LEFT)
- def plot(self):
- os.system('exec immsplot &')
- def do_refresh(self):
+ self.append_item(_('Refresh'), _('Refresh list'),
+ None, None, self.do_refresh)
+ self.append_item(_('Plot'), _('Show graph of rates'),
+ None, None, self.plot)
+ self.append_item(_('Current'), _('Get current song'),
+ None, None, self.do_get_current)
+ def plot(self, data):
+ os.system('/home/fabien/bin/immsplot &')
+ def do_refresh(self, data):
if (self.refresh_command):
self.refresh_command()
- def do_get_current(self):
+ def do_get_current(self, data):
if (self.get_current):
self.get_current()
-root = Tkinter.Tk()
-root.wm_title(_("IMMSview"))
-iview = IMMSView(XMMSControl(), IMMSDb(), root)
-iview.pack(side = Tkinter.BOTTOM, expand = 1, fill = Tkinter.BOTH)
+root = gtk.Window()
+root.set_name(_("IMMSview"))
+root.connect('destroy', gtk.mainquit)
+vbox = gtk.VBox(spacing = 3)
+root.add(vbox)
+vbox.show()
+xmms_control = XMMSControl()
+model = IMMSStore(IMMSDb(), xmms_control)
+iview = IMMSView(model, xmms_control)
+scroll = gtk.ScrolledWindow()
+scroll.add(iview)
+vbox.pack_end(scroll)
+iview.show()
+scroll.show()
toolbar = IMMSToolbar()
-toolbar.refresh_command = iview.refresh
-toolbar.get_current = iview.select_current
-toolbar.pack(side = Tkinter.TOP, fill = Tkinter.X)
-root.mainloop()
+toolbar.refresh_command = model.refresh
+toolbar.get_current = model.set_current_song
+vbox.pack_start(toolbar, expand = gtk.FALSE)
+toolbar.show()
+root.show()
+model.refresh()
+model.set_current_song()
+gtk.main()