From 46a55aff7cd87de54393343e3ec08456e9329fcf Mon Sep 17 00:00:00 2001 From: Matthieu Jolimaitre Date: Tue, 10 Sep 2024 23:40:21 +0200 Subject: [PATCH] init --- .gitignore | 1 + README.md | 22 ++++++++++ deno.json | 7 ++++ deno.lock | 16 ++++++++ update.ts | 87 ++++++++++++++++++++++++++++++++++++++++ wait-network-then-update | 11 +++++ 6 files changed, 144 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 deno.json create mode 100644 deno.lock create mode 100755 update.ts create mode 100755 wait-network-then-update diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cad2309 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/tmp \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..b5e670d --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# xkcd background + +Downloads and set your gnome/cinnamon wallpaper to the current xkcd + +## Dependencies + +- `deno` +- `imagemagick` +- `wget` + +## Usage + +```sh +./update.ts +``` + +For init scripts, it is recommended to wait for network access before updating to avoid fetching errors, the +`wait-for-network-then-update` does precisely that : + +```sh +./wait-network-then-update +``` diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..ae323ca --- /dev/null +++ b/deno.json @@ -0,0 +1,7 @@ +{ + "fmt": { + "useTabs": true, + "lineWidth": 120, + "semiColons": false + } +} \ No newline at end of file diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..cf0a15e --- /dev/null +++ b/deno.lock @@ -0,0 +1,16 @@ +{ + "version": "3", + "remote": { + "https://deno.land/std@0.138.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", + "https://deno.land/std@0.138.0/_util/os.ts": "49b92edea1e82ba295ec946de8ffd956ed123e2948d9bd1d3e901b04e4307617", + "https://deno.land/std@0.138.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3", + "https://deno.land/std@0.138.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09", + "https://deno.land/std@0.138.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b", + "https://deno.land/std@0.138.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633", + "https://deno.land/std@0.138.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee", + "https://deno.land/std@0.138.0/path/mod.ts": "d3e68d0abb393fb0bf94a6d07c46ec31dc755b544b13144dee931d8d5f06a52d", + "https://deno.land/std@0.138.0/path/posix.ts": "293cdaec3ecccec0a9cc2b534302dfe308adb6f10861fa183275d6695faace44", + "https://deno.land/std@0.138.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9", + "https://deno.land/std@0.138.0/path/win32.ts": "31811536855e19ba37a999cd8d1b62078235548d67902ece4aa6b814596dd757" + } +} diff --git a/update.ts b/update.ts new file mode 100755 index 0000000..5b478c1 --- /dev/null +++ b/update.ts @@ -0,0 +1,87 @@ +#!/bin/env -S deno run -A + +import * as path from "https://deno.land/std@0.138.0/path/mod.ts" + +main() +async function main() { + const img_url = await find_daily_xkcd() + const tmp_dir = module_dir(import.meta) + "/tmp" + const dl_path = `${tmp_dir}/downloaded.png` + const bg_path = `${tmp_dir}/gen_${Date.now()}.png` + const curr_path = `${tmp_dir}/latest.png` + log("parameters", { img_url, tmp_dir, dl_path, bg_path, curr_path }) + await run("mkdir", "-p", tmp_dir) + await download_file(img_url, dl_path) + await generate_wallpaper(dl_path, bg_path) + await set_wallpaper(bg_path) + await run("cp", bg_path, curr_path) + log("done") +} + +async function find_daily_xkcd() { + const res = await fetch("https://xkcd.com/info.0.json") + const { img } = await res.json() + return img +} + +async function download_file(url: string, dl_path: string) { + await run("wget", url, "-O", dl_path) +} + +async function generate_wallpaper(src: string, dest: string) { + const [w, h] = await get_max_res() + await run( + "magick", + src, + ...["-gravity", "Center"], + ...["-extent", `${w}x${h}`], + ...["-background", "#ffffff"], + ...["-negate"], + ...["-level", "-50"], + ...["-brightness-contrast", "14x1"], + dest, + ) +} + +async function set_wallpaper(bg_path: string) { + const abs_path = path.resolve(bg_path) + await run( + "gsettings", + "set", + "org.cinnamon.desktop.background", + "picture-uri", + `file://${abs_path}`, + ) +} + +async function get_max_res() { + const output = await run("xrandr") + const stdout = (new TextDecoder()).decode(output.stdout) + const resolutions = [] as [number, number][] + for (const line of stdout.split("\n")) { + const [_, rest] = line.split(" connected ") + if (rest === undefined) continue + const stripped = rest.replace("primary", "") + const [res] = stripped.split("+") + const [w, h] = res.split("x").map((n) => parseInt(n)) + resolutions.push([w, h]) + } + const maxes = [0, 0] as [number, number] + for (const res of resolutions) { + maxes[0] = Math.max(res[0], maxes[0]) + maxes[1] = Math.max(res[1], maxes[1]) + } + return maxes +} + +function log(...args: unknown[]) { + console.log("[download.ts]", ...args) +} + +async function run(name: string, ...args: string[]) { + return await new Deno.Command(name, { args, stdout: "piped", stderr: "inherit" }).output() +} + +function module_dir({ url }: ImportMeta): string { + return path.resolve(path.dirname(path.fromFileUrl(url))) +} diff --git a/wait-network-then-update b/wait-network-then-update new file mode 100755 index 0000000..8537d66 --- /dev/null +++ b/wait-network-then-update @@ -0,0 +1,11 @@ +#!/bin/sh +set -e +cd "$(dirname "$(realpath "$0")")" + + +until ping wikipedia.org -c 1 +do sleep 1s +done + + +./refresh.ts