ocarina/libsaria/collection/lens.py

131 lines
2.9 KiB
Python

# Bryan Schumaker (10/1/2010)
import libsaria
import collection
import random as rand
from libsaria import data
save = data.save
load = data.load
sep = libsaria.path.sep
walk = libsaria.path.walk
join = libsaria.path.join
splitext = libsaria.path.splitext
badfiles = set()
def set_badfiles():
global badfiles
bf = load("badfiles")
if bf != None:
badfiles = bf
class Library(collection.Collection):
def __init__(self):
collection.Collection.__init__(self, "library")
def scan(self, path):
print "Library scanning %s" % path
set_badfiles()
self.update(path)
self.save()
save(badfiles, "badfiles", "")
self.disp()
def update(self, path):
global badfiles
FileRef = libsaria.collection.FileRef
find_id = self.find_id
for root,dirs,files in walk(path):
stripped_root = root.strip(sep)
split_root = stripped_root.split(sep)
for file in files:
ext = splitext(file)[1]
if ext in badfiles:
continue
path = join(root, file)
if find_id(path) != None:
continue
try:
ref = FileRef(path)
except:
badfiles.add(ext)
continue
try:
self.insert_allocate(split_root + [file], ref)
except UnicodeEncodeError:
pass
class Playlist(collection.Collection):
def __init__(self):
collection.Collection.__init__(self, "playlist")
self.last_tracks = []
def next_id(self, last_id):
return_next = False
first = None
visible = self.is_visible
for id in self.walk_ids():
if visible(id):
if first == None:
first = id
if return_next == True:
return id
if id == last_id:
return_next = True
if first != None:
return first
return None
def random(self):
if self.size == 0:
return
getattr = libsaria.collection.get_attr
last = self.last_tracks
for i in xrange(15):
id = self.get_rand_candidate()
artist = getattr(id, "artist")
album = getattr(id, "album")
title = getattr(id, "title")
if (artist, title) in last:
print "Skipping %s by %s because it has played recently." % (title, artist)
continue
score = getattr(id, "score")
if score < 0:
play_anyway = rand.randint(0, 100)
if play_anyway < ((20 * score) + 100):
print "Skipping %s by %s because I don't think you want to hear it." % (title, artist)
continue
last.append((artist, title))
if len(last) > 30:
last.pop(0)
if i > 0:
print "Picking a song took %s iterations" % i
return id
return id
def get_rand_candidate(self):
num = self.num_visible()
next_idx = rand.randint(0, num-1)
func = self.walk_filtered_ids
if self.filtered == False:
func = self.walk_ids
for n in func():
if next_idx == 0:
return n
next_idx -= 1
# We shouldn't ever get here, but for some reason we are.
# We return the last value of n, but I would like to figure
# Out why we leave the loop early eventually.
return n