幻燈片放映模式切換windows terminal背景圖片
指令碼功能
以幻燈片模式
自動切換windows terminal
的背景圖片,可自定義包含圖片的目錄、切換頻率等。
使用命令python change_tty_image.py --help
檢視使用幫助。
程式碼一共就162
行,核心功能程式碼事實上可能只有不到50
行,其他都是一些檢查、日誌等語句。感興趣的可以download
指令碼,自行定製一些功能。
開發需求
近期在折騰windows terminal
,於我而言這款終端軟體也基本完全替代xshell
,特別是win 10
內建了ssh, scp
等命令,用起來非常舒服和流暢。再和wsl
結合起來一起玩,簡直爽到飛起。
windows terminal
可以自定義主題樣式,自定義背景圖片。作為一個偽二次元
愛好者,當然要把背景換成adroable
的小姐姐!
然而,每次終端只能設定一張圖片,根本無法滿足敲命令的時候看不一樣的
二次元小姐姐的需求。聯想到windows
可以設定圖片目錄,並選擇幻燈片
模式動態切換桌面背景,於是去google
一番,發現windows terminal
的settings.json
好像沒有這個選項。查閱[官方文件](Windows Terminal Appearance Profile Settings | Microsoft Docs)如下:
要麼給一個路徑,要麼就和桌面桌布設定為一樣。
所以,如果想要自動切換windows terminal
的背景圖片,有一個折中方案:把backgroundImage
設定為desktopWallpaper
,然後桌面背景搞成幻燈片
模式,也就是下面這樣子:
這樣就能自動切換。
但是像我這樣桌布
比較多的收藏家
,正愁桌布多得無處安放,怎麼能把desktop
和windows terminal
設定成一樣的背景呢?這多不合適!
於是,我花了1
個小時,用python
寫了一個簡單的指令碼,支援設定桌布目錄
、更新頻率
、隨機更新
功能,每個固定時間就為windows terminal
切換一張背景圖片。
使用技術
要實現這個功能其實很簡單,不需要高大上的技術。整個開發需求主要包含兩點:
- 定時任務
- 修改
windows terminal
的settings.json
中的backgroundImage
項,切換為指定目錄下的圖片路徑,並進行輪循設定。
針對兩點需求,實現手段分別為:
- 使用
time.sleep()
設定定時任務。這應該是簡單的方式了,適合簡單的定時任務觸發。 - 使用
IO
操作,先讀取指定目錄的所有image
路徑,然後取一個路徑出來,替換掉backgroundImage
的值即可。
實現起來很簡單,也順便幫我複習了一下python
操作檔案和目錄的一些介面。
time
模組獲取時間,方便記錄日誌random
模組獲取隨機數,得到隨機圖片,顯然,此處無需使用安全隨機數生成器
os.walk()
遍歷所有目錄下所有的圖片路徑- 設定臨時檔案,讀配置的時候,邊讀邊寫,然後可以使用
re
模組,正則匹配含有backgroundImage
的行,替換掉路徑 - 執行緒休眠實現定時任務
操作說明
python change_tty_image.py -h
檢視幫助- 確保
settings.json
中已經預定義了一個路徑 - 每次開始任務之前會備份一份配置檔案,不用擔心原有配置丟失
- 更新頻率至少為
10 min
,太快了不就走馬觀花 - 建議使用
pythonw
後臺執行指令碼
使用示例
檢視幫助
輸入引數使用
關鍵操作都會記錄日誌,或在螢幕輸出!
指令碼詳情
# -*- encoding: utf-8 -*-
'''
@File : change_tty_image.py
@Time : 2021/04/08 21:00:20
@Author : Roderick Chan
@Email : ch22166@163.com
@Desc : Change windows-terminal background image automatically
'''
import os
import sys
import functools
import random
import re
import time
# key word to set image
key_word = "\"backgroundImage\""
# help message
help_msg = """
Usage:
python change_tty_image.py [settings_path] [picture_directory] [update_frequency] [random]
Function:
Change windows-terminal background image automatically.
Note:
settings_path: [required]
The absolute path of windows-terminal setting file.
picture_directory: [required]
A absolute directory path fulled with pictures, only support 'png', 'jpg', 'gif'.
update_frequency: [required]
The frequency to update image, should be more than 10, default value is 30, which represents 30min.
random: [optional]
Select image randomly or not. Default value: False.
Tips:
1. Use `python` to run this script and output log-info on the screen.
2. Use `pythonw` to run this script in the background and output nothing, but your can use 'tasklist' and 'taskkill' to stop.
3. recommendation command:
pythonw change_tty_image.py [settings_path] [picture_directory] [update_frequency] [random] > change_image.log
4. Use `python change_tty_image.py -h` to get help.
"""
def get_time():
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
def log(msg):
print("\033[1;32mINFO\033[0m: {} \033[1;34mTime\033[0m: {}\n".format(msg, get_time()))
# parse args
# check args
args = sys.argv
arg_len = len(args)
# show help
if len(args) > 1 and (args[1] == "-h" or args[1] == "--help"):
print(help_msg)
sys.exit(0)
if arg_len < 4 or arg_len > 5:
print("\033[1;31m[-] Args Error!\033[0m\n")
print(help_msg)
sys.exit(-1)
# validate args
settings_path = args[1]
picture_directory = args[2]
update_frequency = args[3]
random_enabled = False
if arg_len == 5:
random_enabled = bool(args[4])
assert os.path.exists(settings_path), "settings_path doesn't exist."
assert os.path.isfile(settings_path), "settings_path is not a file path."
assert os.path.exists(picture_directory), "picture_directory doesn't exist."
assert os.path.isdir(picture_directory), "picture_directory is not a dir path."
# process settings_path
settings_dir, settings_full_name = os.path.split(settings_path)
settings_name, setting_suffix = os.path.splitext(settings_full_name)
backup_setting_path = os.path.join(settings_dir, settings_name + "_backup" + setting_suffix)
tmp_setting_path = os.path.join(settings_dir, settings_name + "_tmpfile" + setting_suffix)
# process update_frequency
if update_frequency.isdecimal():
update_frequency = int(update_frequency)
if update_frequency < 10:
update_frequency = 30
else:
update_frequency = 30
log('settings_path: {}'.format(settings_path))
log('backup_setting_path: {}'.format(backup_setting_path))
log('picture_directory: {}'.format(picture_directory))
log('update_frequency: {}'.format(update_frequency))
log('random_enabled: {}'.format(random_enabled))
# get all picture path
all_picture_path = []
support_suffix = ('.jpg', '.png', '.gif')
for r, dl, fl in os.walk(picture_directory,):
for f in fl:
is_ok = functools.reduce(lambda a, b : a or b, map(lambda x: f.endswith(x), support_suffix))
if not is_ok:
continue
# check size
if len(all_picture_path) > 0x1000:
continue;
all_picture_path.append(os.path.join(r, f))
assert len(all_picture_path) > 0, 'no pictures appended, check your picture_directory.'
# validate settings_path
flag = False
with open(file=settings_path, mode='r+', encoding='utf-8') as fd:
for line in fd:
if line.strip().startswith(key_word):
flag = True
break
assert flag, "please initial your windows-terminal settings file first, add {} value at least.".format(key_word)
log('all_picture_path : {}'.format(all_picture_path))
# back up
if not os.path.exists(backup_setting_path):
cmd = "copy {} {}".format(settings_path, backup_setting_path)
os.popen(cmd)
log("execute \"{}\"".format(cmd))
idx = -1
while True:
if random_enabled:
idx = random.randint(0, len(all_picture_path) - 1)
else:
idx += 1
idx %= len(all_picture_path)
# replace '\' with '/'
cur_picture_path = all_picture_path[idx].replace("\\", "/")
log('cur_picture_path: {}'.format(cur_picture_path))
with open(file=settings_path, mode='r', encoding='utf-8') as fd_src:
with open(file=tmp_setting_path, mode='w+', encoding='utf-8') as fd_bck:
for line in fd_src:
if not line.strip().startswith(key_word):
fd_bck.write(line)
continue
res = re.sub(r"({}\s?:\s?)\".+\",".format(key_word), r'\1"{}",'.format(cur_picture_path), line)
fd_bck.write(res)
cmd = "copy {} {}".format(tmp_setting_path, settings_path)
os.popen(cmd)
log("execute \"{}\"".format(cmd))
cmd = "del {}".format(tmp_setting_path)
os.popen(cmd)
log("execute \"{}\"".format(cmd))
# sleep
log("sleep start...")
time.sleep(update_frequency * 60)
log("sleep end...")
引用參考
windows terminal profile setting
:<Windows Terminal Appearance Profile Settings | Microsoft Docs>