summaryrefslogtreecommitdiff
path: root/wallpaper.fish
blob: e8cfdd87c9ec20efbe052a3659e71d3529fb16e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/env fish

function get-valid-wallpapers
    identify -ping -format '%i\n' $wallpapers_dir/** 2> /dev/null
end

set script_name (basename (status filename))
set wallpapers_dir (xdg-user-dir PICTURES)/Wallpapers
set threshold 80

# Max 0 non-option args | h, f and d are exclusive | F and t are also exclusive
argparse -n 'caelestia-wallpaper' -X 0 -x 'h,f,d' -x 'F,t' \
    'h/help' \
    'f/file=' \
    'd/directory=' \
    'F/no-filter' \
    't/threshold=!_validate_int --min 0' \
    'T/theme=!test $_flag_value = light -o $_flag_value = dark' \
    -- $argv
or exit

. (dirname (status filename))/util.fish

if set -q _flag_h
    echo 'Usage:'
    echo '    caelestia wallpaper'
    echo '    caelestia wallpaper [ -h | --help ]'
    echo '    caelestia wallpaper [ -f | --file ] [ -T | --theme ]'
    echo '    caelestia wallpaper [ -d | --directory ] [ -F | --no-filter ] [ -T | --theme ]'
    echo '    caelestia wallpaper [ -d | --directory ] [ -t | --threshold ] [ -T | --theme ]'
    echo
    echo 'Options:'
    echo '    -h, --help                        Print this help message and exit'
    echo '    -f, --file <file>                 The file to change wallpaper to'
    echo '    -d, --directory <directory>       The folder to select a random wallpaper from (default '$wallpapers_dir')'
    echo '    -F, --no-filter                   Do not filter by size'
    echo '    -t, --threshold <threshold>       The minimum percentage of the size the image must be greater than to be selected (default '$threshold')'
    echo '    -T, --theme <"light" | "dark">    Set light/dark theme for dynamic scheme'
else
    set state_dir $C_STATE/wallpaper

    # The path to the last chosen wallpaper
    set last_wallpaper_path "$state_dir/last.txt"

    # Use wallpaper given as argument else choose random
    if set -q _flag_f
        set chosen_wallpaper (realpath $_flag_f)

        if ! identify -ping $chosen_wallpaper &> /dev/null
            error "$chosen_wallpaper is not a valid image"
            exit 1
        end
    else
        # The path to the directory containing the selection of wallpapers
        set -q _flag_d && set wallpapers_dir (realpath $_flag_d)

        if ! test -d $wallpapers_dir
            error "$wallpapers_dir does not exist"
            exit 1
        end

        # Get all files in $wallpapers_dir and exclude the last wallpaper (if it exists)
        if test -f "$last_wallpaper_path"
            set last_wallpaper (cat $last_wallpaper_path)
            test -n "$last_wallpaper" && set unfiltered_wallpapers (get-valid-wallpapers | grep -v $last_wallpaper)
        end
        set -q unfiltered_wallpapers || set unfiltered_wallpapers (get-valid-wallpapers)

        # Filter by resolution if no filter option is not given
        if set -q _flag_F
            set wallpapers $unfiltered_wallpapers
        else
            set -l screen_size (hyprctl monitors -j | jq -r 'max_by(.width * .height) | "\(.width)\n\(.height)"')
            set -l wall_sizes (identify -ping -format '%w %h\n' $unfiltered_wallpapers)

            # Apply threshold
            set -q _flag_t && set threshold $_flag_t
            set screen_size[1] (math $screen_size[1] x $threshold / 100)
            set screen_size[2] (math $screen_size[2] x $threshold / 100)

            # Add wallpapers that are larger than the screen size * threshold to list to choose from ($wallpapers)
            for i in (seq 1 (count $wall_sizes))
                set -l wall_size (string split ' ' $wall_sizes[$i])
                if test $wall_size[1] -ge $screen_size[1] -a $wall_size[2] -ge $screen_size[2]
                    set -a wallpapers $unfiltered_wallpapers[$i]
                end
            end
        end

        # Check if the $wallpapers list is unset or empty
        if ! set -q wallpapers || test -z "$wallpapers"
            error "No valid images found in $wallpapers_dir"
            exit 1
        end

        # Choose a random wallpaper from the $wallpapers list
        set chosen_wallpaper (random choice $wallpapers)
    end

    # Thumbnail wallpaper for colour gen
    mkdir -p $C_CACHE/thumbnails
    set -l thumb_path $C_CACHE/thumbnails/(sha1sum $chosen_wallpaper | cut -d ' ' -f 1).jpg
    if ! test -f $thumb_path
        magick -define jpeg:size=256x256 $chosen_wallpaper -thumbnail 128x128 $thumb_path
    end
    cp $thumb_path $state_dir/thumbnail.jpg

    # Light/dark mode detection if not specified
    if ! set -q _flag_T
        set -l lightness (magick $state_dir/thumbnail.jpg -format '%[fx:int(mean*100)]' info:)
        test $lightness -ge 60 && set _flag_T light || set _flag_T dark
    end

    # Generate colour scheme for wallpaper
    set -l src (dirname (status filename))
    MODE=$_flag_T $src/scheme/gen-scheme.fish &

    # Store the wallpaper chosen
    mkdir -p $state_dir
    echo $chosen_wallpaper > $last_wallpaper_path
    ln -sf $chosen_wallpaper "$state_dir/current"
end