File: suggest.py

package info (click to toggle)
mc-foo 0.0.13
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 268 kB
  • ctags: 532
  • sloc: python: 1,967; makefile: 6
file content (69 lines) | stat: -rw-r--r-- 1,969 bytes parent folder | download | duplicates (2)
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
import os, os.path, random

class Cyclic:

    """A cyclic sequence of things. Ask stuff from me with get()
    and it won't repeat often."""
    
    chunksize=1000

    def __init__(self, initlist):
        assert initlist
        if len(initlist)/2 < self.chunksize:
            self.chunksize=len(initlist)/2
        random.shuffle(initlist)
        self.next=initlist[:self.chunksize]
        self.rest=initlist[self.chunksize:]
        self._feed_next()

    def _random_insert_rest(self, weight, item):
        max=len(self.rest)+1
        max=int(max / 2**(weight/10.0))
        if max==0:
            max=1
        i=random.randrange(max)
        self.rest[i:i]=[(weight, item)]

    def _feed_next(self):
        need=self.chunksize-len(self.next)
        if need>0:
            self.next.extend(self.rest[:need])
            del self.rest[:need]
            assert len(self.next) == self.chunksize

    def get(self):
        weight, item=self.next[0]
        self._random_insert_rest(weight, item)
        del self.next[0]
        self._feed_next()
        return item

    def peek(self):
        """Provide a read-only view to first chunksize items."""
        return self.next


class Suggestions:
    def __init__(self, paths, profileTable):
        self.paths=paths
        self.data=None
        self.profileTable=profileTable

    def __getinitargs__(self):
        return [self.paths, self.profileTable]

    def _visit(self, songs, dirname, names):
        for file in os.listdir(dirname):
            l=file.lower()
            if l.endswith(".mp3") or l.endswith(".ogg"):
                filename=dirname+'/'+file
                score=self.profileTable.getScore(filename)
                songs.append((score, filename))

    def get(self):
        if not self.data:
            songs=[]
            for path in self.paths:
                os.path.walk(path, self._visit, songs)
            self.data=Cyclic(songs)
        return self.data.get()