1 Commits

Author SHA1 Message Date
Renovate Bot
4977e66582 Add renovate.json 2025-09-20 07:28:23 +00:00
4 changed files with 13 additions and 162 deletions

View File

@@ -3,7 +3,6 @@ package main
import (
"encoding/json"
"fmt"
"image"
"io"
"math/rand"
"net/http"
@@ -15,12 +14,6 @@ import (
"sort"
"strings"
"time"
_ "image/gif"
"image/jpeg"
"image/png"
"golang.org/x/image/draw"
)
const (
@@ -73,12 +66,6 @@ type WallhavenResponse struct {
} `json:"data"`
}
type monitor struct {
Name string `json:"name"`
Width int `json:"width"`
Height int `json:"height"`
}
func main() {
// Initialize random source
r := rand.New(rand.NewSource(time.Now().UnixNano()))
@@ -175,7 +162,7 @@ func downloadRandomWallpaper(wallpaperPath string, r *rand.Rand, topics []string
fmt.Fprintf(os.Stderr, "Searching for wallpapers related to: %s\n", displayName)
// Get wallpapers from Wallhaven API
resp, err := http.Get(fmt.Sprintf("%s/search?q=%s&purity=100&categories=110&sorting=random&atleast=3440x1440", wallhavenAPI, query))
resp, err := http.Get(fmt.Sprintf("%s/search?q=%s&purity=100&categories=110&sorting=random", wallhavenAPI, query))
if err != nil {
fmt.Fprintf(os.Stderr, "Error fetching from Wallhaven: %v\n", err)
return "", ""
@@ -226,165 +213,27 @@ func downloadRandomWallpaper(wallpaperPath string, r *rand.Rand, topics []string
return filepath, displayName
}
func activeMonitors() ([]monitor, error) {
out, err := exec.Command("hyprctl", "-j", "monitors").Output()
if err != nil {
return nil, err
}
var monitors []monitor
if err := json.Unmarshal(out, &monitors); err != nil {
return nil, err
}
return monitors, nil
}
func ensureSized(wallpaperPath string) (string, error) {
monitors, err := activeMonitors()
if err != nil {
return "", err
}
if len(monitors) == 0 {
return wallpaperPath, nil
}
targetWidth := 0
targetHeight := 0
for _, m := range monitors {
if m.Width > targetWidth {
targetWidth = m.Width
}
if m.Height > targetHeight {
targetHeight = m.Height
}
}
if targetWidth == 0 || targetHeight == 0 {
return wallpaperPath, nil
}
file, err := os.Open(wallpaperPath)
if err != nil {
return "", err
}
defer file.Close()
src, format, err := image.Decode(file)
if err != nil {
return "", err
}
srcWidth := float64(src.Bounds().Dx())
srcHeight := float64(src.Bounds().Dy())
targetW := float64(targetWidth)
targetH := float64(targetHeight)
// Calculate scale factor to fit image within target while maintaining aspect ratio
scaleW := targetW / srcWidth
scaleH := targetH / srcHeight
scale := min(scaleW, scaleH)
// If image already fits within target dimensions, no resize needed
if scale >= 1.0 {
return wallpaperPath, nil
}
// Calculate new dimensions maintaining aspect ratio (best fit)
newWidth := int(srcWidth * scale)
newHeight := int(srcHeight * scale)
dst := image.NewRGBA(image.Rect(0, 0, newWidth, newHeight))
draw.CatmullRom.Scale(dst, dst.Bounds(), src, src.Bounds(), draw.Over, nil)
var ext string
switch format {
case "jpeg":
ext = ".jpg"
case "png":
ext = ".png"
case "gif":
ext = ".png"
default:
ext = filepath.Ext(wallpaperPath)
if ext == "" {
ext = ".jpg"
}
}
base := strings.TrimSuffix(filepath.Base(wallpaperPath), filepath.Ext(wallpaperPath))
resizedPath := filepath.Join(filepath.Dir(wallpaperPath), fmt.Sprintf("%s-%dx%d%s", base, newWidth, newHeight, ext))
outFile, err := os.Create(resizedPath)
if err != nil {
return "", err
}
defer outFile.Close()
switch format {
case "png", "gif":
if err := png.Encode(outFile, dst); err != nil {
return "", err
}
default:
if err := jpeg.Encode(outFile, dst, &jpeg.Options{Quality: 90}); err != nil {
return "", err
}
}
return resizedPath, nil
}
func changeWallpaper(wallpaperPath, topic string) {
resizedPath, err := ensureSized(wallpaperPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Error resizing wallpaper: %v\n", err)
resizedPath = wallpaperPath
}
if resizedPath == "" {
resizedPath = wallpaperPath
}
// Save current wallpaper path
homeDir, _ := os.UserHomeDir()
wallpaperFile := filepath.Join(homeDir, ".wallpaper")
if err := os.WriteFile(wallpaperFile, []byte(resizedPath), 0644); err != nil {
if err := os.WriteFile(wallpaperFile, []byte(wallpaperPath), 0644); err != nil {
fmt.Fprintf(os.Stderr, "Error saving wallpaper path: %v\n", err)
}
monitors, monitorErr := activeMonitors()
if monitorErr != nil {
fmt.Fprintf(os.Stderr, "Error getting monitors: %v\n", monitorErr)
}
cmd := exec.Command("hyprctl", "hyprpaper", "preload", resizedPath)
// Change wallpaper using hyprctl
cmd := exec.Command("hyprctl", "hyprpaper", "reload", ","+wallpaperPath)
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error preloading wallpaper: %v\n", err)
}
if monitorErr != nil || len(monitors) == 0 {
cmd = exec.Command("hyprctl", "hyprpaper", "wallpaper", ","+resizedPath)
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error applying wallpaper: %v\n", err)
}
} else {
for _, m := range monitors {
cmd = exec.Command("hyprctl", "hyprpaper", "wallpaper", fmt.Sprintf("%s,%s", m.Name, resizedPath))
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error applying wallpaper for monitor %s: %v\n", m.Name, err)
}
}
}
cmd = exec.Command("hyprctl", "hyprpaper", "reload")
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error reloading hyprpaper: %v\n", err)
fmt.Fprintf(os.Stderr, "Error changing wallpaper: %v\n", err)
}
// Send notification with wallpaper as icon
filename := filepath.Base(resizedPath)
filename := filepath.Base(wallpaperPath)
message := fmt.Sprintf("Wallpaper changed to %s", filename)
if topic != "" {
message += fmt.Sprintf(" (%s)", topic)
}
notifyWithIcon(message, "normal", resizedPath)
notifyWithIcon(message, "normal", wallpaperPath)
}
func notify(message, urgency string) {

2
go.mod
View File

@@ -1,5 +1,3 @@
module gitea.suda.codes/sudacode/change-wallpaper
go 1.24.2
require golang.org/x/image v0.32.0 // indirect

2
go.sum
View File

@@ -1,2 +0,0 @@
golang.org/x/image v0.32.0 h1:6lZQWq75h7L5IWNk0r+SCpUJ6tUVd3v4ZHnbRKLkUDQ=
golang.org/x/image v0.32.0/go.mod h1:/R37rrQmKXtO6tYXAjtDLwQgFLHmhW+V6ayXlxzP2Pc=

6
renovate.json Normal file
View File

@@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
]
}