IPFS初识体验

本示例所用环境
* 机器:普通电脑 ideapad Y410
* 系统:ArchLinux
什么是IPFS? 以下内容来自维基百科

注意:IPFS官网已经被墙!!!

星际文件系统(InterPlanetary File System,缩写IPFS)是一个旨在创建持久且分布式存储和共享文件的网络传输协议。它是一种内容可寻址的对等超媒体分发协议。在IPFS网络中的节点将构成一个分布式文件系统。它是一个开放源代码项目,自2014年开始由Protocol Labs在开源社区的帮助下发展。其最初由Juan Benet设计。

IPFS是一个对等的分布式文件系统,它尝试为所有计算设备连接同一个文件系统。在某些方面,IPFS类似于万维网,但它也可以被视作一个独立的BitTorrent群、在同一个Git仓库中交换对象。换种说法,IPFS提供了一个高吞吐量、按内容寻址的块存储模型,及与内容相关超链接。这形成了一个广义的Merkle有向无环图(DAG)。IPFS结合了分布式散列表、鼓励块交换和一个自我认证的命名空间。IPFS没有单点故障,并且节点不需要相互信任。分布式内容传递可以节约带宽,和防止HTTP方案可能遇到的DDoS攻击。

该文件系统可以通过多种方式访问,包括FUSE与HTTP。将本地文件添加到IPFS文件系统可使其面向全世界可用。文件表示基于其哈希,因此有利于缓存。文件的分发采用一个基于BitTorrent的协议。其他查看内容的用户也有助于将内容提供给网络上的其他人。IPFS有一个称为IPNS的名称服务,它是一个基于PKI的全局命名空间,用于构筑信任链,这与其他NS兼容,并可以映射DNS、.onion、.bit等到IPNS。

安装

github提供的几种安装方式

怎么使用

简单使用可以参考这篇博方如何使用星际文件传输网络(IPFS)搭建区块链服务,虽然它是转载自这,但它的格式要好太多:) 。

几点疑问
  1. 目前看到的都是用来存储静态文件,感觉和FTP或者CDN有点像,当然也有人在IPFS上写了一个分布式的点对点聊天应用程序。我主要是用PHP来做动态站的,HTTP协议用在客户端与服务端之间的通讯,至于服务端是怎么处理的它并不开心,可是如果用IPFS取代HTTP协议,它怎样处理这种到服务器的请求呢?因为基于IPFS的请求都是返回一个文件,而HTTP请求到服务器后可以通过不同的Web Server进行处理。

  2. 今天写了一个小demo,一个静态页面,加上一些js效果,增加到IPFS结点后都能访问,但是当我通过ajax去请求后端脚本时,POST请求直接405错误,GET请求返回的是整个脚本文件的内容,因为它没有通过对应脚本文件的服务去解析它。我在想它到底怎么才能满足这个需求呢?还是说它已经可以满足了而我还不知道?我的IPFS线上示例

  3. To Be Continue...


补一张本地运行webui后的图,感觉这个地球不错!
webui

敏捷开发

敏捷开发:
迭代开发,价值优先
分解任务,真实进度

站立会议,交流畅通
用户参与,调整方向

结对编程,代码质量
测试驱动,安全可靠

持续集成,尽早反馈
自动部署,一键安装

定期回顾,持续改进
不断学习,提高能力

  • 脱离实际的反方观点会使用争论变味。若对一个想法有成见,你很容易提出一堆不太可能发生或不太实际的情形去批驳它。这是你扪心自问:类似问题以前发生过吗?是否经常发生?
  • 例:我们不能采用这个方案,因为数据库厂商可能会倒闭;用户绝对不会接受这个那个方案。你必须要评判那些场景发生的可能性有多大。

享有盛名的爵士吉他手Pat Methany说过这位一句话:“总是要成为你所在的那个乐队中最差的乐手”

Don't build what you can download;(不要开发你能下载到的东西)
如果你发现自己在做一些花哨的东西(比如从头创建自己的框架),那就醒醒吧,闻闻烟味有多大,马上该起火了。你的代码写的越少,需要维护的东西就越少。

使用tesseract进行验证码识别初体验

本示例所用环境
* 机器:普通电脑 ThinkPad E470c
* 系统:Ubuntu 16.04 LTS
为什么要做验证码自动识别
你被验证码折磨的还不够惨吗!?:)
什么是ocr和tesseract
OCR是Optical Character Rcognition的缩写,意思是光学字符识别,针对印刷体字符,采用光学的方式将纸质文档中的文字转换成为黑白点阵的图像文件,并通过识别软件将图像中的文字转换成文本格式,供文字处理软件进一步编辑加工的技术。

Tesseract是一个跨平台的ocr引擎,适于多种操作系统。它是一款免费软件,根据Apache许可证2.0版发布,当前(2018-03-06)稳定版为3.05.01,自2006年开发以来一直由Google赞助,2006年,Tesseract被认为是当时最准确的开源OCR引擎之一。
怎么使用
我是在Python脚本里使用,先安装相关库,在Debian / Ubuntu上:

sudo apt install tesseract-ocr libtesseract-dev libleptonica-dev
sudo pip3 install tesseroc
sudo pip3 install pillow

pillow fork自PIL库,PIL是Python Imaging Library的缩写,Python图片处理库。

代码片段:

import tesserocr
from PIL import Image

print(tesserocr.tesseract_version())
print(tesserocr.get_languages())

image = Image.open('sample.jpg'))
print(tesserocr.image_to_text(image))

print(tesserocr.file_to_text('sample.jpg'))
更高级的功能
以上功能只能识别简单验证码,稍微复杂一点的验证码都识别不出来,更高级的使用则需要对图片进行各种处理,一般是对图片进行二值化、降噪、切割等,然后对Tesseract进行训练,提高识别率,我没有实践过,就不班门弄斧啦!

完结

从企业人员调整看开去

临近年关(腊月廿二),今天(二零一八年二月七号)公司人事调整,身边几个熟悉的同事突然被撤,心中不禁感慨万千。在北京,这事儿虽然每天都在上演,但搁在自己身边依然会令人五味杂陈,更何况亲身体会的他们呢?

在此记录一下由这事得到的一些体会吧!

  • 企业或者说资本,都是无情的

    从两个方面反映的这点:

    1. 我的后端同事是经历了一个繁忙时刻过来的,现在年底稍较清闲了,然后给别人裁了,是很有卸磨杀驴之嫌的。

    2. 临近年关,真是年关,他们这一“关”就没有过去。从传统意义上来说,裁员一般不会选择在此时,而且是让立即走人,仅补偿一个月薪资。即使是在此时,也应有比较好的补偿,身边也有这样的案例的,正规N+2的补偿,然后可以在年后来办理离职。

    唉,这个年他们可能过的并不那么开心了。

  • 仅仅只靠工作生活是不行的

    不能只靠工资生活,这一点已经非常明晰了,如果你没有负债可能还好点,假如你有房贷、车贷,突然工作又丢了,一旦你不能立马找到与你现在工资相当或更高的工作,你一下子就会陷入焦虑当中,生活很可能出现混乱,导致连锁反应。

    每个人都需要一份副业,可以当作是业余时间的锻炼与自身的扩展,当然最好是有一定的存款,这样就能做到泰然自若,处变不惊。

  • 需要提高自己的综合实力

    不断提升自己的综合实力,不仅仅是技术上,还有为人处事上,有时候被淘汰可能不是技术能力上的问题,有可能问题出在沟通与处理事情的方式上,对于这一点,只要是工作3年以上的人都会深有体会。

    同一件事情,处理的人不一样,给人的感受也会大不一样,一定要避免把事情做了还得罪人的情况出现,但很多人难免这样,包括我自己也是,以后切记。

记于当晚 21:54

MySQL主备复制原理

首先,MySQL主备复制有什么作用?
  • 数据分布
    在不同的地理位置分布数据备份,这对于具有大数据的公司尤为重要。

  • 负载均衡
    通常用作读写分离,将读操作分布到多个服务器上,实现对读密集型应用的优化,并且实现很方便,通过简单的代码修改就能实现基本的负载均衡。

  • 备份
    复制既不是备份也不能够取代备份,但对于备份来说,复制是一项很有意义的技术补充。

  • 高可用性和故障切换
    复制能够帮助应用程序避免MySQL单点失败,一个包含复制的设计良好的故障切换系统能够显著的缩短宕机时间。

  • MySQL升级测试
    在将要升级全部实例前,使用一个更高版本的MySQL作为备库,测试查询是否能够在备库按照预期执行。

那么,MySQL主备复制是如何工作的呢?

一般复制分为三个步骤:

  1. 主库把数据变更记录到二进制日志(Binary Log)中(这些记录也被称为二进制日志事件)

  2. 备库从主库上的二进制日志中读取二进制日志事件,并写在自己的中继日志(Relay Log)中。备库读取日志的方式不是轮询的方式,主备库的关系有点像日本漫画与动画的关系。当动画(备库复制日志)追赶上漫画(主库没有新的事件)的时候,动画制作就会先停止(备库读日志线程会进入睡眼状态),当漫画有更新时(主库有新的事件),动画(备库)被唤醒,接着制作(读取)

  3. 备库读取中继日志中的事件,将其重放到备库数据之上

如下图所示:
MySQL主备复制工作示意图

在Linux下用FFmpeg制作自己喜欢的小视频

前言

你想在Linux下自由的创作自己的视频吗?快来试试FFmpeg吧!

  • 查看自己屏幕分辨率
xrandr
注:"xrandr" 是一款官方的 RandR Wikipedia:X Window System 扩展配置工具。它可以设置屏幕显示的大小、方向、镜像等。比如屏幕分辨率是1366×768

  • 屏幕录制
ffmpeg -video_size 1366x768 -framerate 25 -f x11grab -i :0.0+0,0 -f pulse -ac 2 -i default `date +%Y-%m-%d_%H:%M:%S`.mp4
    注:如果提示:The encoder 'aac' is experimental but experimental codecs are not enabled, add '-strict -2' if you want to use it.
    则按提示增加参数'-strict -2',如:ffmpeg -video_size 1366x768 -framerate 25 -f x11grab -i :0.0+0,0 -f pulse -ac 2 -i default -strict -2 `date +%Y-%m-%d_%H:%M:%S`.mp4

  • 给视频增加或修改背景音乐
ffmpeg -i input.mp3 -i output.mp4 [-strict -2](可选) output.mp4
注:如果视频和音频时间不一样长,需要自己额外处理

  • 视频截取
ffmpeg -i input.mp4 -ss 00:00:10 -t 120 output.mp4
注:从第10秒开始,截取120秒

  • 打马赛克
ffmpeg -i input.mp4 -filter_complex "crop=298:80:115:38, boxblur=10[blurLogo1]; [v:0] [blurLogo1]overlay=115:38" -c:a copy -y output.mp4
注:打马赛克,其实是先从原视频里截取一个小区域并模糊处理,产生新视频,然后再把新视频合并回去,这样看起来原视频的某个区域就像打了马赛克一样

  • 加Logo水印
ffmpeg -i input.mp4 -i ../watermark.jpg -filter_complex "overlay=main_w-overlay_w-55:5" -codec:a copy output.mp4
注:在overlay的位置加上watermark.jpg图片

  • 从视频中截图
ffmpeg -i input.mp4 -y -f image2 -t 0.001 -ss 10 -s 1280x720 output.jpg
注:在视频的第10秒处生成1280×720的图片

  • 制作GIF图
ffmpeg -ss 10 -t 5 -i input.mp4 -r 10 -vf scale=-1:144 -y output.gif
注:从视频的第10秒开始计时5秒生成GIF图片

  • 合并视频
vim filelist.txt
file 'input1.mp4'
file 'input2.mp4'
file 'input3.mp4'
ffmpeg -f concat -i filelist.txt -c copy output.mp4
注:如果有三个视频文件需要合并,建立一个txt文本,把文件名写入,然后用命令合并

  • 混合音频
ffmpeg -i input1.mp3 -i input2.mp3 -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -f mp3 output.mp3
-i 代表输入参数
-filter_complex ffmpeg滤镜功能,非常强大
    amix 是混合多个音频到单个音频输出
    inputs=2 代表是2个音频文件,如果更多则代表对应数字
    duration 确定最终输出文件的长度 longest(最长)|shortest(最短)|first(第一个文件)
    dropout_transition 结束后的过度时间,默认为2秒.
-f mp3  输出文件格式

  • 多张图片制作成视频
ffmpeg -f image2 -r 0.5 -i ./image%01d.jpg -vcodec libx264 -t 120 output.mp4
-r 代表每秒播放图片的帧数,比如,0.5代表每秒播放0.5帧的图片,即是每张图片播放2秒
-i 当前目录下的图片,名称image+数字规律命名的,%01d代表数字,0~99就是01d,0~999即是02d,以此类推
-t 视频时长,设置了-r,好像这个参数就不起作用了,t = (1 / r) * 图片数量,单位秒
  • 给视频增加字幕
ffmpeg -i input.mp4 -vf subtitles=字幕文件.srt output.mp4
字幕文件制作格式(括号里为说明):
1(第一段)
00:00:00,180 --> 00:00:01,800(时间,时:分:秒,毫秒)
什么是比特币?(内容)

2(第二段)
00:00:01,900 --> 00:00:04,900(时间,时:分:秒,毫秒)
比特币是第一个(内容)
去中心化的数字货币。

字幕文件下载地址
完成后的视频地址

Elasticsearch和PHP结合使用搜索分词

本示例所用环境
* 机器:普通电脑 ThinkPad E470c
* 系统:Ubuntu 16.04 LTS(在ArchLinux下测试也没有任何问题)
步骤

一. 学习Python,使用Python爬虫框架Scrapy爬取测试数据,之前准备爬取微博数据,学艺不精,爬取了豆瓣书籍目录下的一些信息。
1. 学习Python,感谢廖雪峰老师关于Python教程所作的贡献,教程地址
2. 感谢Scrapy文档,感叹:只要有一颗学习的心,知识真是唾手可得。
3. 感谢不知名网友,通过他的示例,完成了自己的需求,我自己爬取豆瓣书籍信息的项目地址


二. 爬取数据时,是保存在文件里的,用PHP把数据导入MySQL。
1. 把抓取到的书籍信息文件items.json放入第四步的demo里,然后使用demo里的PHP脚本导入MySQL.


三. 安装Elasticsearch,用PHP把数据从MySQL导入Elasticsearch。
1. 感谢阮一峰老师关于Elasticsearch教程所作的贡献,教程地址
这里面讲讲解了Elastic的安装和简单使用,还有分词插件。
2. 通过上述教程,结合Elastic官方出的elasticsearch-php库,完成了下面的demo。


四. 完成demo。
1. 项目地址
2. 图示
elasticsearch搜索显示示例图片


demo简介
  • Html+jquery+bootstrap+PHP+Elasticsearch中文分词搜索显示的示例。

demo目录结构及文件说明:

README.md 此说明


composer.json composer资源文件,此demo所使用的两个PHP库,Eloquent和elasticsearch-php库。Eloquent是Laravel里使用的数据库ORM,方便好用,能独立于Laravel使用。elasticsearch是PHP调用Elasticsearch服务的库。clone此项目后,使用命令:composer update -vvv安装依赖。


items.json 使用Python爬虫获取的豆瓣读书目录下的一些信息,JSON格式。此文件已从版本库里去掉,文件已共享


book.sql 数据库和数据表结构


douban.sql 爬取的数据导入MySQL后,导出的小部分SQL数据。觉得自己学习爬数据麻烦的同学,可以直接把数据导入MySQL。觉得数据太少的同学可以下载上面的json文件自己使用下面的脚本导入数据库,再从数据库导入ElasticSearch。


import_data_to_book_table_form_items_json.php 把items.json文件内容导入数据表脚本,命令:php 文件名直接执行


start.php PHP第三方库和数据库等前置配置



以下四个文件是单独测试Elasticsearch示例

createIndex.php 创建elasticsearch index、type(类似创建MySQL数据库、数据表),命令:php createIndex.php

insert.php 向elasticsearch插入测试数据,命令:php insert.php

search.php 根据条件查询数据,命令:php search.php

delete.php 删除elasticsearch index或者document,命令:php delete.php


douban 实际搜索显示demo目录

createDoubanIndex.php 创建elasticsearch index、type(类似创建MySQL数据库、数据表),命令:php createDoubanIndex.php

insertDataToEs.php 把之前导入MySQL的数据导入ElasticSearch,使用Eloquent ORM查出数据,然后批量插入Elasticsearch,命令:php insertDataToEs.php

search.php 前端请求的后端地址文件

view 前端模版文件目录

index.html 搜索显示页面,使用ajax分页和向后端传递数据

在自己本地测试访问地址:localhost/项目路径/elasticsearch_example/douban/view/index.html

完结

在Linux Ubuntu下把PDF扫描档转换为可编辑文本文件

本教程所用环境
* 机器:普通电脑 ThinkPad E470c
* 系统:Ubuntu 16.04 LTS
背景
    有一个朋友找我帮忙,需要把他在网上下载的一份pdf文件转换为word文档。刚开始我认为这个操作很简单,网上应该很多成熟的方案,果然,随便找找,就找到很多免费的在线转换网站。
    本以为事情结束了,native :) ,他下载的是一份扫描档pdf文件(每一页类似于一张文件),在线网站还没有找到能直接把pdf扫描档转换为word文档的,花了九牛二虎之力也没有发现简便的方法,最后我觉得应该借助Linux的工具来解决这件事(Windows有收费软件直接解决,更方便)。
方法

概括:先把pdf扫描档转换为图片,然后把图片转换为txt文本文档,最开始找到了一个软件pdfocr,但好像16.04安装不了。

  • 把pdf扫描档转换为图片

    这一步需要借助工具包poppler-utils,这个工具包里含有很多处理pdf文档的工具。

    1. 检测你是否已经安装过此工具dpkg -s poppler-utils,大多数Ubuntu默认已经安装了。如下图:
      pdf转换工具
      可以看到,有很多命令(pdftotext,pdftohtml,pdfimages等)供我们使用,如果是正常pdf文档是可以直接转换为txt文本的,命令:pdftotxt xx.pdf xx.txt

    2. 如果没有安装,则使用sudo apt install poppler-utils命令安装。

    3. 把pdf扫描档转换为png图片:pdfimages xxx.pdf -png 你的/存放/图片/目录/路径,如果你的pdf有多页,那么每页会自动生成一张图片。

  • 把图片转换成txt文档

    这一步需要借助工具是Tesseract,这个软件已经大名顶顶了。

    1. 安装命令sudo apt install tesseract-ocr tesseract-ocr-chi-sim,前一个是软件,后一个是中文简体语言包。语言包有很多,我只安装了中文简体,其它语言包如下图:
      Tesseract语言包

    2. cd进入你的/存放/图片/目录/路径

    3. 先处理单个文件试验一下:tesseract xx.png output -l chi_sim,参数:-l(L字母小写,language首字母) chi_sim是需要识别的语言包,成功后,当前目录下就会多一个output.txt文件,里面内容就是图片上的文字,但要注意,如果图片质量不好,那么识别出来的内容会有挺大的偏差。

    4. 批量处理命令:

    for i in `ls *.png | awk -F '.' '{print $1}'`;do tesseract $i.png $i -l chi_sim;done
    
ps:如果你有更好的方法,可以微信或邮件告知哟!

PHP设计模式-工厂模式

  • 工厂模式

    工厂设计模式提供获取某个对象的新实例的一个接口,同时使调用代码避免确定实际实例化基类的步骤。

    简述:假设,我们现在在获取微信端消息的通知,消息有许多类型,比如文本、图片、语音等,这些类型都包含在微信推送的内容里,需求是要把这些内容都保存在本地的数据库,我们来模拟一下,方法大概有两种:

    微信端消息的通知:用户向某服务号发送信息或触发了一些事件(扫码,上报地理位置等),如果此服务号开启了开发者的一些设置,那么微信会把相关信息或事件推送给服务号设置的接收信息地址。

  1. 获取到微信推送的内容后,判断出信息类型,然后实例化不同的对象来保存对应的信息。
    // 模拟获取信息
    $message = file_get_contents("php://input");
    switch ($message->type) {
        case 'link':
            $object = new Link();
            $object->save($message->content);
            break;
        case 'text':
            $object = new Text();
            $object->save($message->content);
            break;
        case 'image':
            $object = new Image();
            $object->save($message->content);
            break;
        case 'voice':
            $object = new Voice();
            $object->save($message->content);
            break;
        case 'video':
            $object = new Video();
            $object->save($message->content);
            break;
        case 'location':
            $object = new Location();
            $object->save($message->content);
            break;
        default:
            # code...
        break;
    }
    
  2. 使用工厂模式,可以有助于减少主代码流中基于条件的复杂性。
    // 模拟获取信息
    $message = file_get_contents("php://input");
    class MessageFactory {
        public static function create($type) {
            $class = ucfirst(strtolower($type));
    
            return new $class;
        }
    }
    
    $objcet = MessageFactory::create($message->type);
    $object->save($message->content);
    

    可以看到,第二种方式明显比第一种更简洁,不需要做过多的判断。另外,如果微信端增加了新的信息类型,我们在接收时也不需要再增加判断语句,只要增加一个处理对应类型的类即可。

    这种模式有点像硬币自动分拣器一样,不需要每个都判断它是五毛的还是一块的硬币,它会自动去到自己的存放点。见下图:
    硬币自动分拣器