Nov 7, 2016
Life晚上败了个索尼大法,回想起来跑步这么些年,听坏的播放装备简直是……提起来就让人"心痛到无法呼吸”。好了,下面
来盘点一下被我玩坏过的装备。
跑步中会大量出汗,因而选择运动装备,无论是耳机还是播放设备,第一是防水、第二还是防水、第三还是防水—-重要的事情说
三遍! 如果你还没悟到防水的重要,那可能是因为:
1、 你处于高纬度地带,跑步压根不出汗;
2、 你跑步的速度可能有点。。。。。。慢;
3、 你没有汗腺,可以像狗狗一样伸个舌头就散热。。。(开个玩笑)
意外的是,在诸多运动耳机中,我第一时间想到的是Philips的耳机. 便宜、耐操,
防水性超好:
Philips 灵活挂钩式耳机 SHS3200BK/37 :

特点:
非入耳式,跑步时很安全(可以听到汽笛声铃铛声等)。这个耳机是我用过的最耐操的,先后买过两个,
白色和黑色。这个耳机的脆弱点在于,它的与耳朵接触的部位含有少量金属,因而会慢慢被腐蚀,最后
导致声音越来越少。本人右耳出汗稍微多点,每次都是坏右耳。
重音很好。
价格:入手时50左右,现在可能涨了点。
使用寿命:一年+。
飞利浦(PHILIPS) SHQ3200/98 ActionFit:

特点:
入耳式,听各种协奏曲会很爽。耐操程度不如上一个。这个耳机我也买过两个。脆弱点在于:发音部分
含有金属,所以,会被汗液慢慢腐蚀。
缺点: 带上以后,跑公路很危险,因为是入耳式。
使用寿命:9个月左右。
DECATHLON

么有评价,只是告诉你们不要买就是了。买来听两个月就挂的货,毕竟是找到国内企业低成本代工。。。。
Moto SF200

在200左右的价位入手,结果大失所望,听了5个月就坏掉了,一个耳朵没声音。
蓝牙耳机不评论。盖因本人一直用有线听音乐。当然蓝牙适配器也是有的,因为汗水的缘故,已经挂掉了
N个。。。。
跑步时候的播放设备,曾经用过PHILIPS、SANDISK、爱国者的MP3,还有几台NOKIA手机。然而我可以很负责任
的告诉各位—-这些设备现在通通不能用了,因为被汗水诟坏了。
所以,到最后我只能剁手这个:

索尼大法好,希望索尼大法能被我操两年+。
Nov 7, 2016
Technologyimg preparation
First you got a qcow2 file, which could let you startup a virtualmachine, so you
startup a machine like following:
# cp YourQcowFile.qcow2 ./box.img
# qemu-system-x86_64 -net nic -net user,hostfwd=tcp::2222-:22 -hda ./box.img -m 512
--enable-kvm
Login to the machine and run following scripts:
useradd -m vagrant
mkdir /home/vagrant/.ssh
chmod 700 /home/vagrant/.ssh
echo "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key" > /home/vagrant/.ssh/authorized_keys
chmod 600 /home/vagrant/.ssh/authorized_keys
chown -R vagrant.vagrant /home/vagrant/.ssh
# Sudoers
sed -i -r 's/(.* requiretty)/#\1/' /etc/sudoers
cat > /etc/sudoers.d/90-vagrant-users <<EOF
# User rules for vagrant
vagrant ALL=(ALL) NOPASSWD:ALL
EOF
Now close the machine.
Create a new metadata file like following:
# vim metadata.json
{
"provider" : "libvirt",
"format" : "qcow2",
"virtual_size" : 4
}
Create a Vagrantfile like following:
$ vim Vagrantfile
# The contents below were provided by the Packer Vagrant post-processor
Vagrant.configure("2") do |config|
config.vm.provider :libvirt do |libvirt|
libvirt.driver = "kvm"
end
end
# The contents below (if any) are custom contents provided by the
# Packer template during image build.
Now tar the box file via following:
# tar czvf Trusty.box ./metadata.json ./Vagrantfile ./box.img
Using box
Add box file via:
# vagrant box add Trusty.box --name "trusty64"
Nov 6, 2016
Technology近期广州雾霾实在是有点醇厚,所以周末的第一选择当然是进山避霾啦!
今天定它个小目标,快速穿越帽峰山脉。
帽峰山是广州周边我非常喜欢的一座山,距市区有点距离(40公里?),配套设施好、
人流量适中、植被茂密、空气清新。这一年多来去了好几次,每次都有新发现。今天
走的是一条穿越的线路,20公里,白山村->山顶->古庙出口。
早上游泳的缘故,出发得晚,11点多才开始走白山村道,果然没有雾霾,蓝天白云:

水厂后面的山峰郁郁葱葱,深山有好水:

沿途有村民营业的大量取水点,自备矿泉水桶过来装,2元/桶。拉回城应该随便就能卖到20
块一桶吧? 发家致富的路子,窝也只能指点到这了:

锄禾日当午, 要珍惜盘中餐啊,看下图,向我学习:

惭愧,走了一个小时就饿了,果断吃饭,考虑一会要在山里跑,吃素淡点就不点鱼了。喜欢
吃鱼的朋友到了帽峰山可以点鱼吃,铜锣湾水库水质不错,出品的鱼很美味:

这位一直围着桌子喵喵叫的小兄弟, 窝那么富有爱心当然不会忘了你:

山间风景:

15分钟到顶,开始沿着山脊往帽峰山顶广场穿行:

速度有点快,1小时不到抵达帽峰山顶广场:

山顶俯瞰林海, 空气没得说,怎样都是负氧离子饱和:

北国早已寒冷如咧,可这帽峰山里风景, 依然青翠如夏:

下午3点40,自古庙出口下到山底,结束愉快的帽峰山一日之旅。
如此算来,从白山村到杨伙寮,经箫神顶到帽峰山顶景区后经古庙下山,可以在三个小时内完成。
压轴奉上帽峰山脉一景. Life is short, play more.

Nov 5, 2016
Technology背景
众所周知疼讯其实一直是一个很封闭傻逼的企业,早年QZONE的代码就层层加密,
惟恐互联网爬虫爬到它上面取内容。进入到移动互联网时代,就更加变本加厉,盆友
圈里的诸多内容,恐怕诸位都是没办法弄出来的。
早年曾在Blog上添加过分享到朋友圈或分享到微信好友按钮,由于github.io未
被疼讯认可,共享出来的链接通常只有自己能看到,这又是一个拿用户当SB的典型
案例。
还好,对于用户上传图片,疼讯是没法限制的。所以有了以下的开发。
功能参考
在博文里添加按钮一键保存为图片,即可将该篇文章生成为长图片。

参考设计: 锤子便签。顺便吐槽一下锤子便签,添加了关键词过滤,关键词嘛,这也是
党国拿来折腾屁民的一个傻逼玩意,例如有一首歌是这么唱的:
我爱北京关键词,
关键词上太阳升。。
伟大得领袖关键词,
带领我们向前进…
╮〔╯ε╰〕╭ —太多的关键词,容易让写博文的人心情不好。
可选方案
A. wkhtmltoimage.
这个转换起来是全屏转换,所以最初想到的是对网页做再加工,抠取出其中含有内容的一部分。
好处是,真的是所见即所得。
$ wkhtmltoimage http://www.google.com google.jpg
B. html2canvas.
这种方案直接在html页面上做文章,添加按钮后直接用画布来生成对象。缺点是有些格式显示出来
有少量阴影。
暂时基于方案B实现。
Code
参考资料:
https://www.youtube.com/watch?v=-d2FeFiBvEo
https://html2canvas.hertzen.com/
因为本博客基于hugo构建,直接修改hugo使用的主题即可添加html2canvas。
目录结构:
$ ls
config.toml content id_rsa.enc scripts static themes
$ themes/hyde-a
$ ls
archetypes images layouts LICENSE README.md static theme.toml
下载html2canvas.js到主题的static/js目录:
$ cd static/js
$ wget
https://github.com/niklasvh/html2canvas/releases/download/0.4.1/html2canvas.js
在主题的./layouts/partials/head.html文件中添加所需要的js文件及javascript代码
, (+代表新添加代码):
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.5/styles/docco.min.css">
+ <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
+ <script type="text/javascript" src="/js/html2canvas.js"></script>
+ <script type='text/javascript'>//<![CDATA[
+ function genPostShot() {
+ var rightNow = new Date();
+ var imageName = rightNow.toISOString().slice(0,16).replace(/(-)|(:)|(T)/g,"");
+ imageName += '.jpg'
+ html2canvas(document.getElementsByClassName('post'), {
+ onrendered: function(canvas) {
+ // Click them for download
+ $('#test').attr('href', canvas.toDataURL("image/jpeg"));
+ $('#test').attr('download',imageName);
+ $('#test')[0].click();
+ }
+ });
+ };
+ //]]>
+ </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.5/highlight.min.js"></script>
简单解释一下这几行代码:
- 取当时UTC时间作为下载jpg文件名。
- 在当前页面中根据div的class名称找到
post字段,构建一个画布。 - 将画布内容输出为jpeg文件,触发浏览器的一个下载动作。
注意: #test为在html文件中添加的一个不可见链接.
接下来修改每个博文用到的模板文件(layourts/post/single.html):
{{ partial "head.html" . }}
<div class="content container">
<div class="post">
<h1>{{ .Title }}</h1>
+ <p align="right">
+ <a href="javascript:genPostShot()">
+ TurnToJPG --> <i class="fa fa-camera-retro fa-2x"></i>
+ </a>
+ <a id="test"></a>
+ </p>
+ <hr>
<span class="post-date">{{ .Date.Format "Jan 2, 2006" }} {{ if .Site.DisqusShortname }} · <a href="{{ .Permalink }}#disqus_thread">Comments</a>{{ end }}
简单解释一下上述添加的代码:
添加一个超链接,指向上文定义的javascript函数genPostShot().
保存修改,提交到上游仓库,重新生成整个静态网站,现在每个博文里都含有保存图片按钮。
效果
譬如,点击http://purplepalmdash.github.io/2013/11/17/run-in-winter/
效果如下:

点击按钮,下载为文件201611051057.jpg(当前UTC时间戳),效果如下:

打完,收工,以后在盆友圈想怎么咆哮就可以怎么咆哮了。
Trouble-Shooting
之所以加这么个条目是因为,在未定义背景的网页里,有时候截出来的图是黑色背景的,修正:
修改./static/js/html2canvas.js文件:
sTransparent = function(backgroundColor) {
return (backgroundColor === "transparent" || backgroundColor === "rgba(0, 0,
0, 0)");
};
改为:
_html2canvas.Util.isTransparent = function(backgroundColor) {
return (backgroundColor === "transparent" || backgroundColor === "rgba(0, 0,
0, 0)" || backgroundColor === undefined);
};
之后我们在./layouts/partials/head.html中,添加这一行:
html2canvas(document.getElementsByClassName('post'), {
+ background :'#FFFFFF',
onrendered: function(canvas) {
现在生成的图片背景就是白色的了。
Nov 4, 2016
Technology准备
首先需要准备以下Docker image:
$ sudo docker pull registry:latest
$ sudo docker pull registry:2
在/etc/hosts里加一条记录,接下来我们将用这条记录生成签名(注意修改IP地址和域名):
# echo '192.168.0.121 xxx.xxx.xxx.com'>>/etc/hosts
准备所需要的自签名文件(用于tls连接)
mkdir -p certs && openssl req -newkey rsa:4096 -nodes -sha256 -keyout
certs/domain.key -x509 -days 365 -out certs/domain.crt
Generating a 4096 bit RSA private key
....................................................................................................++
......++
writing new private key to 'certs/domain.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Guangdong
Locality Name (eg, city) []:Guangzhou
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DashCom
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:xxx.xxx.xxx.com
Email Address []:xxxxxx@gmail.com
启动容器
首先拷贝出默认的registry容器的配置文件:
$ sudo mkdir -p /data
$ sudo chmod 777 -R /data
$ sudo docker run -it --rm --entrypoint cat registry:2 \
/etc/docker/registry/config.yml > /data/config.yml
修改默认文件,添加proxy字段等,我的配置如下:
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
http:
addr: :5000
tls:
certificate: /var/lib/registry/domain.crt
key: /var/lib/registry/domain.key
headers:
X-Content-Type-Options: [nosniff]
proxy:
remoteurl: https://registry-1.docker.io
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
将上一步生成的domain.crt和domain.key文件也拷贝到/data文件夹下.
现在运行容器:
$ sudo docker run -d --restart=always -p 5000:5000 --name v2-mirror -v
/data:/var/lib/registry registry:2 /var/lib/registry/config.yml
运行完这条命令后,可以用sudo netstat -anp| grep 5000来检查registry服务是否被启动。
使用Registry服务
在客户机上,需要做以下设置, 这里我写成脚本的方式,具体的调整需要根据实际情况:
echo '192.168.0.121 xxx.xxx.xxx.com'>>/etc/hosts
apt-get install -y wget
mkdir -p /etc/docker/certs.d/xxx.xxx.xx.com:5000/
wget -O /etc/docker/certs.d/xxx.xxx.xxx.com:5000/ca.crt http://192.168.0.121/domain.crt
sed -i 's#fd://#fd:// --registry-mirror https://xxx.xxx.xxx.com:5000#' /lib/systemd/system/docker.service
systemctl daemon-reload
systemctl restart docker
这里的http://192.168.0.121/domain.crt是我把domain.crt文件放在一个web服务器上了,可以
直接拷贝现成的,改名即可。
现在测试:
# curl -I https://xxx.xxx.xxx.com:5000/v2 --cacert \
/etc/docker/certs.d/xxx.xxx.xxx.com\:5000/ca.crt
HTTP/1.1 301 Moved Permanently
Docker-Distribution-Api-Version: registry/2.0
Location: /v2/
Date: Fri, 04 Nov 2016 09:42:41 GMT
Content-Type: text/plain; charset=utf-8
检查镜像:
# curl https://xxx.xxx.xxx.com:5000/v2/_catalog --cacert \
/etc/docker/certs.d/xxx.xxx.xxx.com\:5000/ca.crt
{"":[""]}
docker pull一个镜像:
# docker pull busybox:latest
现在检查:
# curl https://xxx.xxx.xxx.com:5000/v2/_catalog --cacert \
/etc/docker/certs.d/xxx.xxx.xxx.com\:5000/ca.crt
{"repositories":["library/busybox","library/ubuntu"]}
可以看到,library/busybox这个镜像已经被缓存在了本地registry仓库中。