<commit_before>from Song import Song
from State import state
from player import PlayerEventCallbacks
from utils import *
import Traits
import math, random
import appinfo


try:
	QueueCallbacks
except NameError:
	# This is fixed. In case we add some, we have to restart.
	class QueueCallbacks:
		onModify = Id("onModify")


def putOnModify(*args, **kwargs):
	state.updates.put((QueueCallbacks.onModify, args, kwargs))

class RandomFileQueueGen:
	randomQuality = 0.5

	def __init__(self, dir):
		import os
		from RandomFileQueue import RandomFileQueue

		self.fileQueue = RandomFileQueue(
			rootdir=os.path.expanduser(dir),
			fileexts=appinfo.formats)

	def next(self):
		return self.fileQueue.getNextFile()


class RandomFromSongDatabaseGen:
	randomQuality = 0.0

	def __init__(self):
		def loadDatabase():
			from SongStore import SongStore
			self.database = SongStore()

			import utils

			print "updating database"

			for dir in appinfo.musicdirs:
				self.database.addMany(utils.getSongsFromDirectory(dir))

			self.randomQuality = 0.5
			print "Done loading songs"

		from threading import Thread

		loadDatabaseThread = Thread(target=loadDatabase, name="loadDatabase")
		loadDatabaseThread.start()

	def next(self):
		try:
			oldSong = state.recentlyPlayedList.getLastN(1)[0]
		except:
			oldSong = None

		songs = self.database.getRandomSongs(oldSong=oldSong, limit=1)

		return next(iter(songs))



class RandomSongs:
	randomQuality = 0.5

	def __init__(self, generators):
		self.generators = [gen() for gen in generators]

	def next(self):
		while True:
			generators = list(self.generators)
			if not generators:
				raise StopIteration
			qualitySum = sum([gen.randomQuality for gen in generators])
			self.randomQuality = qualitySum / len(generators)
			r = random.random() * qualitySum
			i = 0
			gen = generators[i]
			while i < len(generators) - 1 and r > gen.randomQuality:
				r -= gen.randomQuality
				i += 1
				gen = generators[i]
			try:
				return next(gen)
			#except StopIteration:
				#print "warning: generator", gen, "raised StopIteration"
				#sys.excepthook(*sys.exc_info())
				#pass
			except: # just catch any exception, esp non-StopIteration
				print "RandomSongs generator raised exception"
				sys.excepthook(*sys.exc_info())
			generators.pop(i)

	def __iter__(self):
		while True:
			yield self.next()

from collections import deque
from threading import RLock

class ListWrapper: # implements the List trait
	def __init__(self, owner, list): # parent is supposed to be the MainQueue
		self.owner = owner
		self.lock = owner.lock
		self.list = list
	
	def onInsert(self, index, value): pass
	def onRemove(self, index): pass
	def onClear(self): pass
	
	def insert(self, index, value):
		with self.lock:
			self.list.insert(index, value)
			self.onInsert(index, value)
			self.list.save()
		putOnModify()
	def remove(self, index):
		with self.lock:
			del self.list[index]
			self.onRemove(index)
			self.list.save()
		putOnModify()
	def popleft(self):
		with self.lock:
			obj = self.list.pop(0)
			self.onRemove(0)
			self.list.save()
			return obj
		putOnModify()
	def append(self, value):
		with self.lock:
			self.list.append(value)
			self.onInsert(len(self.list)-1, value)
			self.list.save()
		putOnModify()
	def clear(self):
		with self.lock:
			self.list.clear()
			self.onClear()
			self.list.save()
		putOnModify()
	def __getitem__(self, index):
		with self.lock:
			return self.list[index]
	def __len__(self):
		with self.lock:
			return len(self.list)
			
class MainQueue:<commit_msg>fix queue.clear<commit_after>from Song import Song
from State import state
from player import PlayerEventCallbacks
from utils import *
import Traits
import math, random
import appinfo


try:
	QueueCallbacks
except NameError:
	# This is fixed. In case we add some, we have to restart.
	class QueueCallbacks:
		onModify = Id("onModify")


def putOnModify(*args, **kwargs):
	state.updates.put((QueueCallbacks.onModify, args, kwargs))

class RandomFileQueueGen:
	randomQuality = 0.5

	def __init__(self, dir):
		import os
		from RandomFileQueue import RandomFileQueue

		self.fileQueue = RandomFileQueue(
			rootdir=os.path.expanduser(dir),
			fileexts=appinfo.formats)

	def next(self):
		return self.fileQueue.getNextFile()


class RandomFromSongDatabaseGen:
	randomQuality = 0.0

	def __init__(self):
		def loadDatabase():
			from SongStore import SongStore
			self.database = SongStore()

			import utils

			print "updating database"

			for dir in appinfo.musicdirs:
				self.database.addMany(utils.getSongsFromDirectory(dir))

			self.randomQuality = 0.5
			print "Done loading songs"

		from threading import Thread

		loadDatabaseThread = Thread(target=loadDatabase, name="loadDatabase")
		loadDatabaseThread.start()

	def next(self):
		try:
			oldSong = state.recentlyPlayedList.getLastN(1)[0]
		except:
			oldSong = None

		songs = self.database.getRandomSongs(oldSong=oldSong, limit=1)

		return next(iter(songs))



class RandomSongs:
	randomQuality = 0.5

	def __init__(self, generators):
		self.generators = [gen() for gen in generators]

	def next(self):
		while True:
			generators = list(self.generators)
			if not generators:
				raise StopIteration
			qualitySum = sum([gen.randomQuality for gen in generators])
			self.randomQuality = qualitySum / len(generators)
			r = random.random() * qualitySum
			i = 0
			gen = generators[i]
			while i < len(generators) - 1 and r > gen.randomQuality:
				r -= gen.randomQuality
				i += 1
				gen = generators[i]
			try:
				return next(gen)
			#except StopIteration:
				#print "warning: generator", gen, "raised StopIteration"
				#sys.excepthook(*sys.exc_info())
				#pass
			except: # just catch any exception, esp non-StopIteration
				print "RandomSongs generator raised exception"
				sys.excepthook(*sys.exc_info())
			generators.pop(i)

	def __iter__(self):
		while True:
			yield self.next()

from collections import deque
from threading import RLock

class ListWrapper: # implements the List trait
	def __init__(self, owner, list): # parent is supposed to be the MainQueue
		self.owner = owner
		self.lock = owner.lock
		self.list = list
	
	def onInsert(self, index, value): pass
	def onRemove(self, index): pass
	def onClear(self): pass
	
	def insert(self, index, value):
		with self.lock:
			self.list.insert(index, value)
			self.onInsert(index, value)
			self.list.save()
		putOnModify()
	def remove(self, index):
		with self.lock:
			del self.list[index]
			self.onRemove(index)
			self.list.save()
		putOnModify()
	def popleft(self):
		with self.lock:
			obj = self.list.pop(0)
			self.onRemove(0)
			self.list.save()
			return obj
		putOnModify()
	def append(self, value):
		with self.lock:
			self.list.append(value)
			self.onInsert(len(self.list)-1, value)
			self.list.save()
		putOnModify()
	def clear(self):
		with self.lock:
			self.list = []
			self.onClear()
			self.list.save()
		putOnModify()
	def __getitem__(self, index):
		with self.lock:
			return self.list[index]
	def __len__(self):
		with self.lock:
			return len(self.list)
			
class MainQueue:
{'fraction_non_alphanumeric': 0.10524085322785705, 'fraction_numerical': 0.004802938268116966, 'mean_word_length': 3.87603305785124, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2025101', 'n_tokens_mistral': 2743, 'n_tokens_neox': 2328, 'n_words': 630}