#!/usr/bin/env perl use 5.010; use strict; use warnings; use Data::Dump 'pp'; use JSON; if (@ARGV) { require Time::Piece; require LWP::UserAgent; require File::stat; my $target = 'browser-support.inc.pl'; my $source = 'http://caniuse.com/data.json'; my $ua = LWP::UserAgent->new; $ua->agent('sheet.shiar.nl/browser'); $ua->default_header('If-Modified-Since' => scalar gmtime $_->mtime) for File::stat::stat($target); my $res = $ua->get($source) or die "No data from $source\n"; !$res->is_error or die $res->status_line; say $res->status_line; exit 0 if $res->code == 304; # unmodified my $data = decode_json($res->decoded_content) or die "Parse error: $!"; my $updated = eval { s/ GMT$//, return Time::Piece->strptime($_) for $res->header('Last-Modified') }; $data->{-date} = $_->datetime for $updated || (); my $suffix = $updated && $updated->ymd || time; open my $save, '>', (my $download = "browser-support-$suffix.inc.pl"); print {$save} pp($data); close $save; symlink $download, "$target.new" and rename "$target.new", $target or die "New data at $download not linked: $!"; exit 0; } local $/; # slurp my $source = readline; for ($source) { # cleanup s/\A\(// and s/\);?\s*\Z//; # empty callback next if /^\{/; # valid json # convert seperate variables to hash keys s/\A/{\n/; s/^caniuse\.(\w+) *= */"$1":/gm; s/;$/,/gm; s/,\s*\Z/\n}/; # fractions not supported by barekey s/(?<=[,{\n]) (\d*\.\d) (?=:['"])/"$1"/gx; # escapes not supported in singlequote s{: *\K'((?:[^\\']+|\\.)*)'}{ my $_ = $1; s/"/\\"/g; s/\\'/'/g; qq("$_"); }ge; } my $data = from_json($source, { allow_singlequote => 1, allow_barekey => 1, }); print pp($data); __END__ =head1 NAME mkcaniuse - Turn Javascript data into an equivalent Perl structure =head1 SYNOPSIS curl http://caniuse.com/data.json | tools/mkcaniuse.pl > browser-support.inc.pl tools/mkcaniuse.pl auto