至臻完美,只为阅读 —— Kindle Paperwhite 简评

Kindle Paperwhite 3

最近入手了 Kindle Paperwhite 电子书阅读器,用了一段时间后给大家简单地评价一下。


缘起

前些天去日本亚马逊上查看我喜欢的轻小说新刊的出版情况时发现「エロマンガ先生」已经更新到第八卷了,而我只买到第六卷。在网上查了一下,似乎第七卷的翻译都还是遥遥无期,也就不用指望近期有第八卷的中文翻译可以看了,于是打算再次海淘一波轻小说新刊回来看。

但是不幸的是,因为第七卷是在去年八月份发售的,日亚上已经没有现货了,得等 1~3 个星期调货来,再加上两星期多的运输时间,非常吃瘪。再加上海淘高昂的运费,这样下去肯定不是个办法啊,毕竟日版书籍直邮和转运的运费可都不是开玩笑的:

日亚直邮运费

您可能是正版书籍的受害者(摊手)

就在这时,我正好瞄到了这本书有 Kindle 版,又正好看见很多轻小说都在 Kindle 商店出版了,以前又正好得知 Kindle 阅读体验很好而且中亚上有很多便宜的电子书,于是。。。

阅读全文→

博客样式与字体的更新报告

一直想改进一下博客的字体和在手机上的样式,奈何最近一直没有时间,只好作罢。昨天晚上抽出一些时间做了一些改进,顺便写篇博文算是记录灌水(笑)。

标题字体改为 Roboto Slab

Roboto Slab 是粗衬线体,比起 Georgia 更适合做标题。

效果图

(上面是 Georgia,下面是 Roboto Slab)

全局除正文外的西文字体使用 Alegreya

之前正文以外的西文字体都是使用的 Georgia,同样是衬线字体,Alegreya 的衬线更加富有书法气息,比较帅气。

阅读全文→

为何 shadowsocks 要弃用一次性验证 (OTA)

前些天,shadowsocks 提出了 SIP004 草案,旨在使用 AEAD 算法 取代原先的不安全的 流加密 + OTA,并弃用了一次性验证 (OTA)。

新协议的提出对于 shadowsocks 是一个非常非常重大的改进,因此我写了这篇博文为看不懂洋文的友们科普一下「为什么 OTA 会被这么快被弃用」以及「为什么应该使用新协议」。

一、OTA 是什么

OTA(One Time Auth,一次性验证),是之前 shadowsocks 为了增强安全性,抵抗 CCA(Chosen-ciphertext Attack,选择密文攻击)而加入的实验性功能。

我觉得应该很多人都听过这玩意 —— 就算不知道 OTA 是啥好歹也在 shadowsocks 各分支的客户端上看到过「一次性验证」的开关吧?虽然这个名字确实起得有点让人不明所以就是了(笑)。

那么下面我来科普下当初为什么要加入 OTA 功能。

阅读全文→

我的 2016 年终总结

人生天地之间,若白驹之过隙,忽然而已。——《庄子·知北游》

又到了写年终总结的时候了,时间过得真鸡儿快啊。虽然没有 Maxine Caulfield 那样操控时间轴的能力,但是回顾一下我在 2016 的大事件的能力还是有的:

概览

过去的一年里,本博客的基本访问情况如下图:

Google Analytics Overview

这期间,本博客一共迎来了 36,637 位用户,他们一共产生了 56,667 次会话以及 96,728 次浏览。平均每天 100 位用户、155 次会话以及 265 次浏览。

阅读全文→

博客启用新域名 Blessing.Studio

原来的域名 prinzeugen.net 一直被人吐槽说不好记,但苦于没有什么中意的其他的好记的域名,所以换域名的计划就一直搁置着。

其实我以前就听说过 .studio 这个顶级域名了,但是当时(15 年中旬)还没有开放注册,所以后来也就忘却了它的存在。然而几天前在机缘巧合下我得知了它早在 2015.10 就已经开放注册了,并且现在一年只要百来块就能搞到,于是。。

QQ20161224205054.png

这也是没有办法的事情嘛~ QQ20161225134536.jpg

そういうわけで、博客要迁移至新域名 blessing.studio 啦~

目前 prinzeugen.net 已经 301 至新域名,并且提交了 Google Search Console 和 Disqus 评论的转移请求,估计过个一天可以迁移完毕。

嗯?你说 .studio 不能备案,对百度 SEO 不好?

Who cares. QQ20161225135139.jpg

阅读全文→

Laravel 使用 whoops 处理错误最优雅的姿势

filp/whoops 这个错误处理类库有什么好处我这里就不赘述了,谁用谁知道。

Laravel 在 4.x 时代是有集成了 whoops 的,但是在 5.x 去掉了。不过作为一个 out-of-the-box 的错误处理类库,我们依然可以很方便地将 whoops 带回 Laravel 中。

网上有很多文章都讲述了 Laravel 使用 whoops 的方法,但总有些小问题(像是代码太丑了啊,代码太丑了啊之类的)。其中我认为最优雅的实现是这篇文章所描述的:Bringing Whoops Back to Laravel 5,我下面的也是基于他给出的代码修改的。


安装 whoops 之类的步骤我这里就不说了,这些在它的 README 上都有。安装完后打开 app/Exceptions/Handler.php 这个文件,进行如下修改:

/**
 * Render an exception into an HTTP response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Exception  $e
 * @return \Illuminate\Http\Response
 */
public function render($request, Exception $e)  
{
    if ($e instanceof
阅读全文→

手动修改 Laravel url() 函数生成的 URL 中的根地址

大家都晓得 Larevel 的一票帮助函数中有个 url(),可以通过给予的目录生成完整的 URL,是非常方便的一个函数:

// return: https://skin.dev/user/profile
url('user/profile')  

但是这玩意生成的 URL 中要补完的部分是框架内部根据 Request 自动判断的,而自动判断出的东西有时候会出错(譬如在套了一层反向代理之类的情况下)。

文档上并没有提到我们要如何才能自定义它生成的 URL 中的根地址和协议头部分(http(s)),这就非常吃瘪了。那我们要咋办呢?

首先我们来看看 url() 被定义的位置:

# File: src/Illuminate/Foundation/helpers.php

/**
 * Generate a url for the application.
 *
 * @param  string  $path
 * @param  mixed   $parameters
 * @param  bool    $secure
 * @return Illuminate\Contracts\Routing\UrlGenerator|string
 */
function url($path = null, $parameters = [], $secure = null)  
{
    if (is_null($path)) {
        return app(UrlGenerator::class);
    }

    return app(UrlGenerator::class)-&
阅读全文→

Artisan::call('migrate') 在 APP_ENV 为 production 时不工作的解决方法

最近把版本库里 .env.exampleAPP_ENV 字段值从原来的 local 改为了 production,原意是为了更好的区分开发和生产环境。

然而今天在主机壳的虚拟主机上测试我的程序的时候(准备把演示站搬过去),却出现了奇怪的问题——数据库 Migration 不管用了。

我是在控制器里通过调用 Artisan::call('migrate') 来执行数据库迁移操作的(毕竟虚拟主机哪来的 shell 访问),但是这次这条命令竟然没有执行任何事务。

通过 Artisan 执行 Command 的简化流程大概是像这样的:

Illuminate\Foundation\Console\Kernel  
↓
Illuminate\Console\Application  
↓
Illuminate\Console\Command  
↓
Illuminate\Container\Container  
↓
// 这个就是执行 Artisan::call('migrate') 时调用的类
Illuminate\Database\Console\Migrations\MigrateCommand  
↓
……

经过一段时间的排查,最后锁定了是在 MigrateCommand 这个类停止继续往下执行的,即接下来的脚本都没有被执行到,也就是说问题就出在 MigrateCommand 这里。

阅读全文→

使用 Certbot 更新 Let's Encrypt 证书

Let's Encrypt 证书即将过期时会给你发送邮件,这个还是比较贴心的。这样也就不会陷入证书过期却没发现的尴尬境地(Let's Encrypt 的证书只有 90 天的有效期)。

2826714bc9645e4b9828433b8e674800.png

以前我写过使用 Certbot 这个工具申请证书的文章,而同样使用这个工具更新证书只需要一行命令:

certbot renew --post-hook "service nginx reload"  

certbot 这个脚本的位置呀名称啥的自己看着改,对于我来说是 ./certbot-auto。加了个钩子可以让它在证书更新更新完毕后重载 Nginx 配置来更新证书。

b2134999636066c29c9e93a40bd88a57.png

不想每次都登上去更新的也可以把上面那行脚本加入 crontab(crontab -e),让它每个月执行一次:

# 这里用绝对路径,保险一点
0 0 1 * * /home/xxx/certbot-auto renew --post-hook "service nginx reload" >/dev/null 2>&1  

P.S. Xshell 管理远程机子比起单纯的终端来还是很方便的,而且最近也对 Home/School 发放免费许可了。

参考链接:Renewing certificates - Certbot User Guide

阅读全文→

PHP 远程文件下载的进度条实现

PHP 实现远程下载文件到服务端并不是什么新鲜玩意,用 cURLfile_get_contentsfopen 等都能够轻易实现。

但是这几种常规的方法都是在一个线程内下载文件,等文件下载完毕以后才能返回 HTTP 响应。所造成的结果就是用户在页面上点击「下载到服务器」按钮后,会看到空白页和加载的小菊花转啊转,转好久之后才出现「下载成功」的页面。

当然,我上面所举例的情况是只使用纯粹的表单 POST 发送请求的情况。现在的话就算再不济也一般会使用 ajax 发送请求,然后在前台放个加载动画,等收到下载成功的回应之后再进行下一步操作。

但是!即使是去掉了恶心的且需要等待的空白页,这样做还是对用户体验有不好的影响。没有具体的下载进度,只有一个一直转呀转的菊花图,估计挺多用户都无法坐和放宽吧(至少对于我来说是这样的)

而我一个 PHP 项目的一键更新系统正好需要重构,遂研究了如何在 PHP 作为后端时显示远程文件下载进度条,并捣鼓出了个像样的解决方案,在这里分享一下。

阅读全文→