Last.fm stuff, insert rows in library view

git-svn-id: file:///home/anna/Desktop/ocarina-legacy/mithos/ocarina@45 1daee41c-8060-4895-b1f0-2197c00d777a
This commit is contained in:
bjschuma 2009-07-13 03:42:43 +00:00
parent 57393a9150
commit 5b752c95e8
11 changed files with 352 additions and 125 deletions

View File

@ -1,15 +1,26 @@
open: open:
geany src/GuiObjects/*.py & geany &
geany src/GuiObjects/*.py
geany src/*.py geany src/*.py
clean: clean:
rm -rf src/*.pyo rm -rf src/*.pyo
rm -rf src/*~ rm -rf src/*~
rm -rf src/*.c
rm -rf src/*.o
rm -rf src/*.so
rm -rf src/GuiObjects/*.pyo rm -rf src/GuiObjects/*.pyo
rm -rf src/GuiObjects/*~ rm -rf src/GuiObjects/*~
rm -rf src/GuiObjects/*.c
rm -rf src/GuiObjects/*.o
rm -rf src/GuiObjects/*.so
rm *~ rm *~
compile:
cd src && ./cythonize
cd src/GuiObjects && ./cythonize
install: install:
# mkdir ~/bin/ocarina-bin # mkdir ~/bin/ocarina-bin
rsync -avz src/ ~/bin/ocarina-bin/src rsync -avz src/ ~/bin/ocarina-bin/src

View File

@ -16,9 +16,9 @@ class ControlPanel(gtk.HBox):
self.next = plist.next self.next = plist.next
self.pack_start(CheckButton("Random",self.toggleRand,self.data.random),False,False,0) self.pack_start(CheckButton("Random",self.toggleRand,self.data.random),False,False,0)
self.makeProgressBar() self.makeProgressBar()
(self.nextImg,self.nextBtn) = self.makeButton("next","next.png",None,self.next)
(self.stopImg,self.stopBtn) = self.makeButton("stop","stop.png",None,self.stop)
(self.playImg,self.plauseBtn) = self.makeButton("plause","play.png",None,self.plause) (self.playImg,self.plauseBtn) = self.makeButton("plause","play.png",None,self.plause)
(self.stopImg,self.stopBtn) = self.makeButton("stop","stop.png",None,self.stop)
(self.nextImg,self.nextBtn) = self.makeButton("next","next.png",None,self.next)
self.show() self.show()
@ -28,7 +28,8 @@ class ControlPanel(gtk.HBox):
if img: if img:
image = Image(os.path.join("images",img)) image = Image(os.path.join("images",img))
button = Button(name,image,text,func) button = Button(name,image,text,func)
self.pack_end(button,False,False,0) #self.pack_end(button,False,False,0)
self.pack_start(button,False,False,0)
return (image,button) return (image,button)
@ -46,14 +47,13 @@ class ControlPanel(gtk.HBox):
event.show() event.show()
vbox.show() vbox.show()
pbar.show() pbar.show()
gobject.timeout_add(1000,self.updatePBar,pbar) gobject.timeout_add(500,self.updatePBar,pbar)
def pbarclick(self,widgit,data,pbar): def pbarclick(self,widgit,data,pbar):
if data.button == 1: if data.button == 1:
prcnt = float(data.x) / float(pbar.get_allocation()[2]) prcnt = float(data.x) / float(pbar.get_allocation()[2])
self.data.song.seek(int(prcnt * self.data.song.info.duration * 1000000000)) self.data.song.seek(int(prcnt * self.data.song.info.duration * 1000000000))
#print float(data.x)/float(pbar.get_allocation()[0])
# Play/Pause function # Play/Pause function
@ -78,15 +78,16 @@ class ControlPanel(gtk.HBox):
# Update time/progress of the progress bar # Update time/progress of the progress bar
def updatePBar(self,pbar): def updatePBar(self,pbar):
if self.data.song and (self.data.song.playing == False): time = 0
if not self.data.song:
return True return True
try: try:
(success,time) = self.data.song.curTime() time = self.data.song.curTime()
except: except:
success = False time = 0
if success == True: if self.data.song.info.duration > 0:
pbar.set_fraction(float(time)/self.data.song.info.duration) pbar.set_fraction(float(time)/self.data.song.info.duration)
pbar.set_text(self.data.song.info.fixTime(time) + " / " + self.data.song.info.length) pbar.set_text(self.data.song.info.fixTime(time) + " / " + self.data.song.info.length)
return True return True

View File

@ -19,9 +19,9 @@ class InfoView(gtk.VBox):
album = "" album = ""
artist = "" artist = ""
if self.data.song: if self.data.song:
title = self.data.song.info.title.title() title = self.data.song.info.title
album = "from "+self.data.song.info.album.title() album = "from "+self.data.song.info.album
artist = "by "+self.data.song.info.artist.title() artist = "by "+self.data.song.info.artist
self.title.set_text(title) self.title.set_text(title)
self.album.set_text(album) self.album.set_text(album)
self.artist.set_text(artist) self.artist.set_text(artist)

View File

@ -8,10 +8,12 @@ from menuItem import MenuItem
class LibView(gtk.VBox): class LibView(gtk.VBox):
def __init__(self,data): def __init__(self,data):
gtk.VBox.__init__(self,False,0) gtk.VBox.__init__(self,False,0)
data.library.libview = self
self.win = gtk.ScrolledWindow() self.win = gtk.ScrolledWindow()
self.win.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC) self.win.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
self.data = data self.data = data
self.treeview = None self.treeview = None
self.tree = gtk.TreeStore(str,int)
self.col = None self.col = None
self.plist = None self.plist = None
self.pbar = gtk.ProgressBar() self.pbar = gtk.ProgressBar()
@ -25,38 +27,36 @@ class LibView(gtk.VBox):
# Use to update the library pane # Use to update the library pane
def update(self): def update(self):
rval = self.data.library.scanning #if self.treeview:
if self.treeview: #self.win.remove(self.treeview)
self.win.remove(self.treeview) #self.treeview.remove_column(self.col)
self.treeview.remove_column(self.col) #self.tree = gtk.TreeStore(str,int)
self.pbar.pulse() #self.pbar.pulse()
self.pbar.set_text("Found "+str(self.data.library.count)+" files.") #self.pbar.set_text("Found "+str(self.data.library.count)+" files.")
tree = gtk.TreeStore(str,int) #for artist in self.data.library.artAlb.keys():
for artist in self.data.library.artAlb.keys(): # ariter = self.tree.append(None,[artist,-1])
ariter = tree.append(None,[artist.title(),-1]) # for album in self.data.library.artAlb[artist]:
for album in self.data.library.artAlb[artist]: # aliter = self.tree.append(ariter,[album,-1])
aliter = tree.append(ariter,[album.title(),-1]) # for track in self.data.library.albTrk[(artist,album)]:
for track in self.data.library.albTrk[(artist,album)]: # self.tree.append(aliter,[self.data.library.files[track].title,self.data.library.files[track].id])
tree.append(aliter,[self.data.library.files[track].title.title(),self.data.library.files[track].id]) self.tree.set_sort_column_id(0,gtk.SORT_ASCENDING)
tree.set_sort_column_id(0,gtk.SORT_ASCENDING) self.treeview = gtk.TreeView(self.tree)
self.treeview = gtk.TreeView(tree) #self.treeview.set_enable_search(True)
self.treeview.set_enable_search(True)
self.treeview.connect("button_release_event",self.clicked) self.treeview.connect("button_release_event",self.clicked)
self.col = gtk.TreeViewColumn('Library ('+str(self.data.library.count)+')') self.col = gtk.TreeViewColumn('Library ('+str(self.data.library.count)+')')
self.treeview.append_column(self.col) self.treeview.append_column(self.col)
cell = gtk.CellRendererText() cell = gtk.CellRendererText()
self.col.pack_start(cell,True) self.col.pack_start(cell,True)
self.col.add_attribute(cell,'text',0) self.col.add_attribute(cell,'text',0)
self.col.set_sort_column_id(0) #self.col.set_sort_column_id(0)
self.treeview.set_rules_hint(True) self.treeview.set_rules_hint(True)
self.treeview.show() self.treeview.show()
self.selection = self.treeview.get_selection() self.selection = self.treeview.get_selection()
self.selection.set_mode(gtk.SELECTION_MULTIPLE) self.selection.set_mode(gtk.SELECTION_MULTIPLE)
self.win.add(self.treeview) self.win.add(self.treeview)
self.updateLabel() for file in self.data.library.files:
if rval==False: self.insertSong(file)
self.pbar.hide() #self.updateLabel()
return rval
def makeLabel(self): def makeLabel(self):
@ -72,7 +72,22 @@ class LibView(gtk.VBox):
# Begin updating the library # Begin updating the library
def updates(self): def updates(self):
self.pbar.show() self.pbar.show()
gobject.timeout_add(1000,self.update) self.updating = True
gobject.timeout_add(500,self.updateLibview)
def updateLibview(self):
self.pbar.set_text("Found "+str(self.data.library.count)+" files.")
self.pbar.pulse()
#self.updateLabel()
self.col.set_title('Library ('+str(self.data.library.count)+')')
return self.updating
def stopUpdates(self):
self.updating = False
self.pbar.hide()
self.data.dump()
# Right click menu # Right click menu
@ -88,6 +103,37 @@ class LibView(gtk.VBox):
self.rcmenu.popup(None,None,None,data.button,data.time) self.rcmenu.popup(None,None,None,data.button,data.time)
def insertSong(self,song):
foundArt = False
foundAlb = False
artist = song.artist
album = song.album
track = song.title
ariter = self.tree.get_iter_root()
while ariter:
if self.tree[ariter][0]==artist:
foundArt = True
break
else:
ariter = self.tree.iter_next(ariter)
aliter = self.tree.iter_children(ariter)
while aliter:
if self.tree[aliter][0]==album:
foundAlb = True
break
else:
aliter = self.tree.iter_next(aliter)
if foundArt == False:
ariter = self.tree.insert(None,0,[artist,-1])
if foundAlb == False:
aliter = self.tree.insert(ariter,0,[album,-1])
self.tree.insert(aliter,0,[song.title.title(),song.id])
def populatePlaylist(self,widgit,func,data): def populatePlaylist(self,widgit,func,data):
(model,pathlist) = self.selection.get_selected_rows() (model,pathlist) = self.selection.get_selected_rows()
list = [] list = []

View File

@ -112,7 +112,7 @@ class PlistView(gtk.Notebook):
i = len(dst) i = len(dst)
for index in src: for index in src:
track = self.data.library.files[index] track = self.data.library.files[index]
dst.insert(i,[track.id,track.title.title(),track.length,track.artist.title(),track.album.title(),track.count]) dst.insert(i,[track.id,track.title,track.length,track.artist,track.album,track.count])
time+=track.duration time+=track.duration
i+=1 i+=1
return time return time
@ -220,6 +220,7 @@ class PlistView(gtk.Notebook):
self.data.curSong = self.pfilter[iter][0] self.data.curSong = self.pfilter[iter][0]
self.loadSong(False) self.loadSong(False)
self.controls.plause(None,None) self.controls.plause(None,None)
self.data.scrobbler.nowPlaying(self.data.library.files[self.data.curSong])
# Go to the next song in the list # Go to the next song in the list
@ -245,7 +246,7 @@ class PlistView(gtk.Notebook):
self.data.playingQ = True self.data.playingQ = True
self.setTabText("queue") self.setTabText("queue")
elif self.data.random == True: elif self.data.random == True:
self.data.curSong = self.pfilter[random.randint(0,len(self.pfilter))][0] self.data.curSong = self.pfilter[random.randint(0,len(self.pfilter)-1)][0]
else: else:
next = self.pfilter[0][0] next = self.pfilter[0][0]
for i in range(len(self.pfilter)-1): for i in range(len(self.pfilter)-1):
@ -261,6 +262,7 @@ class PlistView(gtk.Notebook):
if pause == False: if pause == False:
self.controls.plause(None,None) self.controls.plause(None,None)
self.data.scrobbler.nowPlaying(self.data.library.files[self.data.curSong])
self.controls.changeImg() self.controls.changeImg()
self.status = CONTINUE self.status = CONTINUE
@ -270,6 +272,7 @@ class PlistView(gtk.Notebook):
if len(self.data.curList) == 0: if len(self.data.curList) == 0:
return return
if self.data.song: if self.data.song:
self.data.scrobbler.submit(self.data.song.timestamp)
self.data.song.close() self.data.song.close()
self.data.song = Song(self.data.library.files[self.data.curSong],self.next) self.data.song = Song(self.data.library.files[self.data.curSong],self.next)
self.info.changeLabels() self.info.changeLabels()
@ -328,13 +331,27 @@ class PlistView(gtk.Notebook):
def hideRows(self,list,iter): def hideRows(self,list,iter):
if self.search != "": if self.search == "":
file = self.data.library.files[list[iter][0]] return True
if re.search(self.search,file.title): elif len(self.search) == 1:
try:
self.data.library.files[list[iter][0]].single[self.search]
return True return True
elif re.search(self.search,file.artist): except:
return False
elif len(self.search) == 2:
try:
self.data.library.files[list[iter][0]].double[self.search]
return True return True
elif re.search(self.search,file.album): except:
return True return False
return False #if self.search in self.data.library.files[list[iter][0]].letters == True:
return True # return True
file = self.data.library.files[list[iter][0]]
if re.search(self.search,file.titlel):
return True
elif re.search(self.search,file.artistl):
return True
elif re.search(self.search,file.albuml):
return True
return False

View File

@ -1,10 +1,12 @@
import urllib
import urllib2 import urllib2
#import pygtk #import pygtk
#pygtk.require('2.0') #pygtk.require('2.0')
import gtk import gtk
import webbrowser import webbrowser
#import thread
import hashlib import hashlib
import datetime
import time
from button import Button from button import Button
@ -20,6 +22,12 @@ class Scrobbler(gtk.VBox):
self.key = "2c76f85a6704efd74b5a358821284ef9" self.key = "2c76f85a6704efd74b5a358821284ef9"
self.secret = "3a6012bfb627b60a884cf33fc044885c" self.secret = "3a6012bfb627b60a884cf33fc044885c"
self.token = "" self.token = ""
# Session ID
self.session = ""
# Now playing URL
self.npurl = ""
# Submission URL
self.suburl = ""
# Run these in new thread so we can keep loading other things while waiting # Run these in new thread so we can keep loading other things while waiting
self.makegui() self.makegui()
@ -30,66 +38,165 @@ class Scrobbler(gtk.VBox):
def makegui(self): def makegui(self):
if self.data.lfm == "": if self.data.lfm == "":
self.nosession = Button("lfm",None,"Click here to configure Ocarina for submitting songs to last.fm",self.setup) uname = gtk.Label("Username:")
self.nosession.set_size_request(100,100) username = gtk.Entry()
self.pack_start(self.nosession,False,False,0) passwd = gtk.Label("Password:")
password = gtk.Entry()
password.set_visibility(False)
username.connect("activate",self.fetchSession,username,uname,password,passwd)
password.connect("activate",self.fetchSession,username,uname,password,passwd)
uname.show()
username.show()
passwd.show()
password.show()
self.pack_start(uname,False,False,0)
self.pack_start(username,False,False,0)
self.pack_start(passwd,False,False,0)
self.pack_start(password,False,False,0)
else:
self.handshake()
#self.labels = [gtk.Label("")]*10
self.similar = []
for i in range(10):
label = gtk.Label(" ")
label.show()
self.pack_start(label,False,False,0)
self.similar+=[label]
# One time setup (in theory) def fetchSession(self,widgit,username,uname,password,passwd):
def setup(self,widgit,data): self.data.lfmuser = username.get_text().lower()
self.nosession.hide() self.data.lfmpass = self.md5(password.get_text())
self.remove(self.nosession) if self.data.lfmuser=="" or self.data.lfmpass=="":
self.contBtn = Button("lfm",None,"Click to continue",self.fetchSession)
self.pack_start(self.contBtn,False,False,0)
self.fetchToken()
self.authorize()
# Fetch the authentication token
def fetchToken(self):
(url,list) = self.addMethod("auth.gettoken")
(url,list) = self.addParam(url,list,"api_key",self.key)
status = self.placeRequest(url)
attr = status.getAttributeNode("status")
if attr.value != "ok":
return return
self.token += hashlib.md5(status.firstChild.nextSibling.firstChild.data).hexdigest() else:
self.token = self.md5(self.data.lfmuser+self.data.lfmpass)
(url,list) = self.addMethod(self.url,"auth.getMobileSession")
(url,list) = self.addParam(url,list,"username",self.data.lfmuser)
(url,list) = self.addParam(url,list,"authToken",self.token)
(url,list) = self.addParam(url,list,"api_key",self.key)
(url,list) = self.addParam(url,list,"api_sig",self.getSig(list))
status = self.parseRequest(url)
attr = status.getAttributeNode("status")
if attr.value != "ok":
return
self.data.lfm = status.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling.firstChild.data
username.hide()
uname.hide()
password.hide()
passwd.hide()
self.makegui()
# Open to authorization page def handshake(self):
def authorize(self): print "shaking hands"
url = "http://www.last.fm/api/auth/?api_key="+self.key url = "http://post.audioscrobbler.com/?hs=true"
#(url,list) = self.addParam(url,[],"api_key",self.key) list = [("hs","true")]
(url,list) = self.addParam(url,[],"token",self.token) (url,list) = self.addParam(url,list,"p","1.2.1")
print url (url,list) = self.addParam(url,list,"c","tst")
#url+="&"+self.token (url,list) = self.addParam(url,list,"v","1.0")
webbrowser.open(url) (url,list) = self.addParam(url,list,"u",self.data.lfmuser)
tstp = self.timestamp()
(url,list) = self.addParam(url,list,"t",tstp)
def fetchSession(self,widgit,data): (url,list) = self.addParam(url,list,"a",self.authToken(tstp))
(url,list) = self.addMethod("auth.getSession")
(url,list) = self.addParam(url,list,"api_key",self.key) (url,list) = self.addParam(url,list,"api_key",self.key)
(url,list) = self.addParam(url,list,"token",self.token) status = self.placeRequest(url).readlines()
sig = self.getSig(list) if status[0].strip() != "OK":
(url,list) = self.addParam(url,None,"api_sig",sig) return
print url self.session = status[1].strip()
#status = self.placeRequest(url) self.npurl = status[2].strip()#+"/?"
return self.suburl = status[3].strip()#+"/?"
#attr = status.getAttributeNode("status") #for line in status:
#if attr.value != "ok": # print line.strip()
# return
#node = status.firstChild.firstChild def nowPlaying(self,info):
#user = node.data vals = {"s":self.session,
#key = node.nextSibling.data "a":info.artist.title(),
#subscriber = node.nextSibling.nextSibling.data "t":info.title.title(),
#print user,key,subscriber "b":info.album.title(),
"l":str(info.duration),
"n":info.tnum,
"m":""}
data = urllib.urlencode(vals)
#status = self.placeRequest(url).readlines()
req = urllib2.Request(self.npurl,data)
req.add_header("User-Agent","Ocarina")
status = urllib2.urlopen(req)
self.fetchSimilar(info.artist)
#if status[0].strip() == "OK":
# print "Submission successful"
def addMethod(self,method): def submit(self,timestp):
info = self.data.song.info
if info.duration < 30:
return
exit = True
if (self.data.song.position > 240):
exit = False
if self.data.song.position > (self.data.song.info.duration/2):
exit = False
if exit == True:
return
vals = {"s":self.session,
"a[0]":info.artist.title(),
"t[0]":info.title.title(),
"i[0]":timestp,
"o[0]":"P",
"r[0]":"",
"l[0]":str(info.duration),
"b[0]":info.album.title(),
"n[0]":info.tnum,
"m[0]":""}
data = urllib.urlencode(vals)
req = urllib2.Request(self.suburl,data)
req.add_header("User-Agent","Ocarina")
status = urllib2.urlopen(req)
for line in status:
print line
#print status
def fetchSimilar(self,artist):
(url,list) = self.addMethod(self.url,"artist.getsimilar")
(url,list) = self.addParam(url,list,"artist",artist)
(url,list) = self.addParam(url,list,"limit","10")
(url,list) = self.addParam(url,list,"api_key",self.key)
status = self.parseRequest(url)
list = status.firstChild.nextSibling.childNodes
for i in range(list.length):
node = list.item(i)
if node.hasChildNodes()==True:
nameNode = node.firstChild.nextSibling.firstChild
self.similar[i/2].set_text(nameNode.data)
#for node in status.firstChild.childNodes:
# print node
def authToken(self,t):
return self.md5(self.data.lfmpass+t)
def md5(self,string):
return hashlib.md5(string).hexdigest()
def timestamp(self):
now = datetime.datetime.now()
return str(int(time.mktime(now.timetuple())))
def addMethod(self,url,method):
return (self.url+"?method="+method,[("method",method)]) return (self.url+"?method="+method,[("method",method)])
def addParam(self,url,list,param,val): def addParam(self,url,list,param,val):
val = val.replace(" ","%20")
url+="&"+param+"="+val url+="&"+param+"="+val
if list: if list:
list += [(param,val)] list += [(param,val)]
@ -102,19 +209,19 @@ class Scrobbler(gtk.VBox):
string = "" string = ""
for entry in list: for entry in list:
string+=entry[0]+entry[1] string+=entry[0]+entry[1]
string = string + self.secret #string = string + self.secret
m = hashlib.md5(string) return self.md5(string+self.secret)
return m.hexdigest() #m = hashlib.md5(string)
#return m.hexdigest()
def sendReq(self,req):
req+=self.secret
#hash = md5.new(req).digest()
#return self.placeRequest(self.url+"?"+hash)
def placeRequest(self,url): def placeRequest(self,url):
#print url #print url
req = urllib2.Request(url) req = urllib2.Request(url)
req.add_header('User-Agent','Ocarina') req.add_header('User-Agent','Ocarina')
return minidom.parse(urllib2.urlopen(req)).documentElement #return minidom.parse(urllib2.urlopen(req)).documentElement
return urllib2.urlopen(req)
def parseRequest(self,url):
return minidom.parse(self.placeRequest(url)).documentElement

View File

@ -9,24 +9,26 @@ import thread
class Library: class Library:
#def __init__(self,prnt): #def __init__(self,prnt):
def __init__(self): def __init__(self):
self.goodTypes = ["ogg","mp3","wav","flac","mid"]#,"wma"] self.goodTypes = ["ogg","mp3","flac"]#,"wma"]
self.reset() self.reset()
self.scanning = False #self.scanning = False
self.libview = None
#self.notAdded = open("/home/bjschuma/Desktop/notAdded.txt",'w') #self.notAdded = open("/home/bjschuma/Desktop/notAdded.txt",'w')
# Begin a scan on dir # Begin a scan on dir
def scan(self,thread,dir): def scan(self,thread,dir):
self.scanning = True #self.scanning = True
self.reset() self.reset()
self.libview.updates()
self.path = os.path.expanduser(dir) self.path = os.path.expanduser(dir)
if os.path.exists(self.path) == False: if os.path.exists(self.path) == False:
#print "Directory not found: %s" % dir #print "Directory not found: %s" % dir
return return
#print "Scanning: "+self.path #print "Scanning: "+self.path
self.traverse("") self.traverse("")
self.scanning = False self.libview.stopUpdates()
#self.scanning = False
#print "Found %s files!" % str(self.count) #print "Found %s files!" % str(self.count)
@ -58,6 +60,7 @@ class Library:
song.filename = os.path.join(self.path,joined) song.filename = os.path.join(self.path,joined)
self.files+=[song] self.files+=[song]
thread.start_new_thread(self.add,(self.hash(joined),self.count)) thread.start_new_thread(self.add,(self.hash(joined),self.count))
#self.add(self.hash(joined),self.count)
self.count += 1 self.count += 1
#self.add(self.hash(joined),joined) #self.add(self.hash(joined),joined)
#else: #else:
@ -99,18 +102,22 @@ class Library:
info.album = t.album info.album = t.album
if t.artist != "": if t.artist != "":
info.artist = t.artist info.artist = t.artist
#info.tnum = str(t.track)
a = f.audioProperties() a = f.audioProperties()
info.setTime(a.length) info.setTime(a.length)
except: except:
print info.filename print info.filename
#print "here"
info.title = info.title.lower() #info.title = info.title.lower()
info.album = info.album.lower() #info.album = info.album.lower()
info.artist = info.artist.lower() #info.artist = info.artist.lower()
artist = info.artist artist = info.artist.lower()
album = info.album info.artistl = artist
album = info.album.lower()
info.albuml = album
title = info.title.lower()
info.titlel = title
if (artist in self.artAlb.keys()) == False: if (artist in self.artAlb.keys()) == False:
self.artAlb[artist] = [album] self.artAlb[artist] = [album]
@ -121,6 +128,24 @@ class Library:
self.albTrk[(artist,album)] = [index] self.albTrk[(artist,album)] = [index]
else: else:
self.albTrk[(artist,album)] += [index] self.albTrk[(artist,album)] += [index]
for letter in title:
info.single[letter] = True
for letter in artist:
info.single[letter] = True
for letter in album:
info.single[letter] = True
for i in range(len(title)-1):
str = title[i]+title[i+1]
info.double[str] = True
for i in range(len(artist)-1):
str = artist[i]+artist[i+1]
info.double[str] = True
for i in range(len(album)-1):
str = album[i]+album[i+1]
info.double[str] = True
self.libview.insertSong(info)
# Return true if file is in the library # Return true if file is in the library

View File

@ -11,6 +11,7 @@ class SavedData:
self.path = path self.path = path
self.song = None self.song = None
self.quit = None self.quit = None
self.scrobbler = None
if os.path.exists(self.path) == False: if os.path.exists(self.path) == False:
os.mkdir(self.path) os.mkdir(self.path)
self.load(path,options) self.load(path,options)
@ -19,10 +20,11 @@ class SavedData:
# Dump user data to a file # Dump user data to a file
def dump(self): def dump(self):
self.library.libview = None
self.save(self.library,"library") self.save(self.library,"library")
self.save([self.curList,self.curQ,self.curSong,self.playingQ],"playlist") self.save([self.curList,self.curQ,self.curSong,self.playingQ],"playlist")
self.save([self.size,self.divider,self.colSizes,self.sortedCol,self.random],"preferences") self.save([self.size,self.divider,self.colSizes,self.sortedCol,self.random],"preferences")
self.save(self.lfm,"last.fm") self.save([self.lfm,self.lfmuser,self.lfmpass],"last.fm")
def save(self,obj,file): def save(self,obj,file):
@ -65,9 +67,15 @@ class SavedData:
self.sortedCol = prefs[3] self.sortedCol = prefs[3]
self.random = prefs[4] self.random = prefs[4]
self.lfm = self.load2("last.fm") lfm = self.load2("last.fm")
if self.lfm == None: if lfm == None:
self.lfm = "" self.lfm = ""
self.lfmuser = ""
self.lfmpass = ""
else:
self.lfm = lfm[0]
self.lfmuser = lfm[1]
self.lfmpass = lfm[2]
def load2(self,file): def load2(self,file):

View File

@ -1,3 +1,5 @@
import datetime
import time
import gst import gst
@ -12,6 +14,7 @@ class Song():
self.bin.set_property("uri","file://"+self.info.filename) self.bin.set_property("uri","file://"+self.info.filename)
self.bin.set_state(gst.STATE_PAUSED) self.bin.set_state(gst.STATE_PAUSED)
self.player.add(self.bin) self.player.add(self.bin)
self.timestamp = str(int(time.mktime(datetime.datetime.now().timetuple())))
# initialize bus # initialize bus
bus = self.player.get_bus() bus = self.player.get_bus()
@ -52,9 +55,9 @@ class Song():
def stop(self): def stop(self):
self.player.set_state(gst.STATE_PAUSED) self.player.set_state(gst.STATE_PAUSED)
self.playing = False self.playing = False
self.current = 0 self.position = 0
#self.player.seek_simple(self.time_format,gst.SEEK_FLAG_FLUSH,self.current) #self.player.seek_simple(self.time_format,gst.SEEK_FLAG_FLUSH,self.current)
self.seek(current) self.seek(self.position)
def seek(self,time): def seek(self,time):
@ -68,7 +71,8 @@ class Song():
# Print out current running time # Print out current running time
def curTime(self): def curTime(self):
if self.playing == False: #if self.playing == False:
return (False,False) # return (True,self.position)
self.position = self.player.query_position(self.time_format,None)[0]/1000000000 self.position = self.player.query_position(self.time_format,None)[0]/1000000000
return (True, self.position) #return (True, self.position)
return self.position

View File

@ -4,13 +4,19 @@ class SongInfo:
def __init__(self): def __init__(self):
self.id = 0 self.id = 0
self.filename = "" self.filename = ""
self.tnum = ""
self.count = 0 self.count = 0
# Length is a string, duration is an int # Length is a string, duration is an int
self.length = "" self.length = ""
self.duration = 0 self.duration = 0
self.title = "" self.title = ""
self.titlel = ""
self.album = "" self.album = ""
self.albuml = ""
self.artist = "" self.artist = ""
self.artistl = ""
self.single = dict()
self.double = dict()
def setTime(self,time): def setTime(self,time):

View File

@ -74,6 +74,7 @@ class Window(gtk.Window):
# Used to select a directory # Used to select a directory
def selectDir(self,widgit,data,func): def selectDir(self,widgit,data,func):
self.deleteLib(None,None)
dirsel = gtk.FileChooserDialog(None,action=gtk.FILE_CHOOSER_ACTION_OPEN,buttons =(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)) dirsel = gtk.FileChooserDialog(None,action=gtk.FILE_CHOOSER_ACTION_OPEN,buttons =(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
dirsel.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER) dirsel.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
response = None response = None
@ -109,6 +110,7 @@ class Window(gtk.Window):
scrobLabel = gtk.Label("Last.fm") scrobLabel = gtk.Label("Last.fm")
scrobLabel.set_angle(90) scrobLabel.set_angle(90)
leftPane.append_page(scrobbler,scrobLabel) leftPane.append_page(scrobbler,scrobLabel)
self.data.scrobbler = scrobbler
self.divider.add1(leftPane) self.divider.add1(leftPane)