利用双鱼眼图制作全景图

许多全景相机,如米家全景相机,由2个鱼眼相机组成. 生成的文件为鱼眼镜头图片,如下图 如果需要将双鱼眼图片制作成为全景图很多时候需要安装专业软件,比如PTGui. 偶然在Github上发现了一个相关项目dualfisheye2equirectangular是特地满足这样的需求. 按照README操作后可以成功生成如下全景图原图 生成的原图在两张鱼眼接缝的对方会有重叠,因为使用了大于180度的鱼眼镜头. »

Author image 月杪 on #Other,

YAML,比JSON更适合作配置文件

很多项目使用JSON作为配置文件,最明显的例子就是npm和yarn使用的package.json文件.当然这更多的是因为JSON和JS千丝万缕的关系. 但是,JSON实际上是一种非常糟糕的配置语言.别误会我的意思,我其实是喜欢JSON的.它是一种相对灵活的文本格式,对于机器和人类来说都很容易阅读,而且是一种非常好的数据交换和存储格式.但作为一种配置语言,它有它的不足. JSON的问题 缺乏注释 注释对于配置语言而言绝对是一个重要的功能.注释可用于标注不同的配置选项,解释为什么要配置成特定的值,更重要的是,在使用不同的配置进行测试和调试时需要临时注释掉部分配置.当然,如果只是把JSON当作是一种数据交换格式,那么就不需要用到注释. 我们可以通过一些方法给JSON添加注释.一种常见的方法是在对象中使用特殊的键作为注释,例如“//”或“__comment”.但是,这种语法的可读性不高,并且为了在单个对象中包含多个注释,需要为每个注释使用唯一的键.David Crockford(JSON的发明者)建议使用预处理器来删除注释.如果你的应用程序需要使用JSON作为配置,那么完全没问题,不过这确实带来了一些额外的工作量. 一些JSON库允许将注释作为输入.例如,Ruby的JSON模块和启用了JsonParser.Feature.ALLOW_COMMENTS功能的Java Jackson库可以处理JavaScript风格的注释.但是,这不是标准的方式,而且很多编辑器无法正确处理JSON文件中的注释,这让编辑它们变得更加困难. 过于严格 JSON规范非常严格,这也是为什么实现JSON解析器会这么简单,但在我看来,它还会影响可读性,并且在较小程度上会影响可写性. 低信噪比 与其他配置语言相比,JSON显得非常嘈杂.JSON的很多标点符号对可读性毫无帮助,况且,对象中的键几乎都是标识符,所以键的引号其实是多余的. 此外,JSON需要使用花括号将整个文档包围起来,所以JSON是JavaScript的子集,并在流中发送多个对象时用于界定不同的对象.但是,对于配置文件来说,最外面的大括号其实没有任何用处.在配置文件中,键值对之间的逗号也是没有必要的.通常情况下,每行只有一个键值对,所以使用换行作为分隔符更有意义. 说到逗号,JSON居然不允许在结尾出现逗号.如果你需要在每个键值对之后使用逗号,那么至少应该接受结尾的逗号,因为有了结尾的逗号,在添加新条目时会更容易,而且在进行commit diff时也更清晰. 长字符串 JSON作为配置格式的另一个问题是,它不支持多行字符串.如果你想在字符串中换行,必须使用“\n”进行转义,更糟糕的是,如果你想要一个字符串在文件中另起一行显示,那就彻底没办法了.如果你的配置项里没有很长的字符串,那就不是问题.但是,如果你的配置项里包括了长字符串,例如项目描述或GPG密钥,你可能不希望只是使用“\n”来转义而不是使用真实的换行符. 数字 此外,在某些情况下,JSON对数字的定义可能会有问题.JSON规范中将数字定义成使用十进制表示的任意精度有限浮点数.对于大多数应用程序来说,这没有问题.但是,如果你需要使用十六进制表示法或表示无穷大或NaN等值时,那么TOML或YAML将能够更好地处理它们. { "name": "rsshub", "version": "0.0.1", "description": "Make RSS Great Again!", "main": "index.js", "scripts": { "start": "node index.js", "docs:dev": "vuepress dev docs", "docs:build": "vuepress build docs", "format": "prettier \"**/*.{js,json,md}\" --write", "lint": "eslint \"**/*.js\" && prettier-check \"**/*.{js,json,md}\"" }, "repository": { "type": "git", "url": "git+https://github.com/DIYgod/RSSHub.git" }, "keywords": [ "RSS" ], "gitHooks": { "pre-commit": "npm run lint" }, "author": "DIYgod", "license": "MIT", "bugs": { "url": "https://github. »

Author image 月杪 on #Linux,

用Nginx和rclone做Google Drive下载页

在写了在Linux上使用rclone挂载Google Drive等服务以后偶然想到能挂载Google Drive等一众网盘以后还能催生出很多玩法,其中一种就是与Nginx等Web server结合起来,做一个方便的下载页面. 准备 要实现下载页主要用到Nginx以及Nginx提供的一些功能. 其中包括自动检索,身份验证等. 配置 默认的情况下Nginx索引到目录会直接返回403,这个时候需要的只是开启autoindex autoindex on; 重载后就可以成功开启autoindex模式了 成功开启后还需要配置身份验证,不然只要知道地址谁可以随意下载网盘中的文件了. Nginx给我们提供了很简单的方式basic auth,配置方法: printf "user:$(openssl passwd -crypt passwd)\n" >> /etc/nginx/conf.d/passwd 其中user代表你的帐号,passwd代表你的密码,/etc/nginx/conf.d/passwd是生成好的验证文件. 然后在Nginx的配置文件相应位置加入 auth_basic "Authorized"; # 必须有basic验证的描述,否则并不会弹出要求验证窗口 auth_basic_user_file /etc/nginx/conf.d/passwd; 重载后再次打开页面,就会看到提醒验证的弹窗了. 美化 经过上面的配置已经基本可用了,不过默认的index界面确实不太美观. 于是找到了Nginx-Fancyindex-Theme这个美化模板,配置好以后的样子大概是这样: 稍微好看了一丢丢. 下载 在页面可以直接得到下载链接,不过脱离了浏览器直接下载的话会出现验证失败的错误信息,比如: curl https://drive.moonagic.com/moonagic.com_ecc.zip -o moonagic.com_ecc.zip <html> <head><title>401 Authorization Required</title></head> <body bgcolor="white"> <center><h1>401 Authorization Required</h1></center> <hr><center>nginx/1.15.2</center> </body> </html> wget https://drive.moonagic.com/moonagic.com_ecc.zip --2018-08-06 21:33:48-- https://drive.moonagic.com/moonagic.com_ecc.zip Resolving drive.moonagic.com (drive.moonagic.com)... 104.199.220.164 Connecting to drive.moonagic.com (drive.moonagic.com)|104.199.220.164|:443... connected. HTTP request sent, awaiting response. »

Author image 月杪 on #Linux,

用acme.sh签发Let's Encrypt证书

这几天用certbot签发Let’s Encrypt证书的时候发现了各种问题, 有Python版本问题以及pip源问题. 反正就是各种蠢 对我这样一个使用者来说Python制造的问题比它解决的问题还多 于是开始使用国人制作的shell工具acme.sh来签发, 这个工具安装使用很简单, 安装: curl https://get.acme.sh | sh 使用: # 使用手动dns验证 acme.sh --issue -d example.com --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please # 续签 acme.sh --issue -d example.com --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please --renew # 续签ecc acme.sh --issue -d example.com --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please --renew --ecc # 签发384位密钥的ecc证书 acme.sh --issue -d example.com --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please --keylength ec-384 # 签发泛域名证书 acme.sh --issue -d example.com -d '*.exmaple.com' --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please --keylength ec-384 第一次执行的时候会提示你需要设定的TXT记录,设定好以后再次执行就可以获取到证书了. »

Stop DHCP From Changing resolv.conf

For DHCP users, there may be times when you need to edit /etc/resolv.conf to use other nameservers. Then, after a period of time (or after a system reboot), you discover that your changes to /etc/resolv.conf have been reverted. This tutorial shows three methods to stop DHCP from changing the /etc/resolv.conf on Debian or Ubuntu. Method 1: Change interface settings to static On a cloud vps, I do not suggest using this method. »

Author image 月杪 on #Linux,

在Linux上使用rclone挂载Google Drive等服务

rclone可以帮助我们在Linux上挂载一些储存服务,包括Google drive, onedrive, box, AWS S3等等.同时不会占用硬盘空间 安装依赖 apt-get install fuse 下载 wget https://downloads.rclone.org/v1.41/rclone-v1.41-linux-amd64.zip 截止目前最新版为1.41,在 https://downloads.rclone.org/ 可以看到历史版本. 下载解压后里面的可执行文件rclone就是我们需要的,可以直接在当前目录使用也可以将其拷贝到/usr/local/bin. 配置 ./rclone config # 当前目录下执行 rclone config # 系统目录下执行 Current remotes: Name Type ==== ==== moonagic drive moonkinstar drive e) Edit existing remote n) New remote d) Delete remote r) Rename remote c) Copy remote s) Set configuration password q) Quit config e/n/d/r/c/s/q> 显示当前已经挂载了2个盘,需要新建的话键入n,然后输入新建盘的名字 Type of storage to configure. Choose a number from below, or type in your own value 1 / Alias for a existing remote \ "alias" 2 / Amazon Drive \ "amazon cloud drive" 3 / Amazon S3 Compliant Storage Providers (AWS, Ceph, Dreamhost, IBM COS, Minio) \ "s3" 4 / Backblaze B2 \ "b2" 5 / Box \ "box" 6 / Cache a remote \ "cache" 7 / Dropbox \ "dropbox" 8 / Encrypt/Decrypt a remote \ "crypt" 9 / FTP Connection \ "ftp" 10 / Google Cloud Storage (this is not Google Drive) \ "google cloud storage" 11 / Google Drive \ "drive" 12 / Hubic \ "hubic" 13 / Local Disk \ "local" 14 / Mega \ "mega" 15 / Microsoft Azure Blob Storage \ "azureblob" 16 / Microsoft OneDrive \ "onedrive" 17 / Openstack Swift (Rackspace Cloud Files, Memset Memstore, OVH) \ "swift" 18 / Pcloud \ "pcloud" 19 / QingCloud Object Storage \ "qingstor" 20 / SSH/SFTP Connection \ "sftp" 21 / Webdav \ "webdav" 22 / Yandex Disk \ "yandex" 23 / http Connection \ "http" Storage> 然后选择你需要挂载的服务的对应序号,比如我们现在要挂载Google Drive的话就键入11. »

Author image 月杪 on #VPS,

Github被微软收购

Congratulations to GitHub on their acquisition by Microsoft! This is validation of the growing influence of software developers in the world, and the importance of modern DevOps. The software community owes a lot to GitHub, and that includes the GitLab community. GitLab was first developed on GitHub and found its first contributors through it. 昨天听到微软收购Github的消息,今早Gitlab已经发布了祝贺Github被收购的文章其中附上了布隆伯格发布的相关新闻. 可能产生的影响 在技术社区里黑微软几乎已经成了政治正确的事情了. 有人列举了很多被微软收购后直接退出主流品牌的公司,比如Nokia,比如wonderlist. 甚至觉得现在的问题是微软玩死Github需要花几年. 这些人忘了微软还收购了SQL server还收购了Skype还收购了Powerpoint.. 另外最重要的一点是Github目前已经是所在领域其他竞争者无法接近的No.1 事实上就算是收购后Github应该也会继续独立运营, 控制代码托管平台又不是微软的目标,商机主要来自GitHub的付费服务,Markplace,如果 GitHub 这么大的开源平台变了味,等于买来砍了,那可太傻了. 要有真正的实质影响很可能就是Github的存储会从AWS迁移到Azure吧,其实对国内那些没有翻墙环境的人来说还有好处. »

Author image 月杪 on #Other,

GDPR到底是什么

最近几天至少收到几十个服务的有关隐私协议的邮件(如果你没收到甚至没听说过GDPR,说明你基本不使用这个星球上的主流网络服务)
那么这个GDPR到底是什么呢?

GDPR介绍

GDPR是欧盟于2018年5月25日正式开始实行的**<通用数据保护条例>**

该条例是近三十年来数据保护立法的最大变动,旨在加强对欧盟境内居民的个人数据和隐私保护.此外,它还将通过统一数据和隐私条例来简化对跨国企业的监管框架.它将取代1995年颁布的<数据保护指令>
1995年的<数据保护指令>95/46/EC是欧盟版的隐私保护条例.其主要目标包括协调数据保护立法,以及规范将个人数据转移到欧盟以外的“第三国”的情形.除了其它一系列措施,各个盟国还各自成立独立的公共机构,监督该指令的实施,并作为与企业和公民互动的监管机构.整体而言,该指令符合经济合作与发展协会(OECD)的最初建议以及隐私权是基本人权的核心概念.
虽然<数据保护指令>旨在团结不同盟国的立法,但这只是一项指令,当置换到各国独立的法律时仍有一定的解释空间.加上当今数据格局的快速变化,尤其是Facebook LinkedIn等社交平台以及云技术的兴起,势必要升级欧盟地区的监管环境.即将到来的GDPR是一项更大的立法,并且在各个成员国即刻可执行.

»

Author image 月杪 on #Other,

用Golang重写Github webhook后台服务

起因 前段时间写过一篇利用Github的Webhook功能进行持续集成, 当时使用nodejs来写了webhook的后台服务. 那个程序已经稳定运行了一段时间,期间并没有出现大的问题. 但是毕竟是js的程序,空转状态就需要占用几十Mb的内存,就一个HTTP监听占用这么大确定不是开玩笑??? 另外一个问题就是该程序跑起来以后在Linux里会是一个node进程,这个时候如果你的服务器上同时运行了好几个由nodejs驱动的程序的话..你可以想到有多壮观 行动 于是决定用go来重新实现这个工具,基本是完全复刻旧的nodejs项目然后添加了配置文件功能. GoWebhook 服务重新跑起来了,内存占用大概只有nodejs项目的八分之一到十分之一. 并且后台也不会显示一个node进程了. 后记 现在看来脚本语言还是不是太适合做服务端开发,即使服务已经跑起来了还是会想用编译语言重新写一遍. 而且得益于语言层面完善的设计和更加现代化的通用库似乎Go的开发效率并不会比js低太多喔. »

for循环中的++i和i++有什么区别

i++和++i是C系语言的经典课题, 我们知道i++和++i的表面区别为++i的返回值为i+1,而i++则为i,而它们的底层实现分别为: ++i实现: int operator ++ () { return i+1; } i++实现: int operator ++ (int flag) { int j = i; i += 1; return j; } 两者实现的本质区别为其中的j,这个j在程序中称为匿名变量. 现在很明显了,因为这个匿名变量的存在直接导致了i++比++i实际开销大. 那么,是否意味着for(int i = 0;i < n;i++)比for(int i = 0;i < n;++i)开销大呢? 带着这个问题,我想可能需要对比汇编才能看出点区别了. 现在分别创建了两份文件,内容分别为: #include <stdio.h> int main() { for (int i = 0; i < 100; ++i) { printf("%d\n", i); } return 0; } #include <stdio.h> int main() { for (int i = 0; i < 100; i++) { printf("%d\n", i); } return 0; } 然而很遗憾,在使用gcc输出汇编代码后这两份C语言代码输出了完全相同的内容: »

Author image 月杪 on #Code,