diff --git a/trunk/Makefile b/trunk/Makefile index 73b3e71f..3cf23418 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -4,3 +4,8 @@ open: clean: rm -rf *.pyc + +install: + rsync *.py ~/bin/ocarina-bin/ + cp ocarina ~/bin/ocarina-bin/ + ln -s ~/bin/ocarina-bin/ocarina ~/bin/ diff --git a/trunk/images/stop.png b/trunk/images/stop.png new file mode 100644 index 00000000..1b2515e4 Binary files /dev/null and b/trunk/images/stop.png differ diff --git a/trunk/library.py b/trunk/library.py index b31e4724..f9f94c0a 100644 --- a/trunk/library.py +++ b/trunk/library.py @@ -10,7 +10,7 @@ class Library(): def __init__(self): #self.prnt = prnt self.data = LibData() - self.goodTypes = ["ogg","mp3","wma"] + self.goodTypes = ["ogg","mp3"]#,"wma"] # Build up directory if library save self.save = os.path.expanduser("~") self.save = os.path.join(self.save,".ocarina") @@ -71,6 +71,20 @@ class Library(): index = len(self.data.files) info = SongInfo() info.filename = os.path.join(self.data.path,file) + #print file + split = file.rsplit(os.sep) + max = 3 + if len(split) < 3: + max = len(split) + for i in range(max): + if i==0: + info.title = split[len(split)-1] + elif i==1: + info.album = split[len(split)-2] + else: + info.artist = split[len(split)-3] + #print info.artist,",", info.title,",", info.album + #print s1,s2,s3 self.data.files+=[info] for word in words: if (word in self.data.map.keys()) == True: @@ -109,3 +123,10 @@ class Library(): if self.data.files[i].banned == False: list += [i] return list + + + def translate(self,sid): + file = self.data.files[sid] + #print file.title, file.artist, file.album + return (sid,file.title,file.artist,file.album,file.playCount) + #return (file.artist,file.album) diff --git a/trunk/ocarina b/trunk/ocarina index e7287eda..c6d52a04 100755 --- a/trunk/ocarina +++ b/trunk/ocarina @@ -1,2 +1,2 @@ #!/bin/bash -`which python` ocarina.py $@ +/usr/bin/python ocarina.py $@ diff --git a/trunk/ocarina.py b/trunk/ocarina.py index 21bdd959..6587c60e 100644 --- a/trunk/ocarina.py +++ b/trunk/ocarina.py @@ -26,6 +26,8 @@ class main: self.library = Library() self.plist = Playlist() self.plist.insert(self.library.nonBanned()) + self.plist.translate = self.library.translate + self.plist.opsNext = self.ops.next self.ops.plist = self.plist self.ops.library = self.library diff --git a/trunk/operations.py b/trunk/operations.py index 9957d072..d86374a5 100644 --- a/trunk/operations.py +++ b/trunk/operations.py @@ -1,13 +1,19 @@ from song import Song +CONTINUE = 0 +QUIT = 1 +PAUSE = 2 + # Use to define various operations class Operations: def __init__(self,exit): self.song = None self.plist = None self.library = None + self.setInfo = None + self.resetInfo = None self.exit = exit - self.after = 0 + self.after = CONTINUE # Begin playback @@ -24,13 +30,25 @@ class Operations: self.song.pause() - def afterTrack(self,widget,data): + def stop(self,widget,data): + if self.song == None: + return + self.song.stop() + + + def afterTrack(self,widget,data,changeFrame): + str = "" if (data=="qafter") and not (self.after==1): - self.after = 1 + self.after = QUIT + str = "Quitting " elif (data=="pafter") and not (self.after==2): - self.after = 2 + self.after = PAUSE + str = "Pausing" else: - self.after = 0 + self.after = CONTINUE + if str != "": + str += " After " + changeFrame(str) # Advance to the next song def next(self,widget,data): @@ -38,10 +56,11 @@ class Operations: if self.song != None: self.song.close() # Are we exiting? - if self.after == 1: + if self.after == QUIT: self.exit(None,None) # Get next song index = self.plist.next() + self.resetInfo() if index > -1: self.song = None info = self.library.data.files[index] @@ -51,9 +70,10 @@ class Operations: # Do we begin playback? #if self.after != 2: self.song.play() - if self.after == 2: + if self.after == PAUSE: self.song.pause() - self.after = 0 + self.after = CONTINUE + self.library.dump() # Mark progress on the progress bar @@ -67,20 +87,6 @@ class Operations: return True - def this(self,widget,data): - # Return if no song found - if self.song == None: - return - # Return if no tags found - if self.song.info.tags == None: - print "Could not find any tags" - return - fields = ["title","artist","track-number","track-count","album"] - for field in fields: - if (field in self.song.info.tags.keys()) == True: - print field+":",self.song.info.tags[field] - - # Print detailed song info def info(self,widget,data): # Return if no song found diff --git a/trunk/playlist.py b/trunk/playlist.py index f6a7c1ed..de6d9692 100644 --- a/trunk/playlist.py +++ b/trunk/playlist.py @@ -1,5 +1,8 @@ import Queue import random +import pygtk +pygtk.require('2.0') +import gtk class Playlist: @@ -10,6 +13,9 @@ class Playlist: self.queue = Queue.Queue() self.curSong = 0 self.random = True + self.translate = None + self.opsNext = None + #self.makeWindow() # Enqueue a song @@ -26,7 +32,8 @@ class Playlist: # Return the next song def next(self): if self.queue.empty() == False: - return self.queue.get() + self.curSong = self.queue.get() + return self.curSong if len(self.list) == 0: return -2 @@ -38,3 +45,68 @@ class Playlist: self.curSong = 0 song = self.list[self.curSong] return song + + + # Play the selected song + def selectSong(self,module,iter,path,data): + self.queueSong(iter[0]) + self.opsNext(None,None) + self.hideWindow(None,None) + + + # Make the playlist window + def makeWindow(self): + self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) + self.window.connect("delete_event",self.hideWindow) + self.window.set_size_request(200,300) + self.scroll = gtk.ScrolledWindow() + self.scroll.set_border_width(0) + self.scroll.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC) + self.window.add(self.scroll) + self.populateList() + + + # Fill in rows in the playlist + def populateList(self): + liststore = gtk.ListStore(int,str,str,str,int) + #liststore = gtk.ListStore(str,str) + for num in self.list: + liststore.append(self.translate(num)) + treeview = gtk.TreeView(liststore) + cell = gtk.CellRendererText() + cols = ["Id","Title","Artist","Album","Count"] + for i in range(len(cols)): + col = gtk.TreeViewColumn(cols[i],cell) + col.add_attribute(cell,'text',i) + col.set_resizable(True) + col.set_sort_column_id(i) + treeview.append_column(col) + + treeview.set_search_column(1) + treeview.connect("row-activated",self.selectSong,"clicked") + treeview.show() + self.scroll.add(treeview) + self.scroll.show() + # Go to current song, enable grid lines + selrow = self.curSong-10 + if selrow < 0: + selrow = 0 + treeview.scroll_to_cell(selrow,None,False,0,0) + treeview.set_grid_lines(True) + treesel = treeview.get_selection() + treesel.select_path(self.curSong) + + + # Hide the playlist + def hideWindow(self,widget,data): + #self.scroll.hide() + self.window.hide() + self.window = None + + + # Show the playlist + def showWindow(self,widget,data): + #self.populateList() + self.makeWindow() + self.window.show() + self.window.maximize() diff --git a/trunk/song.py b/trunk/song.py index c4e5a1d9..a398cedb 100644 --- a/trunk/song.py +++ b/trunk/song.py @@ -15,6 +15,7 @@ class Song(): self.info.tags = dict() self.setInfo = None self.getNext = None + self.current = 0 # initialize player pipeline self.player = gst.Pipeline("player") bin = gst.element_factory_make("playbin",None) @@ -47,6 +48,7 @@ class Song(): err, debug = message.parse_error() #if self.prnt != None: # self.prnt(["Error: "+ str(err) + " " +str(debug)]) + self.close() print "Error: %s" % err, debug print "Trying next song" self.getNext(None,None) @@ -56,6 +58,12 @@ class Song(): tags = message.parse_tag() for tag in tags.keys(): self.info.tags[tag] = tags[tag] + if tag=="title": + self.info.title = tags[tag] + elif tag=="album": + self.info.album = tags[tag] + elif tag=="artist": + self.info.artist = tags[tag] self.setInfo(tags) #self.taglist = message.parse_tag() return @@ -74,6 +82,12 @@ class Song(): self.player.set_state(gst.STATE_PAUSED) + def stop(self): + self.player.set_state(gst.STATE_PAUSED) + self.current = 0 + self.player.seek_simple(self.time_format,gst.SEEK_FLAG_FLUSH,self.current) + + def close(self): self.player.set_state(gst.STATE_NULL) diff --git a/trunk/songInfo.py b/trunk/songInfo.py index 88c19fff..a0dfd591 100644 --- a/trunk/songInfo.py +++ b/trunk/songInfo.py @@ -7,3 +7,6 @@ class SongInfo: self.playCount = 0 self.banned = False self.length = None + self.title = "" + self.album = "" + self.artist = "" diff --git a/trunk/window.py b/trunk/window.py index 8a7237d4..3334292c 100644 --- a/trunk/window.py +++ b/trunk/window.py @@ -28,15 +28,15 @@ class Window(gtk.Window): # Make initial info pane def makeInfoPane(self): - info = gtk.Frame("Current Song:") + self.infoFrame = gtk.Frame("Current Song:") box = gtk.VBox(False,0) - info.add(box) + self.infoFrame.add(box) self.tagLabels["title"] = self.makeLabel("Title: ?",box) self.tagLabels["artist"] = self.makeLabel("Artist: ?",box) self.tagLabels["album"] = self.makeLabel("Album: ?",box) box.show() - info.show() - self.mainLayout.add(info) + self.infoFrame.show() + self.mainLayout.add(self.infoFrame) # Set up a new label, add to container @@ -45,7 +45,7 @@ class Window(gtk.Window): box = gtk.HBox(False,0) label = gtk.Label(text) self.tooltip.set_tip(label,text,tip_private=None) - label.set_max_width_chars(35) + #label.set_max_width_chars(35) label.show() box.pack_start(label,False,False,0) box.show() @@ -65,6 +65,10 @@ class Window(gtk.Window): self.tagLabels[key].show() + def changeFrameTitle(self,label): + self.infoFrame.set_label(label+"Current Track:") + + # Reset label info def resetInfo(self): labels = self.tagLabels.keys() @@ -80,9 +84,10 @@ class Window(gtk.Window): # Make top row buttons self.makeButton("play","images/play.png",None,self.ops.play,topRow) self.makeButton("pause","images/pause.png",None,self.ops.pause,topRow) + self.makeButton("stop","images/stop.png",None,self.ops.stop,topRow) self.makeButton("next","images/next.png",None,self.ops.next,topRow) - self.makeButton("this",None,"This",self.ops.this,topRow) self.makeButton("info",None,"Info",self.ops.info,topRow) + self.makeButton("plist",None,"Plist",self.ops.plist.showWindow,topRow) test = gtk.VBox(False,0) self.makeCheck("Random",self.ops.random,self.ops.plist.random,True,topRow) @@ -157,12 +162,12 @@ class Window(gtk.Window): pback = gtk.Menu() # Pause after current track pafter = gtk.MenuItem(label="Pause After Current Track") - pafter.connect("activate",self.ops.afterTrack,"pafter") + pafter.connect("activate",self.ops.afterTrack,"pafter",self.changeFrameTitle) pafter.show() pback.append(pafter) # Quit after current track qafter = gtk.MenuItem(label="Quit After Current Track") - qafter.connect("activate",self.ops.afterTrack,"qafter") + qafter.connect("activate",self.ops.afterTrack,"qafter",self.changeFrameTitle) qafter.show() pback.append(qafter) @@ -178,13 +183,14 @@ class Window(gtk.Window): 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) response = dirsel.run() + #dirsel = None if response == gtk.RESPONSE_OK: #print dirsel.get_filename(),'selected' - func(dirsel.get_filename()) - dirsel.hide() - #if response == gtk.RESPONSE_CANCEL: - # dirsel.hide() - #elif response == gtk.RESPONSE_OK: - # print module.get_filename(),'selected' - #else: - # print response + #dirsel.hide() + file = dirsel.get_filename() + dirsel.hide() + dirsel = None + func(file) + else: + dirsel.hide() + dirsel = None