群晖默认的登陆页实在是太单调了,之前看过很多抓取必应图片自动更换的例子,今天也想亲自实战一把应用在群晖登陆页上。于是 Google 到了这样一篇文章巧用计划任务修改群晖登录壁纸 ,这是一篇发布时间较久的文章,其中的一些信息可能已经失效,但其他地方的很多文章都是拷贝这里的,所以还是决定按图索骥试一试。
这个文章是用 shell 写的,但我觉得里边的功能用 PHP 也能实现(这怎么会难得住世界上最好的语言呢😜),通过必应首页控制台分析可知,从一个地址https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&nc=1572500909531&pid=hp&FORM=BEHPTB&video=1
获取图片 URI,返回完整结果如下。取的图片 URI 后再以 GET 方式获取图片内容。进一步分析可得,URL中的 idx
为 0 时表示返回当天图片,1 为前一天,以此类推,最大有效值为 8。
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 { "images" : [ { "startdate" : "20191031" , "fullstartdate" : "201910311600" , "enddate" : "20191101" , "url" : "/th?id=OHR.AlbertaOwl_ZH-CN1184867720_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp" , "urlbase" : "/th?id=OHR.AlbertaOwl_ZH-CN1184867720" , "copyright" : "一只坐在白杨树上的大雕鸮,阿尔伯塔 (© Ambre Haller/Getty Images)" , "copyrightlink" : "/search?q=%e5%a4%a7%e9%9b%95%e9%b8%ae&form=HPCAPT&mkt=zh-cn" , "title" : "" , "quiz" : "/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20191031_AlbertaOwl%22&FORM=HPQUIZ" , "wp" : true , "hsh" : "a76d074e286a1dd8aa778815fe611e2e" , "drk" : 1 , "top" : 1 , "bot" : 1 , "hs" : [ ] } ] , "tooltips" : { "loading" : "正在加载..." , "previous" : "上一个图像" , "next" : "下一个图像" , "walle" : "此图片不能下载用作壁纸。" , "walls" : "下载今日美图。仅限用作桌面壁纸。" , "play" : "播放视频" , "pause" : "暂停视频" } }
接下来,我们要分析群晖是从何处读取的图片,从查到的文章可知,图片位于/usr/syno/etc/login_background.jpg
和/usr/syno/etc/login_background_hd.jpg
。所以我们要到终端一探究竟。首先,我们需要在控制面板的终端里开启 ssh 服务
然后我们以命令ssh username@hostname [-p port]
登陆 NAS,由于图片存储位置需要 root 权限,我们还需要用命令sudo -i
切换到 root 用户。(如果需要在公网ssh登陆,只需要在路由器上将 NAS 的 ssh 端口转发即可)
小插曲:当我配置了.ssh/config 想要 ssh 免密登陆时,发现 NAS 仍然每次要求密码,使得我一度以为是配置有误,直到我重新给桌角吃灰的树莓派通电,才发现确实是 NAS 系统的问题,最后找到了这样一篇文章设置群晖 6.1 以及 6.2 使用证书免密登录 ,在按照文章重启 sshd 服务尝试修复时,发现 sshd 服务起不来了😅,最后终于在控制面板 ==> 信息中心 ==> 服务 中重新启动服务。嗯,我觉得我还能忍,也就每次登陆的时候多花两秒钟嘛,强迫症要适时低头
当我进入系统后,发现/usr/syno/etc/
下并没有login_background*.jpg
的文件,然后在控制面板的主题中修改登录页图片,并用ll -t
命令观察该目录下的变化,发现出现了这两个文件,时间也是刚刚操作的时间,因此可以判定确实读取该位置的文件。
接下来,我们通过代码直接获取图片内容及介绍信息,填充登陆页。
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 <?php $img_info = file_get_contents ('https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&pid=hp&FORM=BEHPTB&video=1' );if (false === $img_info ) { file_get_contents ('https://sc.ftqq.com/SCg552xxx.send?text=' . urlencode ('Get bing wallpaper error!' )); } $img_obj = json_decode ($img_info )->images[0 ];$img_url = 'https://cn.bing.com' . $img_obj ->url;$url_params = parse_url ($img_url )['query' ];parse_str ($url_params , $result );$filename = $result ['id' ];$img_rsc = file_get_contents ($img_url );file_put_contents ('/var/services/homes/palemoky/work/bing_wallpaper/' . $filename , $img_rsc );copy ('/var/services/homes/palemoky/work/bing_wallpaper/' . $filename , '/usr/syno/etc/login_background.jpg' );copy ('/var/services/homes/palemoky/work/bing_wallpaper/' . $filename , '/usr/syno/etc/login_background_hd.jpg' );list ($msg , $title ) = explode ('(' , rtrim ($img_obj ->copyright, ')' ));shell_exec ('sed -i "/login_welcome_title/c login_welcome_title=\"' . $title . '\"" /etc/synoinfo.conf' );shell_exec ('sed -i "/login_welcome_msg/c login_welcome_msg=\"' . $msg . '\"" /etc/synoinfo.conf' );
小插曲:这里我们需要修改系统配置文件/etc/synoinfo.conf
,我查询到的 php 修改文件方式都是把整个文件读取出来,然后再把修改后的文件赋值给变量,最后再覆写原来的文件,这种方式不太优雅,我修改一个字符都要读取全部的文件并回写,因此选择使用了 sed 来操作。sed 相同的命令在 Mac 下执行就会报 sed: 1: "synoinfo.conf": unterminated substitute pattern
的错误,但 Linux 下就完全正常,Unix 和 Linux 系统间还是要注意这些微小的差别,害得我调了半天。
把以上代码保存为文件,由于背景图文件是 root 用户,因此需要使用 root 用户执行php .../bing_wallpaper.php
,如果发现在目标位置产生了最新的背景图文件,并在主题设置页生效,则说明代码工作正常。
接下来就是创建计划任务了,离成功只有一步了
至此,大功告成,来看下效果图。emmmm, not bad.
最后,如果你觉得左上角的信息有些无趣,也可以用chinese-poetry 每天自动更换古诗词,或者抓取 One·一个 的每日一句替换,还可以抓包分析豆瓣的 iOS 每日电影 widget,获取电影台词……更多玩法等待解锁。
— 2019.11.10 更 — Chrome 首页插件 Momentum 的图片会以 GET 请求https://api.momentumdash.com/feed/bulk?syncTypes=backgrounds&localDate=2019-11-10
,header
中必须携带authorization
参数,其它参数均为可选。URL 中的localDate
为必填,但没有实际意义,日期结果由x-momentum-clientdate
控制,未设定x-momentum-clientdate
则表示为当日日期。
获取authorization
可在页面网络中查看,以下是 Insomnia 的请求及返回
感谢@我的精神家园 提供的 Python 脚本
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 import timeimport randomimport requestsfrom PIL import Imagefrom urllib.request import urlretrieveclient_id = '' directory = '/friday' filename = directory + '/bg.jpg' bg_blur = directory + '/bg_blur.jpg' today = time.strftime("%Y-%m-%d" ) headers = { 'authorization' : 'Bearer eyJ0eXA...' , 'Host' : 'api.momentumdash.com' , 'Accept' : '*/*' , 'X-Momentum-ClientId' : client_id, 'x-momentum-clientdate' : '2018-03-16' , 'X-Momentum-Version' : '0.100.1' , 'x-momentum-settings-etag' : '0400bf20-0000-0000-0000-5aaf255a0000' , 'X-Momentum-ClientDate' : today, 'X-Requested-With' : 'XMLHttpRequest' , 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, li ke Gecko) Chrome/57.0.2987.133 Safari/537.36' , 'Content-Type' : 'application/json' , 'cookie' : '' } r = requests.get('https://api.momentumdash.com/feed/bulk?syncTypes=backgrounds&localDate=' + today, headers=headers) image_list = r.json()['backgrounds' ] image_url = '' print (image_list)for image in image_list: if image['forDate' ] == today: image_url = image['filename' ] print (image_url)if image_url: urlretrieve(image_url, filename) img = Image.open (filename) new_img = img.resize((1536 , 1023 ), Image.ANTIALIAS) new_img.save(filename, quility=100 )