Something went wrong. Try again.
๐๏ธ apply a wallpaper based on the weather outside
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177import { type Colordx, extend } from "@colordx/core"import lab from "@colordx/core/plugins/lab"import type { ImageAnalysisData } from "../analyze/analysis.ts"import { chalkDebug } from "../utils.ts"import * as path from "@std/path"
extend([lab])
export interface ApplicationConfig { latitude: number longitude: number weatherModel: string lightnessRange: { night: number; dawn: number; noon: number } chromaRange: { start: number; end: number } targetSkyHue: number numberOfWallpapers: number applyWallpaperCommand: string}
export const defaultConfig: ApplicationConfig = { latitude: 0, longitude: 0, weatherModel: "best_match", lightnessRange: { night: 0, dawn: 0.3, noon: 0.8, }, chromaRange: { start: 0, end: 1, }, numberOfWallpapers: 1, targetSkyHue: 264, applyWallpaperCommand: "hyprctl hyprpaper wallpaper , %s",}
export async function getOpenMeteoData( latitude: number, longitude: number, weatherModel: string = "best_match",) { const openMeteoResponse = await fetch( "https://api.open-meteo.com/v1/forecast", { method: "POST", body: new URLSearchParams({ latitude: latitude.toString(), longitude: longitude.toString(), models: weatherModel, current: "cloud_cover", minutely_15: "shortwave_radiation_instant", forecast_minutely_15: "1", past_minutely_15: "1", }), }, )
if (!openMeteoResponse.ok) { throw new Error( `Open-Meteo sent back an error: ${openMeteoResponse.status}`, ) }
const openMeteoData = await openMeteoResponse.json()
const cloudCover: string = openMeteoData.current.cloud_cover
let index = 0 openMeteoData.minutely_15.time.forEach((time: string) => { if (Date.parse(time) > Date.now()) { // if the data point has a time greater than right now, subtract one to find the one just before the current // time index = openMeteoData.minutely_15.time.indexOf(time) - 1 } }) const shortwaveRadiation: string = openMeteoData.minutely_15.shortwave_radiation_instant[index]
return { cloudCover, shortwaveRadiation, }}
export function findMatchingImages(imagesData: ImageAnalysisData, targetColor: Colordx, numberOfImages: number) { const matchingImages = []
let targetDelta = 0.06 while (matchingImages.length < numberOfImages) { console.debug(`Finding matching image with delta E ${targetDelta.toFixed(2)}...`) for (const image of imagesData.files) { if (targetColor.delta(image.colour) <= targetDelta) { matchingImages.push(image) } } console.info(chalkDebug(`Couldn't find matching image with delta E ${targetDelta.toFixed(2)}! Increasing...`)) targetDelta += 0.01 } return matchingImages}
export async function setWindowsWallpaper(tempImagePath: string, ...imagePaths: string[]) { interface Rect { left: number top: number right: number bottom: number }
interface Vector2 { width: number height: number }
const pathToUser32 = path.fromFileUrl( "file:///C:/Windows/System32/user32.dll", ); // jank
const user32 = Deno.dlopen(pathToUser32, { SystemParametersInfoA: { parameters: ["u16", "u16", "pointer", "u16"], result: "bool", },
EnumDisplayMonitors: { parameters: ["pointer", "pointer", "pointer", "i32"], result: "bool", }, });
const monitors: Vector2[] = []
const monitorEnum = new Deno.UnsafeCallback({ parameters: ["pointer", "pointer", "pointer", "i32"], result: "bool", }, (_hMon, _hdc, lprcMonitor, _pData) => { // grab the buffer of our data... const buffer = Deno.UnsafePointerView.getArrayBuffer(lprcMonitor!, 16) // ..convert it to an Int32 array... const array = Array.from(new Int32Array(buffer)) // ..then populate: left - right top - bottom const rect = { width: Math.abs(array[2] - array[0]), height: Math.abs(array[1] - array[3]) } monitors.push(rect) return true });
user32.symbols.EnumDisplayMonitors(null, null, monitorEnum.pointer, 0);
// from this point on monitorsRect is populated
console.log(monitors)
for (let i = 0; i < monitors.length; i++) { const monitor = monitors[i] if (monitor.width >= monitor.height) { await $`magick ${imagePaths[i]} -resize ${monitor.width}x -format "%m" ${path.join(tempImagePath, `monitorImage${i}.png`)}` } else { await $`magick ${imagePaths[i]} -resize x${monitor.height} -format "%m" ${path.join(tempImagePath, `monitorImage${i}.png`)}` } }
// TODO: this isn't the right order of images console.log(await $`magick ${path.join(tempImagePath, `monitorImage*.png`)} +append ${path.join(tempImagePath, "out.png")}`)
const pointer = Deno.UnsafePointer.of( Buffer.from( "C:\\Users\\angelcube\\Pictures\\wallpaper\\vocaloid_morningglory_lobelia.jpg", "ascii", ), );
user32.symbols.SystemParametersInfoA(20, 0, pointer, 3);
user32.close();}