diff --git a/change-wallpaper.go b/change-wallpaper.go new file mode 100644 index 0000000..9325f97 --- /dev/null +++ b/change-wallpaper.go @@ -0,0 +1,171 @@ +package main + +import ( + "encoding/json" + "fmt" + "io" + "math/rand" + "net/http" + "net/url" + "os" + "os/exec" + "path/filepath" + "regexp" + "strings" + "time" +) + +const ( + wallhavenAPI = "https://wallhaven.cc/api/v1" + wallpaperDir = "Pictures/wallpapers/wallhaven" +) + +var topics = []string{ + "132262 - Mobuseka", + "konosuba", + "bunny girl senpai", + "oshi no ko", + "kill la kill", + "lofi", + "eminence in shadow", +} + +type WallhavenResponse struct { + Data []struct { + Path string `json:"path"` + } `json:"data"` +} + +func main() { + // Initialize random source + r := rand.New(rand.NewSource(time.Now().UnixNano())) + + // Check if a file path was provided as argument + if len(os.Args) > 1 { + imgPath := os.Args[1] + if _, err := os.Stat(imgPath); err == nil { + changeWallpaper(imgPath, "") + return + } + } + + // Create wallpaper directory if it doesn't exist + homeDir, err := os.UserHomeDir() + if err != nil { + fmt.Fprintf(os.Stderr, "Error getting home directory: %v\n", err) + os.Exit(1) + } + + wallpaperPath := filepath.Join(homeDir, wallpaperDir) + if err := os.MkdirAll(wallpaperPath, 0755); err != nil { + fmt.Fprintf(os.Stderr, "Error creating wallpaper directory: %v\n", err) + os.Exit(1) + } + + // Download and set new wallpaper + newWallpaper, topic := downloadRandomWallpaper(wallpaperPath, r) + if newWallpaper != "" { + changeWallpaper(newWallpaper, topic) + } else { + notify("Failed to download new wallpaper", "critical") + os.Exit(1) + } +} + +func downloadRandomWallpaper(wallpaperPath string, r *rand.Rand) (string, string) { + // Select random topic + topic := topics[r.Intn(len(topics))] + var query string + var displayName string + + // Check if the topic is a tag ID with name + if tagRegex := regexp.MustCompile(`^(\d+)\s*-\s*(.+)$`); tagRegex.MatchString(topic) { + matches := tagRegex.FindStringSubmatch(topic) + query = fmt.Sprintf("id:%s", matches[1]) + displayName = strings.TrimSpace(matches[2]) + } else { + query = url.QueryEscape(topic) + displayName = topic + } + + 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", wallhavenAPI, query)) + if err != nil { + fmt.Fprintf(os.Stderr, "Error fetching from Wallhaven: %v\n", err) + return "", "" + } + defer resp.Body.Close() + + // Parse response + var wallhavenResp WallhavenResponse + if err := json.NewDecoder(resp.Body).Decode(&wallhavenResp); err != nil { + fmt.Fprintf(os.Stderr, "Error parsing response: %v\n", err) + return "", "" + } + + if len(wallhavenResp.Data) == 0 { + fmt.Fprintf(os.Stderr, "No wallpapers found for topic: %s\n", displayName) + return "", "" + } + + // Select a random image from the results + randomIndex := r.Intn(len(wallhavenResp.Data)) + wallpaperURL := wallhavenResp.Data[randomIndex].Path + filename := filepath.Base(wallpaperURL) + filepath := filepath.Join(wallpaperPath, filename) + + fmt.Fprintf(os.Stderr, "Downloading: %s\n", filename) + + resp, err = http.Get(wallpaperURL) + if err != nil { + fmt.Fprintf(os.Stderr, "Error downloading wallpaper: %v\n", err) + return "", "" + } + defer resp.Body.Close() + + file, err := os.Create(filepath) + if err != nil { + fmt.Fprintf(os.Stderr, "Error creating file: %v\n", err) + return "", "" + } + defer file.Close() + + if _, err := io.Copy(file, resp.Body); err != nil { + fmt.Fprintf(os.Stderr, "Error saving wallpaper: %v\n", err) + return "", "" + } + + return filepath, displayName +} + +func changeWallpaper(wallpaperPath, topic string) { + // Save current wallpaper path + homeDir, _ := os.UserHomeDir() + wallpaperFile := filepath.Join(homeDir, ".wallpaper") + if err := os.WriteFile(wallpaperFile, []byte(wallpaperPath), 0644); err != nil { + fmt.Fprintf(os.Stderr, "Error saving wallpaper path: %v\n", err) + } + + // Change wallpaper using hyprctl + cmd := exec.Command("hyprctl", "hyprpaper", "reload", ","+wallpaperPath) + if err := cmd.Run(); err != nil { + fmt.Fprintf(os.Stderr, "Error changing wallpaper: %v\n", err) + } + + // Send notification + filename := filepath.Base(wallpaperPath) + message := fmt.Sprintf("Wallpaper changed to %s", filename) + if topic != "" { + message += fmt.Sprintf(" (%s)", topic) + } + notify(message, "normal") +} + +func notify(message, urgency string) { + cmd := exec.Command("notify-send", "-i", "hyprpaper", "-u", urgency, "change-wallpaper.go", message) + if err := cmd.Run(); err != nil { + fmt.Fprintf(os.Stderr, "Error sending notification: %v\n", err) + } +} \ No newline at end of file diff --git a/change-wallpaper.sh b/change-wallpaper.sh index c5b9573..fcfc801 100755 --- a/change-wallpaper.sh +++ b/change-wallpaper.sh @@ -10,7 +10,7 @@ TOPICS=( "kill la kill" "lofi" "eminence in shadow" - "mobuseka" + "132262 - Mobuseka" ) # Create wallpaper directory if it doesn't exist @@ -18,17 +18,34 @@ mkdir -p "$WALLPAPER_DIR" # Function to download a random wallpaper from Wallhaven download_random_wallpaper() { - # Select a random topic + # Select random topic local random_topic="${TOPICS[$RANDOM % ${#TOPICS[@]}]}" - local query=$(echo "$random_topic" | sed 's/ /+/g') + local query + local display_name - echo "Searching for wallpapers related to: $random_topic" >&2 + # Check if the topic is a tag ID with name + if [[ "$random_topic" =~ ^([0-9]+)[[:space:]]*-[[:space:]]*(.+)$ ]]; then + query="id:${BASH_REMATCH[1]}" + display_name="${BASH_REMATCH[2]}" + else + query=$(echo "$random_topic" | sed 's/ /+/g') + display_name="$random_topic" + fi + + echo "Searching for wallpapers related to: $display_name" >&2 # Get wallpapers from Wallhaven API local response=$(curl -s "$WALLHAVEN_API/search?q=$query&purity=100&categories=110&sorting=random") - # Get a random image URL from the response - local url=$(echo "$response" | jq -r '.data[0].path') + # Get all image URLs and select a random one + local urls=($(echo "$response" | jq -r '.data[].path')) + if [ ${#urls[@]} -eq 0 ]; then + echo "No wallpapers found for topic: $display_name" >&2 + return 1 + fi + + local random_index=$((RANDOM % ${#urls[@]})) + local url="${urls[$random_index]}" if [ -n "$url" ] && [ "$url" != "null" ]; then local filename=$(basename "$url") @@ -36,12 +53,12 @@ download_random_wallpaper() { curl -s "$url" -o "$WALLPAPER_DIR/$filename" if [ $? -eq 0 ]; then echo "$WALLPAPER_DIR/$filename" - echo "$random_topic" > "$WALLPAPER_DIR/.last_topic" + echo "$display_name" > "$WALLPAPER_DIR/.last_topic" return 0 fi fi - echo "No wallpapers found for topic: $random_topic" >&2 + echo "No wallpapers found for topic: $display_name" >&2 return 1 }