def build_lastfm_menu(self) -> List[Any]: def login_lastfm(_): self.title = f"{Icons.music} Logging into Last.fm, check your browser..." self.lastfm.make_session() self.set_scrobbling(True) self.refresh_menu() def logout_lastfm(_): self.lastfm.reset() self.refresh_menu() def toggle_scrobbling(_): self.set_scrobbling(not self.scrobble) self.refresh() self.refresh_menu() if not self.lastfm.username: self.set_scrobbling(False) return [ 'Not logged in.', None, rumps.MenuItem('Log in with Last.fm...', callback=login_lastfm) ] history = ['No tracks scrobbled yet...'] if self.history: history = ['Last 5 Scrobbles'] for itm in reversed(self.history[-5:]): history.append( make_font(f'• {itm}', NSFont.menuFontOfSize_(12.0))) scrobble_enabled = rumps.MenuItem('Enable scrobbling', callback=toggle_scrobbling) scrobble_enabled.state = self.scrobble return [ f'Logged in as {self.lastfm.username}', scrobble_enabled, None, *history, None, rumps.MenuItem('Log out...', callback=logout_lastfm) ]
def make_font(text, font=NSFont.menuFontOfSize_(0.0)): attr_string = make_attributed_string(text, font) menuitem = rumps.MenuItem("") menuitem._menuitem.setAttributedTitle_(attr_string) return menuitem
def build_menu(self) -> List[Any]: def make_open(p): return lambda _: run(p.value, 'activate') always_visible = [('Open Player', [ rumps.MenuItem(f'{p.name}', callback=make_open(p)) for p in self.mb.players ]), None, ('Last.fm Scrobbling', self.build_lastfm_menu()), None, rumps.MenuItem('Force Refresh', callback=self.force_refresh, key='r'), rumps.MenuItem('Quit', callback=rumps.quit_application, key='q')] player = self.mb.get_active_player() if not player: return ['No player open currently.', None, *always_visible] track = player.get_track() if not track: return ['Nothing playing currently.', None, *always_visible] def make_menu_button(method): def cb(func) -> Callable[[Any], None]: def inner(_: Any) -> None: func() self.refresh() return inner attr = method.lower() return rumps.MenuItem(f'{getattr(Icons, attr)} {method}', callback=cb(getattr(player, attr))) buttons_paused = [make_menu_button('Play')] buttons_playing = [ make_menu_button('Pause'), make_menu_button('Next'), make_menu_button('Previous') ] buttons = buttons_paused if player.status == PlayerStatus.PAUSED else buttons_playing art_menu = [] art_path = player.get_album_cover() if art_path and os.path.isfile(art_path): art_menu = [ rumps.MenuItem("", callback=dummy_callback, icon=art_path, dimensions=[192, 192]), None ] if not player.scrobbling: scrobble_message = f'{Icons.error} No scrobbler running' else: scrobblers = map(lambda scrob: scrob.name, self.mb.get_player_scrobblers(player.app)) scrobble_message = f'Scrobbling using {", ".join(scrobblers)}' song_metadata = [rumps.MenuItem(track.title, callback=dummy_callback)] if track.artist: song_metadata.append(track.artist) if track.album: song_metadata.append( make_font(track.album, NSFont.menuFontOfSize_(12.0))) return [ *buttons, None, *art_menu, *song_metadata, None, f'Now playing on {player.app.name}', make_font(scrobble_message, NSFont.menuFontOfSize_(10.0)), None, *always_visible ]
def make_attributed_string(text, font=NSFont.menuFontOfSize_(0.0)): attributes = propertyListFromPythonCollection({NSFontAttributeName: font}, conversionHelper=lambda x: x) return NSAttributedString.alloc().initWithString_attributes_( text, attributes)