Teased apart old ocarina.collection code
The new code is easier to read, and much less intimidating. I also changed the Library() and Playlist() classes into python modules to make them easier to read.
This commit is contained in:
parent
5c22f959c3
commit
ba4488202a
|
@ -44,6 +44,11 @@ def change_score():
|
|||
if prcnt < 0.33:
|
||||
inc_score(cur_lib_id, -1)
|
||||
|
||||
def play_selected_id(id):
|
||||
change_score()
|
||||
play_id(id)
|
||||
inc_score(id, 1)
|
||||
|
||||
def plist_next():
|
||||
change_score()
|
||||
playlist.next()
|
||||
|
|
|
@ -5,6 +5,7 @@ import tagpy
|
|||
import libsaria
|
||||
import libsaria.path.files
|
||||
import string
|
||||
from libsaria import threads
|
||||
from track import Track
|
||||
splitext = libsaria.path.splitext
|
||||
|
||||
|
@ -18,6 +19,8 @@ visible = None
|
|||
|
||||
FileRef = tagpy.FileRef
|
||||
|
||||
lib_lock = threads.get_mutex("library")
|
||||
loaded = False
|
||||
filtered = False
|
||||
badfiles = set()
|
||||
|
||||
|
@ -53,13 +56,34 @@ def load():
|
|||
global index
|
||||
global tracks
|
||||
global sources
|
||||
global lib_lock
|
||||
global loaded
|
||||
|
||||
objects = libsaria.path.files.load("library", ".lib")
|
||||
if objects == None or len(objects) != 5:
|
||||
reset()
|
||||
return
|
||||
(sources, tracks, fs_tree, tag_tree, index) = objects
|
||||
else:
|
||||
(sources, tracks, fs_tree, tag_tree, index) = objects
|
||||
|
||||
lib_lock.acquire()
|
||||
loaded = True
|
||||
lib_lock.release()
|
||||
libsaria.event.start("POSTLIBLOAD")
|
||||
|
||||
def is_loaded():
|
||||
lib_lock.acquire()
|
||||
val = loaded
|
||||
lib_lock.release()
|
||||
return val
|
||||
|
||||
def load_bg2(callback):
|
||||
load()
|
||||
callback()
|
||||
|
||||
def load_bg(callback):
|
||||
thr = threads.BG_Thread(load_bg2, callback)
|
||||
thr.start()
|
||||
|
||||
def save():
|
||||
global sources
|
||||
libsaria.path.files.save( (sources, tracks, fs_tree, tag_tree, index),
|
||||
|
|
|
@ -4,6 +4,7 @@ import random as rand
|
|||
|
||||
import libsaria
|
||||
import libsaria.path.files
|
||||
from libsaria import threads
|
||||
from libsaria.sources import library
|
||||
call = libsaria.event.call
|
||||
|
||||
|
@ -36,8 +37,18 @@ def load():
|
|||
song_list = libsaria.path.files.load("playlist", ".list")
|
||||
if song_list == None:
|
||||
reset()
|
||||
return
|
||||
song_set = set(song_list)
|
||||
else:
|
||||
song_set = set(song_list)
|
||||
|
||||
def load_bg2(callback):
|
||||
load()
|
||||
while library.is_loaded() == False:
|
||||
pass
|
||||
callback()
|
||||
|
||||
def load_bg(callback):
|
||||
thr = threads.BG_Thread(load_bg2, callback)
|
||||
thr.start()
|
||||
|
||||
def save():
|
||||
libsaria.path.files.save(song_list, "playlist", ".list")
|
||||
|
|
|
@ -9,8 +9,8 @@ import libsaria
|
|||
import ocarina
|
||||
from ocarina import window
|
||||
from ocarina import body
|
||||
|
||||
from ocarina import collection
|
||||
from ocarina import library
|
||||
from ocarina import playlist
|
||||
|
||||
width = libsaria.init_pref("ocarina.window.width", 800)
|
||||
height = libsaria.init_pref("ocarina.window.height", 600)
|
||||
|
@ -21,9 +21,8 @@ window.set_title("%s Your Music Everywhere" % ocarina.__vers__)
|
|||
window.set_icon("images/ocarina.png")
|
||||
window.add(body.body)
|
||||
|
||||
body.add_page("Playlist", collection.Playlist())
|
||||
body.add_page("Library", collection.Library())
|
||||
|
||||
playlist.init()
|
||||
library.init()
|
||||
|
||||
after = now()
|
||||
print "Startup took:", after-before
|
||||
|
|
|
@ -25,6 +25,9 @@ class Page(gtk.VBox):
|
|||
def filter(self, text):
|
||||
self.content.filter(text)
|
||||
|
||||
def reset(self):
|
||||
self.content.reset()
|
||||
|
||||
def visible(self):
|
||||
self.pack_start(page_header, False, False)
|
||||
self.pack_start(self.content, True, True)
|
||||
|
@ -93,3 +96,8 @@ def cur_page_filter(text):
|
|||
cur_num = body.get_current_page()
|
||||
page = body.get_nth_page(cur_num)
|
||||
page.filter(text)
|
||||
|
||||
def cur_page_reset():
|
||||
cur_num = body.get_current_page()
|
||||
page = body.get_nth_page(cur_num)
|
||||
page.reset()
|
||||
|
|
|
@ -3,132 +3,145 @@
|
|||
import ocarina
|
||||
import list
|
||||
import menu
|
||||
from components import image
|
||||
|
||||
libsaria = ocarina.libsaria
|
||||
from libsaria import sources
|
||||
library = sources.library
|
||||
playlist = sources.playlist
|
||||
|
||||
library = sources.library
|
||||
playlist = sources.playlist
|
||||
get_attrs = library.get_attrs
|
||||
|
||||
event = ocarina.libsaria.event
|
||||
gtk = ocarina.gtk
|
||||
|
||||
cols = ["Id", "Title", "Length", "Artist", "Album", "Year"]
|
||||
colw = [ 2, 300, 60, 125, 125, 50]
|
||||
cell = gtk.CellRendererText()
|
||||
cell.set_fixed_height_from_font(1)
|
||||
|
||||
class Actions:
|
||||
class Column(gtk.TreeViewColumn):
|
||||
def __init__(self, index, label):
|
||||
gtk.TreeViewColumn.__init__(self, label, cell)
|
||||
self.add_attribute(cell, 'text', index)
|
||||
self.set_resizable(True)
|
||||
self.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
|
||||
self.set_min_width(2)
|
||||
self.set_max_width(700)
|
||||
self.set_fixed_width(colw[index])
|
||||
|
||||
|
||||
class List(gtk.ListStore):
|
||||
def __init__(self):
|
||||
self.selected_row = None
|
||||
self.refilter = None
|
||||
self.show_rc_menu = None
|
||||
gtk.ListStore.__init__(self, int, str, str, str, str, int)
|
||||
|
||||
|
||||
class ListView(gtk.TreeView):
|
||||
def __init__(self, is_visible, right_click):
|
||||
gtk.TreeView.__init__(self)
|
||||
self.list = List()
|
||||
|
||||
for index, label in enumerate(cols):
|
||||
col = Column(index, label)
|
||||
if index != 0 and index != 6:
|
||||
self.append_column(col)
|
||||
|
||||
self.set_rules_hint(True)
|
||||
self.set_has_tooltip(True)
|
||||
|
||||
self.filter_model = self.list.filter_new()
|
||||
self.filter_model.set_visible_func(is_visible)
|
||||
self.sel = self.get_selection()
|
||||
self.sel.set_mode(gtk.SELECTION_MULTIPLE)
|
||||
self.set_model(self.filter_model)
|
||||
|
||||
self.connect("row-activated", self.double_click)
|
||||
self.connect("button-release-event", self.button_click)
|
||||
self.connect("query-tooltip", self.query_tooltip)
|
||||
|
||||
self.insert = self.list.insert
|
||||
self.refilter = self.filter_model.refilter
|
||||
self.clear = self.list.clear
|
||||
self.right_click = right_click
|
||||
|
||||
self.show_all()
|
||||
|
||||
def button_click(self, widget, event):
|
||||
if event.button == 3:
|
||||
self.right_click(event.button, event.time)
|
||||
|
||||
def double_click(self, widget, path, column):
|
||||
model = self.get_model()
|
||||
iter = model.get_iter(path)
|
||||
row = model[iter]
|
||||
sources.play_selected_id(row[0])
|
||||
|
||||
def for_each_selected(self, func):
|
||||
filter = self.filter_model
|
||||
for iter in self.sel.get_selected_rows()[1]:
|
||||
func(filter[iter][0])
|
||||
|
||||
def freeze(self):
|
||||
self.freeze_child_notify()
|
||||
self.set_model(None)
|
||||
|
||||
def thaw(self):
|
||||
self.set_model(self.filter_model)
|
||||
self.thaw_child_notify()
|
||||
|
||||
def query_tooltip(self, widget, x, y, keyboard, tip):
|
||||
row = self.get_dest_row_at_pos(x,y)
|
||||
if row == None:
|
||||
return False
|
||||
iter = self.filter_model.get_iter(row[0])
|
||||
id = self.filter_model[iter][0]
|
||||
|
||||
attrs = get_attrs(id, "art", "title", "artist", "album", "year", "lenstr", "count")
|
||||
|
||||
art = image.Image()
|
||||
art.set_from_file(attrs[0])
|
||||
art.set_height(52)
|
||||
tip.set_icon(art.get_pixbuf())
|
||||
|
||||
tip.set_markup("<b>%s</b>\nby %s\nfrom %s" %
|
||||
(attrs[1].replace("&", "&"),
|
||||
attrs[2].replace("&", "&"),
|
||||
attrs[3].replace("&", "&"))
|
||||
)
|
||||
|
||||
extra = gtk.Label()
|
||||
extra.set_markup(" Year: %s\n Length: %s\n Play count: %s" %
|
||||
(attrs[4], attrs[5], attrs[6]) )
|
||||
tip.set_custom(extra)
|
||||
return True
|
||||
|
||||
|
||||
class Collection(gtk.ScrolledWindow):
|
||||
def __init__(self, actions):
|
||||
def __init__(self):
|
||||
gtk.ScrolledWindow.__init__(self)
|
||||
self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
self.list = list.List(actions)
|
||||
self.selected_row = actions.selected_row
|
||||
|
||||
self.add(self.list)
|
||||
self.list = None
|
||||
self.filter = None
|
||||
self.show()
|
||||
|
||||
def clear(self):
|
||||
self.list.clear()
|
||||
def init(self, filter, is_visible, right_click, reset):
|
||||
self.list = ListView(is_visible, right_click)
|
||||
self.add(self.list)
|
||||
|
||||
def populate(self, func):
|
||||
self.refilter = self.list.refilter
|
||||
self.filter = filter
|
||||
self.reset = reset
|
||||
self.clear = self.list.clear
|
||||
self.for_each_selected = self.list.for_each_selected
|
||||
|
||||
def fill(self, walk_func):
|
||||
self.list.freeze()
|
||||
insert = self.list.list.insert
|
||||
insert = self.list.insert
|
||||
get_attrs = library.get_attrs
|
||||
ins_next = 0
|
||||
for id in func():
|
||||
insert(ins_next, get_attrs(id, "id", "title", "lenstr", "artist", "album", "year"))
|
||||
for id in walk_func():
|
||||
attrs = get_attrs(id, "id", "title", "lenstr", "artist", "album", "year")
|
||||
insert(ins_next, attrs)
|
||||
ins_next += 1
|
||||
self.list.thaw()
|
||||
|
||||
def add_selected_to_playlist(self, *args):
|
||||
self.list.for_each_selected(playlist.add_id)
|
||||
playlist.save()
|
||||
sources.plist_refresh()
|
||||
|
||||
|
||||
class Library(Collection):
|
||||
def __init__(self):
|
||||
actions = Actions()
|
||||
actions.selected_row = self.select_row
|
||||
actions.refilter = self.refilter
|
||||
actions.show_rc_menu = menu.make_lib_menu
|
||||
|
||||
Collection.__init__(self, actions)
|
||||
libsaria.event.invite("POSTSTART", self.populate, bg=True)
|
||||
libsaria.event.invite("POSTNEWSOURCE", self.refresh, bg=True)
|
||||
|
||||
menu.add_lib_menu_item("Add to playlist", self.add_selected_to_playlist)
|
||||
|
||||
def populate(self):
|
||||
#import datetime
|
||||
#before = datetime.datetime.now()
|
||||
library.load()
|
||||
Collection.populate(self, library.walk)
|
||||
#after = datetime.datetime.now()
|
||||
#print "Populating took: %s" % (after - before)
|
||||
|
||||
def refresh(self, arg):
|
||||
self.clear()
|
||||
Collection.populate(self, library.walk)
|
||||
#self.populate()
|
||||
|
||||
def reset(self):
|
||||
sources.reset()
|
||||
self.clear()
|
||||
|
||||
def select_row(self, row):
|
||||
sources.change_score()
|
||||
sources.play_id(row[0])
|
||||
sources.inc_score(row[0], 1)
|
||||
|
||||
def filter(self, text):
|
||||
library.filter(text)
|
||||
self.list.refilter()
|
||||
|
||||
def refilter(self, list, iter):
|
||||
return library.is_visible(list[iter][0])
|
||||
|
||||
|
||||
class Playlist(Collection):
|
||||
def __init__(self):
|
||||
actions = Actions()
|
||||
actions.selected_row = self.select_row
|
||||
actions.refilter = self.refilter
|
||||
actions.show_rc_menu = menu.make_plist_menu
|
||||
|
||||
Collection.__init__(self, actions)
|
||||
libsaria.event.invite("POSTLIBLOAD", self.populate, bg=True)
|
||||
libsaria.event.invite("PREPLISTREFRESH", self.refresh)
|
||||
|
||||
def refresh(self, arg=None):
|
||||
self.clear()
|
||||
Collection.populate(self, playlist.walk)
|
||||
|
||||
def reset(self):
|
||||
playlist.reset()
|
||||
playlist.save()
|
||||
self.clear()
|
||||
|
||||
def populate(self):
|
||||
#import datetime
|
||||
#before = datetime.datetime.now()
|
||||
#Collection.populate(self, collection.walk_plist)
|
||||
playlist.load()
|
||||
Collection.populate(self, playlist.walk)
|
||||
#after = datetime.datetime.now()
|
||||
#print "Populating took: %s" % (after - before)
|
||||
|
||||
def select_row(self, row):
|
||||
sources.change_score()
|
||||
sources.play_id(row[0])
|
||||
sources.inc_score(row[0], 1)
|
||||
|
||||
def filter(self, text):
|
||||
playlist.filter(text)
|
||||
self.list.refilter()
|
||||
|
||||
def refilter(self, list, iter):
|
||||
return playlist.is_visible(list[iter][0])
|
||||
|
|
|
@ -100,8 +100,8 @@ class ClearButton(Button):
|
|||
def __init__(self):
|
||||
Button.__init__(self, gtk.STOCK_CLEAR, gtk.ICON_SIZE_BUTTON)
|
||||
def clicked(self, button):
|
||||
from ocarina import tabs
|
||||
tabs.reset_current_page()
|
||||
from ocarina import body
|
||||
body.cur_page_reset()
|
||||
|
||||
class ExportButton(Button):
|
||||
def __init__(self):
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
# Bryan Schumaker (11/26/2010)
|
||||
|
||||
import ocarina
|
||||
from ocarina import body
|
||||
from ocarina import collection
|
||||
import menu
|
||||
|
||||
gtk = ocarina.gtk
|
||||
sources = ocarina.libsaria.sources
|
||||
library = sources.library
|
||||
visible = library.is_visible
|
||||
add2plist = None
|
||||
|
||||
libsaria = ocarina.libsaria
|
||||
lib_page = collection.Collection()
|
||||
|
||||
def init():
|
||||
body.add_page("Library", lib_page)
|
||||
library.load_bg(filler)
|
||||
libsaria.event.invite("POSTNEWSOURCE", refresh)
|
||||
|
||||
def filler():
|
||||
lib_page.init(filter, is_visible, right_click, reset)
|
||||
menu.add_lib_menu_item("Add to playlist", add_selected_to_playlist)
|
||||
lib_page.fill(library.walk)
|
||||
|
||||
def filter(text):
|
||||
library.filter(text)
|
||||
lib_page.refilter()
|
||||
|
||||
def is_visible(list, iter):
|
||||
return visible(list[iter][0])
|
||||
|
||||
def reset():
|
||||
import playlist
|
||||
playlist.reset()
|
||||
lib_page.clear()
|
||||
library.reset()
|
||||
library.save()
|
||||
|
||||
def refresh(*args):
|
||||
lib_page.clear()
|
||||
lib_page.fill(library.walk)
|
||||
|
||||
def right_click(button, time):
|
||||
menu.make_lib_menu(button, time)
|
||||
|
||||
def add_selected_to_playlist(menu):
|
||||
import playlist
|
||||
lib_page.for_each_selected(sources.playlist.add_id)
|
||||
sources.playlist.save()
|
||||
playlist.refresh()
|
107
ocarina/list.py
107
ocarina/list.py
|
@ -1,107 +0,0 @@
|
|||
# Bryan Schumaker (8/15/2010)
|
||||
|
||||
import ocarina
|
||||
from components import image
|
||||
libsaria = ocarina.libsaria
|
||||
gtk = ocarina.gtk
|
||||
gobject = ocarina.gobject
|
||||
|
||||
from libsaria.sources import library
|
||||
get_attrs = library.get_attrs
|
||||
|
||||
#UNI = gobject.TYPE_UNICHAR
|
||||
|
||||
class List(gtk.TreeView):
|
||||
def __init__(self, actions):
|
||||
gtk.TreeView.__init__(self)
|
||||
self.actions = actions
|
||||
self.list = gtk.ListStore(int, str, str, str, str, int)
|
||||
|
||||
self.append = self.list.append
|
||||
|
||||
cell = gtk.CellRendererText()
|
||||
cell.set_fixed_height_from_font(1)
|
||||
|
||||
cols = ["Id", "Title", "Length", "Artist", "Album", "Year", "Played"]
|
||||
colw = [ 2, 300, 60, 125, 125, 50, 70]
|
||||
for index, label in enumerate(cols):
|
||||
col = gtk.TreeViewColumn(label, cell)
|
||||
col.add_attribute(cell, 'text', index)
|
||||
col.set_resizable(True)
|
||||
col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
|
||||
col.set_min_width(2)
|
||||
col.set_max_width(700)
|
||||
col.set_fixed_width(colw[index])
|
||||
if label!="Id" and label!="Played":
|
||||
self.append_column(col)
|
||||
|
||||
self.set_rules_hint(True)
|
||||
self.set_has_tooltip(True)
|
||||
|
||||
self.filter_model = self.list.filter_new()
|
||||
self.filter_model.set_visible_func(actions.refilter)
|
||||
self.refilter = self.filter_model.refilter
|
||||
|
||||
self.sel = self.get_selection()
|
||||
self.sel.set_mode(gtk.SELECTION_MULTIPLE)
|
||||
|
||||
self.connect("query-tooltip", self.query_tooltip)
|
||||
self.connect("row-activated", self.row_activated)
|
||||
self.connect("button-release-event", self.button_clicked)
|
||||
|
||||
self.set_model(self.filter_model)
|
||||
self.show_all()
|
||||
|
||||
def button_clicked(self, widget, event):
|
||||
if event.button == 3:
|
||||
self.actions.show_rc_menu(event.button, event.time)
|
||||
|
||||
def row_activated(self, widget, path, column):
|
||||
list = self.filter_model
|
||||
iter = list.get_iter(path)
|
||||
row = list[iter]
|
||||
self.actions.selected_row(row)
|
||||
|
||||
def freeze(self):
|
||||
self.set_model(None)
|
||||
self.freeze_child_notify()
|
||||
|
||||
def thaw(self):
|
||||
self.set_model(self.filter_model)
|
||||
self.thaw_child_notify()
|
||||
|
||||
def clear(self):
|
||||
self.list.clear()
|
||||
|
||||
def for_each_selected(self, func):
|
||||
filter = self.filter_model
|
||||
for iter in self.sel.get_selected_rows()[1]:
|
||||
func(filter[iter][0])
|
||||
|
||||
def query_tooltip(self, widget, x, y, keyboard, tip):
|
||||
row = self.get_dest_row_at_pos(x,y)
|
||||
if row == None:
|
||||
return False
|
||||
iter = self.filter_model.get_iter(row[0])
|
||||
id = self.filter_model[iter][0]
|
||||
|
||||
attrs = get_attrs(id, "art", "title", "artist", "album", "year", "lenstr", "count")
|
||||
|
||||
art = image.Image()
|
||||
art.set_from_file(attrs[0])
|
||||
art.set_height(52)
|
||||
tip.set_icon(art.get_pixbuf())
|
||||
|
||||
tip.set_markup("<b>%s</b>\nby %s\nfrom %s" %
|
||||
(attrs[1].replace("&", "&"),
|
||||
attrs[2].replace("&", "&"),
|
||||
attrs[3].replace("&", "&"))
|
||||
)
|
||||
|
||||
extra = gtk.Label()
|
||||
extra.set_markup(" Year: %s\n Length: %s\n Play count: %s" %
|
||||
(attrs[4], attrs[5], attrs[6]) )
|
||||
tip.set_custom(extra)
|
||||
return True
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# Bryan Schumaker (11/26/2010)
|
||||
|
||||
import ocarina
|
||||
from ocarina import body
|
||||
from ocarina import collection
|
||||
import menu
|
||||
|
||||
gtk = ocarina.gtk
|
||||
sources = ocarina.libsaria.sources
|
||||
playlist = sources.playlist
|
||||
visible = playlist.is_visible
|
||||
|
||||
plist_page = collection.Collection()
|
||||
|
||||
def init():
|
||||
body.add_page("Playlist", plist_page)
|
||||
playlist.load_bg(filler)
|
||||
|
||||
def filler():
|
||||
plist_page.init(filter, is_visible, right_click, reset)
|
||||
plist_page.fill(playlist.walk)
|
||||
|
||||
def filter(text):
|
||||
playlist.filter(text)
|
||||
plist_page.refilter()
|
||||
|
||||
def is_visible(list, iter):
|
||||
return visible(list[iter][0])
|
||||
|
||||
def reset():
|
||||
plist_page.clear()
|
||||
playlist.reset()
|
||||
playlist.save()
|
||||
|
||||
def refresh(*args):
|
||||
plist_page.clear()
|
||||
plist_page.fill(playlist.walk)
|
||||
|
||||
def right_click(button, time):
|
||||
menu.make_plist_menu(button, time)
|
Loading…
Reference in New Issue