Have a working doubly-linked tree based library.

I have a bit more to do before I support everything the old library did.
Mostly getattr work.
This commit is contained in:
Bryan Schumaker 2010-10-06 23:31:36 -04:00
parent 42dbdd2736
commit adcb73dac9
9 changed files with 106 additions and 205 deletions

View File

@ -13,11 +13,8 @@ LIBRARY = 0
PLAYLIST = 1
QUEUE = 2
import collection
library = collection.Collection()
import filters
library2 = filters.Library()
import lens
library2 = lens.Library()
cur_lib_id = -1
@ -33,6 +30,7 @@ def new_source2(path, bg=True):
path = expand(path)
if not exists(path):
return 0
library2.reset()
return call("NEWSOURCE2", library2.scan, path)
def walk_library():
@ -40,10 +38,15 @@ def walk_library():
for track in library:
yield track
def scan_library():
global library2
for track in library2.walk_tags():
yield track
def lib_get_attr(id, attr):
global library
global library2
if id >= 0:
return library.get_attr(id, attr)
return library2.get_attr(id, attr)
return None
def lib_play_id(id):

View File

@ -8,98 +8,11 @@ ins_table = None
ins_index = None
ins_tree = None
class Collection:
def __init__(self):
self.tree = None
def __iter__(self):
if not self.tree:
self.load()
for track in self.tree.walk():
yield track
def get_attr(self, id, attr):
node = self.tree
tags = self.table[id]
for tag in tags:
node = node[tag]
return node[attr]
def scan(self, path):
print "Scanning path:", path
global ins_table
global ins_index
global ins_tree
self.reset()
ins_table = self.table.insert
ins_index = self.index.insert
ins_tree = self.tree. insert
self.update(path)
self.save()
def reset(self):
print "Resetting collection ... "
from table import Table
from index import Index
from tree import Tree
self.table = Table()
self.index = Index()
self.tree = Tree()
def save(self):
from libsaria import data
data.save((self.table, self.index, self.tree), "library", "")
def load(self):
from libsaria import data
objects = data.load("library", "")
if objects == None:
self.reset()
return
(self.table, self.index, self.tree) = objects
def insert(self, file, filepath):
global tag
global audio
global ins_table
global ins_index
global ins_tree
tags = tag(file)
audio_prop = audio(file)
if tags.artist == u"":
tags.artist = "Unknown Artist"
if tags.album == u"":
tags.album = "Unknown Album"
if tags.title == u"":
tags.title = "Unknown Title"
list = [tags.artist, tags.album, tags.title]
id = ins_table(list)
ins_index(id, list)
list.append(id)
ins_tree(list, tags, audio_prop, filepath)
def update(self, path):
global tag
global audio
FileRef = libsaria.collection.FileRef
join = libsaria.path.join
insert = self.insert
tag = FileRef.tag
audio = FileRef.audioProperties
for root,dirs,files in libsaria.path.walk(path):
for file in files:
file = join(root,file)
try:
insert(FileRef(file), file)
except Exception,e:
pass
class TrackRecord:
def __init__(self, year, length):
self.length = 0
self.length = length
self.count = 0
self.year = 0
self.year = year
#self.like = None
self.fs = None
@ -107,22 +20,31 @@ class TrackRecord:
class Collection2:
def __init__(self):
self.fs_tree = None
self.tag_tree = None
self.records = None
self.next_record = 0
def __init__(self, file):
self.file = file
self.load()
def save(self, file):
def save(self):
libsaria.data.save(
[self.fs_tree, self.tag_tree, self.records, self.next_record],
file, "")
[self.fs_tree, self.tag_tree, self.records,
self.next_record, self.size],
self.file, "")
def load(self):
objects = libsaria.data.load(self.file, "")
if objects == None or len(objects) != 5:
self.reset()
return
(self.fs_tree, self.tag_tree, self.records,
self.next_record, self.size) = objects
def reset(self):
from tree import DLTree
self.fs_tree = DLTree()
self.tag_tree = DLTree()
self.records = dict()
self.fs_tree = DLTree()
self.tag_tree = DLTree()
self.records = dict()
self.next_record = 0
self.size = 0
def disp(self):
pass
@ -131,18 +53,31 @@ class Collection2:
#print
#self.tag_tree.disp()
def walk_tags(self):
for tag in self.tag_tree.walk_forwards():
rec = self.records[tag[3]]
yield tag + [rec.year] + [rec.length]
def get_attr(self, id, attr):
rec = self.records[id]
if attr == "filepath":
cmp = rec.fs.walk_backwards()
return libsaria.path.sep.join([""] + cmp)
if attr == "playcount":
return rec.count
def insert_allocate(self, components, ref):
t = ref.tag()
artist = str(t.artist)
album = str(t.album)
title = str(t.title)
artist = t.artist
album = t.album
title = t.title
audio = ref.audioProperties()
if artist == "":
artist = "Unknown Artist"
artist = u"Unknown Artist"
if album == "":
album = "Unknown Album"
album = u"Unknown Album"
if title == "":
title = "Unknown Title"
title = u"Unknown Title"
record = TrackRecord(t.year, audio.length)
@ -155,3 +90,4 @@ class Collection2:
record.fs = fs
record.tags = tags
self.records[id] = record
self.size += 1

View File

@ -12,19 +12,15 @@ splitext = libsaria.path.splitext
class Library(collection.Collection2):
def __init__(self):
collection.Collection2.__init__(self)
collection.Collection2.__init__(self, "DLTree_test")
self.badfiles = set()
pass
#def save(self):
#libsaria.data.save((self.fs_tree, self.tag_tree), "DLTree_test", "")
# libsaria.data.save(self, "DLTree_test", "")
def scan(self, path):
print "Library scanning %s" % path
self.reset()
self.update(path)
self.save("DLTree_test")
self.save()
self.disp()
def update(self, path):

View File

@ -1,70 +1,12 @@
# Bryan Schumaker (8 / 12 / 2010)
get = dict.get
class TagNode(dict):
def __init__(self, id):
dict.__init__(self)
self["id"] = id
def insert(self, tag_list, tags, audio, filepath):
self["artist"] = tags.artist
self["album"] = tags.album
self["title"] = tags.title
self["year"] = tags.year
self["filepath"] = filepath
self["playcount"] = 0
length = audio.length
sf = 0
sec = length % 60
if sec >= 10:
sf = ""
min = (length - sec) / 60
mf = 0
if min >= 10:
mf = ""
self["seconds"] = audio.length
self["length"] = "%s%s:%s%s" % (mf, min, sf, sec)
def walk(self):
yield self
class Tree(dict):
def __init__(self):
dict.__init__(self)
def walk(self):
keys = self.keys()
keys.sort()
get_item = self.__getitem__
for key in keys:
for track in get_item(key).walk():
yield track
def insert(self, tag_list, tags, audio, filepath):
if len(tag_list) == 0:
return
global get
global insert
tag = tag_list[0]
node = get(self, tag, None)
if node == None:
if len(tag_list) == 1:
node = TagNode(tag)
else:
node = Tree()
self[tag] = node
node.insert(tag_list[1:], tags, audio, filepath)
classes = set([str, int, unicode])
class DLTree:
def __init__(self, parent=None):
self.parent = parent
self.children = None
self.child_fwd = dict()
self.child_bck = dict()
def disp(self, level=0):
space = " " * level
@ -77,38 +19,58 @@ class DLTree:
keys.sort()
for key in keys:
if key.__class__ == str or key.__class__ == int:
value = children[key]
print space, key
value.disp(level+1)
if key.__class__ in classes:#== str or key.__class__ == int or key.__class__ == unicode:
#value = children[key]
yield key
#value.disp(level+1)
#if len(self.children) == 0:
# print self.get_path()
def get_path(self, child=None):
def walk_backwards(self, child=None):
if self.parent == None:
return [self.children[child]]
cmp = self.children.get(child, None)
return [self.child_bck[child]]
cmp = self.child_bck.get(child, None)
child = self
path = self.parent.get_path(child)
path = self.parent.walk_backwards(child)
if cmp != None:
path.append(cmp)
return path
def walk_forwards(self):
children = self.child_fwd
keys = children.keys()
keys.sort()
for key in keys:
child = children[key]
has_children = False
for result in child.walk_forwards():
has_children = True
res = [key]
if result != None:
res += result
yield res
# A leaf will have no children, but
# still needs to yield a value
if has_children == False:
yield [key]
def insert(self, path):
cmp = path[0]
child = None
try:
child = self.children[cmp]
child = self.child_fwd[cmp]
except TypeError:
self.children = dict()
#self.children = dict()
child = DLTree(self)
self.children[cmp] = child
self.children[child] = cmp
self.child_fwd[cmp] = child
self.child_bck[child] = cmp
except KeyError:
child = DLTree(self)
self.children[cmp] = child
self.children[child] = cmp
self.child_fwd[cmp] = child
self.child_bck[child] = cmp
if len(path) > 1:
return child.insert(path[1:])
return self

View File

@ -30,13 +30,8 @@ class Collection(gtk.ScrolledWindow):
insert = self.list.list.insert
ins_next = 0
for track in func():
get = track.__getitem__
insert(ins_next, [get("id"),
get("title"),
get("length"),
get("artist"),
get("album"),
get("year"), ""])
insert(ins_next, [track[3], track[2],
track[5], track[0], track[1], track[4], ""])
ins_next += 1
self.list.thaw()
@ -67,7 +62,8 @@ class Library(Collection):
def populate(self):
import datetime
before = datetime.datetime.now()
Collection.populate(self, collection.walk_library)
#Collection.populate(self, collection.walk_library)
Collection.populate(self, collection.scan_library)
after = datetime.datetime.now()
print "Populating took: %s" % (after-before)

View File

@ -6,4 +6,9 @@ gtk = ocarina.gtk
class FilterEntry(gtk.Entry):
def __init__(self):
gtk.Entry.__init__(self)
self.connect("changed", self.changed)
self.show()
def changed(self, entry):
# We want to start filtering here
print entry.get_text()

View File

@ -36,7 +36,6 @@ class FilterBar(Bar):
Bar.__init__(self, False)
global button
global entry
#global libsaria
self.pack(entry.FilterEntry(), True, True)
self.pack(button.OpenButton())

View File

@ -2,9 +2,11 @@
from libsaria import collection
src = "~/Music"
#src = "~/Music"
#src = "~/Music/Foo Fighters"
#src = "~/Music/Foo Fighters/Foo Fighters"
src = "/media/Music"
collection.new_source(src, bg=False)
#print collection.source.index

View File

@ -4,4 +4,6 @@
from libsaria import collection
collection.new_source2("~/Music/")
#collection.new_source2("~/Music/")
collection.new_source2("/media/Music")
print collection.library2.size