Skip to content

Instantly share code, notes, and snippets.

@pansila
Last active June 9, 2023 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pansila/b239188514407e149f0e92c5e1cad5da to your computer and use it in GitHub Desktop.
Save pansila/b239188514407e149f0e92c5e1cad5da to your computer and use it in GitHub Desktop.
Yet another Bing Wallpaper updater, support super resolution. You can run it manually or automatically by Task Scheduler, adding the appropriate triggers, like "At log on", "At startup", "On workstation unlock", etc.
#-*- coding: UTF-8 -*-
import sys
import time
import urllib.request
import urllib.error
import ctypes
import logging
import argparse
import datetime
from io import BytesIO
from pathlib import Path
from logging.handlers import RotatingFileHandler
import requests
from PIL import Image
BINGAPI = "https://global.bing.com/HPImageArchive.aspx?format=js&idx=0&n=9&pid=hp&FORM=BEHPTB&uhd=1&uhdwidth=3840&uhdheight=2160&setmkt={}&setlang=en"
BINGWEB = "http://www.bing.com"
MODEL_URL = "https://github.com/Saafke/EDSR_Tensorflow/raw/master/models/"
CONNECTION_TIMEOUT = 120
SPI_SETDESKWALLPAPER = 20
SPIF_UPDATEINIFILE = 0x1
SPIF_SENDWININICHANGE = 0x2 # forces instant update
CHUNK_SIZE = (256, 256)
PROXIES = {'http': 'http://127.0.0.1:10809',
'https': 'http://127.0.0.1:10809'}
LOCALPATH = Path(__file__).parent
WALLPAPERFILE = LOCALPATH / "BingWallpaper.jpg"
WALLPAPERFILE_SR = LOCALPATH / "BingWallpaper_sr.jpg"
LOGFILE = LOCALPATH / "BingWallpaper.log"
LASTPICFILE = LOCALPATH / "LastWallpaper.txt"
LASTPICFILE.touch()
logger = logging.getLogger('BingWallPaper')
formatter = logging.Formatter('%(name)-12s %(asctime)s %(levelname)-8s %(message)s', '%a, %d %b %Y %H:%M:%S')
stream_handler = logging.StreamHandler(sys.stderr)
file_handler = RotatingFileHandler(LOGFILE, maxBytes=100*1024, backupCount=1)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
logger.setLevel(logging.INFO)
def setWallpaper(path):
return ctypes.windll.user32.SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, str(path), SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE)
def probe_internet():
""" check the availability of Internet """
for cnt in range(CONNECTION_TIMEOUT):
try:
urllib.request.urlopen(BINGWEB, timeout=1)
except urllib.error.URLError:
if cnt % 5 == 0:
logger.warning("Internet is not available, retrying...")
else:
break
time.sleep(1)
else:
raise TimeoutError("Internet is not available")
def superres(args, im):
import cv2
import numpy as np
from cv2 import dnn_superres
upsample_factor = args.superres
model_file = LOCALPATH / f"EDSR_x{args.superres}.pb"
if not model_file.exists() or model_file.stat().st_size == 0:
r = requests.get(MODEL_URL + f"EDSR_x{args.superres}.pb", proxies=PROXIES if args.proxy else None)
with open(model_file, 'wb') as fout:
for chunk in r.iter_content(chunk_size=1024):
fout.write(chunk)
sr = dnn_superres.DnnSuperResImpl_create()
image = cv2.imread(im)
sr.readModel(str(model_file))
sr.setModel('edsr', upsample_factor)
if args.backend == 'cuda':
new_size = (image.shape[1] * upsample_factor, image.shape[0] * upsample_factor)
output_img = np.zeros((new_size[1], new_size[0], image.shape[2]), dtype=np.uint8)
sr.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
sr.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
for y in range(0, image.shape[0], CHUNK_SIZE[1]):
for x in range(0, image.shape[1], CHUNK_SIZE[0]):
chunk = image[y:y+CHUNK_SIZE[1], x:x+CHUNK_SIZE[0], :]
upsampled_chunk = sr.upsample(chunk)
output_img[y*upsample_factor:(y+CHUNK_SIZE[1])*upsample_factor,
x*upsample_factor:(x+CHUNK_SIZE[0])*upsample_factor, :] = upsampled_chunk
else:
output_img = sr.upsample(image)
cv2.imwrite(str(WALLPAPERFILE_SR.with_suffix('.png')), output_img)
def update_wallpaper(args):
r = requests.get(BINGAPI.format(args.region))
urlbase = r.json()['images'][0]['url']
url = BINGWEB + urlbase
if not args.force:
lastpic = LASTPICFILE.read_text().rstrip()
if args.force or urlbase != lastpic:
logger.info(urlbase)
ret = requests.get(url)
im = Image.open(BytesIO(ret.content))
im.save(WALLPAPERFILE, dpi=(600,600))
if args.superres:
superres(args, str(WALLPAPERFILE))
if not setWallpaper(WALLPAPERFILE_SR if args.superres else WALLPAPERFILE):
logger.error("An error happened when settting wallpaper")
return 1
LASTPICFILE.write_text(urlbase)
logger.info("Succeeded to set the wallpaper")
else:
logger.info("Already the latest wall paper")
return 0
def run(args):
update_time = datetime.time(6, 0)
while True:
update_wallpaper(args)
now = datetime.datetime.now()
next_update = datetime.datetime.combine(now.date() + datetime.timedelta(seconds=86400), update_time) - now
sleep = next_update.total_seconds()
logger.info('Sleep %s seconds to update', sleep)
time.sleep(sleep)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-f", "--force", action='store_true', help="force to update the wallpaper")
parser.add_argument("-d", "--daemon", action='store_true', help="run in the background")
parser.add_argument("-s", "--superres", nargs='?', const=2, type=int, help="use super resolution")
parser.add_argument("-b", "--backend", default='cpu', choices=['cpu', 'cuda'], help="specify the backend of opencv")
parser.add_argument("-p", "--proxy", action='store_true', help="use network proxy")
parser.add_argument("-r", "--region", default='zh-CN', choices=["en-US", "zh-CN", "ja-JP", "en-IN", "pt-BR", "fr-FR", "de-DE", "en-CA", "en-GB", "it-IT", "es-ES", "fr-CA"], help="specify the region of Bing")
args = parser.parse_args()
if args.daemon:
run(args)
else:
sys.exit(update_wallpaper(args))
@pansila
Copy link
Author

pansila commented May 6, 2019

dependencies:

$ pip install requests, pillow

and optionally with super resolution (opencv/cpu), be cautious it takes a long time (~5min, Ryzen 5950x)

$ pip install opencv-contrib-python

or build and install opencv/cuda if you want SR GPU accelerated, (~15s, RTX 3060Ti)

@ankit1w
Copy link

ankit1w commented Jan 14, 2022

Good script

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment