G2W Ask and Learn

Chrome 扩展 Tower.im Plus 发布

Tower.im 富文本编辑器的缺陷

最近与朋友合作开发一些小东西,作为远程工作的体验,工具嘛,选择了国内的一个协作工具 Tower.im

Tower 的确是一个非常不错的协作工具,彩程一贯的好设计,任务、讨论及上传文件都很方便。

因为 Tower 不是专门为开发人员设计的,所以并没有全面的支持 Markdown 编辑,而是使用了传统的 富文本编辑器,而这个富文本编辑器的功能还相当基础,支持的功能也比较少。

甚至不支持为选中的文字插入链接,虽然 Tower 为自己内部的地址做了短链接,但学是感觉不方便, 尤其是一些带有中文的链接,直接贴在正文里简直无法直视。我曾经向 Tower 反馈过这个问题, 我有向他们反馈过这个问题,但 Tower 更新的速度自然没有办法满足我的预期的,于是就自己动手了。

编辑器功能增强

目前实现了以下的扩展功能:

  • 添加插入链接的功能
  • 添加缩进和取消缩进的功能
  • 为讨论的编辑器中也添加水平分豁线的功能

此扩展仅是暂时补完一些 Tower.im 目前不完善的功能,希望彩程能够慢慢的把 Tower.im 做的更好, 这个扩展的也将功能越来越少。

讨论

文档

安装与反馈:

在 Webstore 中安装:

https://chrome.google.com/webstore/detail/twoerim-plus/dfhmgoomjkcdlfclkpjpmhjgpdakijke

安装后打开 Tower.im 就可以使用了,本扩展只是一个内容增强脚本, 所以并不会在你浏览器中占据一个图标的位置。

本扩展是开源的:

https://github.com/GDG-Xian/crx-tower

有问题欢迎在 Issue 中提出。

Chrome 划词翻译扩展 TransIt V1.1 发布

自从发布 TransIt 以来以来,收到了大家的许多反馈,又得到了玩儿法博客的推荐,取得了还算不错的成绩。

今天,TransIt 更新到了 1.1

  1. 页面划词时,如果一个单词的翻译还未消失,再次对该词划词,不会重复翻译
  2. 修正部分单词没有查找到翻译仍然显示翻译结果的问题
  3. 页面划词翻译结果增加透明和淡入淡出效果
  4. 为翻译结果添加音标(如果有)
  5. 更新链接文本划词翻译的描述
  6. 解决频繁划词导致翻译结果跑出屏幕的问题(支持使用鼠标滚轮滚动)

大家的反馈很多,目前这一版本只更新了一部分,毕竟精力有限。大家关心的 翻译语言设置大分辨率适配部分网站上划词无法使用自定义翻译结果样式 的问题,我们会逐个在以后的版本中处理。TransIt 会不断进步。

在商店中安装:

https://chrome.google.com/webstore/detail/transit/pfjipfdmbpbkcadkdpmacdcefoohagdc

发布 Chrome 代码高亮扩展 Hiliteme

最近一段时间将我平时做的笔记Sphinx 迁移到了 Evernote,虽然搜索和编辑方便了许多,但 Evernote 毕竟不是专门给开发人员用的,它网页版的编辑器限制很多,比如粘贴内容时会剔除其中的样式,只保留白底黑字, 这样我们就没有办法粘贴漂亮的代码了。

虽然 Evernote 桌面版提供了粘贴带样式的内容的选项,但是 Web 版本一直没有支持,所以只能是通过浏览器扩展来解决了。

Hiliteme

http://hilite.me/ 是我经常使用的一个代码高亮的服务,它基于 Pygments,能提供非常丰富的解析器和样式, 而且它生成的结果样式完全是通过 style="..." 来内嵌到 HTML 元素中的,可以方便的复制到任何支持 HTML 的地方。

更方便的是,hilite.me 还提供 api,这样极大的扩展了 hilite.me 的使用场景,于是 Hiliteme 诞生了。

我尽量延用了 hilite.me 的界面风格,简单方便。

弹出窗口

用法

如果在编辑器中选中了代码片断,点击图标后会自动将选择的代码片断带到弹出窗口的代码框中,点击高亮按钮, 会自动替换页面中选择的部分。

选择代码片断

高亮结果

如果没有选择代码片断,只要将光标置到编辑器中,点击图标手动输入代码,点击高亮按钮后会将高亮的结果插入光标位置。

注意:Hiliteme 可以在 Gmail 和 Evernote 中使用哦,妈妈再也不用担心我贴代码了。

拥抱开源

Hiliteme 当然是开源的,遵循 MIT 协议,

安装 dbus-python

写一个 python 脚本需要用到 dbus,但因为 dbus-python 这个包并没有提供 setup.py , 所以无法通过 pip 直接安装,唯有下载源码手动编译安装一途了。

wget https://pypi.python.org/packages/source/d/dbus-python/dbus-python-0.84.0.tar.gz
tar zxvf dbus-python-0.84.0.tar.gz
cd dbus-python-0.84.0

但事有不顺,在 ./configure 的过程中,还是出了一些错。

configure: error: Package requirements (dbus-1 >= 1.0) were not met:

No package 'dbus-1' found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables DBUS_CFLAGS
and DBUS_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

这显然是缺失了依赖库

sudo apt-get install libdbus-glib-1-dev

然后安装就就可以顺利进行了

./configure
make
sudo make install

用 Python 批量创建云梯 VPN 连接配置

缘起

大家都知道,最近的网络不怎么和谐,速度慢不说,VPN 还总断,好在云梯 提供了挺多的服务器可以切换, 但云梯的服务器又挺多,Linux 的 Network Manager 又不支持批量添加配置,甚至配置文件都不能复制新建, 每个服务器的配置都得手动加,非常麻烦。

当然,也可以每次切换时打开配置,光改地址,但是这也非常不方便。

作为一个合格的开发人员,当然会想到用程序批量生成配置,我选择使用 Python。

寻找配置文件的位置

要批量创建配置,首先得知道配置文件在哪里,比如自己的云梯 VPN 地址中包含 example 字样,这样找起来就方便了。

grep 'example'  ~/.config -r
grep 'example'  /etc/ -r

于是轻松的定位到了配置文件的位置

grep: /etc/NetworkManager/system-connections/yunti.pptp.a: Permission denied
grep: /etc/NetworkManager/system-connections/yunti.pptp.b: Permission denied
grep: /etc/NetworkManager/system-connections/yunti.pptp.c: Permission denied

了解配置文件结构

拿一个配置文件出来看看:

[connection]
id=yunti.pptp.tw1
uuid=063db9b5-5915-4f3e-8bb4-2fe58abf5be5
type=vpn
permissions=user:greatghoul:;
autoconnect=false

[vpn]
service-type=org.freedesktop.NetworkManager.pptp
gateway=tw1.example.com
require-mppe=yes
user=greatghoul
refuse-chap=yes
refuse-eap=yes
password-flags=1
refuse-pap=yes

[ipv4]
method=auto
dns=8.8.8.8;8.8.4.4;
ignore-auto-dns=true

显然,有这么几个部分需要动态生成的

  • connection.id 这个需要是唯一的
  • connection.uuid 就是 uuid 生成一个就好了
  • connection.permissions 要添加上你的用户名嘛
  • vpn.gateway VPN 服务器的地址
  • vpn.user VPN 服务的帐户名
  • ipv4.dns 按你喜好配置就好

既然了解了,就开工吧

准备配置信息及模板

首先,让我们准备好材料:

VPN_SERVERS = [
    { 'id': 'yunti.pptp.a',  'gateway': 'a.example.com' },
    { 'id': 'yunti.pptp.b',  'gateway': 'b.example.com' },
    { 'id': 'yunti.pptp.c',  'gateway': 'c.example.com' },
]

配置中 uuid 需要动态生成了

>>> import uuid
>>> str(uuid.uuid1())
'0621ba62-888a-11e3-805c-44334c786649'

至于 connection.permissionsvpn.useripv4.dns 直接写在配置模板中即可。

tpl.cfg

[connection]
id=%(id)s
uuid=%(uuid)s
type=vpn
permissions=user:greatghoul:;
autoconnect=false

[vpn]
service-type=org.freedesktop.NetworkManager.pptp
gateway=%(gateway)s
require-mppe=yes
user=greatghoul
refuse-chap=yes
refuse-eap=yes
password-flags=1
refuse-pap=yes

[ipv4]
method=auto
dns=8.8.8.8;8.8.4.4;
ignore-auto-dns=true

生成 VPN 连接配置文件

剩下的事,就只有遍历 VPN 服务器信息,生成模板了

def add_connection(tpl, conn_info):
    filename = os.path.join(CFG_DIR, conn_info['id'])
    print '  Creating file:', filename 
    out = open(filename, 'w')
    out.write(tpl % conn_info)
    out.close()
    os.chmod(filename, 0600)

def create_all():
    tpl = open(os.path.join(CURRENT_DIR, 'tpl.cfg'), 'r').read()

    print 'Creating yunti connection files under', CFG_DIR
    for conn_info in VPN_SERVERS:
        conn_info.update(uuid=str(uuid.uuid1()))
        add_connection(tpl, conn_info)

我测试过,虽然 VPN 配置文件的文件名怎么写都行,但是如果在 NetworkManager 中修改了该连接的信息,NetworkManager 会自动将该配置文件重命为 Connection Name (也就是配置文件中 id),所以在创建文件时,还是保持文件名与 id 一致才好。

还有一个注意点是,连接配置文件必须属于 root:root 并且权限设置为 600, 因为我们需要通过 sudo 执行脚本,所以这里只需要控制 chmod 就行了。

os.chmod(filename, 0600)

完整的脚本

https://gist.github.com/greatghoul/9066705

享受成果

修改 tpl.cfg 中相关的用户名为自己的,然后执行下面的命令。

$ sudo python create_yunti_config.py 
Cleaning up yunti connection files...
  Removing file: /etc/NetworkManager/system-connections/yunti.pptp.a
  Removing file: /etc/NetworkManager/system-connections/yunti.pptp.b
  Removing file: /etc/NetworkManager/system-connections/yunti.pptp.c
Creating yunti connection files under /etc/NetworkManager/system-connections
  Creating file: /etc/NetworkManager/system-connections/yunti.pptp.a
  Creating file: /etc/NetworkManager/system-connections/yunti.pptp.b
  Creating file: /etc/NetworkManager/system-connections/yunti.pptp.c

开始使用云梯吧 :)

连接

PS: 第一次点击 VPN 连接会要求输入密码。

参考资料

在 XFCE 中使用截图工具

在 Ubuntu 中,我一直以来都是使用的 Shutter 作为主要的截图工具,它拥有超级多的截图方案, 还内置了非常棒的图片编辑工具,可以方便的添加标注。但公司的机器比较垃圾,我甚至从 GNOME 换到了 XFCE,所以尽量去挑选一些比较精致的工具来使用,而且我对 Shutter 大部分的功能也用不上, 于是卸载了 Shutter,准备换成 XFCE 的截图工具。

xfce-screenshoter

在安装 XFCE 截图之前,先卸载掉 Shutter 和 GNOME 自带的截图工具

sudo apt-get purge shutter
sudo apt-get purge gnome-screenshot

然后顺手安装 XFCE 截图工具

sudo apt-get install xfce4-screenshooter-plugin

XFCE 并没有默认的截图快捷键绑定,需要我们自己配置,可以使用 Application Finder 打开 Keyboard 工具,在 Application Shortcuts 选项卡下添加下面的配置:

xfce4-screenshooter -f  Print
xfce4-screenshooter -w  Ctrl + Print
xfce4-screenshooter -r  Shift + Print

shortcuts

参考资料:

修改终端下vim的PopupMenu选种项的背景颜色

我平常比较喜欢使用终端下的 VIM,最方便的就是随时可以使用 ctrl+z 切换到终端下执行命令, 然后再通过 fg 切换回 VIM。如果再有个透明效果,那就更赞了。不过最近换了一个配色ron 后, 有个比较困扰的问题:自动完成的弹出菜单中选中项的背景颜色和文字颜色相同!

shit

这样完全无法看清到底选择的项是什么,虽然 set background=light 可以解决,但是配色会变化, 有些刺眼。所以还是需要通过其它方式解决:覆盖颜色!

.vimrc 中加入如下配置

colors ron
hi PmenuSel ctermbg=lightblue

注意第二行,一定要在 colors ron 之后调用,不然不会生效。

治疗效果:

screenshot

当然,你也可以修改其它的颜色,比如:

:hi Pmenu ctermbg=red  "for vim
:hi Pmenu guibg=red    "for gvim

参考:http://stackoverflow.com/a/10988620/260793

更多的设置详见: :help hi

在 turbolinks 的页面中使用 contentscripts

很多网站升级到 Rails 4 以后,turbolinks 就成了标配,网站响应快了, 但为开发 Chrome 扩展的我,也带来了一些困扰。

问题

使用了 Turbolinks 的网站,并不会像传统网站那样,页面变化后,会有 DOMContentLoaded 这样的事件。

With Turbolinks pages will change without a full reload, so you can't rely on DOMContentLoaded or jQuery.ready() to trigger your code. Instead Turbolinks fires events on document to provide hooks into the lifecycle of the page.

参考: https://github.com/rails/turbolinks#events

也就是说,在 turbolinks 的页面上,你点击链接跳转时,不会再触发 jQuery.ready(), 这样一来,初始化的一些 方法就失效了。如果你的 Chrome 扩展中使用了 content script,那里面通过 DOMContentLoaded 来执行的代码, 除非页面进行了 full reload,不然就不会触发了。

方案

Turbolinks 吃掉了 DOMContentLoaded,但也给我们留下了其它的接口来捕获页面加载的事件,不然很多依靠这个 状态的脚本都会失效。

Instead Turbolinks fires events on document to provide hooks into the lifecycle of the page.

page:load is fired at the end of the loading process.

我们不是还有个 page:load 事件可以用。

如果之前使用的 jQuery,可能是这样做的。

$(document).ready(function() {
    // initialize code here...
});

只要增加下面的方式即可:

$(document).on('page:load', function() {
    // initialize code on page load here...
});

注:之所以不直接替换,是因为如果是直接通过网址访问的,那会有一次 full reload,并不会触发 page:load 事件。

参考资料

2013年总结

又一个年头过去了,这一年,我失去了一个人,又得到了一个人。母亲年初终于没有能 战胜癌症,离开了人世,去往没有病痛的世界。年底我和欢欢在经历了三年多的恋爱后 终于结为夫妻,做着一起生活一辈子的打算。逝去的不能挽回,但未来却还有很多路要 走,虽然少不了争吵,但我们会坚持一起走下去。

这一年无疑是充实的:

技术上,经过一年的学习和实践,对于 Ruby On Rails 这项技术更加巩固,已经能够较为熟 练的使用 ROR 开发自己喜欢的应用了,但是有所欠缺的是使用 RSpec 测试这块,同时对于 Rails 4 也没有多少接触,是接下来的一年需要实践的点。

西安技术氛围越来越浓,西安 GDG 越办越火,又成立了西安的 Ruby 圈子,都有积极参加, 认识不了少不错的朋友,在技术和生活上,都得到了这些朋友的指点和帮助。很多程序员都 比较羞涩,不擅长与人交流,而西安的这些圈子正是让宅居的技术人员走出去,认识朋友, 扩大交际圈的好地方,我也强迫自己做了几次分享,现在已经爱上了分享,能把自己的知识 扩散出来,并获得不同声音的反馈是一件非常有意义的事情,批评和赞扬都会让人进步

生活上,失去亲人和迈入婚姻都让我一定程度上更加成熟,虽然还没有完全适应,但自己要 开始承担许多责任,不能像以前一样不顾后果的做事,我不能再只为了自己和努力,这一步 其实非常不容易,但我必须去面对,虽然我做的并不怎么样,但妻子其实很是包容我,虽然 有时她会有些小脾气,但这才是她的性格,让她流了太多眼泪,我必须要让自己更加担当。

因为不怎么和村里人接触的关系,见了村里人,我都不知道该怎么称呼,于是经常是低着头 走过去,很没有礼貌,这一年,我刻意记住了一些面孔,见了面也尽力去打招呼,虽然有时 叫错了,有些尴尬,但总比不礼貌来的好些。算是一种进步吧。结婚时有录录像,里面有好 多村子里的面孔,于是想开发一个从视频中提取人脸的 Android 应用来辅助自己识人。

工作上,这一年并不怎么顺利,虽然纯粹从技术上讲,我无疑是在跑步前进,但公司却一直 在走下坡路,虽然这和我们技术人员关系不大,但身在其位,没有利用自己的技术优势帮公 司争取更多的资源,也是有些小愧疚的。这个公司,待了两年了,有苦有乐,但这一年来苦 多一些,不过我有付出全力,算是问心无愧了。

这一年,总的来说还是在积极的向前进的,无论是从积累还是心态上来讲。我开始购买自己 喜欢的软件或服务,比如百度音乐Newszeit云梯,当然,钱花的最值 的就是买了一个二手的 Kindle 3,它极大的推动了我的阅读。

2014年,这一年有好多事情去做,准备读至少5本好书,并提高自己的英语书写和听力,书写我 已经在努力进行,每天坚持抄写一篇好文章,算是读写同步进行,效果很好。至于听力,打算从 Youtube 上找几个好的技术视频然后听写字幕,还没有开始实施。年底,我对 AngularJS 产生 了兴趣,新的一年,一定要学起来,练一练。

还打算在年后买一个 MBPR,还没有和老婆谈妥,但是 Andy 说的很对 家里所有的家用电器, 只有笔记本是能给你赚钱, 有什么理由不买个好的? MBP 对一个热衷技术的人来说,是一种投资, 也是一种催化剂!

我需要一个更好的工具来激发自己的技术潜力,心里有太多的技术热情想要喷勃而出,就差个 称手的工具,好似孙大圣需要一根金箍棒。

2014年,我准备投入到远程工作的怀抱,在听了 Andy远程工作那些事儿后,我觉得这 种工作方式太适合我了。自认有很好的自我管理和交流能力,剩下的就是过硬的技术了,新的一 年,要好好学习和实践测试驱动开发,2013年积极做社区分享的奖品 The RSpec Book 就是 我的开味菜,2014年,依然是要起飞的!

Chrome 划词翻译扩展 TransIt

无间断阅读

西安 GDG DevFest 2013 活动中,我和 andy 聊到了目前我们用的 Chrome 翻译扩展进行划词翻译 后都会在最显眼位置弹出翻译结果的浮层,甚至你还要手动关闭它,从而打断了阅读

我们只是想知道这个词的意思然后继续我们的阅读而已,甚至都不关心它怎么发音。所以,我们两个都需要一 个对阅读打扰比较小的翻译扩展,正好 david 也有兴趣,所以后来我们专门聚了下,准备一起用业务时间做 一个翻译扩展 TransIt

TransIt

TransIt 是一款简单的划词翻译扩展,它的目的是划词翻译时尽可能的减小对阅读的影响。

TransIt 目前的特性:

  • 划词后在页面右上角显示简单的翻译结果,指定时间后自动消失
  • 支持连续对多个单词进行划词翻译,翻译结果会顺序显示在页面上
  • 在超链接上按住 Shift 键可以临时禁用该链接,方便对链接中的文本进行划词翻译
  • 本地缓存已查询过的单词,再次查询时能够迅速返回翻译结果
  • 可能通过设置开启/禁用页面划词、链接划词,也可以设置翻译结果显示的时间
  • 更新设置后立即生效,不用再刷新页面

扩展截图:

1

2

3

扩展已经发布在 Webstore 上面

https://chrome.google.com/webstore/detail/transit/pfjipfdmbpbkcadkdpmacdcefoohagdc?utm_source=chrome-ntp-icon&gl=CN&hl=zh-CN

欢迎试用,目前 TransIt 还有许多问题,我们会不断的改进它,如果你觉得它给你带来了便利或者它还有哪些缺陷, 都欢迎在 Webstore 上进行反馈。

我们的团队

为了开发这个扩展,我们成立了微酷团队(Veaku),以后还会给大家带来更多好用的小工具。

« Previous