diff --git a/configs/waybar_l/M1Pro/shvedes/Scale1.6x/README.md b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/README.md new file mode 100644 index 0000000..5365be3 --- /dev/null +++ b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/README.md @@ -0,0 +1,3 @@ +## [shvedes's github](https://github.com/shvedes/dotfiles) + +### 5/12/24 - Unable to make the `spotify.py` script to work, everything else works, except for `cpu-temp` as well diff --git a/configs/waybar_l/M1Pro/shvedes/Scale1.6x/config b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/config new file mode 100644 index 0000000..5d57f7f --- /dev/null +++ b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/config @@ -0,0 +1,112 @@ + +{ + "layer": "bottom", + "position": "top", + "height": 28, + "reload_style_on_change": true, + + "modules-left": [ "custom/spotify", "custom/cpu", "memory", "disk", "battery" ], + "modules-center": [ "hyprland/workspaces" ], + "modules-right": [ "network", "clock#time", "tray", "idle_inhibitor" ], + + "custom/spotify": { + "exec": "$HOME/.config/waybar/scripts/spotify.py --player spotify", + "format": "{}", + "return-type": "json", + "on-click": "playerctl -p spotify play-pause", + "on-scroll-up": "playerctl -p spotify next", + "on-scroll-down": "playerctl -p spotify previous", + "on-click-right-release": "hyprctl dispatch workspace 6", + "tooltip": false + }, + + "memory": { + "interval": 1, + "format": "{used:0.1f}GiB" + }, + + "disk": { + "interval": 60, + "format": "{used}", + "tooltip": false + }, + + "hyprland/workspaces": { + "format": "{icon}", + "on-click-release": "activate", + "sort-by-numbers": false, + "on-scroll-up": "hyprctl dispatch workspace e+1", + "on-scroll-down": "hyprctl dispatch workspace e-1", + "format-icons": { + "1": "I", + "2": "II", + "3": "III", + "4": "IV", + "5": "V", + "6": "VI", + "7": "VII", + "8": "VIII", + "9": "IX", + "10": "X" + } + }, + + "network": { + "interval": 1, + "format-wifi": "{icon} {essid}{bandwidthUpBytes}{bandwidthDownBytes} ", + "format-disconnected": "", + "format-ethernet": "Connected", + "on-click-right-release": "alacritty --class nmtui -T 'Network Settings' -e nmtui", + "on-click-release": "$HOME/.config/waybar/scripts/network.sh", + "format-icons": [ + "󰤯 ", + "󰤟 ", + "󰤢 ", + "󰤥 ", + "󰤨 " + ] + }, + + "clock#time": { + "interval": 1, + "format": "{:%I:%M %p} ", + "tooltip": false, + "on-click-release": "bash $HOME/.config/waybar/scripts/date.sh" + + }, + + "custom/cpu": { + "exec": "$HOME/.config/waybar/scripts/monitoring/cpu-temp.c", + "format": "{}", + "tooltip": false + }, + + "idle_inhibitor": { + "format": "{icon}", + "format-icons": { + "activated": "󰆪 ", + "deactivated":"󰗥 " + } + }, + "battery": { + "states": { + "good": 95, + "warning": 30, + "critical": 20 + }, + "format": "{icon} {capacity}%", + "format-charging": "\udb80\udc84 {capacity}%", + "format-plugged": "\udb81\udea5 {capacity}%", + "format-alt": "{time} {icon}", + "format-icons": ["\udb80\udc7a", "\udb80\udc7b", "\udb80\udc7c", "\udb80\udc7d", "\udb80\udc7e", "\udb80\udc7f", "\udb80\udc80", "\udb80\udc81", "\udb80\udc82", "\udb80\udc79"] + }, + + "tray": { + "icon-size": 14, + "spacing": 10, + "show-passive-items": true + } + +} + +// vim:ft=jsonc diff --git a/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/date.sh b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/date.sh new file mode 100755 index 0000000..ab9cf3d --- /dev/null +++ b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/date.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +source $HOME/.local/bin/variables.sh + +DATE=$(date +"%A, %dth %B") + +notify-send -r 2 -i "${ICON}/calendar.svg" "Date" "$DATE" diff --git a/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/monitoring/cpu-temp.c b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/monitoring/cpu-temp.c new file mode 100755 index 0000000..4f5d8b6 --- /dev/null +++ b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/monitoring/cpu-temp.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include + +int millidegree_to_celsius(int millidegree) { + return millidegree / 1000; +} + +int main() { + while (1) { + FILE *file = fopen("SYSFS_PATH", "r"); + if (file == NULL) { + perror("No such file or directory"); + return 1; + } + + int temperature; + fscanf(file, "%d", &temperature); + fclose(file); + + int celsius = millidegree_to_celsius(temperature); + + printf("%d°C\n", celsius); + fflush(stdout); + usleep(500000); + } + + return 0; +} + diff --git a/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/monitoring/gpu-temp.c b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/monitoring/gpu-temp.c new file mode 100644 index 0000000..91ad30a --- /dev/null +++ b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/monitoring/gpu-temp.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include + +int millidegree_to_celsius(int millidegree) { + return millidegree / 1000; +} + +int main() { + while (1) { + FILE *file = fopen("SYSFS_PATH", "r"); + if (file == NULL) { + perror("No such file or directory"); + return 1; + } + + int temperature; + fscanf(file, "%d", &temperature); + fclose(file); + + int celsius = millidegree_to_celsius(temperature); + + printf("%d°C\n", celsius); + fflush(stdout); + usleep(500000); + } + + return 0; +} + + diff --git a/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/network.sh b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/network.sh new file mode 100755 index 0000000..b3ffc90 --- /dev/null +++ b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/network.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +source $HOME/.local/bin/variables.sh + +COMMAND="$(nmcli connection show | awk 'NR=1 {print $1}' | sed -n '2p')" + +if [[ "$COMMAND" == "Wired" ]]; then + notify-send -r 2 -i "${ICON}/ethernet.svg" "Connection" "Ethernet connected" +else + notify-send -r 2 -i "${ICON}/wifi.svg" "Connection" "Connected to $COMMAND" +fi diff --git a/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/spotify.py b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/spotify.py new file mode 100755 index 0000000..ad71431 --- /dev/null +++ b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/scripts/spotify.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python3 +import gi +gi.require_version("Playerctl", "2.0") +from gi.repository import Playerctl, GLib +from gi.repository.Playerctl import Player +import argparse +import logging +import sys +import signal +import gi +import json +import os +from typing import List + +logger = logging.getLogger(__name__) + +def signal_handler(sig, frame): + logger.info("Received signal to stop, exiting") + sys.stdout.write("\n") + sys.stdout.flush() + # loop.quit() + sys.exit(0) + + +class PlayerManager: + def __init__(self, selected_player=None): + self.manager = Playerctl.PlayerManager() + self.loop = GLib.MainLoop() + self.manager.connect( + "name-appeared", lambda *args: self.on_player_appeared(*args)) + self.manager.connect( + "player-vanished", lambda *args: self.on_player_vanished(*args)) + + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGPIPE, signal.SIG_DFL) + self.selected_player = selected_player + + self.init_players() + + def init_players(self): + for player in self.manager.props.player_names: + if self.selected_player is not None and self.selected_player != player.name: + logger.debug(f"{player.name} is not the filtered player, skipping it") + continue + self.init_player(player) + + def run(self): + logger.info("Starting main loop") + self.loop.run() + + def init_player(self, player): + logger.info(f"Initialize new player: {player.name}") + player = Playerctl.Player.new_from_name(player) + player.connect("playback-status", + self.on_playback_status_changed, None) + player.connect("metadata", self.on_metadata_changed, None) + self.manager.manage_player(player) + self.on_metadata_changed(player, player.props.metadata) + + def get_players(self) -> List[Player]: + return self.manager.props.players + + def write_output(self, text, player): + logger.debug(f"Writing output: {text}") + + output = {"text": text, + "class": "custom-" + player.props.player_name, + "alt": player.props.player_name} + + sys.stdout.write(json.dumps(output) + "\n") + sys.stdout.flush() + + def clear_output(self): + sys.stdout.write("\n") + sys.stdout.flush() + + def on_playback_status_changed(self, player, status, _=None): + logger.debug(f"Playback status changed for player {player.props.player_name}: {status}") + self.on_metadata_changed(player, player.props.metadata) + + def get_first_playing_player(self): + players = self.get_players() + logger.debug(f"Getting first playing player from {len(players)} players") + if len(players) > 0: + # if any are playing, show the first one that is playing + # reverse order, so that the most recently added ones are preferred + for player in players[::-1]: + if player.props.status == "Playing": + return player + # if none are playing, show the first one + return players[0] + else: + logger.debug("No players found") + return None + + def show_most_important_player(self): + logger.debug("Showing most important player") + # show the currently playing player + # or else show the first paused player + # or else show nothing + current_player = self.get_first_playing_player() + if current_player is not None: + self.on_metadata_changed(current_player, current_player.props.metadata) + else: + self.clear_output() + + def on_metadata_changed(self, player, metadata, _=None): + logger.debug(f"Metadata changed for player {player.props.player_name}") + player_name = player.props.player_name + artist = player.get_artist() + title = player.get_title() + + track_info = "" + if player_name == "spotify" and "mpris:trackid" in metadata.keys() and ":ad:" in player.props.metadata["mpris:trackid"]: + track_info = "Advertisement" + elif artist is not None and title is not None: + track_info = f"{artist} - {title}" + else: + track_info = title + + if track_info: + if player.props.status == "Playing": + track_info = track_info + else: + track_info = track_info + # only print output if no other player is playing + current_playing = self.get_first_playing_player() + if current_playing is None or current_playing.props.player_name == player.props.player_name: + self.write_output(track_info, player) + else: + logger.debug(f"Other player {current_playing.props.player_name} is playing, skipping") + + def on_player_appeared(self, _, player): + logger.info(f"Player has appeared: {player.name}") + if player is not None and (self.selected_player is None or player.name == self.selected_player): + self.init_player(player) + else: + logger.debug( + "New player appeared, but it's not the selected player, skipping") + + def on_player_vanished(self, _, player): + logger.info(f"Player {player.props.player_name} has vanished") + self.show_most_important_player() + +def parse_arguments(): + parser = argparse.ArgumentParser() + + # Increase verbosity with every occurrence of -v + parser.add_argument("-v", "--verbose", action="count", default=0) + + # Define for which player we"re listening + parser.add_argument("--player") + + parser.add_argument("--enable-logging", action="store_true") + + return parser.parse_args() + + +def main(): + arguments = parse_arguments() + + # Initialize logging + if arguments.enable_logging: + logfile = os.path.join(os.path.dirname( + os.path.realpath(__file__)), "media-player.log") + logging.basicConfig(filename=logfile, level=logging.DEBUG, + format="%(asctime)s %(name)s %(levelname)s:%(lineno)d %(message)s") + + # Logging is set by default to WARN and higher. + # With every occurrence of -v it's lowered by one + logger.setLevel(max((3 - arguments.verbose) * 10, 0)) + + logger.info("Creating player manager") + if arguments.player: + logger.info(f"Filtering for player: {arguments.player}") + player = PlayerManager(arguments.player) + player.run() + + +if __name__ == "__main__": + main() diff --git a/configs/waybar_l/M1Pro/shvedes/Scale1.6x/style.css b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/style.css new file mode 100644 index 0000000..a59609e --- /dev/null +++ b/configs/waybar_l/M1Pro/shvedes/Scale1.6x/style.css @@ -0,0 +1,64 @@ +* { + border: none; + font-family: JetBrainsMono Nerd Font; + font-weight: bold; + font-size: 11px; + min-height: 0; +} + +tooltip { + background: #282828; + border: 0px solid; + border-radius: 0px; +} + +window#waybar { + background: #282828; + color: #ebdbb2; +} + +#workspaces button { + padding: 0 0.6em; + color: #a89984; + background: #504945; + border-radius: 0px; + margin-right: 4px; + margin-left: 4px; + margin-top: 2px; + margin-bottom: 2px; +} + +#workspaces button.active { + color: #ebdbb2; + background: #665c54; +} + +#workspaces button.urgent { + color: #1d2021; + background: #fb4934; +} + +#workspaces button:hover { + background: #665c54; +} + +#disk, +#clock, +#memory, +#network, +#workspaces, +#battery, +#idle_inhibitor, +#custom-cpu, +#custom-spotify, +#tray { + color: #d5c4a1; + background: #433e3c; + padding: 0 0.6em; + margin-right: 4px; + margin-left: 2px; + margin-top: 4px; + margin-bottom: 4px; + border-radius: 0px; +} +