前言※
不少朋友注意到本站新增了一个「现在」页面,其中可以自动同步网易云、豆瓣等信息,有些朋友对这个功能有兴趣,于是此处分享一下实现方法。
准备工作※
- 安装并部署了Ankia博客主题
- Ankia - Theme 更新到 v1.7 版本以上
在博客中新增一个页面※
使用本博客系统新增一个界面十分简单,初次部署时你需要在「Ankia - Theme.ejs」下新建一个名为「now」的ejs类型笔记(该笔记不允许空白,你可以添加一段无关紧要的代码,比如添加一个<hr>标签),然后在「DIY 导航栏」笔记下方新建一个名为「现在」的文字笔记,并且在此笔记中添加以下属性:
#categoryName=现在 #shareAlias=now
本页面与其他页面一致,同样支持显示评论等功能,如果需要增加额外功能,详见: Trilium博客主题:Ankia 使用指南
一个空白的网页就建立完成了,你所有在「现在」笔记中写下的内容都会同步至此页面,其内容是你可以自由 DIY 的,尽情发挥创意吧!
注:此页面必须填写一些内容,否则无法正常显示后文的豆瓣、网易云等信息
接下来将介绍一下如何同步豆瓣和网易云信息,在 Ankia - Theme 的 v1.7 版本中已经内置了相应的样式,你需要「now」笔记中按照以下格式添加一个板块,比如添加豆瓣观影记录板块:
<p><span class="text-huge">📚最近看的电影和书籍</span></p>
<div class="fLinkContainer">
<% const filmRecord = JSON.parse(note.getLabelValue('filmRecord').replace(/<\/?pre>/g, '').replace(/[\n\s]/g, ""));
for (let key in filmRecord) {%>
<a class="filmBox">
<img src="<%= filmRecord[key]['img'] %>" alt="<%= filmRecord[key]['title'] %>">
<div class="filmTitle"><%= filmRecord[key]['type'] %><br><%= filmRecord[key]['title'] %></div>
<div class="watchDate"><%= filmRecord[key]['pubDate'] %></div>
</a>
<% }%>
</div>
其中,
filmRecord
是你在下文中自定义的属性名
现在在浏览器中打开此页面应该会报错,不用着急,我们还没有配置完成。
同步豆瓣观影信息※
获取个人 RSS 地址※
在网页版的豆瓣中打开个人主页,找到这个位置:
点击它,将地址栏中的地址记下来。
解析 RSS 并储存到笔记※
在任何你想存放此笔记的地方建立一个 JS backend
类型的笔记,粘贴以下代码,并修改代码中的 RSSURL
和 NOTEID
为实际的值:
const RSSURL = "rss"; //你的个人豆瓣 RSS 地址
const NOTEID = ""; //上一步中建立的「现在」笔记的 NoteID
async function fetchRSSData(url) {
const response = await api.axios.get(url);
const data = response.data;
const jsonData = await api.xml2js.parseStringPromise(data);
const keyWord = ["看过","在看","想看","读过","在读","想读"];
const items = {};
let num = 0;
function splitStringByKeywords(str) {
const regex = new RegExp(keyWord.join('|'));
const match = str.match(regex);
if (match) {
const index = str.indexOf(match[0]);
const prefix = str.substring(0, index + match[0].length);
const suffix = str.substring(index + match[0].length);
return [prefix, suffix];
}
return [str];
}
if (jsonData.rss && jsonData.rss.channel && jsonData.rss.channel[0].item) {
for (const item of jsonData.rss.channel[0].item) {
const date = api.dayjs(item.pubDate[0]);
const formattedDate = date.locale('zh-cn').format('YYYY 年 MM 月 DD 日');
const updatedText = splitStringByKeywords(item.title[0]);
items[num] = {
type : updatedText[0],
title : `《${updatedText[1]}》`,
link : item.link[0],
img:item.description[0].match(/<img[^>]+src="([^">]+)"/)[1],
pubDate : formattedDate
};
num+=1;
}
}
return items;
}
fetchRSSData(RSSURL).then((items) => {
const note = api.getNote(NOTEID);
note.setLabel("filmRecord",JSON.stringify(items));
});
你可以立即运行一次试试,现在在浏览器中查看此界面应该能够看到效果了,如果你需要定时更新的话,请在刚刚创建的脚本笔记中设置 #run=hourly
属性实现每小时更新一次。
小提示:在添加了以上属性的基础上,你可以继续添加
#runAtHour=3
属性将更新时间变更为每天 3 点,或者添加#runOnInstance=xxx
属性让其只在某个特定实例上运行。
同步网易云音乐※
注:此方法目前还存在一定的不稳定性,比如需要定期更换 cookie,偶尔会获取失败等问题。
与上一步类似,我们需要先在「now」中添加一个用于显示的板块:
<p><span class="text-huge">🎶最近喜欢的音乐</span></p>
<div class="fLinkContainer">
<% const musicRecord = JSON.parse(note.getLabelValue('musicRecord').replace(/<\/?pre>/g, '').replace(/[\n\s]/g, ""));
for (let key in musicRecord) {%>
<a class="filmBox">
<img src="<%= musicRecord[key]['imgUrl'] %>" alt="<%= musicRecord[key]['musicName'] %>">
<div class="filmTitle"><%= musicRecord[key]['musicName'] %></div>
<!-- 此处为播放按钮的样式,点击可自动播放音乐(只可以播放免费音源),如果需要此功能可以取消注释
<svg class="playMusicButton" musicid="<%= musicRecord[key]['musicId'] %>" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-play-circle">
<circle cx="12" cy="12" r="10"></circle>
<polygon points="10 8 16 12 10 16 10 8"></polygon>
</svg>
-->
<div class="watchDate"><%= musicRecord[key]['artists'] %></div>
</a>
<% }%>
</div>
然后通过脚本定时获取数据:
const NOTEID = "" //上一步中建立的「现在」笔记的 NoteID
const USERID = "" //网易云的歌单 ID
const cookie = "" //网易云登录 cookie
async function fetchMusicDetails() {
const headers = {
'Cookie': cookie
}
var musicDetails = {}
let num = 0
let success = false
let retryCount = 0
while (!success && retryCount < 4) {
try {
const response = await api.axios.get(`https://music.163.com/api/playlist/detail?id=${USERID}`, {
headers: headers
})
const tracks = response.data.result.tracks.slice(0, 10)
tracks.forEach((track) => {
musicDetails[num] = {
musicName: track.name,
musicId: track.id,
artists: track.artists.map(artist => artist.name).join('/'),
imgUrl: track.album.picUrl
}
num += 1
})
success = true
} catch (error) {
retryCount++
}
}
return musicDetails
}
fetchMusicDetails().then((musicDetails) => {
const note = api.getNote(NOTEID);
note.setLabel("musicRecord",JSON.stringify(musicDetails));
});
歌单 ID 的获取方式很简单,登录网页版网易云后,点击「我喜欢的音乐」页面,地址栏中的数字就是歌单 ID;cookie 则需要打开 F12,在请求的 Cookie 中找到包含MUSIC_U
字段的数据。
结语※
总结以下,添加一个板块需要进行以下几个步骤:
- 在「now」笔记中添加一个模板;
- 获取需要的信息源;
- 将获取的数据保存在「现在」笔记的属性中;
通过以上步骤,你可以同步任何你喜欢的信息源。
关联阅读: