技术

Firefox 扩展 之 王小峰的音乐盒

这两天,三表连续写了几篇知会一声DJ 等等,在他的 blog 首页上放了一个音乐盒。

因为我用的是 Firefox 浏览器,头一天发现页面上显示那个音乐盒有点异常,把音乐盒链接在新的页面上单独打开才有效果,但是整块页面空空荡荡的,就在中间嵌一个小的音乐盒,不大美观(现在音乐盒链接换了一个新的,正常了)。

今天看到有人在回复里提 Fx 里显示不正常的问题,回答他的问题的同时突然有一个想法,做一个 Fx 扩展,打开一个只有音乐盒大小的新的窗口,这样看起来小巧精致,把音乐盒跟他的 blog 页面剥离了(没有必要为了听音乐老开着 blog 页面吧)。

因为以前研究过一些 Fx 的扩展,比这个复杂得多,所以它很快就搞定了,爽!

扩展详细信息:王小峰的音乐盒

更新:

昨天搞定了1.0 版。工具栏的按钮加上了,右键菜单里的图标也加上了,算是一个满意的版本。费尽千辛万苦做了透明背景的图片(盗版的 PhotoShop 是一定不能用的),配了国际米兰的颜色,好看,哈哈——20070321

Topic: 技术 音乐

推荐一个 WYSIWYG HTML 编辑器

今天从前同事吕志良的 blog 看到的,COMEditor

这里摘抄几句说明:其实,现在已经有了许多可以跨浏览器运行的 HTML 编辑器,代码成熟度已经很高了。但是它们的设计结构,对于开发人员来说,我觉得十分不友好。设计层次不清晰,业务逻辑与组件逻辑夹杂在一起,严重地影响了编辑器的二次开发。并且,一旦出现脚本错误,调试成本相对来说也非常的高。COMEditor 由于采用了组件的方式,所以功能层次明确,更容易开发人员二次开发和调试。

我是相当的信任吕志良的水平的,所以这里特地推荐这个项目。也感谢 eYou/zhanzuo.com,将代码以 MPL 1.1 发布。

Topic: 技术

config vs script(配置文件还是脚本?)

周五的 mailteam 技术例会上,说起运营监控系统的配置,当时我提出直接写脚本来配置就好了,但遭到了一堆人的反对,指出现在使用的 XML 工作的很好...

会上并没有就这个问题深入讨论,会后就想着就这个问题写一篇 blog,正好看到沈崴也刚刚写了一篇文章阐述类似的问题,不过他介绍的是如何用 py 进行配置的实作,非常有价值。

我没有他那样的实际经验,只是以前在和 zhb 的一系列讨论后隐隐约约总结出 script 比 config 有莫大的好处:
1. 机器的可读性。script 引擎本身就是一个天然的配置分析程序,这点上和 XML 打个平手。
2. 人类的可读性。这个比 XML 强太多

3. 可配置性。这个也比 XML 强太多,或者说实现起来比 XML 自然的多

会议上提到的脚本配置的缺点是如果脚本写错了会影响程序执行,其实并不是理由,因为 python 是可以动态 import 的,对导入配置的异常做额外处理就好了,事实上任何系统配置都免不了要做这个。

另外一个很容易被想到的缺点就是 XML 配置文件可以应用于各种语言写就的程序,而 py 脚本貌似只能在 python 里面使用。实际上 py 脚本(或者说 python 对象)是可以在 C/C++ 里面访问的,现在网游客户端包括 QQ 不都是这么做的么。

在我看来,问题真正的核心在于配置文件编写人员,或者说习惯于在 web 上提交表单的管理员们,是否愿意去学习一门新的脚本语言

记得一个超有名的黑客说他教文职秘书们配置 emacs,她们没有人意识到实际上是在写 lisp 程序。 :)

Topic: 技术

最近报告出去的两个 bug

一个是腾讯 TT 的 bug,keydown 事件无法捕获 'l'、'n'、'o'、's' 四个按键。这个 bug 真是匪夷所思,不晓得开发人员怎么犯下的如此的弱智错误。不过我们的项目最后还是绕过了过去,就是额外写了不少垃圾代码。然后在 QQ 的论坛上报告,昨天有一个腾讯的测试人员联系我要测试用例,于是写了这个 http://www.dup2.net/tt.html,今天一大早就告诉我开发人员已经改过来了,等下个版本了。估计 TT 的开发人员也经常加班工作,呵呵。

另一个是 twisted.words.protocols.msn 的 bug。严格来说不是它的问题,而是 MSN Shell 没有很好的遵从 MSN 协议规范发消息;但结果会导致无法和 MSN Shell 正常通话。写了一个 patch 解决这个问题提交给 twisted,还不晓得维护人员愿不愿意为了一个中国的 MSN 插件而接受这个 patch

Topic: 技术

老婆果然是比我聪明...

听说北京神州行、动感地带即将单向收费后,我今天在下班的公交上突然想到这样就可以一有来电就自动接通,然后向打电话的人放 mp3,甚至可以做到不同的拨打者放不同的歌;按下接听则将声音输入从 mp3 转到 Mic 上。

这样岂不是比现有的彩铃灵活很多?简直是语音业务的又一大 killer app 啊。就算手机厂商不做这个功能,在 S60/WindowsMobile 这样开发性很好的平台上应该是很容易实现的。貌似唯一的遗憾就是有些费电.....

于是俺回家后兴冲冲的把这个主意告诉了老婆。老婆想都没想就一棒子把我打回原形:接电话是不掏钱了,那打电话的呢?

......无语......

Topic: 技术

twisted 简单的 daemonize,以及 cron 功能的实现

年前系统监控脚本已经写好了,同事实现了检查 resin 状态和 https 用户口令校验,出状况则短信通知... 春节期间一直没有收到报警短信 :)

但还是比较粗糙,比如脚本是要依赖 nohup 启动的,想起以前写 echo server 的时候曾考察过 daemonize ,于是把代码抄来试试

结果发现直接 copy 过来的东东在 twisted 2.5 下不能运行。追踪了一下,发现是不知道从什么版本开始完善了对 win32 平台的支持,它将原来 twistd 的东西又封装了一遍。现在把 "from twisted.scripts import twistd" 这行改成 "from twisted.scripts import _twistd_unix as twistd" 就好了。

另外貌似 twisted 并不推荐这种直接初始化 App() 的方法,而是用 twistd 程序来启动 app,回头需要再学习学习..

顺便又了解一下怎么实现一个简单的 cron,发现可以用 twisted.internet.task 封装的 LoopingCall 来完成,核心应该算是一个叫 callLater 的东东。

Sample:

  1. import os, time
  2. from twisted.internet import selectreactor as bestreactor
  3. bestreactor.install()
  4.  
  5. from twisted.internet import reactor
  6.  
  7. def crontask():
  8.     open("/tmp/crontask",'ab+').write(str(time.time())+"\n")
  9.     time.sleep(2)
  10.  
  11. class App:
  12.     pidfile = "/tmp/cron.pid"
  13.  
  14.     def __init__(self):
  15.         twistd.checkPID(self.pidfile)
  16.         # checkPID 后再 daemonize,否则看不到 checkPID 向终端输出的错误报告
  17.         twistd.daemonize()
  18.         # 先 daemonize 再写 pidfile。因为写入的得是 daemonize 后的 PID
  19.         open(self.pidfile,'wb').write(str(os.getpid()))
  20.         reactor.addSystemEventTrigger('before', 'shutdown', self.shuttingDown)
  21.         cron = task.LoopingCall(crontask)
  22.         cron.start(5)
  23.  
  24.     def shuttingDown(self):
  25.         twistd.removePID(self.pidfile)
  26.  
  27. #from twisted.scripts import twistd
  28. from twisted.scripts import _twistd_unix as twistd
  29.  
  30. from twisted.internet import task
  31.  
  32. def main():
  33.     app = App()
  34.     reactor.run()
  35.  
  36. if __name__ == "__main__":
  37.     main()
Topic: 技术

twisted.words.protocols.msn 协议简述

首先推荐一个关于 MSN 协议描述的网址:

http://www.hypothetic.org/docs/msn/index.php

在试着改写 twisted sample 的过程中,基本上是靠这个网站上的内容来学习 MSN 协议的。

在 twisted 里面定义了三类 ClientFactory,分别对应 dispatch server、notification server、switchboard server

客户端启动的时候首先去请求 dispatch server (messenger.msn.com),它会告诉客户端一个可用的 notification server,然后立刻关闭连接。

客户端接下去连接 notification server,其间还会到别的服务器上去认证一下(就是通过 https 把用户名密码送到一台机器上,然后获得一个临时令牌,再告诉 notification 这个令牌信息,认证就通过了)。最终身份确认后,在 MSN 登录其间就不会再断掉这个 TCP 连接了,所有的 presence 信息就是通过这个链接传递的。

可以想象 MSN 有无数台 NS,那么连接在不同 NS 上的用户之间怎么传递消息呢?Jabber/XMPP 的类似机制是 router,用一个专门的服务来帮助寻径。MSN 的解决方案是 switchboard server。

就是说 A 想和 B 说话的时候,就临时请求一个 switchboard server 资源,然后自己连接上去,B 也会接受到一个通知对话发起的 notification,里面包括 sb server 的地址。B 连接上去以后两个人就可以通过这台 sb server 进行通信了。

写到这里突然想到,notification 好像都是明文传输。理论上我们可以监听 MSN 的 notification 拿到 IP/Port/SessionID/Key,然后先 B 一步连接上 sb server,这样就可以冒充 B 的身份和 A 聊天了,想恶作剧的可以尝试一下(黑客可以利用这个来伪造信任身份传恶意 URL,还是挺可怕的)。

除了 dispatch、notification、switchboard 的概念外,我的例子里面还涉及到了联系人的信任状态,即 forward、reverse、allow、block。其实这篇文档里面介绍的很详细了,英文也很容易懂,就不再多说了。

Topic: 技术

利用 twisted 来写 MSN 机器人 (有例子下载)

具体到 MSN 机器人的实现,我倾向于使用 twisted 框架。无奈网上相关的资料非常少,找了半天只有这个中文 blog entry 稍微有些帮助。后来把 twisted 自带的 sample 增加了一些功能,现在放出来供需要的人参考。

msnclient.py (因为是修改自 twisted 的代码,所以也用 MIT license 吧)

这个简单的 MSN 机器人目前可以自动加好友,以及实现了一个消息 echo 机制——对它说的话会原文返回来。为了帮助理解 MSN 协议,我也打印了大量的协议文本到终端上。

如果是在 win32 环境下调试,pyOpenSSL 主页上并没有最新版本的预编译包,我现在用的是 webcleaner 编译好的(http://webcleaner.sourceforge.net/pyOpenSSL-0.6.win32-py2.5.exe),同时还需要安装 OpenSSL 的 win32 库

MSN 的字符流都是 UTF-8 的,本来我在 Linux 下的 zh_CN.UTF-8 环境下信息输出的很好,但在中文 windows 上就不能正确输出,无奈在例子里很多地方增加了 locale 判断

default_locale = locale.getdefaultlocale()
foobar_str.decode('UTF-8').encode(default_locale[1])

Topic: 技术

计划用 python 实现一个运营监控系统

现在搜狐通行证项目在技术实现上已经差不多了,接下来要考虑的事情就是运营保障,以及数据统计分析。

关于运营监控这部分 CPC 已经有系统在做了,主要就是请求 URL,然后看返回结果;有问题就发 email 或短信。不过我觉得还不太好,比如如果要处理 HTTP POST 检查,或者是监控 MySQL 的话,扩展性就太差;而且出问题了话报告哪些人也不容易扩展;另外,还很希望实现 MSN 报警,这样比起 EMAIL/SMS,还能实现一些交互的能力。

我现在的计划是这样:对每一项需要监控的服务实例化一个特定的对象,包括执行怎么样的操作,操作返回结果怎样才算正常,连续出错 N 次后向哪些人去报警,系统恢复正常后再向哪些人去通知。基本上 EMAIL 报警可以考虑取消了,首先看报警接受人是否 MSN 在线,如果在线则发报警信息;报警信息包括一个流水号,接受人必须在 MSN 上响应这个流水号,否则不停的在 MSN 上发送报警信息,直至最后发送短信进行提醒。

Topic: 技术

DV-2-XviD 0.8.3

又是一个老外报告了 bug,如果目标文件夹路径包括空格的话,lame.exe 执行会失败。很容易就改好了。

关于 DV-2-XviD 的中文信息可参考这里

另:今天看到一篇文章 (http://weblogs.mozillazine.org/roadmap/archives/2007/02/threads_suck.html)

看起来 JS 未来将会加上对线程的支持,就是说 Ajax 应用将会更有效的利用你的多核系统的计算资源。感觉 Gecko 在 JS/ECMAScript 上还是很有话语权的。

Topic: 技术
订阅 RSS - 技术 | BT的花