#!/usr/bin/perl ## # Fetch images for screensaver from the chromecast page. # # The images used by the Chromecast screensaver are embedded in a # webpage. They could be changed by Google at any time, and - of course # provide a way for Google to track how many users of the device there # are. And maybe which individual devices, if it were to supply more # unique identification in the headers. # # Regardless, they're just embedded in a JSON encoded string, which we # can easily extract and store in a directory. # my $url = "https://clients3.google.com/cast/chromecast/home/v/c9541b08"; my $storedir = "pictures"; use LWP::Simple; use JSON; use Data::Dumper; # Fetch page my $page = get($url); # Extract the JSON content my ($json) = ($page =~ /JSON.parse\('(.*?)'\)/); # Remove the escaped strings $json =~ s/\\x([a-f0-9]{2})/sprintf "%c", hex($1)/eg; $json =~ s/\\n/\n/g; my $data = decode_json($json); # The structure is pretty simple, although I'm not sure what all the # values are: # all array of everything # [0] array of pictures items # ... array of details about the picture # [0] URL of the picture # [1] Author's name # [2] undef # [3] undef # [4] 120 (I'd guess this is the time to show for?) # [5] undef # [6] undef # [7] undef # [8] undef # [9] undef # [10] undef # [11] undef # [12] "Photo by " + author's name (no i18n?) # [13] undef # [1] array of application id? # [0] uuid # [1] big number ('1408149221009' at the present time) # [2] undef # [3] array of... # [0] the number 1 # [4] 120 (default display time?) mkdir $storedir, 0755; # Extract each of these pictures, in a sorted order by URL, so that we # get an unchanging list (hopefully). my $n = 0; for my $picture (sort { $a->[0] cmp $b->[0] } @{ $data->[0] }) { print "URL: $picture->[0]\n"; print " by: $picture->[1]\n"; print "\n"; # Fetch the picture my $picture = get($picture->[0]); if (!defined $picture) { die "Could not fetch picture from $picture\n"; } # Where we'll write the file my $filename = sprintf "pictures/%03d-%s", $n++, $picture->[1]; # Find the filetype and store the picture based on it. # There are better ways of doing this, but I just put this # together to catch simple cases. Consider using LWP direct, # and getting the media type of the resource, rather than # sniffing the file data. my $ext = undef; if ($picture =~ /^\x89\x50\x4e\x47/) { $ext = 'png'; } elsif ($picture =~ /^\xff\xd8/) { $ext = 'jpg'; } elsif ($picture =~ /^GIF8[79]a/) { $ext = 'gif'; } # Write out the file $filename .= ".$ext"; open(my $fh, ">", $filename) || die "Could not write $filename\n"; print $fh $picture; close($fh); }