131 lines
2.9 KiB
Python
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
|
|
|
|
|
|
|
|
|