diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6dfeef3 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +keyboard==0.13.4 +PyChromecast==4.1.0 diff --git a/src/app.py b/src/app.py index a792a2a..f90a4c6 100644 --- a/src/app.py +++ b/src/app.py @@ -8,25 +8,27 @@ CONFIG_NAME = "config.json" CONFIG_PATH = os.path.join(CONFIG_DIR, CONFIG_NAME) DEFAULT_CONFIG = { - "DEVICE_NAME": "Chromecast Audio", - "PREV_KEY": "f15", - "PLAY_KEY": "f16", - "NEXT_KEY": "f17", - "MUTE_KEY": "f18", - "VOLD_KEY": "f19", - "VOLU_KEY": "f20" + "DEVICE_NAME": "Chromecast Audio", + "PREV_KEY": "f15", + "PLAY_KEY": "f16", + "NEXT_KEY": "f17", + "MUTE_KEY": "f18", + "VOLD_KEY": "f19", + "VOLU_KEY": "f20", + "TEXT_SHOWN": True } KEY_NAMES = { - "PREV_KEY": "Previous", - "PLAY_KEY": "Play/Pause", - "NEXT_KEY": "Next", - "MUTE_KEY": "Mute/Unmute", - "VOLD_KEY": "Volume Down", - "VOLU_KEY": "Volume Up" + "PREV_KEY": "Previous", + "PLAY_KEY": "Play/Pause", + "NEXT_KEY": "Next", + "MUTE_KEY": "Mute/Unmute", + "VOLD_KEY": "Volume Down", + "VOLU_KEY": "Volume Up" } # ICONS_PATH = "src/icons" ICONS_PATH = "." + class CastMenuApp(rumps.App): def __init__(self): @@ -55,45 +57,63 @@ def __setCastIcon(self, playing=True): self.icon = os.path.join(ICONS_PATH, "cast_disconnected.png") def setMenu(self, connected=True): - self.prevItem = rumps.MenuItem("Previous", callback=lambda _: self.device.previous()) - self.playPauseItem = rumps.MenuItem("Play", callback=lambda _: self.__onPlayPauseClicked()) - self.nextItem = rumps.MenuItem("Next", callback=lambda _: self.device.next()) - - self.volumeDescItem = rumps.MenuItem("Volume", callback=lambda _: self.__onMuteClicked()) - self.volumeItem = rumps.SliderMenuItem(value=0, min_value=0, max_value=100, callback=lambda item: self.__onVolumeChanged(item.value)) + self.prevItem = rumps.MenuItem( + "Previous", callback=lambda _: self.device.previous()) + self.playPauseItem = rumps.MenuItem( + "Play", callback=lambda _: self.__onPlayPauseClicked()) + self.nextItem = rumps.MenuItem( + "Next", callback=lambda _: self.device.next()) + + self.volumeDescItem = rumps.MenuItem( + "Volume", callback=lambda _: self.__onMuteClicked()) + self.volumeItem = rumps.SliderMenuItem( + value=0, min_value=0, max_value=100, callback=lambda item: self.__onVolumeChanged(item.value)) self.preferencesItem = rumps.MenuItem("Preferences") self.deviceSelectedItem = rumps.MenuItem(f"Device: {self.deviceName}") + self.textShownItem = rumps.MenuItem("Show Artist > Title in Menu Bar", callback=lambda _: self.__onTextShownChanged()) + self.textShownItem.state = int(self.config["TEXT_SHOWN"]) # self.deviceSelectedItem = rumps.MenuItem(f"Device: {self.deviceName}", callback=lambda _ : self.__onDeviceSelectedClicked()) for cc in self.chromecasts: name = cc.device.friendly_name - self.deviceSelectedItem.add(rumps.MenuItem(name, callback=self.__onDeviceSelected)) + self.deviceSelectedItem.add(rumps.MenuItem( + name, callback=self.__onDeviceSelected)) self.preferencesItem.add(self.deviceSelectedItem) + self.preferencesItem.add(self.textShownItem) self.preferencesItem.add(None) for key in ["PREV_KEY", "PLAY_KEY", "NEXT_KEY", "MUTE_KEY", "VOLD_KEY", "VOLU_KEY"]: - self.preferencesItem.add(rumps.MenuItem(f"{KEY_NAMES[key]}: {self.config[key]}", callback=self.__onKeyClicked)) + self.preferencesItem.add(rumps.MenuItem( + f"{KEY_NAMES[key]}: {self.config[key]}", callback=self.__onKeyClicked)) self.preferencesItem.add(None) - self.reattachKeysItem = rumps.MenuItem("Reload conf", callback=lambda _: self.__init__()) + self.reattachKeysItem = rumps.MenuItem( + "Reload conf", callback=lambda _: self.__init__()) self.preferencesItem.add(self.reattachKeysItem) - self.aboutItem = rumps.MenuItem("About", callback=lambda item: os.system("open \"\" https://pierrejacquier.com/castmenu")) - self.quitItem = rumps.MenuItem("Quit", callback=lambda item: rumps.quit_application()) + self.aboutItem = rumps.MenuItem("About", callback=lambda item: os.system( + "open \"\" https://pierrejacquier.com/castmenu")) + self.quitItem = rumps.MenuItem( + "Quit", callback=lambda item: rumps.quit_application()) self.menu.clear() self.menu = [self.prevItem, self.playPauseItem, self.nextItem, None, - self.volumeDescItem, self.volumeItem, None, - self.preferencesItem, self.aboutItem, self.quitItem] - + self.volumeDescItem, self.volumeItem, None, + self.preferencesItem, self.aboutItem, self.quitItem] def setHotkeys(self): for hk in self.hotkeys: keyboard.remove_hotkey(hk) - self.hotkeys.append(keyboard.add_hotkey(self.config["PREV_KEY"], lambda: self.device.previous())) - self.hotkeys.append(keyboard.add_hotkey(self.config["PLAY_KEY"], lambda: self.device.togglePlay())) - self.hotkeys.append(keyboard.add_hotkey(self.config["NEXT_KEY"], lambda: self.device.next())) - self.hotkeys.append(keyboard.add_hotkey(self.config["MUTE_KEY"], lambda: self.device.toggleMute())) - self.hotkeys.append(keyboard.add_hotkey(self.config["VOLD_KEY"], lambda: self.device.volumeDown())) - self.hotkeys.append(keyboard.add_hotkey(self.config["VOLU_KEY"], lambda: self.device.volumeUp())) + self.hotkeys.append(keyboard.add_hotkey( + self.config["PREV_KEY"], lambda: self.device.previous())) + self.hotkeys.append(keyboard.add_hotkey( + self.config["PLAY_KEY"], lambda: self.device.togglePlay())) + self.hotkeys.append(keyboard.add_hotkey( + self.config["NEXT_KEY"], lambda: self.device.next())) + self.hotkeys.append(keyboard.add_hotkey( + self.config["MUTE_KEY"], lambda: self.device.toggleMute())) + self.hotkeys.append(keyboard.add_hotkey( + self.config["VOLD_KEY"], lambda: self.device.volumeDown())) + self.hotkeys.append(keyboard.add_hotkey( + self.config["VOLU_KEY"], lambda: self.device.volumeUp())) def __onPlayPauseClicked(self): self.device.togglePlay() @@ -107,7 +127,8 @@ def __onDeviceSelected(self, item): def __onKeyClicked(self, item): key_name = item.title.split(": ")[0] key = next(k for k in KEY_NAMES if KEY_NAMES[k] == key_name) - self.window = rumps.Window(f"Select key for {KEY_NAMES[key]}", title="Enter the key", default_text=self.config[key]) + self.window = rumps.Window( + f"Select key for {KEY_NAMES[key]}", title="Enter the key", default_text=self.config[key]) res = self.window.run() self.editConfigKey(key, res.text) self.setMenu() @@ -115,11 +136,13 @@ def __onKeyClicked(self, item): def __onDeviceSelectedClicked(self): print(self.chromecasts) - availableNames = "\n".join([c.device.friendly_name for c in self.chromecasts]) + availableNames = "\n".join( + [c.device.friendly_name for c in self.chromecasts]) message = "Available devices on network:\n" + availableNames print(message) - - self.window = rumps.Window(message, title="Enter the Chromecast-enabled device name:", default_text=self.deviceName) + + self.window = rumps.Window( + message, title="Enter the Chromecast-enabled device name:", default_text=self.deviceName) res = self.window.run() self.deviceName = res.text self.deviceSelectedItem.title = f"Device: {self.deviceName}" @@ -129,6 +152,10 @@ def __onDeviceSelectedClicked(self): def __onMuteClicked(self): self.device.toggleMute() + def __onTextShownChanged(self): + self.editConfigKey("TEXT_SHOWN", not self.config["TEXT_SHOWN"]) + self.setMenu() + def __onVolumeChanged(self, newVolume): self.__updateVolumeDesc(int(newVolume)) self.device.setVolume(newVolume) @@ -170,7 +197,7 @@ def getConfig(self): print("Creating config file...") self.saveConfig(DEFAULT_CONFIG) return DEFAULT_CONFIG - + with f: config = json.load(f) - return config \ No newline at end of file + return config diff --git a/src/icons/cast_connected.png b/src/icons/cast_connected.png index 21cbabc..45e8d84 100755 Binary files a/src/icons/cast_connected.png and b/src/icons/cast_connected.png differ diff --git a/src/icons/cast_disconnected.png b/src/icons/cast_disconnected.png index 78ea518..afe3698 100755 Binary files a/src/icons/cast_disconnected.png and b/src/icons/cast_disconnected.png differ