-- Leo's gemini proxy

-- Connecting to gemini.splashgel.net:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini


Getting the Bing wallpaper of the day with perl


Introduction

As detestable as Microsoft and its founder are, the Bing homepage has some lovely pictures on it. On Windows you can install the Bing

toolbar, which gives you the capability to use these as a daily desktop image. But is there a way to do this without using the toolbar?


Source data

As it turns out, the information about the daily wallpaper is available at a given URL:


https://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1&mkt=en-US

This gives you an XML file with information about the wallpaper, for example:


<?xml version="1.0" encoding="utf-8"?>
<images>
  <image>
    <startdate>20230821</startdate>
    <fullstartdate>202308210000</fullstartdate>
    <enddate>20230822</enddate>
    <url>/th?id=OHR.EmeraldLakeYukon_EN-US0522450551_1920x1080.jpg&amp;rf=LaDigue_1920x1080.jpg&amp;pid=hp</url>
    <urlBase>/th?id=OHR.EmeraldLakeYukon_EN-US0522450551</urlBase>
    <copyright>Emerald Lake, South Klondike Highway, Yukon, Canada (© artherng/Getty Images)</copyright>
    <copyrightlink>https://www.bing.com/search?q=yukon+canada&amp;form=hpcapt&amp;filters=HpDate%3a%2220230821_0700%22</copyrightlink>
    <headline>A day for discovery</headline>
    <drk>1</drk>
    <top>1</top>
    <bot>1</bot>
    <hotspots/>
  </image>
</images>

It should be fairly obvious what this means; the image is available at the 'url', which is a relative to the Bing homepage, and it is described in the contents of the 'copyright' tag.


Of course you could download this file and copy and paste the URL, download the image and set it as your wallpaper each time. Or you could automate the process.


Processing the XML file

First we need to download the XML file. The perl module Mojo::UserAgent is very handy for such tasks, and integrates with Mojo::DOM so that we can immediately access the parsed XML. We save the Bing URL as a 'constant'.


use v5.38; # this brings in 'say', turns on warnings etc.

use Mojo::UserAgent;
use constant {
  BING_URL => 'https://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1&mkt=en-US',
};

my $ua = Mojo::UserAgent->new;

Now with the user agent at our disposal we can get a DOM (document object model, a way of accessing the structure of the XML programmatically) straight away. It is then very easy to extract the contents of the tags that are of interest.


my $dom = $ua->get(BING_URL)->result->dom;
my $url = 'https://www.bing.com/' . $dom->at('url')->text;
my $info =$dom->at('copyright')->text;

Downloading the wallpaper

So with four lines (plus the preamble) we have the URL of our image and the information about it. Now to download the image, the simplest thing is to create a temporary file for it. File::Temp is the module of choice in this case. This snippet downloads the full image file to a temporary file which will be deleted when the program exits.


use File::Temp qw(tempfile);

my ($fh, $filename) = tempfile(UNLINK => 1);

print $fh $ua->get($url)->result->body;
close($fh);

Setting the background

Finally we call feh to set the background and print the image description:


system("feh --bg-scale '$filename'");

say "Wallpaper set: $info";

Full Script

Here is the full script. It has some enhancements, namely that it uses the User-Agent from Edge for stealth purposes. It also removes any boring copyright string when printing the image information.


use v5.38;

use utf8;
use open qw(:std :utf8);

use Mojo::UserAgent;
use File::Temp qw(tempfile);
use constant {
  BING_URL => 'https://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1&mkt=en-US',
  EDGE_UA  => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36 Edg/102.0.1245.33',
};

my ($fh, $filename) = tempfile(UNLINK => 1);

my $ua = Mojo::UserAgent->new;
$ua->transactor->name(EDGE_UA);

my $dom = $ua->get(BING_URL)->result->dom;
my $url = 'https://www.bing.com/' . $dom->at('url')->text;
my $info =$dom->at('copyright')->text;
# many image descriptions end with a copyright message which is uninteresting
$info =~ s/\(©.*$//;

print $fh $ua->get($url)->result->body;
close($fh);

system("feh --bg-scale '$filename'");

say "Wallpaper set: $info";

Links

Mojo::UserAgent

-- Response ended

-- Page fetched on Sun May 19 01:16:05 2024