dot/outerheaven.init3.home/.config/sway/scripts/wallpaper.py

84 lines
3 KiB
Python
Executable file

#!/usr/bin/env python3
"""
wallpaper.py - random wallpaper/output utility for i3/Sway
usage: wallpaper.py [-h] [--select {common,unique}] directory
Selection modes:
Common: One wallpaper selected and shared for *all* displays
Unique: One wallpaper selected for *each* display
"""
import argparse
import os
import sys
import random
import asyncio
from typing import List
from i3ipc.aio import Connection
EXTS = ['.jpg', '.jpeg', '.png', '.bmp', '.gif']
def parse_args():
'''Handles argparse on startup'''
parser = argparse.ArgumentParser(description='Random Wallpaper Setter for Sway')
parser.add_argument('directory', type=str, help='Directory containing wallpapers')
parser.add_argument('--select',
type=str,
choices=['common', 'unique'],
default='common',
help='Wallpaper selection mode: all displays, or each?')
return parser.parse_args()
async def main():
'''you know what it is'''
args = parse_args()
sway = await Connection(auto_reconnect=True).connect()
def list_image_files(d: str) -> List[str]:
'''
Given the path to a *'directory'*, returns a list of image files to consider for wallpapers.
'''
return [os.path.join(d, f) for f in os.listdir(d) if os.path.splitext(f)[1].lower() in EXTS]
async def set_wallpaper(file_path: str, output=None):
'''
Given an image path, sets the wallpaper for (optional) outputs in i3/Sway.
If no output is specified then *all* will receive the wallpaper.
'''
print(f"{output if output else 'all'}: wallpaper='{file_path}'")
if output:
await sway.command(f'output "{output}" bg "{file_path}" fill')
else:
for _output in await sway.get_outputs():
await sway.command(f'output "{_output.name}" bg "{file_path}" fill')
if os.path.isdir(args.directory):
image_files = list_image_files(args.directory)
else:
sys.exit(f'ERR: not a directory: {args.directory}')
if not image_files:
print("No image files found in the specified directory.")
return
print(f'Found {len(image_files)} candidate image files')
outputs = await sway.get_outputs()
if args.select == 'common':
wallpaper = random.choice(image_files)
await set_wallpaper(wallpaper)
else: # args.select == 'unique', we need to determine a wallpaper for each display
for output in outputs:
if len(image_files) == 0:
print(f"Not enough images in '{args.directory}' for each display.")
break
wallpaper = random.choice(image_files)
image_files.remove(wallpaper)
await set_wallpaper(wallpaper, output.name)
if __name__ == "__main__":
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
loop.run_until_complete(main())
except KeyboardInterrupt:
pass