tabs->spaces

This commit is contained in:
John Mertz 2023-01-06 14:41:31 -05:00
parent ecd9920a37
commit 6d33d9446f
41 changed files with 1221 additions and 1203 deletions

View File

@ -9,10 +9,10 @@ use XML::Hash::XS; # CPAN or libxml-hash-xs-perl on Debian
# Feeds that should be used if no arguments are provided
my @default_feeds = (
# CBC FrontBurner
"https://www.cbc.ca/podcasting/includes/frontburner.xml",
# Majority Report AM Quickie
"https://feeds.fans.fm/5883fe04-e11e-4578-a018-3b93ddfb5723.xml"
# CBC FrontBurner
"https://www.cbc.ca/podcasting/includes/frontburner.xml",
# Majority Report AM Quickie
"https://feeds.fans.fm/5883fe04-e11e-4578-a018-3b93ddfb5723.xml"
);
# Player command (must accept stream as STDIN)
@ -28,14 +28,14 @@ my $player = "> /tmp/fifo.mp3 & omxplayer /tmp/fifo.mp3";
# Multiple feeds can be given as CLI arguments instead
my @feeds;
if (scalar @ARGV) {
foreach (@ARGV) {
push @feeds, $_;
}
foreach (@ARGV) {
push @feeds, $_;
}
}
# Only use default feeds if no CLI feeds were given
unless (scalar @feeds) {
@feeds = @default_feeds;
@feeds = @default_feeds;
}
# Local function to get date pattern provided as 'pubDate'
@ -48,36 +48,36 @@ my $xml = XML::Hash::XS->new(utf8 => 0, encoding => 'utf-8');
my @playlist;
# Go through each feed
foreach my $url (@feeds) {
# Ensure that it's actual an XML link
next unless $url =~ m#^https?://.*\.xml$#;
# Ensure it is fetched okay
my $raw = $ua->get("$url")->content() || next;
# Ensure it is parsed okay
my $xml_hash = $xml->xml2hash($raw) || next;
# Ensure that it's actual an XML link
next unless $url =~ m#^https?://.*\.xml$#;
# Ensure it is fetched okay
my $raw = $ua->get("$url")->content() || next;
# Ensure it is parsed okay
my $xml_hash = $xml->xml2hash($raw) || next;
# Collect all episodes published today
foreach my $item (@{$xml_hash->{'channel'}->{'item'}}) {
if ($item->{'pubDate'} =~ m/$today/) {
# Add any found to playlist
push @playlist, $item->{'enclosure'}->{'url'};
}
# Collect all episodes published today
foreach my $item (@{$xml_hash->{'channel'}->{'item'}}) {
if ($item->{'pubDate'} =~ m/$today/) {
# Add any found to playlist
push @playlist, $item->{'enclosure'}->{'url'};
}
}
}
# Fetch each item and pass it to player via STDIN
foreach (@playlist) {
# Uncomment the following to print the media URL
print $_ . "\n";
system("curl -NL $_ $player");
# Uncomment the following to print the media URL
print $_ . "\n";
system("curl -NL $_ $player");
}
unlink("/tmp/fifo.mp3");
sub get_date
{
my ($second, $minute, $hour, $day, $month, $year) = localtime(time);
my @months = (
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
);
return $day . ' ' . $months[$month] . ' ' . ($year+1900);
my ($second, $minute, $hour, $day, $month, $year) = localtime(time);
my @months = (
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
);
return $day . ' ' . $months[$month] . ' ' . ($year+1900);
}

View File

@ -13,41 +13,41 @@ my $lat_lon = fetch_lat_lon($location);
my $pid = fork;
unless ($pid) {
open(my $fh, ">", $ENV{HOME}."/.spool/gammastep.pid");
print $fh $$;
close($fh);
open($fh, ">", $ENV{HOME}."/.spool/gammastep.status");
print $fh 1;
close($fh);
open(my $fh, ">", $ENV{HOME}."/.spool/gammastep.pid");
print $fh $$;
close($fh);
open($fh, ">", $ENV{HOME}."/.spool/gammastep.status");
print $fh 1;
close($fh);
open STDIN, '/dev/null';
open STDOUT, '>>/dev/null';
open STDERR, '>>/dev/null';
open STDIN, '/dev/null';
open STDOUT, '>>/dev/null';
open STDERR, '>>/dev/null';
if (! -e "/run/.containerenv" && ! -e "/.dockerenv" ) {
exec "exec /bin/distrobox-enter -n debian12 -- gammastep -l $lat_lon -b 0.7:0.3";
} else {
exec "exec gammastep -l $lat_lon -b 0.7:0.3";
}
if (! -e "/run/.containerenv" && ! -e "/.dockerenv" ) {
exec "exec /bin/distrobox-enter -n debian12 -- gammastep -l $lat_lon -b 0.7:0.3";
} else {
exec "exec gammastep -l $lat_lon -b 0.7:0.3";
}
}
sub fetch_lat_lon
{
my ($location) = shift;
my ($location) = shift;
my $ua = LWP::UserAgent->new();
my $json = JSON::XS->new();
my $ua = LWP::UserAgent->new();
my $json = JSON::XS->new();
my $raw = $ua->get($location)->content();
my $raw = $ua->get($location)->content();
if (defined $raw) {
my $decoded = $json->decode($raw);
if (defined $decoded->{lat} && defined $decoded->{lon}) {
return "$decoded->{lat}:$decoded->{lon}";
}
if (defined $raw) {
my $decoded = $json->decode($raw);
if (defined $decoded->{lat} && defined $decoded->{lon}) {
return "$decoded->{lat}:$decoded->{lon}";
}
sleep 5;
return fetch_lat_lon($ua, $json, $location);
}
sleep 5;
return fetch_lat_lon($ua, $json, $location);
}
exit;

View File

@ -6,8 +6,8 @@ echo "Available Distrobox sessions, with matching gnome-terminal profiles, are:"
echo ""
distrobox list | grep -v 'IMAGE' | cut -d '|' -f 2
for i in 10 9 8 7 6 5 4 3 2 1; do
printf "\rExitting in $i ..."
sleep 1
printf "\rExitting in $i ..."
sleep 1
done
echo ""
exit

View File

@ -4,25 +4,25 @@ LAYOUT=`cat ~/.config/screenlayout/i3.current`
MIDDLE="eDP-1"
if [[ $LAYOUT == 'home' ]]; then
RIGHT="DP-2-2"
LEFT="DP-2-1"
RIGHT="DP-2-2"
LEFT="DP-2-1"
elif [[ $LAYOUT == 'work' ]]; then
RIGHT="DP-2-2"
LEFT="DP-2-1"
RIGHT="DP-2-2"
LEFT="DP-2-1"
elif [[ $LAYOUT == '3' ]]; then
MIDDLE="DP-2-2"
LEFT="DP-2-1"
RIGHT="eDP-1"
MIDDLE="DP-2-2"
LEFT="DP-2-1"
RIGHT="eDP-1"
else
echo "No external displays connected"
echo "No external displays connected"
fi
if [[ $1 == 'right' ]]; then
i3 move workspace to output $RIGHT
i3 move workspace to output $RIGHT
elif [[ $1 == 'middle' ]]; then
i3 move workspace to output $MIDDLE
i3 move workspace to output $MIDDLE
elif [[ $1 == 'left' ]]; then
i3 move workspace to output $LEFT
i3 move workspace to output $LEFT
else
echo "Invalid direction. Requires either 'up', 'left', or 'middle'"
echo "Invalid direction. Requires either 'up', 'left', or 'middle'"
fi

View File

@ -4,7 +4,7 @@ ROFI=$(pgrep -xc rofi | cut -b 1)
echo $ROFI
if [[ "$ROFI" -eq "0" ]]; then
rofi -config /home/jpm/.config/rofi/config.rasi -theme /home/jpm/.config/rofi/sidebar.rasi -show drun -lines 20
rofi -config /home/jpm/.config/rofi/config.rasi -theme /home/jpm/.config/rofi/sidebar.rasi -show drun -lines 20
else
killall rofi 2&>1 /dev/null
killall rofi 2&>1 /dev/null
fi

View File

@ -5,25 +5,25 @@
res=$(echo "Connection|John.Me.tz|MailCleaner|Disconnect|Restart" | rofi -sep "|" -dmenu -i -p 'P ' "" -columns 9 -width 45 -l 1 -config /home/jpm/.config/rofi/config.rasi -theme /home/jpm/.config/rofi/sidebar -hide-scrollbar -eh 1 -location 0 -auto-select -no-fullscreen)
if [ $res = "Connection" ]; then
/usr/bin/uxterm -e 'sudo /usr/bin/nmtui'
/usr/bin/uxterm -e 'sudo /usr/bin/nmtui'
elif [ $res = "John.Me.tz" ]; then
sudo /usr/bin/systemctl stop openvpn-client@mailcleaner
sudo /usr/bin/systemctl restart wg-quick@wg0
sudo /usr/bin/systemctl stop openvpn-client@mailcleaner
sudo /usr/bin/systemctl restart wg-quick@wg0
elif [ $res = "MailCleaner" ]; then
sudo /usr/bin/systemctl stop wg-quick@wg0
sudo /usr/bin/systemctl restart openvpn-client@mailcleaner
sudo /usr/bin/systemctl stop wg-quick@wg0
sudo /usr/bin/systemctl restart openvpn-client@mailcleaner
elif [ $res = "Disconnect" ]; then
sudo /usr/bin/systemctl stop openvpn-client@mailcleaner
sudo /usr/bin/systemctl stop wg-quick@wg0
sudo /usr/bin/systemctl stop openvpn-client@mailcleaner
sudo /usr/bin/systemctl stop wg-quick@wg0
elif [ $res = "Restart" ]; then
if [ "`ip addr show wg0 2> /dev/null`" != "" ]; then
sudo /usr/bin/systemctl restart wg-quick@wg0
fi
if [ "`ip addr show tun0 2> /dev/null`" != "" ]; then
sudo /usr/bin/systemctl restart openvpn-client@mailcleaner
fi
if [ "`ip addr show wg0 2> /dev/null`" != "" ]; then
sudo /usr/bin/systemctl restart wg-quick@wg0
fi
if [ "`ip addr show tun0 2> /dev/null`" != "" ]; then
sudo /usr/bin/systemctl restart openvpn-client@mailcleaner
fi
else
exit
exit
fi
# Waybar sometimes doesn't update with the VPN IP, for whatever reason. Restart it.

View File

@ -1,7 +1,7 @@
#!/bin/bash
INPUT="$(rofi -dmenu -i -p 'Kodi:' "" -columns 1 -rows 7 -width 32 -l 1 \
-theme /home/jpm/.config/rofi/sidebar.rasi -hide-scrollbar -eh 1 -location \
0 -padding 12 -opacity 100)"
-theme /home/jpm/.config/rofi/sidebar.rasi -hide-scrollbar -eh 1 -location \
0 -padding 12 -opacity 100)"
/home/jpm/scripts/send-to-kodi.sh $INPUT 2>&1 /dev/null

View File

@ -10,32 +10,32 @@ rofi -sep "|" -dmenu -i -p 'P ' "" -columns 1 -rows 1 -width 45 -l 1 -config \
echo $res > /home/jpm/.last_ssh_shortcut
if [ $res = "john.me.tz" ]; then
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs w'
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs w'
elif [ $res = "root@john.me.tz" ]; then
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs r'
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs r'
elif [ $res = "shb.ng" ]; then
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs s'
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs s'
elif [ $res = "kipary.fastnet.ch" ]; then
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs d'
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs d'
elif [ $res = "camera.lan.john.me.tz" ]; then
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs c'
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs c'
elif [ $res = "hud.lan.john.me.tz" ]; then
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs h'
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs h'
elif [ $res = "media.lan.john.me.tz" ]; then
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs m'
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs m'
elif [ $res = "programmer.lan.john.me.tz" ]; then
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs p'
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs p'
elif [ $res = "t470s.lan.john.me.tz" ]; then
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs l'
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs l'
elif [ $res = "therm.lan.john.me.tz" ]; then
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs t'
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs t'
elif [ $res = "vm.lan.john.me.tz" ]; then
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs v'
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs v'
elif [ $res = "light.lan.john.me.tz" ]; then
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs light'
/usr/bin/urxvt -e /bin/bash -c '/home/jpm/scripts/sshs light'
elif [ $res = "mac.lan.john.me.tz" ]; then
/usr/bin/gvncviewer 192.168.2.10 >> /home/jpm/macos
/usr/bin/gvncviewer 192.168.2.10 >> /home/jpm/macos
elif [ $res = "AndroidUSB" ]; then
/usr/bin/scrcpy
/usr/bin/scrcpy
fi
exit 0

View File

@ -4,13 +4,13 @@
res=$(echo "Rotate 0 (Normal)|Rotate 90 (Keyboard right)|Rotate 180 (Upside-down)|Rotate 270 (Keyborad left)" | rofi -sep "|" -dmenu -i -p 'P ' "" -columns 9 -width 45 -l 1 -config /home/jpm/.config/rofi/config.rasi -theme /home/jpm/.config/rofi/sidebar.rasi -hide-scrollbar -eh 1 -location 0 -auto-select -no-fullscreen)
if [[ $res == "Rotate 0 (Normal)" ]]; then
swaymsg output eDP-1 transform 0
swaymsg output eDP-1 transform 0
elif [[ $res == "Rotate 90 (Keyboard right)" ]]; then
swaymsg output eDP-1 transform 90
swaymsg output eDP-1 transform 90
elif [[ $res == "Rotate 180 (Upside-down)" ]]; then
swaymsg output eDP-1 transform 180
swaymsg output eDP-1 transform 180
elif [[ $res == "Rotate 270 (Keyboard left)" ]]; then
swaymsg output eDP-1 transform 270
swaymsg output eDP-1 transform 270
else
exit
exit
fi

View File

@ -3,10 +3,10 @@
RUNNING=$(pgrep yubioath-deskto)
if [ "$RUNNING" ]; then
kill $RUNNING
sudo systemctl stop pcscd.socket
sudo systemctl restart pcscd.service
sudo systemctl start pcscd.socket
kill $RUNNING
sudo systemctl stop pcscd.socket
sudo systemctl restart pcscd.service
sudo systemctl start pcscd.socket
fi
QT_QPA_PLATFORMTHEME=qt5ct QT_QPA_PLATFORM=wayland QT_PLUGIN_PATH=/usr/lib/qt/plugins /usr/bin/yubioath-desktop &

View File

@ -9,10 +9,10 @@ sed -e 's/^\([0-9]*\)\t*\(.*\)/\2 \1/' |
rofi -dmenu -config ~/.config/rofi/sidebar.rasi | {
read -r
read -r
id=`echo $REPLY | rev | cut -d' ' -f1 | rev`
id=`echo $REPLY | rev | cut -d' ' -f1 | rev`
swaymsg "[con_id=$id]" focus
swaymsg "[con_id=$id]" focus
}

View File

@ -12,74 +12,74 @@ SUSPEND_TIMEOUT=3600 # one hour
function usage()
{
echo "usage: $0 <option>
start - Initialize 'swayidle' script. This should be declared in Sway config.
stop - Kill 'swayidle' script. Consider idle-inhibitor instead.
fade - First idle action. Fades all windows to show background.
unfade - Restore opacity for faded windows.
dim - Reduce display brightness to minimum.
undim - Restore brightness to level prior to 'dim'.
lock - Mark as inactive and start 'swaylock'.
unlock - (Run upon unlock) Mark as active again.
sleep - Disable displays, but continue background processes.
wake - Re-enable displays.
hibernate - Hibernate.
help - This message."
exit
echo "usage: $0 <option>
start - Initialize 'swayidle' script. This should be declared in Sway config.
stop - Kill 'swayidle' script. Consider idle-inhibitor instead.
fade - First idle action. Fades all windows to show background.
unfade - Restore opacity for faded windows.
dim - Reduce display brightness to minimum.
undim - Restore brightness to level prior to 'dim'.
lock - Mark as inactive and start 'swaylock'.
unlock - (Run upon unlock) Mark as active again.
sleep - Disable displays, but continue background processes.
wake - Re-enable displays.
hibernate - Hibernate.
help - This message."
exit
}
if [ -z $1 ]; then
echo "Missing argument"
usage
echo "Missing argument"
usage
elif [ $1 == "-h" ] || [ $1 == "--help" ] || [ $1 == "help" ]; then
usage
usage
elif [ $1 == "start" ]; then
swayidle -w \
timeout $FADE_TIMEOUT "$0 fade" \
resume "$0 unfade" \
timeout $DIM_TIMEOUT "$0 dim" \
resume "$0 undim" \
timeout $LOCK_TIMEOUT "$0 lock" \
resume "$0 unlock" \
timeout $DPMS_TIMEOUT "$0 sleep" \
resume "$0 wake" \
timeout $SUSPEND_TIMEOUT "$0 hibernate"
swayidle -w \
timeout $FADE_TIMEOUT "$0 fade" \
resume "$0 unfade" \
timeout $DIM_TIMEOUT "$0 dim" \
resume "$0 undim" \
timeout $LOCK_TIMEOUT "$0 lock" \
resume "$0 unlock" \
timeout $DPMS_TIMEOUT "$0 sleep" \
resume "$0 wake" \
timeout $SUSPEND_TIMEOUT "$0 hibernate"
elif [ $1 == "stop" ]; then
pkill swayidle
pkill swayidle
elif [ $1 == "fade" ]; then
if [ ! -e $HOME/.spool/sway-hidden ]; then
kill -USR2 `cat $HOME/.spool/sway-transparency`
fi
if [ ! -e $HOME/.spool/sway-hidden ]; then
kill -USR2 `cat $HOME/.spool/sway-transparency`
fi
elif [ $1 == "unfade" ]; then
if [ -e $HOME/.spool/sway-hidden ]; then
kill -USR2 `cat $HOME/.spool/sway-transparency`
fi
if [ -e $HOME/.spool/sway-hidden ]; then
kill -USR2 `cat $HOME/.spool/sway-transparency`
fi
elif [ $1 == "dim" ]; then
echo $($HOME/scripts/thinkpad/blc.pl %) > $BLFILE
$HOME/scripts/thinkpad/blc.pl = 1 &>-
echo $($HOME/scripts/thinkpad/blc.pl %) > $BLFILE
$HOME/scripts/thinkpad/blc.pl = 1 &>-
elif [ $1 == "undim" ]; then
$HOME/scripts/thinkpad/blc.pl = `cat $BLFILE` &>-
$HOME/scripts/thinkpad/blc.pl = `cat $BLFILE` &>-
elif [ $1 == "lock" ]; then
# Change nick to AFK
#ssh jpm@john.me.tz -i /home/jpm/.ssh/no_pass -t \
#'screen -S irssi -X stuff "/nick jpmAFK^M"'
:
# Change nick to AFK
#ssh jpm@john.me.tz -i /home/jpm/.ssh/no_pass -t \
#'screen -S irssi -X stuff "/nick jpmAFK^M"'
:
elif [ $1 == "unlock" ]; then
# Change nick to AFK
#ssh jpm@john.me.tz -i /home/jpm/.ssh/no_pass -t \
#'screen -S irssi -X stuff "/nick jpm^M"'
:
# Change nick to AFK
#ssh jpm@john.me.tz -i /home/jpm/.ssh/no_pass -t \
#'screen -S irssi -X stuff "/nick jpm^M"'
:
elif [ $1 == "sleep" ]; then
for i in `cat $OPFILE`; do swaymsg "output $i dpms off"; done
for i in `cat $OPFILE`; do swaymsg "output $i dpms off"; done
elif [ $1 == "wake" ]; then
/home/jpm/scripts/sway/displays.pl
/home/jpm/scripts/sway/displays.pl
elif [ $1 == "hibernate" ]; then
if [ -e $NOHIBERNATE ]; then
::
else
sudo systemctl start hibernate.target
fi
if [ -e $NOHIBERNATE ]; then
::
else
sudo systemctl start hibernate.target
fi
else
echo "Invalid argument: $1"
usage
echo "Invalid argument: $1"
usage
fi

View File

@ -11,15 +11,15 @@ my $now = sprintf("%.0f",($start->[0]*1000) + ($start->[1]/1000));
my $end = $now + 30000;
while ($now < $end) {
my $remaining = ($end - $now);
my $notification = Gtk2::Notify::new('Idle', sprintf("%.0f",($remaining/1000)), '', "status_lock");
$notification->set_hint_string('x-canonical-private-synchronous','idle');
$notification->set_urgency('NOTIFY_URGENCY_LOW');
$notification->set_hint_int32('value',($remaining/300));
$notification->set_timeout(150);
$notification->show();
usleep(100);
$now = utime( undef, undef );
$start = [gettimeofday];
$now = sprintf("%.0f",($start->[0]*1000) + ($start->[1]/1000));
my $remaining = ($end - $now);
my $notification = Gtk2::Notify::new('Idle', sprintf("%.0f",($remaining/1000)), '', "status_lock");
$notification->set_hint_string('x-canonical-private-synchronous','idle');
$notification->set_urgency('NOTIFY_URGENCY_LOW');
$notification->set_hint_int32('value',($remaining/300));
$notification->set_timeout(150);
$notification->show();
usleep(100);
$now = utime( undef, undef );
$start = [gettimeofday];
$now = sprintf("%.0f",($start->[0]*1000) + ($start->[1]/1000));
}

View File

@ -1,5 +1,5 @@
#!/bin/bash
for i in `seq 0 30`; do
notify-send -a 'swayidle' -t 999 "Sleeping" $(expr 30 - $i); sleep 1
notify-send -a 'swayidle' -t 999 "Sleeping" $(expr 30 - $i); sleep 1
done

View File

@ -19,63 +19,63 @@ my $root = $json->decode($raw);
my $display = $root->{focus}->[0];
my ($workspace, $term_id, $term_ws);
foreach my $d (@{$root->{nodes}}) {
# If both the current workspace and terminal have been found
# nothing else to look for
if (defined($workspace) && defined($term_id)) {
# If both the current workspace and terminal have been found
# nothing else to look for
if (defined($workspace) && defined($term_id)) {
last;
# If the display from this iteration of the loop is in focus
# look for the active workspace
} elsif ($d->{id} eq $display) {
foreach my $w (@{$d->{nodes}}) {
# Again, if both found, skip
if (defined($workspace) && defined($term_id)) {
last;
# If the display from this iteration of the loop is in focus
# look for the active workspace
} elsif ($d->{id} eq $display) {
foreach my $w (@{$d->{nodes}}) {
# Again, if both found, skip
if (defined($workspace) && defined($term_id)) {
last;
# Otherwise if the current workspace is active, mark it
} elsif ($w->{id} eq $d->{focus}->[0]) {
$workspace = $w->{name};
}
# In any case, look for the terminal app
foreach my $n (@{$w->{floating_nodes}}) {
if ($n->{name} eq $term) {
$term_id = $n->{id};
$term_ws = $w->{name};
last;
}
}
}
# All other displays only need to be quickly searched for the term_id
} else {
foreach my $w (@{$d->{nodes}}) {
if (defined($term_id)) {
last;
}
foreach my $n (@{$w->{floating_nodes}}) {
if ($n->{name} eq $term) {
$term_id = $n->{id};
$term_ws = $w->{name};
last;
}
}
# Otherwise if the current workspace is active, mark it
} elsif ($w->{id} eq $d->{focus}->[0]) {
$workspace = $w->{name};
}
# In any case, look for the terminal app
foreach my $n (@{$w->{floating_nodes}}) {
if ($n->{name} eq $term) {
$term_id = $n->{id};
$term_ws = $w->{name};
last;
}
}
}
# All other displays only need to be quickly searched for the term_id
} else {
foreach my $w (@{$d->{nodes}}) {
if (defined($term_id)) {
last;
}
foreach my $n (@{$w->{floating_nodes}}) {
if ($n->{name} eq $term) {
$term_id = $n->{id};
$term_ws = $w->{name};
last;
}
}
}
}
}
print "Active workspace = $workspace\n"
. "Terminal ID = $term_id\n"
. "Terminal WS = $term_ws\n";
. "Terminal ID = $term_id\n"
. "Terminal WS = $term_ws\n";
# If there is no terminal found, spawn one
if (!defined($term_id)) {
print "No term running, starting one\n";
exec $term
print "No term running, starting one\n";
exec $term
# If the current workspace is known and terminal isn't on it, bring and focus
} elsif ($workspace != $term_ws) {
print "Term not on current workspace, bringing it\n";
`swaymsg "[con_id=$term_id]" move workspace $workspace`;
`swaymsg "[con_id=$term_id]" focus`;
`swaymsg "[con_id=$term_id]" sticky enable`;
print "Term not on current workspace, bringing it\n";
`swaymsg "[con_id=$term_id]" move workspace $workspace`;
`swaymsg "[con_id=$term_id]" focus`;
`swaymsg "[con_id=$term_id]" sticky enable`;
# Otherwise hide it from whereever it is
} else {
print "Term is on current workspace or lost, moving to $hidden\n";
`swaymsg "[con_id=$term_id]" sticky disable`;
`swaymsg "[con_id=$term_id]" move workspace $hidden`;
print "Term is on current workspace or lost, moving to $hidden\n";
`swaymsg "[con_id=$term_id]" sticky disable`;
`swaymsg "[con_id=$term_id]" move workspace $hidden`;
}

View File

@ -4,45 +4,45 @@
# Determine if Sway or i3
if [ -z ${SWAYSOCK+x} ]; then
WM="i3"
WM="i3"
else
WM="sway"
WM="sway"
fi
if [[ $WM == 'i3' ]]; then
res=$(printf "⚿ Lock|↩ Logout|↻ Reload i3|↹ Restart i3|↯ Hibernate|🡙 Reboot|⏻ Shutdown" | rofi -sep "|" -dmenu -i -p 'Power: ' "" -columns 1 -rows 7 -width 32 -l 1 -theme /home/jpm/.config/rofi/sidebar.rasi -hide-scrollbar -eh 1 -location 0 -padding 12 -opacity 100 -auto-select -no-fullscreen)
res=$(printf "⚿ Lock|↩ Logout|↻ Reload i3|↹ Restart i3|↯ Hibernate|🡙 Reboot|⏻ Shutdown" | rofi -sep "|" -dmenu -i -p 'Power: ' "" -columns 1 -rows 7 -width 32 -l 1 -theme /home/jpm/.config/rofi/sidebar.rasi -hide-scrollbar -eh 1 -location 0 -padding 12 -opacity 100 -auto-select -no-fullscreen)
else
res=$(printf "⚿ Lock\n🖵 Toggle Displays\n⚿ Yubico Authenticator\n↻ Reload Sway\n↻ Reload Waybar\n↩ Logout\n↯ Hibernate\n🡙 Reboot\n⏻ Shutdown" | wofi -I -s $HOME/.dotfiles/wofi/style.css -c $HOME/.dotfiles/wofi/sidebar --show dmenu
)
res=$(printf "⚿ Lock\n🖵 Toggle Displays\n⚿ Yubico Authenticator\n↻ Reload Sway\n↻ Reload Waybar\n↩ Logout\n↯ Hibernate\n🡙 Reboot\n⏻ Shutdown" | wofi -I -s $HOME/.dotfiles/wofi/style.css -c $HOME/.dotfiles/wofi/sidebar --show dmenu
)
fi
if [ "$res" == "⚿ Lock" ]; then
${WM}lock -c 000000
${WM}lock -c 000000
elif [ "$res" == "↩ Logout" ]; then
# Prevent auto-login
rm /home/jpm/.config/last_login_gui
${WM} exit
# Prevent auto-login
rm /home/jpm/.config/last_login_gui
${WM} exit
elif [ "$res" == "🖵 Toggle Displays" ]; then
/home/jpm/scripts/sway/toggle_outputs.sh
/home/jpm/scripts/sway/toggle_outputs.sh
elif [ "$res" == "⚿ Yubico Authenticator" ]; then
/home/jpm/scripts/rofi/rofi-yubioath.sh
/home/jpm/scripts/rofi/rofi-yubioath.sh
elif [ "$res" == "↻ Reload i3" ]; then
i3 reload
i3 reload
elif [ "$res" == "↹ Restart i3" ]; then
i3 restart
i3 restart
elif [ "$res" == "↻ Reload Sway" ]; then
sway reload
/home/jpm/scripts/sway/displays.pl
sway reload
/home/jpm/scripts/sway/displays.pl
elif [ "$res" == "↻ Reload Waybar" ]; then
# Need to integrate with sway/displays.pl for alternative outputs
/home/jpm/scripts/sway/displays.pl -w
# Need to integrate with sway/displays.pl for alternative outputs
/home/jpm/scripts/sway/displays.pl -w
elif [ "$res" == "🡙 Reboot" ]; then
rm $SSH_AUTH_SOCK
sudo systemctl reboot -i
rm $SSH_AUTH_SOCK
sudo systemctl reboot -i
elif [ "$res" == "⏻ Shutdown" ]; then
rm $SSH_AUTH_SOCK
sudo systemctl poweroff -i
rm $SSH_AUTH_SOCK
sudo systemctl poweroff -i
elif [ "$res" == "↯ Hibernate" ]; then
sudo systemctl hibernate -i
sudo systemctl hibernate -i
fi
exit 0

View File

@ -3,7 +3,7 @@
PID=`cat /tmp/$USER-wallpaper.pid`
if [ $PID ]; then
kill -SIGUSR1 $PID
kill -SIGUSR1 $PID
else
systemctl --user restart wallpapers.service
systemctl --user restart wallpapers.service
fi

View File

@ -3,9 +3,9 @@
CURRENT=`cat /home/jpm/.config/last_display`
if [ "$CURRENT" == "detached" ]; then
/home/jpm/scripts/sway/displays.pl TV
/home/jpm/scripts/sway/displays.pl TV
else
/home/jpm/scripts/sway/displays.pl detached
/home/jpm/scripts/sway/displays.pl detached
fi
pkill mako
mako &

View File

@ -12,368 +12,314 @@ use lib "$ENV{HOME}/perl5/lib/perl5";
$ENV{PWD} = '/tmp' unless (defined($ENV{PWD}));
use constant ERROR => {
LOG_EMERG => 8,
LOG_ALERT => 7,
LOG_CRIT => 6,
LOG_ERR => 5,
LOG_WARNING => 4,
LOG_NOTICE => 3,
LOG_INFO => 2,
LOG_DEBUG => 1
LOG_EMERG => 8,
LOG_ALERT => 7,
LOG_CRIT => 6,
LOG_ERR => 5,
LOG_WARNING => 4,
LOG_NOTICE => 3,
LOG_INFO => 2,
LOG_DEBUG => 1
};
our @e;
sub usage()
{
my $self = shift;
print("$0 [output(s)] [-d|--daemon]\n
my $self = shift;
print("$0 [output(s)] [-d|--daemon]\n
Sets a wallpaper by cropping an appropriate sized section of a larger image.\n
All arguments other than the below are assumed to be output names, as defined
in my sway/displays.pl script. If no outputs are provided, all available that
are currently enabled will be set.\n
--path=<path> Path to wallpaper directory.
-p <path> Default: $ENV{HOME}/wallpapers\n
--daemon=N Configures the wallpaper to be periodically rotated for all
-d N of the given outputs. N indicates the number of seconds between
each rotation, if provided (default: 300).\n
--nocrop Don't crop a selection from the image. Instead, pass the whole
-n image to swaybg and let it handle the scaling\n
--path=<path> Path to wallpaper directory.
-p <path> Default: $ENV{HOME}/wallpapers\n
--daemon=N Configures the wallpaper to be periodically rotated for all
-d N of the given outputs. N indicates the number of seconds between
each rotation, if provided (default: 300).\n
--nocrop Don't crop a selection from the image. Instead, pass the whole
-n image to swaybg and let it handle the scaling\n
--verbose=N Define minimum log level. Counting from 1: LOG_DEBUG, LOG_INFO,
-v N LOG_NOTICE, LOG_WARNING, LOG_ERR, LOG_CRIT, LOG_ALERT, LOG_EMERG
Default: 5; If provided without a value for N then all (1).
-v N LOG_NOTICE, LOG_WARNING, LOG_ERR, LOG_CRIT, LOG_ALERT, LOG_EMERG
Default: 5; If provided without a value for N then all (1).
--recursive=N Enumerate images recursively through directories in the path.
-r N N indicates the directory depth, unlimited if no N is provided.
--help This menu
-r N N indicates the directory depth, unlimited if no N is provided.
--help This menu
-h\n
You can send SIGUSR1 to force the daemon to reload immediately. Rotation timer
will be reset.\n");
exit(0);
exit(0);
}
sub new
{
my ($class, %args) = @_;
my ($class, %args) = @_;
use AnyEvent::Sway;
$args{ipc} = AnyEvent::Sway->new();
use Image::Magick;
$args{im} = Image::Magick->new();
$args{error} = ();
use AnyEvent::Sway;
$args{ipc} = AnyEvent::Sway->new();
use Image::Magick;
$args{im} = Image::Magick->new();
$args{error} = ();
$args{pidfile} = "/tmp/$ENV{USER}-wallpaper.pid";
$args{pidfile} = "/tmp/$ENV{USER}-wallpaper.pid";
return bless { %args };
return bless { %args };
}
my $wp = new("Wallpapers");
if (-e $wp->{pidfile}) {
if (-r $wp->{pidfile}) {
if (open(my $fh, '<', $wp->{pidfile})) {
my $pid = <$fh>;
chomp($pid);
use Proc::ProcessTable;
my $pt = Proc::ProcessTable->new();
foreach my $p ( @{ $pt->table() } ) {
if ($p->{pid} eq $pid) {
my $name = $0;
$name =~ s/$ENV{PWD}//;
if ($p->{'cmndline'} =~ m#$name#) {
$wp->do_log("LOG_CRIT", "Another process is already running with PID: $pid (running and listed in $wp->{pidfile})");
# Die locally because do_log will remove pidfile that this iteration does not belong to
exit(1);
} else {
$wp->do_log("LOG_CRIT", "Found matching $pid with different cmdline: $p->{cmndline} (not $0)",1);
# PID in pidfile doesn't look like it is another wallpaper
unlink($wp->{pidfile});
last;
}
return $p->{'pid'};
}
}
} else {
$wp->do_log("LOG_CRIT", "Pidfile $wp->{pidfile} exists, but cannot be opened. Assuming it is running already.");
# Die locally because do_log will remove pidfile that this iteration does not belong to
exit(1);
}
} else {
$wp->do_log("LOG_CRIT", "Pidfile $wp->{pidfile} exists, but is not readable. Assuming it is running already.");
# Die locally because do_log will remove pidfile that this iteration does not belong to
exit(1);
}
}
# SIGUSR reset the timer, force immediate reload, continue looping
$SIG{USR1} = sub {
alarm 0;
$wp->do_log("LOG_INFO", "Reloading due to SIGUSR1");
};
# SIGTERM reset the timer, clean pid, and allow for the main loop to finish run
$SIG{TERM} = sub {
$wp->do_log("LOG_INFO", "Going down clean due to SIGTERM");
clean($wp);
$wp->{daemon} = 0;
};
# SIGKILL clean pid then exit immediately
$SIG{KILL} = sub {
$wp->do_log("LOG_INFO", "Hard kill with SIGKILL, attempting to remove pidfile");
clean($wp);
exit(0);
};
# simply returns the array of hashes provided by swaymsg
sub get_outputs
{
my $self = shift;
my $o = $self->{ipc}->get_outputs->recv() || $self->do_log('LOG_WARNING',"Failed to query 'get_outputs'");
die "No outputs detected.\n" unless (scalar(@$o) > 0);
return $o;
my $self = shift;
my $o = $self->{ipc}->get_outputs->recv() || $self->do_log('LOG_WARNING',"Failed to query 'get_outputs'");
die "No outputs detected.\n" unless (scalar(@$o) > 0);
return $o;
}
# returns the same as above but with the 'name' as a hash key for easier lookup
sub get_active
{
my $self = shift;
if (defined($self->{outputs}) && scalar($self->{outputs})) {
my %active = ();
foreach my $o (@{$self->{outputs}}) {
my $name;
my %details;
next unless ($o->{active});
$active{$o->{name}} = ();
foreach (keys(%$o)) {
$active{$o->{name}}->{$_} = $o->{$_} unless ($_ eq 'name');
}
}
$self->do_log('LOG_WARNING',"No outputs detected.") unless (scalar(keys(%active)));
return \%active;
} else {
print "You haven't initialized get_outputs";
$self->do_log('LOG_WARNING',"Output list not defined yet. Try 'get_outputs()' first");
return \{};
my $self = shift;
if (defined($self->{outputs}) && scalar($self->{outputs})) {
my %active = ();
foreach my $o (@{$self->{outputs}}) {
my $name;
my %details;
next unless ($o->{active});
$active{$o->{name}} = ();
foreach (keys(%$o)) {
$active{$o->{name}}->{$_} = $o->{$_} unless ($_ eq 'name');
}
}
$self->do_log('LOG_WARNING',"No outputs detected.") unless (scalar(keys(%active)));
return \%active;
} else {
print "You haven't initialized get_outputs";
$self->do_log('LOG_WARNING',"Output list not defined yet. Try 'get_outputs()' first");
return \{};
}
}
sub clean
{
my $self = shift;
if (-e $self->{pidfile}) {
open (my $fh, '<', $self->{pidfile});
my $p = <$fh>;
close($fh);
chomp $p;
kill($p);
unlink($self->{pidfile});
}
my $self = shift;
if (-e $self->{pidfile}) {
open (my $fh, '<', $self->{pidfile});
my $p = <$fh>;
close($fh);
chomp $p;
kill($p);
unlink($self->{pidfile});
}
}
sub dig_dirs
{
my $self = shift;
my $paths_ref = shift;
my $path = shift;
my $depth = shift || 0;
unless (-e $path) {
return(undef);
}
my $self = shift;
my $paths_ref = shift;
my $path = shift;
my $depth = shift || 0;
unless (-e $path) {
return(undef);
}
if ($path =~ m/\/\.\.?$/) {
return;
}
foreach (glob("$path/*"), glob("$path/.*")) {
if ($path =~ m/\/\.\.?$/) {
return;
}
foreach (glob("$path/*"), glob("$path/.*")) {
if ($path =~ m/\/\.\.?$/) {
next();
} elsif (-l $_) {
push(@$paths_ref, $_);
} elsif (-d $_ && ($self->{recursive} == '-1' || $depth < $self->{recursive})) {
$self->dig_dirs($paths_ref,$_,$depth+1);
} else {
push(@$paths_ref, $_);
}
next();
} elsif (-l $_) {
push(@$paths_ref, $_);
} elsif (-d $_ && ($self->{recursive} == '-1' || $depth < $self->{recursive})) {
$self->dig_dirs($paths_ref,$_,$depth+1);
} else {
push(@$paths_ref, $_);
}
}
}
sub choose_image
{
my $self = shift;
my $self = shift;
my @i;
my $depth = 0;
my @w;
$self->dig_dirs(\@w,$self->{path});
return undef unless (scalar(@w));
$self->do_log("LOG_DEBUG", "Found ".scalar(@w)." files in $self->{path} up to depth $self->{recursive}");
foreach (@w) {
if (-d $_) {
$self->do_log("LOG_DEBUG", "Ignoring sub-directory $_");
next;
}
if ($_ =~ m/\.(png|jpg)$/) {
push(@i,$_);
}
my @i;
my $depth = 0;
my @w;
$self->dig_dirs(\@w,$self->{path});
return undef unless (scalar(@w));
$self->do_log("LOG_DEBUG", "Found ".scalar(@w)." files in $self->{path} up to depth $self->{recursive}");
foreach (@w) {
if (-d $_) {
$self->do_log("LOG_DEBUG", "Ignoring sub-directory $_");
next;
}
if ($_ =~ m/\.(png|jpg)$/) {
push(@i,$_);
}
}
return $i[rand(scalar(@i))] || return undef;
return $i[rand(scalar(@i))] || return undef;
}
sub crop
{
my $self = shift;
my $image = shift;
my $ow = shift;
my $oh = shift;
my $self = shift;
my $image = shift;
my $ow = shift;
my $oh = shift;
my $cropped = $image;
$cropped =~ s#^.*/([^/]*)\.([^\.]+)$#$self->{'path'}$1-cropped.$2#;
my $cropped = $image;
$cropped =~ s#^.*/([^/]*)\.([^\.]+)$#$self->{'path'}$1-cropped.$2#;
#$image = "/tmp/Pharma-out.png.jpg";
use Image::Magick;
my $im = Image::Magick->new();
die "$image is not readable" unless (-r $image);
my $ret = $im->Read($image);
return 0 if ($ret);
my ($iw, $ih) = $im->Get("columns", "rows");
$self->do_log("LOG_DEBUG", "Image has dimensions ${iw}x${ih}");
#$image = "/tmp/Pharma-out.png.jpg";
use Image::Magick;
my $im = Image::Magick->new();
die "$image is not readable" unless (-r $image);
my $ret = $im->Read($image);
return 0 if ($ret);
my ($iw, $ih) = $im->Get("columns", "rows");
$self->do_log("LOG_DEBUG", "Image has dimensions ${iw}x${ih}");
# Return full size if it is smaller in either dimension then the output
if ($iw <= $ow || $ih <= $oh) {
$self->do_log("LOG_DEBUG", "Not cropping because ${iw}x${ih} is smaller or equal to the output (${ow}x${oh}) in at least 1 dimension.");
return undef;
}
# Return full size if it is smaller in either dimension then the output
if ($iw <= $ow || $ih <= $oh) {
$self->do_log("LOG_DEBUG", "Not cropping because ${iw}x${ih} is smaller or equal to the output (${ow}x${oh}) in at least 1 dimension.");
return undef;
}
my ($x, $y);
$x = int(rand($iw-$ow));
$y = int(rand($ih-$oh));
my ($x, $y);
$x = int(rand($iw-$ow));
$y = int(rand($ih-$oh));
my $err = $im->Crop(geometry=>"${ow}x${oh}+${x}+${y}");
die "$err" if ($err);
$err = $im->Write($cropped);
die "$err" if ($err);
return $cropped if ( -e $cropped );
my $err = $im->Crop(geometry=>"${ow}x${oh}+${x}+${y}");
die "$err" if ($err);
$err = $im->Write($cropped);
die "$err" if ($err);
return $cropped if ( -e $cropped );
}
sub set_background
{
my $self = shift;
my $target = shift || return "No target or image provided";
my $cropped = shift || return "No image provided";
# TODO get fallback from javascript
my $cmd = "output $target background $cropped fill #000000";
$self->do_log("LOG_DEBUG", "Running $cmd\n");
my $ret = $self->{ipc}->message(0,$cmd)->recv;
if ($ret->[0]->{success}) {
$self->do_log("LOG_DEBUG", "Success!");
return undef;
}
return "Failed to run Sway IPC command '$cmd'";
my $self = shift;
my $target = shift || return "No target or image provided";
my $cropped = shift || return "No image provided";
# TODO get fallback from javascript
my $cmd = "output $target background $cropped fill #000000";
$self->do_log("LOG_DEBUG", "Running $cmd\n");
my $ret = $self->{ipc}->message(0,$cmd)->recv;
if ($ret->[0]->{success}) {
$self->do_log("LOG_DEBUG", "Success!");
return undef;
}
return "Failed to run Sway IPC command '$cmd'";
}
sub do_log
{
my $self = shift;
my $level = shift;
my $msg = shift;
my $die = shift || 0;
my $min = $self->{verbose} || 5;
my $self = shift;
my $level = shift;
my $msg = shift;
my $die = shift || 0;
my $min = $self->{verbose} || 5;
# Journald is borked. Just don't bother logging
return 0;
if ($self->{daemon}) {
use Log::Journald qw(send);
send(
PRIORITY => ERROR->{$level},
MESSAGE => $msg,
PERL_PACKAGE => 'Sway Wallpapers'
) || warn "Could not send log ($level $msg): $!";
if ($die) {
$msg = '(FATAL) ' . $msg;
exit(1);
}
} else {
if (ERROR->{$level} >= $min) {
printf("%11s %s\n", $level, $msg);
}
}
# Journald is borked. Just don't bother logging
return 0;
if ($self->{daemon}) {
#use Log::Journald qw(send);
#send(
#PRIORITY => ERROR->{$level},
#MESSAGE => $msg,
#PERL_PACKAGE => 'Sway Wallpapers'
#) || warn "Could not send log ($level $msg): $!";
if ($die) {
$self->clean();
exit(1);
$msg = '(FATAL) ' . $msg;
exit(1);
}
} else {
if (ERROR->{$level} >= $min) {
printf("%11s %s\n", $level, $msg);
}
}
if ($die) {
$self->clean();
exit(1);
}
}
sub run
{
my $self = shift;
$self->do_log("LOG_DEBUG", "Fetching outputs from IPC");
$self->{outputs} = $self->get_outputs();
# Local copy of targets so that it will re-check active every time
my @t = @{$self->{targets}} if (scalar(@{$self->{targets}}));
$self->do_log("LOG_DEBUG", "Removing inactive ouputs");
my $active = $self->get_active();
# If specific targets were not defined, use all active
unless (scalar(@t)) {
@t = keys(%$active);
push(@{$self->{error}}, "No target outputs") unless (scalar(@t));
my $self = shift;
$self->do_log("LOG_DEBUG", "Fetching outputs from IPC");
$self->{outputs} = $self->get_outputs();
# Local copy of targets so that it will re-check active every time
print "Changing $_\n" foreach(@{$self->{targets}});
my @t = @{$self->{targets}} if (scalar(@{$self->{targets}}));
$self->do_log("LOG_DEBUG", "Removing inactive ouputs");
my $active = $self->get_active();
# If specific targets were not defined, use all active
unless (scalar(@t)) {
@t = keys(%$active);
push(@{$self->{error}}, "No target outputs") unless (scalar(@t));
}
$self->do_log("LOG_DEBUG", "Looping desired ouputs");
foreach my $target (@t) {
print $target."\n";
$self->do_log("LOG_DEBUG", "Ensuring that desired output is active");
unless (defined($active->{$target})) {
$self->do_log('LOG_DEBUG', "Target $target is not an active output");
next;
}
$self->do_log("LOG_DEBUG", "Looping desired ouputs");
foreach my $target (@t) {
$self->do_log("LOG_DEBUG", "Ensuring that desired output is active");
unless (defined($active->{$target})) {
$self->do_log('LOG_DEBUG', "Target $target is not an active output");
next;
}
$self->do_log("LOG_DEBUG", "Selecting image for $target");
my $image = $self->choose_image();
if (defined($image)) {
$self->do_log('LOG_DEBUG', "Selected $image");
if ( -r "$image" ) {
my $cropped;
if ($self->{crop}) {
$self->do_log('LOG_DEBUG',"Cropping image for '$target' using '$image'");
$cropped = $self->crop(
$image,
$active->{$target}->{rect}->{width},
$active->{$target}->{rect}->{height}
);
if ($cropped) {
} else {
# Create a tmp copy since it will be deleted later
# If PWD is the wallpaper path, make the tmp in /tmp
if ($self->{path} eq $ENV{PWD}) {
$cropped = $image;
$cropped =~ s%$ENV{PWD}%/tmp%;
# Else make the tmp in PWD
} else {
$cropped = '/'.$image;
$cropped =~ s%.*/([^/+])%$ENV{PWD}/$1%;
}
$self->do_log('LOG_DEBUG',"Creating copy of original: $cropped");
File::Copy::copy($image,$cropped) || $self->do_log('LOG_WARNING',"Failed to copy to $cropped: $!");
}
} else {
$self->do_log('LOG_DEBUG', "Cropping is disabled");
$cropped = $image;
}
$self->set_background($target,$cropped);
if ($self->{crop}) {
# Give swaybg a second, otherwise the file will be missing before it ends
sleep(1);
$self->do_log('LOG_DEBUG', "Deleting $cropped");
unlink($cropped) || $self->do_log("LOG_WARNING", "Failed to delete $cropped after setting: $!");
}
$self->do_log("LOG_DEBUG", "Selecting image for $target");
my $image = $self->choose_image();
if (defined($image)) {
$self->do_log('LOG_DEBUG', "Selected $image");
if ( -r "$image" ) {
my $cropped;
if ($self->{crop}) {
$self->do_log('LOG_DEBUG',"Cropping image for '$target' using '$image'");
$cropped = $self->crop(
$image,
$active->{$target}->{rect}->{width},
$active->{$target}->{rect}->{height}
);
if ($cropped) {
} else {
# Create a tmp copy since it will be deleted later
# If PWD is the wallpaper path, make the tmp in /tmp
if ($self->{path} eq $ENV{PWD}) {
$cropped = $image;
$cropped =~ s%$ENV{PWD}%/tmp%;
# Else make the tmp in PWD
} else {
$self->do_log("LOG_WARNING", "Failed to read $image");
$cropped = '/'.$image;
$cropped =~ s%.*/([^/+])%$ENV{PWD}/$1%;
}
$self->do_log('LOG_DEBUG',"Creating copy of original: $cropped");
File::Copy::copy($image,$cropped) || $self->do_log('LOG_WARNING',"Failed to copy to $cropped: $!");
}
} else {
$self->do_log("LOG_WARNING", "Failed to select image from $self->{path}");
$self->do_log('LOG_DEBUG', "Cropping is disabled");
$cropped = $image;
}
$self->set_background($target,$cropped);
if ($self->{crop}) {
# Give swaybg a second, otherwise the file will be missing before it ends
sleep(1);
$self->do_log('LOG_DEBUG', "Deleting $cropped");
unlink($cropped) || $self->do_log("LOG_WARNING", "Failed to delete $cropped after setting: $!");
}
} else {
$self->do_log("LOG_WARNING", "Failed to read $image");
}
} else {
$self->do_log("LOG_WARNING", "Failed to select image from $self->{path}");
}
}
}
################################################################################
# Collect arguments
################################################################################
my $wp = new("Wallpapers");
my @targets;
my $daemon;
my $delay;
@ -381,51 +327,92 @@ my $crop;
my $path;
my $verbose;
my $recursive = 0;
while (my $arg = shift(@ARGV)) {
if ($arg eq '-h' || $arg eq '--help') {
$wp->usage();
} elsif ($arg =~ m/^\-\-path=?(.+)$/) {
die "Redundant argument '$arg'. Wallpaper path already set.\n" if ($path);
$path = $1;
} elsif ($arg eq '-p') {
die "Redundant argument '$arg'. Wallpaper path already set.\n" if ($path);
$path = shift(@ARGV);
} elsif ($arg =~ m/^\-\-daemon=?(.+)?$/) {
die "Redundant argument '$arg'. Daemon mode already set.\n" if ($daemon);
$delay = $1 || 300;
$daemon = 1;
} elsif ($arg eq '-d') {
die "Redundant argument '$arg'. Daemon mode already set.\n" if ($daemon);
if (scalar(@ARGV) && $ARGV[0] =~ m/^\d+$/) {
$delay = shift(@ARGV);
}
$daemon = 1;
} elsif ($arg eq '--nocrop' || $arg eq '-n') {
die "Redundant argument '$arg'. No-crop already set.\n" if (defined($crop));
$crop = 0;
} elsif ($arg =~ m/^\-\-verbose=?(.+)?$/) {
die "Redundant argument '$arg'. Verbosity already set.\n" if ($verbose);
$verbose = $1 || 1;
} elsif ($arg eq '-v') {
die "Redundant argument '$arg'. Verbosity already set.\n" if ($verbose);
if (scalar(@ARGV) && $ARGV[0] =~ m/^\d$/) {
$verbose = shift(@ARGV);
}
} elsif ($arg =~ m/^\-\-recursive=?(.+)?$/) {
die "Redundant argument '$arg'. Recursive search already set.\n" unless ($recursive == 0);
$recursive = $1 || -1;
} elsif ($arg eq '-r') {
die "Redundant argument '$arg'. Recursive search already set.\n" unless ($recursive == 0);
if (scalar(@ARGV) && $ARGV[0] =~ m/^\d+$/) {
$recursive = shift(@ARGV);
} else {
$recursive = -1;
}
} elsif ($arg =~ m/^-/) {
die "Unrecognized argument: $arg\n";
} else {
push(@targets,$arg);
if ($arg eq '-h' || $arg eq '--help') {
$wp->usage();
} elsif ($arg =~ m/^\-\-path=?(.+)$/) {
die "Redundant argument '$arg'. Wallpaper path already set.\n" if ($path);
$path = $1;
} elsif ($arg eq '-p') {
die "Redundant argument '$arg'. Wallpaper path already set.\n" if ($path);
$path = shift(@ARGV);
} elsif ($arg =~ m/^\-\-daemon=?(.+)?$/) {
die "Redundant argument '$arg'. Daemon mode already set.\n" if ($daemon);
$delay = $1 || 300;
$daemon = 1;
} elsif ($arg eq '-d') {
die "Redundant argument '$arg'. Daemon mode already set.\n" if ($daemon);
if (scalar(@ARGV) && $ARGV[0] =~ m/^\d+$/) {
$delay = shift(@ARGV);
}
$daemon = 1;
} elsif ($arg eq '--nocrop' || $arg eq '-n') {
die "Redundant argument '$arg'. No-crop already set.\n" if (defined($crop));
$crop = 0;
} elsif ($arg =~ m/^\-\-verbose=?(.+)?$/) {
die "Redundant argument '$arg'. Verbosity already set.\n" if ($verbose);
$verbose = $1 || 1;
} elsif ($arg eq '-v') {
die "Redundant argument '$arg'. Verbosity already set.\n" if ($verbose);
if (scalar(@ARGV) && $ARGV[0] =~ m/^\d$/) {
$verbose = shift(@ARGV);
}
} elsif ($arg =~ m/^\-\-recursive=?(.+)?$/) {
die "Redundant argument '$arg'. Recursive search already set.\n" unless ($recursive == 0);
$recursive = $1 || -1;
} elsif ($arg eq '-r') {
die "Redundant argument '$arg'. Recursive search already set.\n" unless ($recursive == 0);
if (scalar(@ARGV) && $ARGV[0] =~ m/^\d+$/) {
$recursive = shift(@ARGV);
} else {
$recursive = -1;
}
} elsif ($arg =~ m/^-/) {
die "Unrecognized argument: $arg\n";
} else {
print "Adding $arg to targets\n";
push(@targets,$arg);
print "Setting $_\n" foreach(@targets);
$wp->{targets} = \@targets || undef;
print "Set $_\n" foreach(@{$wp->{targets}});
}
}
if (-e $wp->{pidfile}) {
if (-r $wp->{pidfile}) {
if (open(my $fh, '<', $wp->{pidfile})) {
my $pid = <$fh>;
chomp($pid);
use Proc::ProcessTable;
my $pt = Proc::ProcessTable->new();
foreach my $p ( @{ $pt->table() } ) {
if ($p->{pid} eq $pid) {
my $name = $0;
$name =~ s/$ENV{PWD}//;
if ($p->{'cmndline'} =~ m#$name#) {
$wp->do_log("LOG_CRIT", "Another process is already running with PID: $pid (running and listed in $wp->{pidfile})");
# Die locally because do_log will remove pidfile that this iteration does not belong to
exit(1);
} else {
$wp->do_log("LOG_CRIT", "Found matching $pid with different cmdline: $p->{cmndline} (not $0)",1);
# PID in pidfile doesn't look like it is another wallpaper
unlink($wp->{pidfile});
last;
}
return $p->{'pid'};
}
}
} else {
$wp->do_log("LOG_CRIT", "Pidfile $wp->{pidfile} exists, but cannot be opened. Assuming it is running already.");
# Die locally because do_log will remove pidfile that this iteration does not belong to
exit(1);
}
} else {
$wp->do_log("LOG_CRIT", "Pidfile $wp->{pidfile} exists, but is not readable. Assuming it is running already.");
# Die locally because do_log will remove pidfile that this iteration does not belong to
exit(1);
}
}
################################################################################
@ -438,7 +425,6 @@ die "Invalid wallpaper path '$path'. Not a directory." if (defined($path) && !-d
die "Invalid verbosity level: '$verbose'\n" if (defined($verbose) && $verbose !~ m/^[1-8]$/);
$wp->do_log("LOG_DEBUG", "Configuring object");
$wp->{targets} = \@targets || undef;
$wp->{daemon} = $daemon || 0;
$wp->{path} = $path || "$ENV{HOME}/wallpapers";
$wp->{crop} = $crop || 1;
@ -452,23 +438,23 @@ $wp->{error} = [];
################################################################################
if ($wp->{daemon}) {
$wp->do_log("LOG_DEBUG", "Forking daemon");
my $p = fork();
if ($p) {
$wp->do_log("LOG_DEBUG", "Writing PID ($p) to pidfile ($wp->{pidfile})");
if (open(my $fh, ">", $wp->{pidfile})) {
print $fh "$p" || die "Failed to write pid ($p) to pidfile ".$wp->{pidfile};
close($fh);
} else {
print "Failed to open pidfile ".$wp->{pidfile}.": $!\n";
}
# Short delay necessary for SystemD to find PID
sleep(1);
exit(0);
$wp->do_log("LOG_DEBUG", "Forking daemon");
my $p = fork();
if ($p) {
$wp->do_log("LOG_DEBUG", "Writing PID ($p) to pidfile ($wp->{pidfile})");
if (open(my $fh, ">", $wp->{pidfile})) {
print $fh "$p" || die "Failed to write pid ($p) to pidfile ".$wp->{pidfile};
close($fh);
} else {
print "Failed to open pidfile ".$wp->{pidfile}.": $!\n";
}
$wp->do_log("LOG_DEBUG", "Daemon running");
setpgrp(0, 0);
umask 0;
# Short delay necessary for SystemD to find PID
sleep(1);
exit(0);
}
$wp->do_log("LOG_DEBUG", "Daemon running");
setpgrp(0, 0);
umask 0;
}
################################################################################
@ -477,22 +463,46 @@ if ($wp->{daemon}) {
my $first = 1;
do {
$wp->do_log("LOG_INFO", "Reloading wallpaper") unless ($first);
$wp->run();
if ($wp->{daemon}) {
my $normal = "reload wallpaper";
eval {
$SIG{ALRM} = sub { return "$normal" };
alarm $wp->{delay};
POSIX::pause();
alarm 0;
};
$wp->do_log("LOG_WARNING", "Reload failed: $@") if ($@ && $@ !~ quotemeta($normal));
}
$first = 0 if ($first);
$wp->do_log("LOG_INFO", "Reloading wallpaper") unless ($first);
$wp->run();
if ($wp->{daemon}) {
my $normal = "reload wallpaper";
eval {
$SIG{ALRM} = sub { return "$normal" };
alarm $wp->{delay};
POSIX::pause();
alarm 0;
};
$wp->do_log("LOG_WARNING", "Reload failed: $@") if ($@ && $@ !~ quotemeta($normal));
}
$first = 0 if ($first);
} while ($wp->{daemon});
# If we made it to here, it was not daemonized. Output errors and exit
$wp->do_log("LOG_DEBUG", "Finishing") unless ($wp->{daemon});
################################################################################
# Signals
################################################################################
# SIGUSR reset the timer, force immediate reload, continue looping
$SIG{USR1} = sub {
alarm 0;
$wp->do_log("LOG_INFO", "Reloading due to SIGUSR1");
};
# SIGTERM reset the timer, clean pid, and allow for the main loop to finish run
$SIG{TERM} = sub {
$wp->do_log("LOG_INFO", "Going down clean due to SIGTERM");
clean($wp);
$wp->{daemon} = 0;
};
# SIGKILL clean pid then exit immediately
$SIG{KILL} = sub {
$wp->do_log("LOG_INFO", "Hard kill with SIGKILL, attempting to remove pidfile");
clean($wp);
exit(0);
};
exit(0);

View File

@ -3,7 +3,7 @@
use strict;
use warnings;
our $debug = 1; # For testing, will output configuration and errors if true
our $debug = 1; # For testing, will output configuration and errors if true
use AnyEvent::Sway;
our $s = AnyEvent::Sway->new();
@ -13,37 +13,37 @@ die "No outputs detected.\n" unless (scalar(@$o) > 1);
sub usage()
{
print("$0 [value] [-p|--plus] [-m|--minus] [-a x|--attribute=x] [-d N|--delay=N]
print("$0 [value] [-p|--plus] [-m|--minus] [-a x|--attribute=x] [-d N|--delay=N]
Fade the opacity of one or more windows via the Sway IPC interface.\n
value The target opacity or offset between 0 (full transparency) and 1
(fully opaque). Change will be made in increments of 0.01 with a
delay between each.\n
--attribute=x Attribute of window(s) to fade.
-a x Default: [title="*"]\n
--plus Increases opacity by increment instead of setting it directly
-p to that increment.\n
--minus Decreases opacity by increment instead of setting it directly
-m to that increment.\n
--delay=N Change the delay in ms between each percentage point change in
-d N opacity. Default: 20\n
--help This menu
value The target opacity or offset between 0 (full transparency) and 1
(fully opaque). Change will be made in increments of 0.01 with a
delay between each.\n
--attribute=x Attribute of window(s) to fade.
-a x Default: [title="*"]\n
--plus Increases opacity by increment instead of setting it directly
-p to that increment.\n
--minus Decreases opacity by increment instead of setting it directly
-m to that increment.\n
--delay=N Change the delay in ms between each percentage point change in
-d N opacity. Default: 20\n
--help This menu
-h\n");
exit(0);
exit(0);
}
sub set_opacity
{
my $attribute = shift || return "No target or image provided";
my $target = shift || return "No image provided";
# TODO get fallback from javascript
my $cmd = "output $attribute opacity $target";
print "Running $cmd\n";
my $ret = $s->message(0,$cmd)->recv;
if ($ret->[0]->{success}) {
print "Success!\n";
return undef;
}
return "Failed to run Sway IPC command '$cmd'";
my $attribute = shift || return "No target or image provided";
my $target = shift || return "No image provided";
# TODO get fallback from javascript
my $cmd = "output $attribute opacity $target";
print "Running $cmd\n";
my $ret = $s->message(0,$cmd)->recv;
if ($ret->[0]->{success}) {
print "Success!\n";
return undef;
}
return "Failed to run Sway IPC command '$cmd'";
}
my @targets;
@ -53,123 +53,123 @@ my $crop = 1;
my $path;
while (my $arg = shift(@ARGV)) {
if ($arg eq '-h' || $arg eq '--help') {
usage();
} elsif ($arg =~ m/^\-\-path=?(.+)$/) {
die "Redundant argument '$arg'. Wallpaper path already set.\n" if ($path);
$path = $1;
} elsif ($arg eq '-p') {
die "Redundant argument '$arg'. Wallpaper path already set.\n" if ($path);
$path = shift(@ARGV);
} elsif ($arg =~ m/^\-\-daemon=?(.+)$/) {
die "Redundant argument '$arg'. Daemon mode already set.\n" if ($daemon);
$delay = $1;
$daemon = 1;
} elsif ($arg eq '-d') {
die "Redundant argument '$arg'. Daemon mode already set.\n" if ($daemon);
if ($ARGV[0] =~ m/^\d+$/) {
$delay = shift(@ARGV);
}
$daemon = 1;
} elsif ($arg eq '--nocrop' || $arg eq '-') {
die "Redundant argument '$arg'. No-crop already set.\n" unless ($crop);
} else {
push(@targets,$arg);
}
if ($arg eq '-h' || $arg eq '--help') {
usage();
} elsif ($arg =~ m/^\-\-path=?(.+)$/) {
die "Redundant argument '$arg'. Wallpaper path already set.\n" if ($path);
$path = $1;
} elsif ($arg eq '-p') {
die "Redundant argument '$arg'. Wallpaper path already set.\n" if ($path);
$path = shift(@ARGV);
} elsif ($arg =~ m/^\-\-daemon=?(.+)$/) {
die "Redundant argument '$arg'. Daemon mode already set.\n" if ($daemon);
$delay = $1;
$daemon = 1;
} elsif ($arg eq '-d') {
die "Redundant argument '$arg'. Daemon mode already set.\n" if ($daemon);
if ($ARGV[0] =~ m/^\d+$/) {
$delay = shift(@ARGV);
}
$daemon = 1;
} elsif ($arg eq '--nocrop' || $arg eq '-') {
die "Redundant argument '$arg'. No-crop already set.\n" unless ($crop);
} else {
push(@targets,$arg);
}
}
die "Invalid rotation delay: $delay" unless ($delay =~ m/^\d+$/);
if ($path) {
die "Invalid wallpaper path '$path'. Not a directory." unless (-d $path);
die "Invalid wallpaper path '$path'. Not a directory." unless (-d $path);
} else {
$path = "$ENV{HOME}/wallpapers";
$path = "$ENV{HOME}/wallpapers";
}
if (scalar(@targets)) {
my @kept;
foreach my $t (@targets) {
my $hit = 0;
foreach (@$o) {
if ($_->{name} eq $t) {
push(@kept, $t);
$hit++;
last;
}
}
print STDERR "Requested output '$t' not found\n" unless ($hit);
}
die "None of the requested outputs are active" unless (scalar(@kept));
@targets = @kept;
my @kept;
foreach my $t (@targets) {
my $hit = 0;
foreach (@$o) {
if ($_->{name} eq $t) {
push(@kept, $t);
$hit++;
last;
}
}
print STDERR "Requested output '$t' not found\n" unless ($hit);
}
die "None of the requested outputs are active" unless (scalar(@kept));
@targets = @kept;
}
if ($daemon) {
my $p = fork();
if ($p) {
print "Daemonized as PID: $p\n";
exit(0);
}
my $p = fork();
if ($p) {
print "Daemonized as PID: $p\n";
exit(0);
}
}
if ($debug) {
print "Initial configuration:\n";
print " Targets: ( " . ( join(" ",@targets) || "All active" ) . " )\n";
print " Daemon: $daemon\n";
print " Path: $path\n";
print "Initial configuration:\n";
print " Targets: ( " . ( join(" ",@targets) || "All active" ) . " )\n";
print " Daemon: $daemon\n";
print " Path: $path\n";
}
my @e;
do {
my @err;
# Local copy of targets so that it will re-check active every time
my @t = @targets;
unless (scalar(@t)) {
@t = get_active();
push(@err, "No target outputs") unless (scalar(@t));
}
foreach my $a (@t) {
my $image = choose_image($path);
if (defined($image)) {
if ( -r "$image" ) {
print "selected $image\n";
my $cropped;
if ($crop) {
if ($debug) {
print "Cropping image for '$a' using '$image'\n";
}
my ($ow, $oh) = get_size($a);
$cropped = crop($image, $ow, $oh);
unless ($cropped) {
push(@err, "Failed to generate cropped image") unless ($cropped);
next;
}
} else {
$cropped = $image;
}
my $e = set_background($a,$cropped);
push(@err, $e) if (defined($e));
if ($crop) {
print "Deleting $cropped\n";
#unlink($cropped) || push(@err, "Failed to delete $cropped after setting: $!");
}
} else {
push(@err, "$a: Unable to read image $image");
}
} else {
push(@err, "$a: Unable to select image from $path");
}
}
if ($debug && $daemon) {
print STDERR join("\n",@err);
sleep($delay);
} else {
@e = @err;
}
my @err;
# Local copy of targets so that it will re-check active every time
my @t = @targets;
unless (scalar(@t)) {
@t = get_active();
push(@err, "No target outputs") unless (scalar(@t));
}
foreach my $a (@t) {
my $image = choose_image($path);
if (defined($image)) {
if ( -r "$image" ) {
print "selected $image\n";
my $cropped;
if ($crop) {
if ($debug) {
print "Cropping image for '$a' using '$image'\n";
}
my ($ow, $oh) = get_size($a);
$cropped = crop($image, $ow, $oh);
unless ($cropped) {
push(@err, "Failed to generate cropped image") unless ($cropped);
next;
}
} else {
$cropped = $image;
}
my $e = set_background($a,$cropped);
push(@err, $e) if (defined($e));
if ($crop) {
print "Deleting $cropped\n";
#unlink($cropped) || push(@err, "Failed to delete $cropped after setting: $!");
}
} else {
push(@err, "$a: Unable to read image $image");
}
} else {
push(@err, "$a: Unable to select image from $path");
}
}
if ($debug && $daemon) {
print STDERR join("\n",@err);
sleep($delay);
} else {
@e = @err;
}
} while ($daemon);
if (scalar(@e)) {
die "Failure while not running as daemon:\n" .
join("\n",@e);
die "Failure while not running as daemon:\n" .
join("\n",@e);
}
exit(0);

View File

@ -9,65 +9,65 @@ our $sleepfile = "$ENV{HOME}/.spool/kbd_sleep";
sub readFile
{
my $file = shift;
my $ret;
if (open(my $fh, '<', $file)) {
$ret = readline($fh);
chomp $ret;
close($fh);
} else {
die "Failed to read $file: $?\n";
}
return $ret;
my $file = shift;
my $ret;
if (open(my $fh, '<', $file)) {
$ret = readline($fh);
chomp $ret;
close($fh);
} else {
die "Failed to read $file: $?\n";
}
return $ret;
}
sub writeFile
{
my ($file, $value) = @_;
if (open(my $fh, '>', $file)) {
print $fh $value;
close($fh);
} else {
die "Failed to write $current\n";
}
my ($file, $value) = @_;
if (open(my $fh, '>', $file)) {
print $fh $value;
close($fh);
} else {
die "Failed to write $current\n";
}
}
sub sleepFile
{
my $now = readFile($current);
writeFile($sleepfile,$now);
writeFile($current,0);
my $now = readFile($current);
writeFile($sleepfile,$now);
writeFile($current,0);
}
sub restoreFile
{
unless (-e $sleepfile) {
die "Missing '$sleepfile'. Must not have slept prior to restore.\n"
}
my $value = readFile($sleepfile);
writeFile($current,$value);
unlink($sleepfile);
unless (-e $sleepfile) {
die "Missing '$sleepfile'. Must not have slept prior to restore.\n"
}
my $value = readFile($sleepfile);
writeFile($current,$value);
unlink($sleepfile);
}
sub rotateFile
{
my $max = readFile($maxfile);
my $now = readFile($current);
my $new = (($now+1) % ($max+1));
writeFile($current,$new);
my $max = readFile($maxfile);
my $now = readFile($current);
my $new = (($now+1) % ($max+1));
writeFile($current,$new);
}
if (defined($ARGV[0])) {
if ($ARGV[0] eq 'sleep') {
sleepFile();
exit(0);
} elsif ($ARGV[0] eq 'restore') {
restoreFile();
exit(0);
} elsif ($ARGV[0] ne 'rotate') {
die "Invalid mode '".$ARGV[0]."'. 'rotate', 'sleep', or 'restore'\n";
}
if ($ARGV[0] eq 'sleep') {
sleepFile();
exit(0);
} elsif ($ARGV[0] eq 'restore') {
restoreFile();
exit(0);
} elsif ($ARGV[0] ne 'rotate') {
die "Invalid mode '".$ARGV[0]."'. 'rotate', 'sleep', or 'restore'\n";
}
}
rotateFile();

View File

@ -4,160 +4,170 @@ my $output;
my ($bar, $pretty) = (0, 0);
if ( defined($ARGV[0]) && $ARGV[0] ne '-b' && $ARGV[0] ne '--bar' && $ARGV[0] ne '-p' && $ARGV[0] ne '--pretty' ) {
print'
print'
pow.pl - Power Status Script
Usage: pow.pl
Prints information about all power devices as JSON.
-p --pretty Display as human-readable
-b --bar Waybar simplified output
-h --help Display help. This is the only option.
-p --pretty Display as human-readable
-b --bar Waybar simplified output
-h --help Display help. This is the only option.
';
exit();
} elsif ($ARGV[0] eq '-b' || $ARGV[0] eq '--bar') {
$bar = 1;
$bar = 1;
} elsif ($ARGV[0] eq '-p' || $ARGV[0] eq '--pretty') {
$pretty = 1;
$pretty = 1;
}
my %battery_total = (
'current' => 0,
'max' => 0,
'percentage' => 0
'current' => 0,
'max' => 0,
'percentage' => 0
);
my @devices = <"/sys/class/power_supply/*">;
unless (scalar(@devices)) {
print('{"AC":{"Type":"AC","Status":"Plugged-In"}}');
exit();
}
my $nobat = 1;
$output .= "{";
foreach (@devices) {
my $path = $_;
my $name = $_;
$name =~ s/.*\///;
$output .= '"' . $name . '":{';
open(my $t,'<',"$_/type");
my $type = <$t>;
chomp $type;
close $t;
$output .= '"Type":"' . $type . '"';
if ($name =~ /BAT[0-9]+/) {
open(my $s,'<',"$_/status");
my $status = <$s>;
chomp $status;
$output .= ',"Status":"' . $status . '"';
my $path = $_;
my $name = $_;
$name =~ s/.*\///;
$output .= '"' . $name . '":{';
open(my $t,'<',"$_/type");
my $type = <$t>;
chomp $type;
close $t;
$output .= '"Type":"' . $type . '"';
if ($name =~ /BAT[0-9]+/) {
$nobat = 0;
open(my $s,'<',"$_/status");
my $status = <$s>;
chomp $status;
$output .= ',"Status":"' . $status . '"';
} else {
open(my $s,'<',"$_/online");
my $status = <$s>;
chomp $status;
if ($status) {
$status = "Plugged-In";
} else {
open(my $s,'<',"$_/online");
my $status = <$s>;
chomp $status;
if ($status) {
$status = "Plugged-In";
} else {
$status = "Unplugged";
}
$output .= ',"Status":"' . $status . '"';
$status = "Unplugged";
}
close $s;
if ($name =~ /BAT[0-9]+/) {
open(my $m,'<',"$_/energy_full");
my $max = <$m>;
close $m;
chomp $max;
$battery_total{'max'} += $max;
open(my $c,'<',"$_/energy_now");
my $current = <$c>;
chomp $current;
#$current =~ s/\n//;
$battery_total{'current'} += $current;
close $c;
$output .= ',"Current":"'
. $current
. '","Max":"'
. $max
. '","Percentage":"'
. int($current/$max*100)
. '"';
}
$output .= "},";
$output .= ',"Status":"' . $status . '"';
}
close $s;
if ($name =~ /BAT[0-9]+/) {
open(my $m,'<',"$_/energy_full");
my $max = <$m>;
close $m;
chomp $max;
$battery_total{'max'} += $max;
open(my $c,'<',"$_/energy_now");
my $current = <$c>;
chomp $current;
#$current =~ s/\n//;
$battery_total{'current'} += $current;
close $c;
$output .= ',"Current":"'
. $current
. '","Max":"'
. $max
. '","Percentage":"'
. int($current/$max*100)
. '"';
}
$output .= "},";
}
unless ($nobat) {
print('{"AC":{"Type":"AC","Status":"Plugged-In"}}');
exit();
}
$battery_total{'percentage'} = sprintf("%0d",
$battery_total{'current'} / $battery_total{'max'} * 100
$battery_total{'current'} / $battery_total{'max'} * 100
);
$output .= '"Total":{"Current":"'
. $battery_total{'current'}
. '","Max":"'
. $battery_total{'max'}
. '","Percentage":"'
. $battery_total{'percentage'}
. '"}}';
. $battery_total{'current'}
. '","Max":"'
. $battery_total{'max'}
. '","Percentage":"'
. $battery_total{'percentage'}
. '"}}';
if ($bar) {
use JSON::XS;
my $json = JSON::XS->new();
my $powref = $json->decode($output);
my $class = 'discharging';
$output = '';
if ($powref->{AC}->{Status} eq "Plugged-In") {
$class = 'charging';
$output .= "";
} elsif ($powref->{Total}->{Percentage} <= 10) {
$class = 'critical';
$output .= "";
} elsif ($powref->{Total}->{Percentage} <= 35) {
$class = 'low';
$output .= "";
} elsif ($powref->{Total}->{Percentage} <= 60) {
$output .= "";
} elsif ($powref->{Total}->{Percentage} <= 85) {
$output .= "";
} else {
$output .= "";
}
$output = '{'
. '"text":"' . $output . '\u200a' . $powref->{Total}->{Percentage} . '%",'
. '"icon":"' . $output . '",'
. '"percentage":"' . $powref->{Total}->{Percentage} . '",'
. '"tooltip":"' . $class . '",'
. '"class":"' . $class . '"'
. '}';
use JSON::XS;
my $json = JSON::XS->new();
my $powref = $json->decode($output);
my $class = 'discharging';
$output = '';
if ($powref->{AC}->{Status} eq "Plugged-In") {
$class = 'charging';
$output .= "";
} elsif ($powref->{Total}->{Percentage} <= 10) {
$class = 'critical';
$output .= "";
} elsif ($powref->{Total}->{Percentage} <= 35) {
$class = 'low';
$output .= "";
} elsif ($powref->{Total}->{Percentage} <= 60) {
$output .= "";
} elsif ($powref->{Total}->{Percentage} <= 85) {
$output .= "";
} else {
$output .= "";
}
$output = '{'
. '"text":"' . $output . '\u200a' . $powref->{Total}->{Percentage} . '%",'
. '"icon":"' . $output . '",'
. '"percentage":"' . $powref->{Total}->{Percentage} . '",'
. '"tooltip":"' . $class . '",'
. '"class":"' . $class . '"'
. '}';
} elsif ($pretty) {
use JSON::XS;
my $json = JSON::XS->new();
my $powref = $json->decode($output);
my $total = '';
$output = "Device Status Percentage\n";
foreach my $device (keys %{$powref}) {
my $status;
if ($powref->{$device}->{Status} eq "Plugged-In") {
$status = "";
} elsif (!defined($powref->{$device}->{Percentage}) || $powref->{$device}->{Percentage} == 0) {
$status = " ";
} elsif ($powref->{$device}->{Percentage} <= 10) {
$status = " " . $powref->{$device}->{'Percentage'} . "%";
} elsif ($powref->{$device}->{Percentage} <= 35) {
$status = " " . $powref->{$device}->{'Percentage'} . "%";
} elsif ($powref->{$device}->{Percentage} <= 60) {
$status = " " . $powref->{$device}->{'Percentage'} . "%";
} elsif ($powref->{$device}->{Percentage} <= 85) {
$status = " " . $powref->{$device}->{'Percentage'} . "%";
} else {
$status = " " . $powref->{$device}->{'Percentage'} . "%";
}
if ($device eq 'Total') {
$total .= sprintf("%-24s %-12s", $device, $status);
} else {
#$output .= sprintf("%".length($powref->{$device->{'Type'}})."s (%".length($powref->{$device->{'Type'}})."s): %3d\%\n", $device, $device->{'Type'}, $device->{'Percentage'});
my $name = ' ('.$powref->{$device}->{'Type'}.')';
if ((length($device)+length($name)) >= 24) {
$name = substr($device, 0, (21-length($name))) . '...' . $name;
} else {
$name = substr(($device.$name), 0, 24);
}
$output .= sprintf("%-24s %-12s %-12s\n", $name, $powref->{$device}->{Status}, $status);
}
}
$output .= $total;
use JSON::XS;
my $json = JSON::XS->new();
my $powref = $json->decode($output);
my $total = '';
$output = "Device Status Percentage\n";
foreach my $device (keys %{$powref}) {
my $status;
if ($powref->{$device}->{Status} eq "Plugged-In") {
$status = "";
} elsif (!defined($powref->{$device}->{Percentage}) || $powref->{$device}->{Percentage} == 0) {
$status = " ";
} elsif ($powref->{$device}->{Percentage} <= 10) {
$status = " " . $powref->{$device}->{'Percentage'} . "%";
} elsif ($powref->{$device}->{Percentage} <= 35) {
$status = " " . $powref->{$device}->{'Percentage'} . "%";
} elsif ($powref->{$device}->{Percentage} <= 60) {
$status = " " . $powref->{$device}->{'Percentage'} . "%";
} elsif ($powref->{$device}->{Percentage} <= 85) {
$status = " " . $powref->{$device}->{'Percentage'} . "%";
} else {
$status = " " . $powref->{$device}->{'Percentage'} . "%";
}
if ($device eq 'Total') {
$total .= sprintf("%-24s %-12s", $device, $status);
} else {
#$output .= sprintf("%".length($powref->{$device->{'Type'}})."s (%".length($powref->{$device->{'Type'}})."s): %3d\%\n", $device, $device->{'Type'}, $device->{'Percentage'});
my $name = ' ('.$powref->{$device}->{'Type'}.')';
if ((length($device)+length($name)) >= 24) {
$name = substr($device, 0, (21-length($name))) . '...' . $name;
} else {
$name = substr(($device.$name), 0, 24);
}
$output .= sprintf("%-24s %-12s %-12s\n", $name, $powref->{$device}->{Status}, $status);
}
}
$output .= $total;
}
print $output . "\n";

View File

@ -3,8 +3,8 @@ Description=Give ownership of backlight to %I
[Service]
ExecStart=chown %i:%i \
/sys/class/backlight/intel_backlight/brightness \
/sys/class/leds/tpacpi::kbd_backlight/brightness
/sys/class/backlight/intel_backlight/brightness \
/sys/class/leds/tpacpi::kbd_backlight/brightness
[Install]
WantedBy=multi-user.target

View File

@ -12,51 +12,51 @@ my $working = "/tmp/firefox.new";
# Download link as provided by https://www.mozilla.org/$lang/firefox/developer/
my $url = 'https://download.mozilla.org/?product=firefox-devedition-latest-ssl'
. '&os=linux64&lang='.$lang;
. '&os=linux64&lang='.$lang;
# Ensure that we can unzip
unless (which("bunzip2")) {
die "Requires bunzip2. Try:\n"
. "sudo apt install zutils or your distro's equivalent\n";
die "Requires bunzip2. Try:\n"
. "sudo apt install zutils or your distro's equivalent\n";
}
# Only understood argument is to not bother verifying the package
my ($download_key, $verify) = (0,1);
if (defined $ARGV[0]) {
if ($ARGV[0] eq '--no-verify') {
$verify = 0;
} else {
die "Didn't understand argument $ARGV[0]\n";
}
if ($ARGV[0] eq '--no-verify') {
$verify = 0;
} else {
die "Didn't understand argument $ARGV[0]\n";
}
}
# If verification is to be done, make sure we have the key
unless ($verify) {
print "Checking for Mozilla GPG key in keyring...\n";
system("gpg --list-keys release\@mozillla.com 2>&1 > /dev/null");
if ($?) {
my $YN = prompt (-in => *STDIN, "You don't currently have "
. "Mozilla's GPG key in your keyring.\n"
. "Would you like to install it? If not, installation "
. "will not be verified. [y/N]: ",
-single
);
if ($YN eq 'y' || $YN eq 'Y') {
$download_key = 1;
} else {
$verify = 0;
}
print "Checking for Mozilla GPG key in keyring...\n";
system("gpg --list-keys release\@mozillla.com 2>&1 > /dev/null");
if ($?) {
my $YN = prompt (-in => *STDIN, "You don't currently have "
. "Mozilla's GPG key in your keyring.\n"
. "Would you like to install it? If not, installation "
. "will not be verified. [y/N]: ",
-single
);
if ($YN eq 'y' || $YN eq 'Y') {
$download_key = 1;
} else {
$verify = 0;
}
}
}
# If a previous download still exists remove it
if ( -e $working ) {
system("rm -rf $working");
if ($?) {
die "Working directory "
. $working
. "already exists and failed to remove: $!\n";
}
system("rm -rf $working");
if ($?) {
die "Working directory "
. $working
. "already exists and failed to remove: $!\n";
}
}
# Get version currently installed
@ -75,13 +75,13 @@ my ($location, $version);
# This redirect will have the version id, so we can use that to determine if a
# new version actually exists
if ($head->{'_msg'}) {
$version = $location = $head->{'_previous'}->{'_headers'}->{'location'};
$version =~ s/^.*\-([^\-]*)\.tar\.bz2$/$1/;
if ($version eq $current) {
die "Current ($current) is the same as New ($version)\n";
}
$version = $location = $head->{'_previous'}->{'_headers'}->{'location'};
$version =~ s/^.*\-([^\-]*)\.tar\.bz2$/$1/;
if ($version eq $current) {
die "Current ($current) is the same as New ($version)\n";
}
} else {
print "unable to find new download\n";
print "unable to find new download\n";
}
mkdir($working) || die "Couldn't make $working: $!\n";
@ -90,105 +90,105 @@ mkdir($working) || die "Couldn't make $working: $!\n";
print "Fetching package $location...\n";
$mech->get($location);
$mech->save_content( $working."/firefox-".$version.".tar.bz2",
binmode => ':raw',
decoded_by_headers => 1
binmode => ':raw',
decoded_by_headers => 1
);
# If verification is required, get signature as well
if ($verify) {
$location .= '.asc';
print "Fetching GPG signature $location...\n";
$mech->get($location);
$mech->save_content( $working."/firefox-".$version.".tar.bz2.asc",
binmode => ':raw',
decoded_by_headers => 1
);
$location .= '.asc';
print "Fetching GPG signature $location...\n";
$mech->get($location);
$mech->save_content( $working."/firefox-".$version.".tar.bz2.asc",
binmode => ':raw',
decoded_by_headers => 1
);
}
# If key still needs to be fetched, get it
if ($download_key) {
$location =~ s/linux-x86_64.*$/KEY/;
print "Fetching GPG key $location...\n";
$mech->get($location);
$mech->save_content( $working."/mozilla.pgp",
binmode => ':raw',
decoded_by_headers => 1
);
# And install it
print "Installing Mozilla GPG key in keyring...\n";
system("gpg --import $working/mozilla.pgp 2>&1 > /dev/null");
if ($?) {
die "Warning: failed to import key. Cannot verify integrity.\n"
. "Downloaded to "
. $working
. ". You can check and install it to "
. $install
. "manually: "
. $!
. "\n";
}
unlink("$working/mozilla.pgp");
$location =~ s/linux-x86_64.*$/KEY/;
print "Fetching GPG key $location...\n";
$mech->get($location);
$mech->save_content( $working."/mozilla.pgp",
binmode => ':raw',
decoded_by_headers => 1
);
# And install it
print "Installing Mozilla GPG key in keyring...\n";
system("gpg --import $working/mozilla.pgp 2>&1 > /dev/null");
if ($?) {
die "Warning: failed to import key. Cannot verify integrity.\n"
. "Downloaded to "
. $working
. ". You can check and install it to "
. $install
. "manually: "
. $!
. "\n";
}
unlink("$working/mozilla.pgp");
}
# Verify the package
if ($verify) {
print "Verifying download with Mozilla GPG key...\n";
system("gpg --verify $working/firefox-$version.tar.bz2.asc");
if ($?) {
die "Warning: failed to verify download. Signing failed.\n"
. "Downloaded to "
. $working
. ". You can check and install it to "
. $install
. " manually: "
. $!
. "\n";
}
print "Verifying download with Mozilla GPG key...\n";
system("gpg --verify $working/firefox-$version.tar.bz2.asc");
if ($?) {
die "Warning: failed to verify download. Signing failed.\n"
. "Downloaded to "
. $working
. ". You can check and install it to "
. $install
. " manually: "
. $!
. "\n";
}
}
# Uncompress
print "Uncompressing download with bunzip2...\n";
system("bunzip2 $working/firefox-$version.tar.bz2");
if ($?) {
die "Failed to uncompress: $!\n";
die "Failed to uncompress: $!\n";
}
# Extract
print "Extracting from TAR archive...\n";
system("tar -xf $working/firefox-$version.tar -C $working");
if ($?) {
die "Failed to extract: $!\n";
die "Failed to extract: $!\n";
}
# Bin the old backup
if (-e "$install/.firefox.old") {
print "Removing previous backup folder...\n";
system("rm -rf $install/.firefox.old");
if ($?) {
die "Failed to remove: $!\n";
}
print "Removing previous backup folder...\n";
system("rm -rf $install/.firefox.old");
if ($?) {
die "Failed to remove: $!\n";
}
}
# Move current to old
print "Backing up currently installed version ("
. $current
. ") to "
. $install
. "/.firefox.old...\n";
. $current
. ") to "
. $install
. "/.firefox.old...\n";
system("mv $install/firefox $install/.firefox.old");
if ($?) {
die "Failed to move: $!\n";
die "Failed to move: $!\n";
}
# Move new to current
print "Moving new version to $install for final installation...\n";
system("mv $working/firefox $install/");
if ($?) {
die "Failed to move: $!\n";
die "Failed to move: $!\n";
}
# Hurray!
print "Installation of version "
. $version
. " complete. You should restart firefox whenever it is convenient.\n";
. $version
. " complete. You should restart firefox whenever it is convenient.\n";
exit();

View File

@ -8,21 +8,21 @@ int main(int argc, char*argv[])
{
int pid;
if (argc <= 1) {
printf("No PID given\n");
return(1);
printf("No PID given\n");
return(1);
} else if (argc > 2) {
printf("Too many arguments\n");
return(1);
printf("Too many arguments\n");
return(1);
} else {
long val;
char *next;
val = strtol(argv[1], &next, 10);
if ((next == argv[1]) || (*next != '\0')) {
printf("Argument '%s' is not a number\n", argv[1]);
return(1);
} else {
pid = val;
}
long val;
char *next;
val = strtol(argv[1], &next, 10);
if ((next == argv[1]) || (*next != '\0')) {
printf("Argument '%s' is not a number\n", argv[1]);
return(1);
} else {
pid = val;
}
}
kill(pid, SIGUSR1);
return(0);

View File

@ -2,31 +2,31 @@
ARG=$1
if [[ $ARG == '' ]]; then
ARG="toggle"
ARG="toggle"
fi
if [[ $ARG == 'toggle' ]]; then
if [[ -e '/home/jpm/.config/waybar/.hidden' ]]; then
rm '/home/jpm/.config/waybar/.hidden';
else
touch '/home/jpm/.config/waybar/.hidden';
fi
if [[ -e '/home/jpm/.config/waybar/.hidden' ]]; then
rm '/home/jpm/.config/waybar/.hidden';
else
touch '/home/jpm/.config/waybar/.hidden';
fi
elif [[ $ARG == 'hide' ]]; then
if [[ ! -e '/home/jpm/.config/waybar/.hidden' ]]; then
touch '/home/jpm/.config/waybar/.hidden';
else
echo 'Already hidden. You may need to use the "invert" option if action is reversed';
exit;
fi
if [[ ! -e '/home/jpm/.config/waybar/.hidden' ]]; then
touch '/home/jpm/.config/waybar/.hidden';
else
echo 'Already hidden. You may need to use the "invert" option if action is reversed';
exit;
fi
elif [[ $ARG == 'show' ]]; then
if [[ -e '/home/jpm/.config/waybar/.hidden' ]]; then
rm '/home/jpm/.config/waybar/.hidden';
else
echo 'Already shown. You may need to use the "invert" option if action is reversed';
exit;
fi
if [[ -e '/home/jpm/.config/waybar/.hidden' ]]; then
rm '/home/jpm/.config/waybar/.hidden';
else
echo 'Already shown. You may need to use the "invert" option if action is reversed';
exit;
fi
elif [[ $ARG != 'invert' ]]; then
echo "Invalid argument";
echo "Invalid argument";
fi
/home/jpm/scripts/waybar/toggle `pgrep waybar`

View File

@ -3,7 +3,7 @@
RUNNING=$(pgrep pavucontrol)
if [ "$RUNNING" ]; then
kill $RUNNING 2&>1 /dev/null
kill $RUNNING 2&>1 /dev/null
else
/usr/bin/pavucontrol
/usr/bin/pavucontrol
fi

View File

@ -1,7 +1,7 @@
#!/bin/bash
if [ "$(pgrep -c htop)" -gt 0 ]; then
pkill htop
pkill htop
else
/usr/bin/uxterm -e htop
/usr/bin/uxterm -e htop
fi

View File

@ -1,36 +1,36 @@
#!/bin/bash
if [ "$1" == 'bar' ]; then
if [ ! -e ${HOME}/.spool/apt-upgradeable ]; then
sudo apt update >/dev/null 2>/dev/null
COUNT=`apt list --upgradable 2> /dev/null | wc -l`
let COUNT--
echo $COUNT > /home/jpm/.spool/apt-upgradeable
else
COUNT=`cat ${HOME}/.spool/apt-upgradeable`
fi
if [ $COUNT -eq 0 ]; then
echo '{"text": "🗹", "tooltip": "Up-to-date", "class": "up-to-date"}'
else
echo '{"text": "⭳'$COUNT'", "tooltip": "'$COUNT' updates available (click to download)", "class": "updateable"}'
fi
if [ ! -e ${HOME}/.spool/apt-upgradeable ]; then
sudo apt update >/dev/null 2>/dev/null
COUNT=`apt list --upgradable 2> /dev/null | wc -l`
let COUNT--
echo $COUNT > /home/jpm/.spool/apt-upgradeable
else
COUNT=`cat ${HOME}/.spool/apt-upgradeable`
fi
if [ $COUNT -eq 0 ]; then
echo '{"text": "🗹", "tooltip": "Up-to-date", "class": "up-to-date"}'
else
echo '{"text": "⭳'$COUNT'", "tooltip": "'$COUNT' updates available (click to download)", "class": "updateable"}'
fi
elif [ "$SUDO_USER" != '' ]; then
echo "Don't run with sudo. Run normally, but with a sudoer user"
echo "Don't run with sudo. Run normally, but with a sudoer user"
elif [ $UID -eq 0 ]; then
echo "Don't run as root. Run normally, but with a sudoer user"
echo "Don't run as root. Run normally, but with a sudoer user"
elif [ "$1" == 'upgrade' ]; then
/usr/bin/uxterm -e "sudo apt-get update && sudo apt-get full-upgrade -y && sudo apt-get autoremove -y && sudo apt-get clean -y && exit"
COUNT=`apt list --upgradable 2> /dev/null | wc -l`
let COUNT--
echo $COUNT > /home/jpm/.spool/apt-upgradeable
/usr/bin/uxterm -e "sudo apt-get update && sudo apt-get full-upgrade -y && sudo apt-get autoremove -y && sudo apt-get clean -y && exit"
COUNT=`apt list --upgradable 2> /dev/null | wc -l`
let COUNT--
echo $COUNT > /home/jpm/.spool/apt-upgradeable
if [ -e /var/run/reboot-required ]; then
grep -B1 -A4 upgrade /var/log/apt/history.log | tail -n 6 | swaynag --config=${HOME}/.dotfiles/sway/swaynag --edge=bottom --message="New packages require restart" --button="Restart Now" "sudo systemctl reboot" --dismiss-button="Later" --detailed-message --detailed-button "Show/Hide Upgrade Details"
grep -B1 -A4 upgrade /var/log/apt/history.log | tail -n 6 | swaynag --config=${HOME}/.dotfiles/sway/swaynag --edge=bottom --message="New packages require restart" --button="Restart Now" "sudo systemctl reboot" --dismiss-button="Later" --detailed-message --detailed-button "Show/Hide Upgrade Details"
fi
elif [ "$1" == 'update' ]; then
sudo apt update >/dev/null 2>/dev/null
COUNT=`apt list --upgradable 2> /dev/null | wc -l`
let COUNT--
echo $COUNT > /home/jpm/.spool/apt-upgradeable
sudo apt update >/dev/null 2>/dev/null
COUNT=`apt list --upgradable 2> /dev/null | wc -l`
let COUNT--
echo $COUNT > /home/jpm/.spool/apt-upgradeable
else
echo "Missing argument: update, upgrade, bar"
echo "Missing argument: update, upgrade, bar"
fi

View File

@ -1,7 +1,7 @@
#!/bin/bash
notify-send -t 0 Disks \
"$(lsblk -o NAME,SIZE,FSUSE%,MOUNTPOINT | grep -vP '^loop' | \
sed 's/MOUNTPOINT/MOUNT/' | sed -e 's/│ └─/+---/' | \
sed -e 's/ └─/+---/' | sed -e 's/├─/+-/' | sed -e 's/└─/+-/' | \
awk {'printf "%-20s %-7s %- 6s %-7s\n", $1, $2, $3, $4'})"
"$(lsblk -o NAME,SIZE,FSUSE%,MOUNTPOINT | grep -vP '^loop' | \
sed 's/MOUNTPOINT/MOUNT/' | sed -e 's/│ └─/+---/' | \
sed -e 's/ └─/+---/' | sed -e 's/├─/+-/' | sed -e 's/└─/+-/' | \
awk {'printf "%-20s %-7s %- 6s %-7s\n", $1, $2, $3, $4'})"

View File

@ -2,37 +2,37 @@
COUNT=0
function count() {
RESULTS="`rpm-ostree upgrade --check 2> /dev/null | grep Diff: | sed 's/.*\([0-9][0-9]*\).*/\1/'`"
COUNT=0
for i in $RESULTS; do
i=`echo $i | sed 's/;//'`
let COUNT=$COUNT+$i
done
RESULTS="`rpm-ostree upgrade --check 2> /dev/null | grep Diff: | sed 's/.*\([0-9][0-9]*\).*/\1/'`"
COUNT=0
for i in $RESULTS; do
i=`echo $i | sed 's/;//'`
let COUNT=$COUNT+$i
done
}
if [ "$1" == 'bar' ]; then
if [ ! -e ${HOME}/.spool/ostree-upgradeable ]; then
count
echo $COUNT > /home/jpm/.spool/ostree-upgradeable
else
COUNT=`cat ${HOME}/.spool/ostree-upgradeable`
fi
if [ $COUNT -eq 0 ]; then
echo '{"text": "🗹", "tooltip": "Up-to-date", "class": "up-to-date"}'
else
echo '{"text": "⭳'$COUNT'", "tooltip": "'$COUNT' updates available (click to download)", "class": "updateable"}'
fi
if [ ! -e ${HOME}/.spool/ostree-upgradeable ]; then
count
echo $COUNT > /home/jpm/.spool/ostree-upgradeable
else
COUNT=`cat ${HOME}/.spool/ostree-upgradeable`
fi
if [ $COUNT -eq 0 ]; then
echo '{"text": "🗹", "tooltip": "Up-to-date", "class": "up-to-date"}'
else
echo '{"text": "⭳'$COUNT'", "tooltip": "'$COUNT' updates available (click to download)", "class": "updateable"}'
fi
elif [ "$SUDO_USER" != '' ]; then
echo "Don't run with sudo. Run normally, but with a sudoer user"
echo "Don't run with sudo. Run normally, but with a sudoer user"
elif [ $UID -eq 0 ]; then
echo "Don't run as root. Run normally, but with a sudoer user"
echo "Don't run as root. Run normally, but with a sudoer user"
elif [ "$1" == 'upgrade' ]; then
/usr/bin/uxterm -e "rpm-ostree upgrade"
count
echo $COUNT > /home/jpm/.spool/ostree-upgradeable
/usr/bin/uxterm -e "rpm-ostree upgrade"
count
echo $COUNT > /home/jpm/.spool/ostree-upgradeable
elif [ "$1" == 'update' ]; then
count
echo $COUNT > /home/jpm/.spool/ostree-upgradeable
count
echo $COUNT > /home/jpm/.spool/ostree-upgradeable
else
echo "Missing argument: update, upgrade, bar"
echo "Missing argument: update, upgrade, bar"
fi

View File

@ -1,60 +1,66 @@
#!/bin/bash
PID=$(pgrep gammastep)
RUNNING=`cat $HOME/.spool/gammastep.status`
RUNNING=0
if [ -e $HOME/.spool/gammastep.status ]; then
RUNNING=`cat $HOME/.spool/gammastep.status`
fi
ACTION=$1
if [[ "$1" == '' ]]; then
ACTION='bar'
ACTION='bar'
fi
if [[ $ACTION == 'bar' ]]; then
:
:
elif [[ $ACTION == 'toggle' ]]; then
if [ "$PID" ]; then
kill -SIGUSR1 $PID
else
echo 'Gammastep is not running'
fi
if [ "$PID" ]; then
kill -SIGUSR1 $PID
else
echo 'Gammastep is not running'
fi
elif [[ $ACTION == 'start' ]]; then
if [ "$PID" ]; then
echo 'Gammastep is already running'
else
$HOME/scripts/sway/gammastep.pl
fi
if [ "$PID" ]; then
echo 'Gammastep is already running'
else
$HOME/scripts/sway/gammastep.pl
fi
elif [[ $ACTION == 'stop' ]]; then
if [ "$PID" ]; then
kill $PID
else
echo 'Gammastep is not running'
fi
if [ "$PID" ]; then
kill $PID
else
echo 'Gammastep is not running'
fi
elif [[ $ACTION == 'enable' ]]; then
if [ $PID ]; then
if [ $RUNNING ]; then
echo 'Already enabled'
else
kill -SIGUSR1 $PID
fi
if [ $PID ]; then
if [ $RUNNING ]; then
echo 'Already enabled'
else
echo 'Gammastep is not running'
kill -SIGUSR1 $PID
fi
else
echo 'Gammastep is not running'
fi
elif [[ $ACTION == 'disable' ]]; then
if [ $PID ]; then
if [ $RUNNING ]; then
kill -SIGUSR1 $PID
else
echo 'Already disabled'
fi
if [ $PID ]; then
if [ $RUNNING ]; then
kill -SIGUSR1 $PID
else
echo 'Gammastep in not running'
echo 'Already disabled'
fi
else
echo 'Gammastep in not running'
fi
else
echo "Invalid argument '$ACTION'. Use 'bar', 'toggle', 'start', 'stop', 'enable', 'disable'."
echo "Invalid argument '$ACTION'. Use 'bar', 'toggle', 'start', 'stop', 'enable', 'disable'."
fi
RUNNING=`cat $HOME/.spool/gammastep.status`
if [ "$RUNNING" ]; then
echo '{"text":"ɣ","icon":"ɣ","tooltip":"Disable Gammastep","class":"enabled"}'
else
echo '{"text":"ɣ","icon":"ɣ","tooltip":"Enable Gammastep","class":"disabled"}'
RUNNING=0
if [ -e $HOME/.spool/gammastep.status ]; then
RUNNING=`cat $HOME/.spool/gammastep.status`
fi
if [ "$RUNNING" ]; then
echo '{"text":"ɣ","icon":"ɣ","tooltip":"Disable Gammastep","class":"enabled"}'
else
echo '{"text":"ɣ","icon":"ɣ","tooltip":"Enable Gammastep","class":"disabled"}'
fi

View File

@ -2,23 +2,23 @@
FILE="$HOME/.spool/hibernate_inhibitor"
if [ -e $FILE ]; then
INHIBITED=1
INHIBITED=1
else
INHIBITED=0
INHIBITED=0
fi
if [ -z $1 ] || [[ "$1" == "bar" ]]; then
if [[ $INHIBITED == 1 ]]; then
echo '{"text":"☕","icon":"☕","tooltip":"Allow hibernation","class":"enabled"}'
else
echo '{"text":"💤","icon":"💤","tooltip":"Prevent hibernation","class":"disabled"}'
fi
if [[ $INHIBITED == 1 ]]; then
echo '{"text":"☕","icon":"☕","tooltip":"Allow hibernation","class":"enabled"}'
else
echo '{"text":"💤","icon":"💤","tooltip":"Prevent hibernation","class":"disabled"}'
fi
elif [[ "$1" == "toggle" ]]; then
if [[ $INHIBITED == "1" ]]; then
rm $FILE
else
touch $FILE
fi
if [[ $INHIBITED == "1" ]]; then
rm $FILE
else
touch $FILE
fi
else
echo "Invalid argumuent $1"
echo "Invalid argumuent $1"
fi

View File

@ -2,9 +2,9 @@
FILE=/home/jpm/.spool/onscreen-keyboard
if [ -f $FILE ]; then
rm $FILE
busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b false
rm $FILE
busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b false
else
touch $FILE
busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b true
touch $FILE
busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b true
fi

View File

@ -1,5 +1,5 @@
#!/bin/bash
notify-send -t 0 'Memory Usage' "`free -h | \
awk '{printf(\"%6s %6s %6s %6s\n\", $1, $2, $3, $4)}' | \
sed -r 's/(.*) shared$/ \1/'`"
awk '{printf(\"%6s %6s %6s %6s\n\", $1, $2, $3, $4)}' | \
sed -r 's/(.*) shared$/ \1/'`"

View File

@ -3,8 +3,8 @@
RUNNING=$(pgrep ncmpcpp)
if [ "$RUNNING" ]; then
kill $RUNNING 2&>1 /dev/null
kill $RUNNING 2&>1 /dev/null
else
echo "starting"
/usr/bin/xterm -e /usr/bin/ncmpcpp
echo "starting"
/usr/bin/xterm -e /usr/bin/ncmpcpp
fi

View File

@ -3,7 +3,7 @@
RUNNING=$(pgrep todotxt-machine)
if [ "$RUNNING" ]; then
kill $RUNNING 2&>1 /dev/null
kill $RUNNING 2&>1 /dev/null
else
/usr/bin/xterm -e "/home/jpm/.local/bin/todotxt-machine /home/jpm/nextcloud/phone/todo.txt"
/usr/bin/xterm -e "/home/jpm/.local/bin/todotxt-machine /home/jpm/nextcloud/phone/todo.txt"
fi

View File

@ -5,29 +5,29 @@ use warnings;
my $cmd = 'bar';
if (defined($ARGV[0])) {
$cmd = $ARGV[0];
$cmd = $ARGV[0];
}
my $url = "https://john.me.tz/weather/weather.json";
my %icons = (
'01d' => "☀",
'01n' => "☾",
'02d' => "☁",
'02n' => "☁",
'03d' => "☁",
'03n' => "☁",
'04d' => "☁",
'04n' => "☁",
'10d' => "🌧",
'10n' => "🌧",
'01d' => "☀",
'01n' => "☾",
'02d' => "☁",
'02n' => "☁",
'03d' => "☁",
'03n' => "☁",
'04d' => "☁",
'04n' => "☁",
'10d' => "🌧",
'10n' => "🌧",
);
use LWP::UserAgent;
my $ua = LWP::UserAgent->new();
my $ret = $ua->get($url);
unless (defined($ret->{_rc}) && $ret->{_rc} == 200) {
die "Failed to fetch $url";
die "Failed to fetch $url";
}
use JSON::XS;
@ -36,12 +36,12 @@ my $json = JSON::XS->new();
my $ref = $json->decode($ret->{_content});
if ($cmd eq 'bar') {
my $temp = $ref->{current}->{temp} - 273.15;
my $icon = $ref->{current}->{weather}->[0]->{icon};
my $temp = $ref->{current}->{temp} - 273.15;
my $icon = $ref->{current}->{weather}->[0]->{icon};
printf("<span font='Anonymous Pro 18'>%s</span>%.1f%s", $icons{$icon}, ${temp}, "°C");
printf("<span font='Anonymous Pro 18'>%s</span>%.1f%s", $icons{$icon}, ${temp}, "°C");
} elsif ($cmd eq 'notify') {
`notify-send weather TODO`;
`notify-send weather TODO`;
} else {
die "Invalid command\n";
die "Invalid command\n";
}

View File

@ -1,22 +1,14 @@
#!/bin/bash
swaymsg -t get_tree |
jq -r '.nodes[].nodes[] | if .nodes then [recurse(.nodes[])] else [] end + .floating_nodes | .[] | select(.nodes==[]) | if .app_id then ((.app_id | tostring) + " -- " + .name) else .name end' |
grep -v __i3_scratch |
sed -e 's/^.*\-\- \(.*\)$/\1/' |
sed -e 's/^\(.*\) [—-] .*$/\1/'|
sed -e 's/^\([0-9]*\)\t*\(.*\)/\2 \1/' |
<<<<<<< HEAD
wofi -s $HOME/.dotfiles/wofi/style.css -c \
$HOME/.dotfiles/wofi/sidebar -d | {
read -r
id=`echo $REPLY | rev | cut -d' ' -f1 | rev`
swaymsg "[con_id=$id]" focus
}
echo $id $REPLY
=======
wofi -I -s /home/jpm/.dotfiles/wofi/style.css -c \
$HOME/.dotfiles/wofi/sidebar --show dmenu | {
read -r id name
swaymsg "[con_id=$id]" focus
}
>>>>>>> master
jq -r '.nodes[].nodes[] | if .nodes then [recurse(.nodes[])] else [] end + .floating_nodes | .[] | select(.nodes==[]) | if .app_id then ((.app_id | tostring) + " -- " + .name) else .name end' |
grep -v __i3_scratch |
sed -e 's/^.*\-\- \(.*\)$/\1/' |
sed -e 's/^\(.*\) [—-] .*$/\1/'|
sed -e 's/^\([0-9]*\)\t*\(.*\)/\2 \1/' |
wofi -s $HOME/.dotfiles/wofi/style.css -c \
$HOME/.dotfiles/wofi/sidebar -d | {
read -r
id=`echo $REPLY | rev | cut -d' ' -f1 | rev`
swaymsg "[con_id=$id]" focus
}
echo $id $REPLY

View File

@ -4,7 +4,7 @@ WOFI=$(pgrep -xc wofi | cut -b 1)
echo $WOFI
if [[ "$WOFI" -eq "0" ]]; then
wofi -s /home/jpm/.dotfiles/wofi/style.css -c $HOME/.dotfiles/wofi/sidebar --show drun -I
wofi -s /home/jpm/.dotfiles/wofi/style.css -c $HOME/.dotfiles/wofi/sidebar --show drun -I
else
killall wofi 2&>1 /dev/null
killall wofi 2&>1 /dev/null
fi

View File

@ -10,11 +10,11 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
FIELDS=SSID,SECURITY
if [ -r "$DIR/config" ]; then
source "$DIR/config"
source "$DIR/config"
elif [ -r "$HOME/.dotfiles/wofi/wifi" ]; then
source "$HOME/.dotfiles/wofi/wifi"
source "$HOME/.dotfiles/wofi/wifi"
else
echo "WARNING: config file not found! Using default values."
echo "WARNING: config file not found! Using default values."
fi
LIST=$(nmcli --fields "$FIELDS" device wifi list | sed '/^--/d')
@ -26,13 +26,13 @@ CONSTATE=$(nmcli -fields WIFI g)
CURRSSID=$(LANGUAGE=C nmcli -t -f active,ssid dev wifi | awk -F: '$1 ~ /^yes/ {print $2}')
if [[ ! -z $CURRSSID ]]; then
HIGHLINE=$(echo "$(echo "$LIST" | awk -F "[ ]{2,}" '{print $1}' | grep -Fxn -m 1 "$CURRSSID" | awk -F ":" '{print $1}') + 1" | bc )
HIGHLINE=$(echo "$(echo "$LIST" | awk -F "[ ]{2,}" '{print $1}' | grep -Fxn -m 1 "$CURRSSID" | awk -F ":" '{print $1}') + 1" | bc )
fi
if [[ "$CONSTATE" =~ "enabled" ]]; then
TOGGLE="toggle off"
TOGGLE="toggle off"
elif [[ "$CONSTATE" =~ "disabled" ]]; then
TOGGLE="toggle on"
TOGGLE="toggle on"
fi
CHENTRY=$(echo -e "$TOGGLE\nmanual\n$LIST" | uniq -u | wofi -s $HOME/.dotfiles/wofi/style.css -i -d --prompt "Wi-Fi SSID: " -c $HOME/.dotfiles/wofi/sidebar)
@ -45,42 +45,42 @@ CHSSID=$(echo "$CHENTRY" | sed 's/\s\{2,\}/\|/g' | awk -F "|" '{print $1}')
# If the user inputs "manual" as their SSID in the start window, it will bring them to this screen
if [ "$CHENTRY" = "manual" ] ; then
# Manual entry of the SSID and password (if appplicable)
MSSID=$(echo "enter the SSID of the network (SSID,password)" | wofi -s $HOME/.dotfiles/wofi/style.css -d "Manual Entry: " -c $HOME/.dotfiles/wofi/sidebar)
# Separating the password from the entered string
MPASS=$(echo "$MSSID" | awk -F "," '{print $2}')
# Manual entry of the SSID and password (if appplicable)
MSSID=$(echo "enter the SSID of the network (SSID,password)" | wofi -s $HOME/.dotfiles/wofi/style.css -d "Manual Entry: " -c $HOME/.dotfiles/wofi/sidebar)
# Separating the password from the entered string
MPASS=$(echo "$MSSID" | awk -F "," '{print $2}')
#echo "$MSSID"
#echo "$MPASS"
#echo "$MSSID"
#echo "$MPASS"
# If the user entered a manual password, then use the password nmcli command
if [ "$MPASS" = "" ]; then
nmcli dev wifi con "$MSSID"
else
nmcli dev wifi con "$MSSID" password "$MPASS"
fi
# If the user entered a manual password, then use the password nmcli command
if [ "$MPASS" = "" ]; then
nmcli dev wifi con "$MSSID"
else
nmcli dev wifi con "$MSSID" password "$MPASS"
fi
elif [ "$CHENTRY" = "toggle on" ]; then
nmcli radio wifi on
nmcli radio wifi on
elif [ "$CHENTRY" = "toggle off" ]; then
nmcli radio wifi off
nmcli radio wifi off
else
# If the connection is already in use, then this will still be able to get the SSID
if [ "$CHSSID" = "*" ]; then
CHSSID=$(echo "$CHENTRY" | sed 's/\s\{2,\}/\|/g' | awk -F "|" '{print $3}')
fi
# If the connection is already in use, then this will still be able to get the SSID
if [ "$CHSSID" = "*" ]; then
CHSSID=$(echo "$CHENTRY" | sed 's/\s\{2,\}/\|/g' | awk -F "|" '{print $3}')
fi
# Parses the list of preconfigured connections to see if it already contains the chosen SSID. This speeds up the connection process
if [[ $(echo "$KNOWNCON" | grep "$CHSSID") = "$CHSSID" ]]; then
nmcli con up "$CHSSID"
else
if [[ "$CHENTRY" =~ "WPA2" ]] || [[ "$CHENTRY" =~ "WEP" ]]; then
WIFIPASS=$(echo "if connection is stored, hit enter" | wofi -s $HOME/.dotfiles/wofi/style.css -P -d --prompt "password" -c $HOME/.dotfiles/wofi/sidebar)
fi
nmcli dev wifi con "$CHSSID" password "$WIFIPASS"
fi
# Parses the list of preconfigured connections to see if it already contains the chosen SSID. This speeds up the connection process
if [[ $(echo "$KNOWNCON" | grep "$CHSSID") = "$CHSSID" ]]; then
nmcli con up "$CHSSID"
else
if [[ "$CHENTRY" =~ "WPA2" ]] || [[ "$CHENTRY" =~ "WEP" ]]; then
WIFIPASS=$(echo "if connection is stored, hit enter" | wofi -s $HOME/.dotfiles/wofi/style.css -P -d --prompt "password" -c $HOME/.dotfiles/wofi/sidebar)
fi
nmcli dev wifi con "$CHSSID" password "$WIFIPASS"
fi
fi