class LCDProcPlugin (GObject.Object, Peas.Activatable): object = GObject.property(type=GObject.Object) def __init__(self): super(LCDProcPlugin, self).__init__() def do_activate(self): print "Activating Plugin" self.entry = None self.duration = 0 self.artist = " " self.title = " " self.album = " " # Initialise LCD try: self.lcd = Server(LCDPROC_HOST, debug=True) except SocketError: print "Failed to connect to LCDd" return False self.lcd.start_session() self.screen1 = self.lcd.add_screen("Rhythmbox") self.title1_widget = self.screen1.add_title_widget("Title", "Rhythmbox") self.label1_widget = self.screen1.add_string_widget("Label", KEY_LABELS, 1, 2) self.screen2 = self.lcd.add_screen("Rhythmbox-info") self.screen2.set_heartbeat("off") self.lcd.output("on") width = self.lcd.server_info["screen_width"] self.album_widget = self.screen2.add_scroller_widget("AlbumWidget", top = ALBUM_LINE, bottom = ALBUM_LINE, right = width, text = "Album") self.artist_widget = self.screen2.add_scroller_widget("ArtistWidget", top = ARTIST_LINE, bottom = ARTIST_LINE, right = width, text = "Artist") self.title_widget = self.screen2.add_scroller_widget("TitleWidget", top = TITLE_LINE, bottom = TITLE_LINE, right = width, text = "Title") self.progress_bar = self.screen2.add_hbar_widget("HBarWidget", x=1, y=TIME_LINE, length=0) self.time_widget = self.screen2.add_string_widget("TimeWidget", "", 1, TIME_LINE) self.displayed_lines = 4 if SHOW_LABELS: self.label_widget = self.screen2.add_string_widget("LabelWidget", KEY_LABELS, 1, LABEL_LINE) self.displayed_lines += 1 self.bounce_roll_length = width + BOUNCE_ROLL_THRESHOLD self.screen_width_pxl = width * self.lcd.server_info["cell_width"] for key in keyUse.keys(): self.lcd.add_key(key) # Connect call-back functions to interesting events. sp = self.object.props.shell_player self.pc_id = sp.connect('playing-changed', self.playing_changed) self.psc_id = sp.connect('playing-song-changed', self.playing_song_changed) self.pspc_id = sp.connect('playing-song-property-changed', self.playing_song_property_changed) self.ec_id = sp.connect('elapsed-changed', self.elapsed_changed) # LCDd processes key input at 32Hz. self.pollcbtag = GObject.timeout_add(1000 / 32, self.poll_cb) print sp.get_playback_state() if sp.get_playing(): print "Activating: playing" self.set_entry(sp.get_playing_entry()) self.screen1.set_priority("background") self.screen2.set_priority("foreground") else: print "Activating: stopped" self.screen1.set_priority("info") self.screen2.set_priority("background") print "Plugin Activated" def do_deactivate(self): print "Deactivating Plugin" if not hasattr(self, 'pc_id'): return sp = self.object.props.shell_player sp.disconnect(self.pc_id) sp.disconnect(self.psc_id) sp.disconnect(self.pspc_id) sp.disconnect(self.ec_id) GObject.source_remove(self.pollcbtag) # Disconnect LCD del self.title1_widget del self.label1_widget del self.artist_widget del self.album_widget del self.title_widget del self.progress_bar del self.time_widget if SHOW_LABELS: del self.label_widget del self.screen1 del self.screen2 self.lcd.tn.close() del self.lcd print "Plugin Deactivated" def poll_cb(self): response = self.lcd.poll() if response: print "Poll Response: %s" % (response[:-1]) bits = (response[:-1]).split(" ") if bits[0] == "key": action = keyUse[bits[1]] sp = self.object.props.shell_player # Used by some actions. print action try: exec action except GError as e: if e.args[0] in ('Not currently playing', 'No previous song'): print "%s safe to ignore." % e.args[0] else: print "%s unexpected." % e.args raise except: print "Blast! Unexpected error:", sys.exc_info()[0] raise return True def playing_changed(self, player, playing): if playing: print "Playing" self.set_entry(player.get_playing_entry()) self.screen1.set_priority("background") self.screen2.set_priority("foreground") else: print "Not playing" self.entry = None self.screen1.set_priority("info") self.screen2.set_priority("background") def playing_song_changed(self, player, entry): print "Playing song changed %s" % (entry) if player.get_playing(): self.set_entry(entry) def playing_song_property_changed(self, player, uri, song_property, old, new): print "Playing song %s property (%s) changed (%s to %s)" % (uri, song_property, old, new) if player.get_playing(): if song_property in (NORMAL_ALBUM, STREAM_ALBUM): self.album = new elif song_property in (NORMAL_ARTIST, STREAM_ARTIST): self.artist = new elif song_property in (NORMAL_TITLE): self.title = new elif song_property in (STREAM_TITLE): if new.count(" - ") >= 1: # contains "Artist - Title" fields = new.split(" - ",1) self.artist = fields[0] self.title = fields[1] else: # only title self.title = new self.artist = "" self.album = uri self.duration = 0 else: return else: return self.set_display() def elapsed_changed(self, player, time): # print "Elapsed changed %d" % time if (time >= 0 and self.duration > 0): progress = self.screen_width_pxl * time / self.duration self.progress_bar.set_length(progress) progress_str = "%d:%02d" % (time/60, time%60) if (time < self.duration / 2): self.time_widget.set_x(self.lcd.server_info["screen_width"] - len(progress_str) + 1) else: self.time_widget.set_x(1) self.time_widget.set_text(progress_str) else: self.progress_bar.set_length(0) self.time_widget.set_text("") def set_entry(self, entry): if rb.entry_equal(entry, self.entry): return self.entry = entry if entry is None: return self.album = entry.get_string(RB.RhythmDBPropType.ALBUM) self.artist = entry.get_string(RB.RhythmDBPropType.ARTIST) self.title = entry.get_string(RB.RhythmDBPropType.TITLE) self.duration = entry.get_ulong(RB.RhythmDBPropType.DURATION) # sp = self.object.props.shell_player # self.duration = sp.get_playing_song_duration() self.rating = entry.get_double(RB.RhythmDBPropType.RATING) print "Song rating %g" % self.rating db = self.object.get_property("db") if entry.get_entry_type().props.category == RB.RhythmDBEntryCategory.STREAM: if not self.album: self.album = db.entry_request_extra_metadata(entry, STREAM_ALBUM) if not self.artist: self.artist = db.entry_request_extra_metadata(entry, STREAM_ARTIST) if not self.title: self.title = db.entry_request_extra_metadata(entry, STREAM_TITLE) self.set_display() def set_display(self): album_text = self.album if DONT_SCROLL: album_text = album_text[0:self.lcd.server_info["screen_width"]] elif len(album_text) < self.bounce_roll_length: self.album_widget.set_direction("h") # Bounce text to show characters that don't fit else: self.album_widget.set_direction("m") # Roll text to show characters that don't fit album_text += " * " self.album_widget.set_text(album_text) artist_text = self.artist if DONT_SCROLL: artist_text = artist_text[0:self.lcd.server_info["screen_width"]] elif len(artist_text) < self.bounce_roll_length: self.artist_widget.set_direction("h") else: self.artist_widget.set_direction("m") artist_text += " * " self.artist_widget.set_text(artist_text) title_text = self.title if DONT_SCROLL: title_text = title_text[0:self.lcd.server_info["screen_width"]] elif len(title_text) < self.bounce_roll_length: self.title_widget.set_direction("h") else: self.title_widget.set_direction("m") title_text += " * " self.title_widget.set_text(title_text) def new_line(self, current, step): print "newline %d,%d" % (current, step) current += step if current > self.displayed_lines: return 1 if current == 0: current = self.displayed_lines return current def scroll(self, step): self.album_widget.set_top(self.new_line(self.album_widget.top, step)) self.album_widget.set_bottom(self.new_line(self.album_widget.bottom, step)) self.artist_widget.set_top(self.new_line(self.artist_widget.top, step)) self.artist_widget.set_bottom(self.new_line(self.artist_widget.bottom, step)) self.title_widget.set_top(self.new_line(self.title_widget.top, step)) self.title_widget.set_bottom(self.new_line(self.title_widget.bottom, step)) self.progress_bar.set_y(self.new_line(self.progress_bar.y, step)) self.time_widget.set_y(self.new_line(self.time_widget.y, step)) if SHOW_LABELS: self.label_widget.set_y(self.new_line(self.label_widget.y, step))