diff --git a/trunk/images/ocarina.png b/trunk/images/ocarina.png index e8ec8879..cea8953b 100644 Binary files a/trunk/images/ocarina.png and b/trunk/images/ocarina.png differ diff --git a/trunk/images/ocarina.png.new b/trunk/images/ocarina.png.new new file mode 100644 index 00000000..e8ec8879 Binary files /dev/null and b/trunk/images/ocarina.png.new differ diff --git a/trunk/images/ocarina.png.old b/trunk/images/ocarina.png.old new file mode 100644 index 00000000..7835d24c Binary files /dev/null and b/trunk/images/ocarina.png.old differ diff --git a/trunk/images/ocarina512.png b/trunk/images/ocarina512.png new file mode 100644 index 00000000..cea8953b Binary files /dev/null and b/trunk/images/ocarina512.png differ diff --git a/trunk/src/GuiObjects/__init__.py b/trunk/src/GuiObjects/__init__.py index cf6fbd76..2d9d7956 100644 --- a/trunk/src/GuiObjects/__init__.py +++ b/trunk/src/GuiObjects/__init__.py @@ -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'] diff --git a/trunk/src/GuiObjects/button.py b/trunk/src/GuiObjects/button.py index 8d05c6b5..6ca28563 100644 --- a/trunk/src/GuiObjects/button.py +++ b/trunk/src/GuiObjects/button.py @@ -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) diff --git a/trunk/src/GuiObjects/controlPanel.py b/trunk/src/GuiObjects/controlPanel.py index 35196549..7d0ad262 100644 --- a/trunk/src/GuiObjects/controlPanel.py +++ b/trunk/src/GuiObjects/controlPanel.py @@ -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 diff --git a/trunk/src/GuiObjects/plistView.py b/trunk/src/GuiObjects/plistView.py index 5990011c..0f8f3aa7 100644 --- a/trunk/src/GuiObjects/plistView.py +++ b/trunk/src/GuiObjects/plistView.py @@ -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)) diff --git a/trunk/src/GuiObjects/scrobbler.py b/trunk/src/GuiObjects/scrobbler.py index fbaf6bab..3834c792 100644 --- a/trunk/src/GuiObjects/scrobbler.py +++ b/trunk/src/GuiObjects/scrobbler.py @@ -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 diff --git a/trunk/src/library.py b/trunk/src/library.py index 63676c50..447c884c 100644 --- a/trunk/src/library.py +++ b/trunk/src/library.py @@ -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() diff --git a/trunk/src/ocarina.py b/trunk/src/ocarina.py index b387bdd7..e966faac 100644 --- a/trunk/src/ocarina.py +++ b/trunk/src/ocarina.py @@ -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() diff --git a/trunk/src/saveddata.py b/trunk/src/saveddata.py index 0b2347d5..791cb5ba 100644 --- a/trunk/src/saveddata.py +++ b/trunk/src/saveddata.py @@ -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 diff --git a/trunk/src/song.py b/trunk/src/song.py index d7411a99..cbecee33 100644 --- a/trunk/src/song.py +++ b/trunk/src/song.py @@ -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) diff --git a/trunk/src/window.py b/trunk/src/window.py index 139d1355..7692afe7 100644 --- a/trunk/src/window.py +++ b/trunk/src/window.py @@ -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):