about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndinus <andinus@nand.sh>2020-06-17 17:00:55 +0530
committerAndinus <andinus@nand.sh>2020-06-17 17:00:55 +0530
commit335c080d974462c3795c5da0292157d7d4a72188 (patch)
tree71ef05dc4421d8d4fd6f28b79fe5d43aec74b15d
parent430e6c16eb07531df436a42e34a667477c3e469a (diff)
downloadcrux-335c080d974462c3795c5da0292157d7d4a72188.tar.gz
Add crux.pl, Initial commit
-rwxr-xr-xcrux.pl132
1 files changed, 132 insertions, 0 deletions
diff --git a/crux.pl b/crux.pl
new file mode 100755
index 0000000..a769860
--- /dev/null
+++ b/crux.pl
@@ -0,0 +1,132 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use feature 'say';
+
+use lib::relative 'lib';
+use UnsplashSource;
+
+use IPC::Run3;
+use Getopt::Long qw( GetOptions );
+use Term::ANSIColor qw( :pushpop colored );
+
+local $SIG{__WARN__} = sub { print colored( $_[0], 'yellow' ); };
+
+my %options = ( resolution => '1920x1080' );
+
+use constant is_OpenBSD => $^O eq "openbsd";
+require OpenBSD::Unveil
+    if is_OpenBSD;
+sub unveil {
+    if (is_OpenBSD) {
+        if ( $options{debug} ) {
+            # Check if defined because unveil can also be called blank
+            # to block it.
+            if ( defined($_[0]) and defined($_[1]) ) {
+                say "Unveil :: $_[0] :: $_[1]";
+            } else {
+                say "Unveil :: Block";
+            }
+        }
+        return OpenBSD::Unveil::unveil(@_);
+    } else {
+        warn "Calling dummy unveil...\n" if $options{debug};
+        return 1;
+    }
+}
+
+# Unveil @INC.
+foreach my $path (@INC) {
+    unveil( $path, 'rx' )
+        or die "Unable to unveil: $!\n";
+}
+
+GetOptions(
+    "resolution=s" => \$options{resolution},
+
+    "search=s{1,}" => \@{$options{search}},
+    "featured" => \$options{featured},
+
+    "user=s" => \$options{user},
+    "userlikes|user-likes" => \$options{user_likes},
+
+    "collection=s" => \$options{collection_id},
+
+    "daily" => \$options{daily},
+    "weekly" => \$options{weekly},
+
+    "debug" => \$options{debug},
+    "help|h|?" => sub { HelpMessage() },
+) or die "Error in command line arguments\n";
+
+
+sub HelpMessage {
+    print LOCALCOLOR GREEN "Crux:
+    --help         Print this help message
+    --debug        Print debugging information
+
+Unsplash:
+    --resolution   Device resolution (default: 1920x1080)
+
+    --search=s     Search term (space seperated)
+    --featured     Unsplash curated photos
+
+    --user=s       Photos by user
+    --userlikes    Photos by user from user's likes
+
+    --collection=s Photos from collection
+
+    --daily        Daily photo
+    --weekly       Weekly photo
+";
+    print LOCALCOLOR CYAN "
+Additional information:
+    Options above are seperated by groups, no groups can be mixed. If
+    you pass options from multiple groups then expect unexpected
+    results.
+
+    - user & search option can be passed with daily or weekly.
+    - resolution can be passed with any group, it will be ignored if
+      not applicable.
+";
+    exit;
+}
+
+# %unveil contains list of paths to unveil with their permissions.
+my %unveil = (
+    "/usr" => "rx",
+    "/var" => "rx",
+    "/etc" => "rx",
+    "/dev" => "rx",
+);
+
+# Unveil each path from %unveil. We use sort because otherwise keys is
+# random order everytime.
+foreach my $path ( sort keys %unveil ) {
+    unveil( $path, $unveil{$path} )
+        or die "Unable to unveil: $!\n";
+}
+
+# Unveil $PATH.
+foreach my $path ( split(/:/, $ENV{PATH}) ) {
+    unveil( $path, "rx" )
+        or die "Unable to unveil: $!\n";
+}
+
+my $response = UnsplashSource::get( %options );
+
+if ( $options{debug} ) {
+    require Data::Printer;
+    Data::Printer->import;
+    p($response);
+}
+
+die "Unexpected response\n"
+    unless $response->{status} == 302;
+
+run3 ["feh", "--bg-fill", "$response->{headers}{location}"];
+
+# Block further unveil calls.
+unveil()
+    or die "Unable to lock unveil: $!\n";