/earth-view

Set background wallpaper to a random image from Google Earth View.

Primary LanguageGo

🌎 earth-view

Go NixOS Home Manager FlakeHub

Randomly set desktop background from 2600+ images sourced from Google Earth View.

Currently supporting:

  • X desktops
  • GNOME on Wayland or X11
  • KDE on Wayland or X11

Wayland compositors support will come soon.

Disclaimer: this project is not affiliated with Google in any way. Images are protected by copyright and are licensed only for use as wallpapers.

📥 Installation

❄️ NixOS

Flakes (recommended)

{
  # Use unstable to get latest updates
  inputs.earth-view.url = "github:nicolas-goudry/earth-view";

  # Pin to a given version
  #inputs.earth-view.url = "github:nicolas-goudry/earth-view/v1.4.1";

  # Use FlakeHub
  #inputs.earth-view.url = "https://flakehub.com/f/nicolas-goudry/earth-view/*.tar.gz";

  # You may optionally follow your nixpkgs input
  #inputs.earth-view.inputs.nixpkgs.follows = "nixpkgs";

  outputs = { self, nixpkgs, earth-view }: {
    nixosConfigurations.yourhostname = nixpkgs.lib.nixosSystem {
      # Customize to your system
      system = "x86_64-linux";
      modules = [
        ./configuration.nix
        earth-view.nixosModules.earth-view
      ];
    };
  };
}

fetchTarball

{ lib, ... }:

{
  imports = let
    # Replace this with an actual commit or tag
    rev = "<replace>";
  in [
    "${builtins.fetchTarball {
      url = "https://github.com/nicolas-goudry/earth-view/archive/${rev}.tar.gz";
      # Replace this with an actual hash
      sha256 = lib.fakeHash;
    }}/modules/nixos"
  ];
}

🏠 Home Manager

Flakes: NixOS system-wide home-manager configuration

{
  # Use unstable to get latest updates
  inputs.earth-view.url = "github:nicolas-goudry/earth-view";

  # Pin to a given version
  #inputs.earth-view.url = "github:nicolas-goudry/earth-view/v1.4.1";

  # Use FlakeHub
  #inputs.earth-view.url = "https://flakehub.com/f/nicolas-goudry/earth-view/*.tar.gz";

  # You may optionally follow your nixpkgs input
  #inputs.earth-view.inputs.nixpkgs.follows = "nixpkgs";

  outputs = { self, nixpkgs, home-manager, earth-view }: {
    nixosConfigurations.yourhostname = nixpkgs.lib.nixosSystem {
      # Customize to your system
      system = "x86_64-linux";
      modules = [
        ./configuration.nix
        home-manager.nixosModules.home-manager {
          home-manager.sharedModules = [
            inputs.earth-view.homeManagerModules.earth-view
          ];
        }
      ];
    };
  };
}

Flakes: Configuration via home.nix

{ inputs, ... }:

{
  imports = [
    inputs.earth-view.homeManagerModules.earth-view
  ];
}

fetchTarball: Configuration via home.nix

{ lib, ... }:

{
  imports = let
    # Replace this with an actual commit or tag
    rev = "<replace>";
  in [
    "${builtins.fetchTarball {
      url = "https://github.com/nicolas-goudry/earth-view/archive/${rev}.tar.gz";
      # Replace this with an actual hash
      sha256 = lib.fakeHash;
    }}/modules/home-manager"
  ];
}

🧑‍💻 Usage

{
  # Default values
  services.earth-view = {
    enable = false;
    interval = null;
    imageDirectory = ".earth-view";
    display = "fill";
    enableXinerama = true;
    autoStart = false;
    gc = {
      enable = false;
      keep = 10;
      interval = null;
      sizeThreshold = "0";
    };
  };
}

Tip

If autoStart is set to false, the service will only be started on the next login. To set the background after installation you have to manually start the main service:

systemctl --user start earth-view

This command can also be used to manually switch the background.

Same goes for the timer, if autoStart is set to false, it will only be started on the next login. To launch the timer after installation you have to manually start it:

systemctl --user start earth-view.timer

enable

Whether to enable Earth View service.

Note, if you are using NixOS and have set up a custom desktop manager session for Home Manager, then the session configuration must have the bgSupport option set to true or the background image set by this module may be overwritten.

interval

The duration between changing background image. Set to null to only set background when logging in. Should be formatted as a duration understood by systemd.

imageDirectory

The directory to which background images should be downloaded, relative to $HOME.

display

Display background images according to this option. See feh documentation for details.

Note

This option has no effect neither on GNOME nor KDE.

enableXinerama

Will place a separate image per screen when enabled, otherwise a single image will be stretched across all screens.

Note

This option has no effect neither on GNOME nor KDE.

autoStart

Whether to start the service automatically, along with its timer when interval is set.

Note

This feature relies on activation scripts from NixOS (system.userActivationScripts) and Home Manager (home.activation).

If you are using Home Manager, you may want to use systemd.user.startServices instead.

gc.enable

Whether to enable automatic garbage collection.

gc.keep

The number of images to keep from being garbage collected. Only the most recent images will be kept. The current background will never be deleted.

gc.interval

The duration between garbage collection runs. Set to null to run garbage collection along with the main service. Should be formatted as a duration understood by systemd.

gc.sizeThreshold

Garbage collect images only if collection size exceeds this threshold. Should be formatted as a string understood by du's size option.

Examples:

  • "10M" or "10MiB": deletes images when collection exceeds 10MiB (power of 1024)
  • "1GB": deletes images when collection exceeds 1GB (power of 1000)

🧐 How it works

Source of truth

All discovered images URLs from Earth View are saved in earth-view.json, which is the source of truth of this Nix module.

To create this file, we use a custom CLI application written in Go which provides commands to list and download images from Google Earth View. In particular, we use the list command which scrapes the Earth View static assets in order to find valid identifiers for images. If you want to use the CLI locally:

# Use go (go must be available in your path! Hint: nix shell 'nixpkgs#go_1_22')
cd src
go run .

# Use a devshell
nix develop # ...or nix-shell
earth-view

# Run via nix
nix run '.#earth-view'

# Build it
nix build '.#earth-view' # ...or nix-build -A earth-view
./result/bin/earth-view

Image selection

To select an image, the fetch random command is used to select a random image identifier from the source of truth, download it and save it to the imageDirectory directory.

systemd

Both modules use a systemd user-managed unit, along with a timer when interval is specified.

The service executes a Bash script which uses the Go module described in the previous section to fetch the image and then set the desktop background accordingly. Read further for more details.

Some background

Setting the background depends on the desktop manager in use. We detect the current desktop environment with the XDG_CURRENT_DESKTOP environment variable and set the background with the right program:

  • GNOME on Wayland or X11: gsettings
  • KDE on Wayland or X11: plasma-apply-wallpaperimage
  • X: feh

Why not only use feh, would you ask? Well, as of today it does not support setting the GNOME background image. And it may not ever support it. It seems that it also does not work with KDE. And obviously it does not work with Wayland compositors.

🎩 Acknowledgments

This module is heavily based on the random-background service of home-manager, by rycee.

The idea to create this module was triggered by the Google Earth Wallpaper Gnome extension, which is not anymore compatible with Gnome 45 or Gnome 46.

Last but not least, this would not be possible without the great Google Earth View website (if it is down, use the Wayback Machine to browse it) and the Chrome extension.

📝 TODO

  • 🏗 Setup Github Actions to update the image URLs source file
  • ✨ Add support for all Wayland compositors with swaybg
  • 📡 Make sure network is up to avoid image download failure