-
Notifications
You must be signed in to change notification settings - Fork 0
/
bobina.py
92 lines (74 loc) · 2.81 KB
/
bobina.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import os
import logging
logger = logging.getLogger(__name__)
from queue import Queue
from PyQt4 import QtCore
from config_manager import get_config
from log import cls_logger
from cacheutils import CacheCopy, AudioCacheFile
_libraries = {}
def get_libraries():
return _libraries
def find_libraries(path):
path = os.path.abspath(path)
for directory in next(os.walk(path))[1]:
yield directory, AudioLibrary([os.path.join(path, directory)])
class Bobina:
"""A Bobina manages the default random dir(s), with prefetching"""
@cls_logger
def __init__(self):
self.log.debug("%s instantiating" % self.__class__.__name__)
self.library = AudioLibrary(get_config()['BOBINA_PATH'])
self.pool = Queue()
self.library_index = 0
self.prefetch(10)
def get_next(self):
audio = self.pool.get_nowait()
self.log.debug("got %s from pool" % audio)
self.prefetch()
return AudioCacheFile(os.path.abspath(audio))
def prefetch(self, n=1):
"""run a background process to get `n` new audio"""
#TODO: make some sense out of it
if n <= 0:
return
#TODO: random.choice facile da usare, ma cosi' e' piu' testabile!
try:
el = self.library.file_list[self.library_index]
except IndexError:
self.library_index = 0
el = self.library.file_list[self.library_index]
self.library_index = (self.library_index + 1) % \
len(self.library.file_list)
self.prepare(el)
self.prefetch(n-1)
def prepare(self, el):
'''fetch an element and put into the queue'''
self.log.debug("Preparing %s" % el)
copy_process = CacheCopy(el)
QtCore.QObject.connect(copy_process, QtCore.SIGNAL('copied(QString)'),
lambda path: self.pool.put(path),
QtCore.Qt.QueuedConnection)
copy_process.start()
class AudioLibrary:
"""Indexes some directories"""
@cls_logger
def __init__(self, dirs):
self.log.debug("%s instantiating(%s)" % (self.__class__.__name__, dirs))
self.dirs = dirs
#This implementation is highly inefficient, because it does not rely on
#an external file, and consumes lot of memory
self.file_list = []
self.scan()
def scan(self):
#TODO: cache!
for d in self.dirs:
if not os.path.exists(d):
self.log.warn("Directory %s does not exist, skipping" % d)
continue
for root, subfolders, files in os.walk(d):
for f in files:
if f.lower().endswith('.wav'):
self.file_list.append(
os.path.abspath(os.path.join(root, f)))
self.file_list.sort()