immsview
author fabien
Sun, 01 Feb 2004 11:12:45 -0500
branchimmsview
changeset 3 d488fff3852f
parent 2 fc119540f904
child 4 2bd676cc3f22
permissions -rwxr-xr-x
[svn] Add current and correct plot function.

#!/usr/bin/python

_immsview_version = "$Id: immsview 1685 2004-02-01 16:12:45Z fabien $"

# Copyright (C) 2004 by Fabien Ninoles

# IMMSView is aim to be a replacement to XMMS playlist editor
# with better support for IMMS plugin.

# IMMSView is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.

# IMMSView is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with GNU Emacs; see the file COPYING.  If not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

# The aim of immsview is to become a better playlist editor than the
# normal

# TODO:
# * IMMS:
#   - Add Artist, Title, SID, etc.
#   - Add composed rating
#   - Columns ordering (should pass to GTK probably for this).
#   - Rating edition
# * XMMS:
#   - selecting a song
#   - getting current playlist
#   - editing playlist
# * File support:
#   - adding, deleting, suppressing a file (including updating other
#     interface).

import sys
import os
import sqlite
import Tkinter
import ScrolledText
import gettext
import xmms.control
import time

gettext.bindtextdomain('immsview', '/usr/share/immsview/LANG')
gettext.textdomain('immsview')
_ = gettext.gettext

_dbname = os.environ['HOME'] + '/.imms/imms.db'

def strtime(seconds):
    secs = abs(round(seconds))
    minutes = secs / 60;
    hours = minutes / 60;
    days = hours / 24;
    secs = secs % 60;
    minutes %= 60;
    hours %= 24;

    if seconds < 0:
            s = "-"
    else:
            s = ""
    if days >= 1:
            s += "%dd %dh" % (days, hours)
    elif hours >= 1:
            s += "%dh%02d" % (hours, minutes)
    elif minutes >= 1:
            s += "%d'%02d\"" % (minutes, secs)
    else:
            s += "%d\"" % (secs)
    return s


class IMMSDb:
	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, master = None):
		Tkinter.Frame.__init__(self, master)
		self.db = IMMSDb()
                self.xmms = xmms.control
		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.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_playlist_file(
                        self.xmms.get_playlist_pos())
                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)

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):
		if (self.refresh_command):
			self.refresh_command()
        def do_get_current(self):
                if (self.get_current):
                        self.get_current()

root = Tkinter.Tk()
iview = IMMSView(root)
iview.pack(side = Tkinter.BOTTOM, expand = 1, fill = Tkinter.BOTH)
toolbar = IMMSToolbar()
toolbar.refresh_command = iview.refresh
toolbar.get_current = iview.select_current
toolbar.pack(side = Tkinter.TOP, fill = Tkinter.X)
root.mainloop()