Skip to content

Instantly share code, notes, and snippets.

@2shortplanks
Created March 13, 2018 12:20
Show Gist options
  • Save 2shortplanks/bcfe86e3f191abb4b1e94234254be60d to your computer and use it in GitHub Desktop.
Save 2shortplanks/bcfe86e3f191abb4b1e94234254be60d to your computer and use it in GitHub Desktop.
A script to scrape the school website and send me the motd the day - which is contained in a squarespace JSON data structure!
#!/usr/bin/perl
use strict;
use warnings;
use File::Spec::Functions qw(catfile);
use File::Basename qw(dirname);
use HTML::Strip ();
use JSON::PP qw(decode_json);
use LWP::UserAgent ();
sub read_file {
my $file = shift;
my $filename = catfile(dirname(__FILE__), $file);
open my $fh, '<:utf8', $filename
or die "Can't open '$filename': $!";
local $/;
return scalar <$fh>;
}
sub write_file {
my $file = shift;
my $filename = catfile(dirname(__FILE__), $file);
open my $fh, '>:utf8', $filename
or die "Can't open '$filename': $!";
print $fh @_;
}
sub send_message {
my $ua = LWP::UserAgent->new();
my $response = $ua->post(
'http://api.pushover.net/1/messages.json',
{
token => 'XXXX',
user => 'XXXX',
@_,
}
);
my $content = $response->decoded_content();
my $ds = decode_json($content);
die "$content" if $ds->{status} != 1;
}
sub strip_html {
my $string = shift;
my $hs = HTML::Strip->new();
return $hs->parse( $string );
}
my $src = read_file('menu.html');
# extract the JSON with a regex!
$src =~ qr!
(?(DEFINE)
(?<JSONWHITESPACE>
[\x20\x09\x0A\x0D]*
)
(?<OBJECT>
\{ (?&JSONWHITESPACE)
(?:
(?&KV)
(?: (?&JSONWHITESPACE) , (?&JSONWHITESPACE) (?&KV) )*
)?
(?&JSONWHITESPACE) \}
)
(?<KV>
(?&STRING) (?&JSONWHITESPACE) : (?&JSONWHITESPACE) (?&VALUE)
)
(?<ARRAY>
\[ (?&JSONWHITESPACE)
(?:
(?&VALUE)
(?: (?&JSONWHITESPACE) , (?&JSONWHITESPACE) (?&VALUE) )*
)?
(?&JSONWHITESPACE) \]
)
(?<STRING>
"
(?:
# Any UNICODE character except " or \ or control character
[^\\"\x00-\x1f]+
|
\\ ["\\/bfnrt]
|
\\ u [0-9A-Fa-f]{4}
)*
"
)
(?<NUMBER>
-?
(?: 0 | [1-9][0-9]* )
(?: \. [0-9]+ )?
(?: [eE] [-+]? [0-9]+ )?
)
(?<VALUE>
(
(?&STRING)
|
(?&NUMBER)
|
(?&OBJECT)
|
(?&ARRAY)
|
true
|
false
|
null
)
)
)
(?<=Static[.]SQUARESPACE_CONTEXT [ ] = [ ]) ((?&OBJECT))
!xms or exit;
# get the part of the json we care about
my $data = decode_json($&);
my $annoucement = $data->{websiteSettings}{announcementBarSettings}{text} // "";
# don't do anything if nothing has changed
my $prev = read_file('alert.html');
exit if $annoucement eq $prev;
# send the notification
if (length ($annoucement)) {
send_message(
message => strip_html($annoucement),
sound => 'updown',
);
}
# update the file on disk
write_file('alert.html', $annoucement);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment