aocinit (4527B) - raw
1 #!/usr/bin/env perl 2 3 # 4 # Make sure you place this file somewhere in your $PATH 5 # 6 7 use strict; 8 use warnings; 9 use autodie; 10 use v5.32; 11 use Term::ANSIColor; 12 use Scalar::Util qw(looks_like_number); 13 use File::HomeDir; 14 use File::Spec::Functions; 15 use Mojo::UserAgent; 16 17 my $AOC_FIRST_YEAR = 15; # first event was in 2015 18 my $HOME = File::HomeDir->my_home; 19 my $DOMAIN = 'adventofcode.com'; 20 21 # 22 # User-defined constants: 23 ############################################################################## 24 my $PATH_FROM_HOME = "programs"; 25 my $DIR_PREFIX = "aoc20"; 26 # store your browser cookie session ID in the environment variable 27 # `$SESSIONID`: 28 # $ export SESSIONID="8374....907d" 29 ############################################################################## 30 # 31 32 sub invalid_arguments { 33 die "Usage (with two-digit year and two-digit day): $0 ", 34 colored( '[year]', 'underline'), ' ', 35 colored( '[day]', 'underline'); 36 } 37 38 sub process_arguments { 39 my @arguments = @{ shift() }; 40 invalid_arguments if ( scalar @arguments != 2 ); 41 my ( $year, $day ) = @arguments; 42 invalid_arguments unless ( looks_like_number( $year ) && 43 looks_like_number( $day ) ); 44 invalid_arguments if ( $year < $AOC_FIRST_YEAR or 45 $year > (localtime)[5] % 100 ); 46 invalid_arguments if ( $day < 1 or $day > 24 ); 47 $day = '0' . $day if ( $day =~ m/^\d$/ ); 48 return ( $year, $day ); 49 } 50 51 sub create_year_directory { 52 my $year_directory = shift; 53 if ( -e $year_directory ) { 54 say "$year_directory already exists"; 55 } else { 56 say "creating $year_directory..."; 57 mkdir $year_directory, 0755 or 58 die "Cannot create directory $year_directory: $!"; 59 } 60 } 61 62 sub create_day_subdirectory { 63 my $day_subdir = shift; 64 if ( -e -d $day_subdir ) { 65 say "$day_subdir already exists."; 66 } else { 67 say "creating $day_subdir..."; 68 mkdir $day_subdir, 0755 or 69 die "Cannot create directory $day_subdir: $!"; 70 } 71 } 72 73 sub read_boilerplate { 74 my ( $year, $day ) = @_; 75 ( my $boilerplate = qq[ 76 #!/usr/local/bin/perl 77 # day 20$year-$day 78 79 use strict; 80 use warnings; 81 use v5.32; 82 83 \@ARGV = "input" unless \@ARGV; 84 chomp( my \$input = do { local \$/; <> } ); 85 ] ) =~ s/^ {8}//mg; # remove leading 8 spaces 86 $boilerplate =~ s/\A\n//; # remove leading line break 87 return $boilerplate; 88 } 89 90 sub create_boilerplate_file { 91 my ( $day_file, $boilerplate ) = @_; 92 say "creating boilerplate file..."; 93 if ( -e $day_file ) { 94 # don't overwrite existing file 95 warn "solution file for this day already exists"; 96 return; 97 } 98 open my $bp_file, '>', $day_file; 99 say $bp_file $boilerplate; 100 close $bp_file; 101 chmod 0755, $day_file; 102 } 103 104 sub download_input { 105 my ( $year, $day, $day_subdir ) = @_; 106 $day =~ s/^0//; # remove leading 0 107 my $ua = Mojo::UserAgent->new; 108 my $url = "https://$DOMAIN/20$year/day/$day/input"; 109 $ua->cookie_jar->add( 110 Mojo::Cookie::Response->new( 111 name => 'session', 112 value => $ENV{SESSIONID}, 113 domain => $DOMAIN, 114 path => '/' 115 ) 116 ); 117 118 say "downloading input file..."; 119 my $res = $ua->get( $url )->result; 120 if ($res->is_success) { 121 my $filename = catfile( $day_subdir, 'input' ); 122 if ( -e $filename ) { 123 # don't overwrite existing file 124 die "input file for this day already exists."; 125 } 126 open my $input_fh, '>', $filename; 127 say $input_fh $res->body; 128 close $input_fh; 129 } 130 elsif ($res->is_error) { 131 say "unable to dowload input file.\n", $res->message; 132 } 133 elsif ($res->code == 301) { 134 say "input file not found.\n", $res->headers->location; 135 } 136 else { 137 say 'unexpected error encountered while downloading input file.'; 138 } 139 } 140 141 my ( $year, $day ) = process_arguments( \@ARGV ); 142 my $year_directory = "$HOME/$PATH_FROM_HOME/$DIR_PREFIX$year"; 143 my $day_subdir = catfile( $year_directory, "day" . $day ); 144 my $day_file = catfile( $day_subdir, "day". $day . ".pl" ); 145 my $boilerplate = read_boilerplate( $year, $day ); 146 147 create_year_directory ( $year_directory ); 148 create_day_subdirectory( $day_subdir ); 149 create_boilerplate_file( $day_file, $boilerplate ); 150 download_input ( $year, $day, $day_subdir );