Another new icon from andrew, keeping track of play count, more work on last.fm

git-svn-id: file:///home/anna/Desktop/ocarina-legacy/mithos/ocarina@41 1daee41c-8060-4895-b1f0-2197c00d777a
This commit is contained in:
bjschuma 2009-07-02 04:40:56 +00:00
parent 0bf69cb3e3
commit 22c61164c1
14 changed files with 185 additions and 87 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
trunk/images/ocarina512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -1,3 +1,3 @@
# Used for initializing things in the GuiObjects directory
__all__ = ['button','menuItem','libView','infoView','plistView']
__all__ = ['button','check','controlPanel','image','scrobbler','menuItem','libView','infoView','plistView']

View File

@ -14,8 +14,10 @@ class Button(gtk.Button):
#box.add(image)
if text != None:
label = gtk.Label(text)
label.set_line_wrap(True)
label.set_size_request(100,100)
label.show()
box.pack_start(label,False,False,0)
box.pack_start(label,True,True,0)
box.show()
self.add(box)
self.connect("clicked",func,name)

View File

@ -71,7 +71,7 @@ class ControlPanel(gtk.HBox):
except:
success = False
if success == True:
time = time/1000000000
#time = time/1000000000
pbar.set_fraction(float(time)/self.data.song.info.duration)
pbar.set_text(self.data.song.info.fixTime(time) + " / " + self.data.song.info.length)
return True

View File

@ -121,7 +121,7 @@ class PlistView(gtk.Notebook):
col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
col.set_min_width(2)
col.set_max_width(700)
col.set_sort_indicator(True)
col.set_sort_indicator(False)
if cols[i] != "Id":
tree.append_column(col)
tree.set_rules_hint(True)
@ -197,6 +197,15 @@ class PlistView(gtk.Notebook):
# Go to the next song in the list
def next(self,widgit,data):
self.data.playingQ = False
#print float(self.data.song.position)/float(self.data.song.info.duration)
if (float(self.data.song.position)/float(self.data.song.info.duration)) >= 0.75:
for row in self.plist:
if row[0]==self.data.curSong:
row[5]+=1
break
self.data.library.files[self.data.curSong].count+=1
#if self.plist[self.data.curSong][0]==self.data.curSong:
# self.plist[self.data.curSong][5]+=1
if len(self.data.curQ) > 0:
self.data.curSong = self.qlist[0][0]
self.data.curQ.pop(self.data.curQ.index(self.data.curSong))

View File

@ -4,6 +4,9 @@ pygtk.require('2.0')
import gtk
import webbrowser
import thread
import hashlib
from button import Button
import xml.dom
from xml.dom import minidom
@ -14,40 +17,103 @@ class Scrobbler(gtk.VBox):
gtk.VBox.__init__(self,False,0)
self.data = data
self.url = "http://ws.audioscrobbler.com/2.0/"
self.key = "api_key=2c76f85a6704efd74b5a358821284ef9"
self.token = "token="
self.key = "2c76f85a6704efd74b5a358821284ef9"
self.secret = "3a6012bfb627b60a884cf33fc044885c"
self.token = ""
# Run these in new thread so we can keep loading other things while waiting
thread.start_new_thread(self.setup,("setup",None))
#self.fetchToken()
#self.authorize()
self.makegui()
#thread.start_new_thread(self.setup,("setup",None))
#self.makeRequest()
self.show()
def makegui(self):
if self.data.lfm == "":
self.nosession = Button("lfm",None,"Click here to configure Ocarina for submitting songs to last.fm",self.setup)
self.nosession.set_size_request(100,100)
self.pack_start(self.nosession,False,False,0)
# One time setup (in theory)
def setup(self,widgit,data):
self.nosession.hide()
self.remove(self.nosession)
self.contBtn = Button("lfm",None,"Click to continue",self.fetchSession)
self.pack_start(self.contBtn,False,False,0)
self.fetchToken()
self.authorize()
def addMethod(self,method):
return self.url+"?method="+method
def authorize(self):
url = "http://www.last.fm/api/auth/?"
url+=self.key+"&"+self.token
webbrowser.open(url)
# Fetch the authentication token
def fetchToken(self):
url = self.addMethod("auth.gettoken")+"&"+self.key
req = urllib2.Request(url)
req.add_header('User-Agent','Ocarina')
status = minidom.parse(urllib2.urlopen(req)).documentElement
(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
self.token += status.firstChild.nextSibling.firstChild.data
print self.token
self.token += hashlib.md5(status.firstChild.nextSibling.firstChild.data).hexdigest()
# Open to authorization page
def authorize(self):
url = "http://www.last.fm/api/auth/?"
(url,list) = self.addParam(url,[],"api_key",self.key)
(url,list) = self.addParam(url,[],"token",self.token)
#url+="&"+self.token
webbrowser.open(url)
def fetchSession(self,widgit,data):
(url,list) = self.addMethod("auth.getSession")
(url,list) = self.addParam(url,list,"api_key",self.key)
(url,list) = self.addParam(url,list,"token",self.token)
sig = self.getSig(list)
(url,list) = self.addParam(url,None,"api_sig",sig)
print url
#status = self.placeRequest(url)
return
attr = status.getAttributeNode("status")
if attr.value != "ok":
return
node = status.firstChild.firstChild
user = node.data
key = node.nextSibling.data
subscriber = node.nextSibling.nextSibling.data
#print user,key,subscriber
def addMethod(self,method):
return (self.url+"?method="+method,[("method",method)])
def addParam(self,url,list,param,val):
url+="&"+param+"="+val
if list:
list += [(param,val)]
return url,list
#return (url+"&"+param+"="+val,list+[(param,val)])
def getSig(self,list):
list.sort()
string = ""
for entry in list:
string+=entry[0]+entry[1]
string = string + self.secret
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):
print url
req = urllib2.Request(url)
req.add_header('User-Agent','Ocarina')
return minidom.parse(urllib2.urlopen(req)).documentElement

View File

@ -9,9 +9,10 @@ import thread
class Library:
#def __init__(self,prnt):
def __init__(self):
self.goodTypes = ["ogg","mp3"]#,"wma"]
self.goodTypes = ["ogg","mp3","wav","avi","flac","mid"]#,"wma"]
self.reset()
self.scanning = False
#self.notAdded = open("/home/bjschuma/Desktop/notAdded.txt",'w')
# Begin a scan on dir
@ -53,9 +54,14 @@ class Library:
tSplit = entry.rsplit('.')
type = tSplit[len(tSplit)-1].lower()
if (type in self.goodTypes) == True:
song = SongInfo()
song.filename = os.path.join(self.path,joined)
self.files+=[song]
thread.start_new_thread(self.add,(self.hash(joined),self.count))
self.count += 1
thread.start_new_thread(self.add,(self.hash(joined),joined,self.count-1))
#self.add(self.hash(joined),joined)
#else:
# self.notAdded.write(os.path.join(self.path,joined)+"\n")
# Hash a file and return list of words
@ -68,11 +74,8 @@ class Library:
# Add song to library
def add(self,words,file,index):
#self.files+=[SongInfo()]
self.files.insert(index,SongInfo())
def add(self,words,index):
info = self.files[index]
info.filename = os.path.join(self.path,file)
info.count = 0
info.id = index
split = info.filename.rsplit(os.sep)
@ -87,18 +90,20 @@ class Library:
else:
info.artist = split[len(split)-3]
f = tagpy.FileRef(info.filename)
t = f.tag()
if t.title != "":
info.title = t.title
if t.album != "":
info.album = t.album
if t.artist != "":
info.artist = t.artist
a = f.audioProperties()
info.setTime(a.length)
try:
f = tagpy.FileRef(info.filename)
t = f.tag()
if t.title != "":
info.title = t.title
if t.album != "":
info.album = t.album
if t.artist != "":
info.artist = t.artist
a = f.audioProperties()
info.setTime(a.length)
except:
print info.filename
artist = info.artist.lower()
album = info.album.lower()

View File

@ -39,7 +39,7 @@ class main:
self.data.size = self.window.get_size()
self.data.divider = self.window.divider.get_position()
self.window.plistview.saveCols()
self.data.clearSong()
#self.data.clearSong()
self.data.dump()
#self.library.dump()
gtk.main_quit()

View File

@ -1,3 +1,4 @@
import gobject
import os
import cPickle as pickle
from library import Library
@ -7,60 +8,74 @@ from song import Song
class SavedData:
def __init__(self,options):
path = os.path.join(options.user,".ocarina")
path = os.path.join(path,"ocarina-data.data")
self.size = (800,600)
self.divider = 150
self.library = Library()
self.curList = []
self.curQ = []
self.updateQ = False
self.playingQ = False
self.curSong = 0
self.colSizes = [110,110,110,110,110]
self.sortedCol = 3
self.updateList = False
self.path = path
self.song = None
self.random = False
self.quit = None
if os.path.exists(path):
try:
self.load(path,options)
except:
if options.verbose == True:
print "Error loading user data"
if os.path.exists(self.path) == False:
os.mkdir(self.path)
self.load(path,options)
#gobject.timeout_add(600000,self.dump)
# Dump user data to a file
def dump(self):
out = open(self.path,'w')
self.save(self.library,"library")
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.lfm,"last.fm")
def save(self,obj,file):
out = open(os.path.join(self.path,file),'w')
p = pickle.Pickler(out,1)
p.dump(self)
p.dump(obj)
out.close()
def clearSong(self):
self.song.close()
self.song = None
return
# Read user data from the file
# Create values if files do not exist
def load(self,path,options):
if options.verbose == True:
print "User data found, loading..."
p = pickle.Unpickler(open(path))
data = p.load()
#self.size = data.size
self.divider = data.divider
self.library = data.library
self.curList = data.curList
self.curSong = 0
self.colSizes = data.colSizes
self.path = data.path
self.random = data.random
self.curSong = data.curSong
self.curQ = data.curQ
self.playingQ = data.playingQ
self.library = self.load2("library")
if self.library == None:
self.library = Library()
plist = self.load2("playlist")
if plist == None:
self.curList = []
self.curQ = []
self.curSong = 0
self.playingQ = False
else:
self.curList = plist[0]
self.curQ = plist[1]
self.curSong = plist[2]
self.playingQ = plist[3]
prefs = self.load2("preferences")
if prefs == None:
self.size = (800,600)
self.divider = 150
self.colSizes = [110,110,110,110,110]
self.sortedCol = 3
self.random = False
else:
self.size = prefs [0]
self.divider = prefs[1]
self.colSizes = prefs[2]
self.sortedCol = prefs[3]
self.random = prefs[4]
self.lfm = self.load2("last.fm")
if self.lfm == None:
self.lfm = ""
def load2(self,file):
path = os.path.join(self.path,file)
if os.path.exists(path):
p = pickle.Unpickler(open(path))
data = p.load()
return data
return None

View File

@ -68,4 +68,5 @@ class Song():
def curTime(self):
if self.playing == False:
return (False,False)
return (True, self.player.query_position(self.time_format,None)[0])
self.position = self.player.query_position(self.time_format,None)[0]/1000000000
return (True, self.position)

View File

@ -62,7 +62,7 @@ class Window(gtk.Window):
def deleteLib(self,widgit,data,other=None):
self.data.library.reset()
self.libview.update()
self.clearPlist()
self.clearPlist(None,None)
def clearPlist(self,widgit,data,other=None):