My favorites | Sign in
Project Logo
                
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# Copyright (C) 2007-2008 - Eric Casteleijn, Alexandre Rosenfeld
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.

import os
import urllib
from time import time
import gconf
import rb, rhythmdb

from autoqueue import AutoQueueBase, SongBase

GCONFPATH = '/apps/rhythmbox/plugins/autoqueue/'

class Song(SongBase):
"""A wrapper object around rhythmbox song objects."""
def __init__(self, song, db):
self.song = song
self.db = db

def get_artist(self):
"""return lowercase UNICODE name of artist"""
return unicode(
self.db.entry_get(self.song, rhythmdb.PROP_ARTIST).lower(), 'utf-8')

def get_title(self):
"""return lowercase UNICODE title of song"""
return unicode(
self.db.entry_get(self.song, rhythmdb.PROP_TITLE).lower(), 'utf-8')

def get_tags(self):
"""return a list of tags for the songs"""
return []

def get_length(self):
return self.db.entry_get(self.song, rhythmdb.PROP_DURATION)

def get_filename(self):
location = self.db.entry_get(self.song, rhythmdb.PROP_LOCATION)
if location.startswith("file://"):
return urllib.unquote(location[7:])
return None

def get_last_started(self):
return self.db.entry_get(self.song, rhythmdb.PROP_LAST_PLAYED)


class AutoQueuePlugin(rb.Plugin, AutoQueueBase):
def __init__(self):
rb.Plugin.__init__(self)
self.use_db = True
self.store_blocked_artists = True
AutoQueueBase.__init__(self)
self.gconfclient = gconf.client_get_default()
self.verbose = False
self.by_mirage = False
self.log("initialized")

def activate(self, shell):
self.shell = shell
self.rdb = shell.get_property('db')
sp = shell.get_player ()
self.pec_id = sp.connect(
'playing-song-changed', self.playing_entry_changed)

def deactivate(self, shell):
self.rdb = None
self.shell = None
sp = shell.get_player()
sp.disconnect(self.pec_id)

def log(self, msg):
"""print debug messages"""
if not self.verbose:
return
print msg

def playing_entry_changed(self, sp, entry):
if entry:
self.on_song_started(Song(entry, self.rdb))

def player_get_userdir(self):
"""get the application user directory to store files"""
folder = os.path.join(
os.getenv('HOME'), '.gnome2', 'rhythmbox', 'autoqueue')
if not os.path.isdir(folder):
os.mkdir(folder)
return folder

def player_construct_track_search(self, artist, title, restrictions):
"""construct a search that looks for songs with this artist
and title"""
result = (rhythmdb.QUERY_PROP_EQUALS, rhythmdb.PROP_ARTIST_FOLDED,
artist.encode('utf-8'), rhythmdb.QUERY_PROP_EQUALS,
rhythmdb.PROP_TITLE_FOLDED, title.encode('utf-8'))
if restrictions:
result += restrictions
return result

def player_construct_tag_search(self, tags, exclude_artists, restrictions):
"""construct a search that looks for songs with these
tags"""
return None

def player_construct_artist_search(self, artist, restrictions):
"""construct a search that looks for songs with this artist"""
result = (rhythmdb.QUERY_PROP_EQUALS, rhythmdb.PROP_ARTIST_FOLDED,
artist.encode('utf-8'))
if restrictions:
result += restrictions
return result

def player_construct_restrictions(
self, track_block_time, relaxors, restrictors):
"""contstruct a search to further modify the searches"""
seconds = track_block_time * 24 * 60 * 60
now = time()
cutoff = now - seconds
return (
rhythmdb.QUERY_PROP_LESS, rhythmdb.PROP_LAST_PLAYED, cutoff)

def player_set_variables_from_config(self):
"""Initialize user settings from the configuration storage"""
#XXX Still to do
pass

def player_get_queue_length(self):
"""Get the current length of the queue"""
return sum([
self.rdb.entry_get(
row[0], rhythmdb.PROP_DURATION) for row in
self.shell.props.queue_source.props.query_model])

def player_enqueue(self, song):
"""Put the song at the end of the queue"""
self.shell.add_to_queue(
self.rdb.entry_get(song.song, rhythmdb.PROP_LOCATION))

def player_search(self, search):
"""perform a player search"""
query = self.rdb.query_new()
self.rdb.query_append(query, search)
query_model = self.rdb.query_model_new_empty()
self.rdb.do_full_query_parsed(query_model, query)
result = []
for row in query_model:
result.append(Song(row[0], self.rdb))
return result

def player_get_songs_in_queue(self):
"""return (wrapped) song objects for the songs in the queue"""
return [
Song(row[0], self.rdb) for row in
self.shell.props.queue_source.props.query_model]
Show details Hide details

Change log

r288 by thisfred on Oct 02, 2009   Diff
block performers as well as artists
Go to: 
Sign in to write a code review

Older revisions

r276 by thisfred on Sep 16, 2009   Diff
refactored how mirage analysis is
used. Mostly simplified, and
normalized so outliers are more likely
to be found.
r245 by thisfred on Feb 08, 2009   Diff
up to date with latest autoqueue, and
works with mirage
r206 by thisfred on Dec 30, 2008   Diff
reverted to 164

All revisions of this file

File info

Size: 5813 bytes, 166 lines
Hosted by Google Code