Tominysun

前言

大概从22年9月份,我开始使用Obsidian作为我的记录工具。

在此之前,我曾使用纸笔等方式持续记录日记,也曾使用过OneNote和有道云笔记。

随着环境和个人想法的变化,我开始转向电子化记录,尝试了Obsidian。

初见

作为新手,无论是知乎,还是各种笔记软件推荐帖,抑或是Obsidian的官方中文论坛,都向我提供了无比丰富的资源和建议。

丰富的插件和主题,让我有一种期待与烦躁交织的心理。基于Electron,Obsidian拥有基本框架内的无限可能。

但过了一段时间后,我还是认识到,记录才是初衷,若是让插件和主题迷了眼,那这软件不用也罢!

一站式

无意中发现了DIYgod-Obsidian-Starter,其中绝大部分所需插件都已经提前打包在Repositories里面了。

美观度也符合我的预期,其中Templater和Periodic Notes的搭配使用更提高自动化程度,减少重复手动操作。

我个人在配置好Remotely Save插件后,便准备开始使用了。

问题

但当我反复测试后才发现,原作者Diygod设定的Templater的自定义函数,在Windows环境下存在不小的问题。

具体情况如这条issue所述,我尝试了许多解决方案。但最终并未深究其中细节,出于一定的偷懒考虑,我选择了服务器端代理的做法。

以下记录下相关shell及部分不成熟的想法。

原Templater自定义函数

获得当日本地天气
curl wttr.in/"$(curl -s --header "user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36" https://api.ip.sb/geoip | /opt/homebrew/bin/jq -r ".city" | sed 's/ /%20/')"\?format="%l+%c%t"
获得当日本地月相
curl wttr.in/"$(curl -s --header "user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36" https://api.ip.sb/geoip | /opt/homebrew/bin/jq -r ".city" | sed 's/ /%20/')"\?format="%m"

其中最关键的实现部分是使用https://api.ip.sb/geoip提供的IP地理位置,使用jq进行格式化处理,提供给wttr.in。(若不提供则会使用网站自己的IP地理数据库,精确度欠佳)

由于原作者使用MacOS,类Unix环境。在win环境下,我难以使用同样的操作。由于上述代码仅部分参数不同,下文将讨论其中的关键实现步骤如何在win环境下移植。

curl

我当时研究curl参数半天,但是结果发现在powershell下大部分参数都无法使用。这时才发现,win系统自带的curl是个冒牌货,它只是Invoke-WebRequestalias。(这里我不知怎么想的,坚持使用假冒的curl,实际操作中也可以将curl.exe目录放到Path下,访问时即可使用原版的curl)

发现问题后,我查找了相关文档,终于实现了win下curl访问https://api.ip.sb/geoip以获取IP地理位置。

GET请求并获取完整的content

ps> curl https://www.google.com | Select -ExpandProperty Content

添加header

-Headers @{"accept"="application/json"}

指定Method

-Method Get

阶段成果

curl -Method Get -Headers @{"User-Agent"="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0"} -URi https://api.ip.sb/geoip | Select -ExpandProperty Content

jq

实际操作中,win下的jq参数-r ".city"同样不起作用。Powershell下传递content给jq的方式我也并没有研究透彻,总不能保存本地文件,传参jq,最后删除。
于是研究在powershell下截取字符串的方式,诸如正则,findstrsubstrmatch等方法,但大多都难以写成单行形式。最后我没办法,只好选择了一个笨办法——split方法

split

curl wttr.in/$(((((curl -Method Get -Headers @{"User-Agent"="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0"} -URi https://api.ip.sb/geoip | Select -ExpandProperty Content ) -split ":")[3]) -split '"')[1])?format=\"%l+%c%t\" | Select -ExpandProperty Content

虽然在powershell下执行正常,可以获得预期结果。但在Templater中仍然无法正常工作。
或许是Electron的问题?或许是Templater插件的问题?还是Windows环境的问题?还是我shell脚本的问题?可能存在问题的地方是在太多太多。我无法深究。

毕竟,官方文档中将天气地区写在了查询的URL中。(System Commands - Templater

最后

最后,由于wttr.in的服务本身会遇到阻断,并且实现地区查询再请求在win环境下难以实现。我选择了服务器代理的形式。由于我希望固定Templater的配置文件,于是改变地理位置的任务就给到服务端。采用php+nginx反向代理简单实现。

其中我在判断get参数时,学习了php7新特性:NULL合并运算符

以前我们这样写三元运算符:
$site = isset($_GET['site']) ? $_GET['site'] : '123';
现在我们可以直接这样写:
$site = $_GET['site'] ?? '123';

结语

有关wttr.in参数,可自行在相应文档中获取。
我的实现方法非常不优雅,但这是无奈之举。以后若有机会,争取用更好的方式实现相关功能!

链接

基于 Obsidian 的生活记录系统 - DIYgod
https://github.com/DIYgod/DIYgod-Obsidian-Starter
https://superuser.com/questions/344927/powershell-equivalent-of-curl
在PowerShell中使用curl(Invoke-WebRequest)_weixin_33939380的博客-CSDN博客
Windows——cmd findstr 字符串查找增强使用说明 - 鸭子船长 - 博客园
cmd 截取字符串命令_chaofanwei的博客-CSDN博客_cmd 字符串截取
powershell 字符串处理提取_shrekz的博客-CSDN博客_powershell 字符串截取
PowerShell使用match提取字符串中的指定内容 - PowerShell - 洪哥笔记
[原创]用PowerShell对字符串处理_PowerShell的博客-CSDN博客_powershell运行 echo中的字符
Select-String (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Learn
System Commands - Templater
Nginx系列教程(7)nginx rewrite配置规则详细说明
php 判断是否get传值的参数是否存在
PHP判断null,别再=了,你真控制不住 - 腾讯云开发者社区-腾讯云
PHP substr() 函数
PHP NULL 合并运算符 | 菜鸟教程

添加新评论