qyb的博客

预报:3月4日清晨月全食

今天北京的天气不错,不知道到时候能不能看到。看完后还可以补个回笼觉

我家达达还在湖北,到时候让奶奶把她弄起床看"天狗吃月亮",哈哈

介绍这里有

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: 技术

回家

每次快要回家的时候,MSN 上的名字都会换成"那刻着我的名字/年老的树/是否依然茁壮",虽然我大抵是从来没有在树上刻过自己的名字,但每当想起这歌的时候,总好像家里有这么棵树在等着我回去一般。

买到的是 16 号的车票,T15,终点站广州。

细想就会觉得到武汉的火车真是很多,除了暴多的 Z、T 字车,去长沙、广州的车也通常会在汉口武昌停一下,所以每次春运都能有惊无险的拿到车票。

票是托人(其实也可以算是一个票贩子)买的,因为信任他的能力,也从没有考虑从别的途径去买票。结果 15 号晚上才拿到票,而 qyt 同志已经实在等不及又搞了一张票上车走了。于是晚上立刻上网登出一条火车票转让信息。

网上卖票从另一侧面印证了北京到武汉的车票之充裕,反正是在 n 个网站上都发布了消息,但只有一个人来询问信息,听说我是在清华东门附近后也打消了念头。

直到坐上前往西站的 47,才有人打手机联系,最后敲定在西站交易,一起上车。到了西站,就听广播说还剩余到武汉、青岛、南京.. n 多热门地点的卧铺,乘客可到 18 号窗口购买云云,实在是令人 faint.

T15 发车甚早,下午 6 点多就开了,晚饭就在餐车上解决,正好也尝尝粤式餐车的特色。平心而论 T15 做的菜还是很可口的,老婆和我要了 2 菜 1 汤,2 碗米饭,吃的干干净净。总价 69 不算便宜,但考虑餐厅特殊的地理位置,也确实不算贵。

吃完饭后还是远没到睡觉的时候,幸亏我早准备了一本关于萨特的书。作为理科学生,以前大学里面从来没有接触过萨特——尽管其大名在还没有上大学的时候就如雷贯耳的——看的是津津有味。存在主义的确很有意思,尤其适合当代中国从小学习马列再寻求哲学突破的境遇。估计看我 blog 的人也以理科生为主,这里推荐补补课。

武昌车站正在大修(后来知道是要修很多配套以及地铁),拐了好多个弯才走出车站。然后就是到处找过早的地方,这里不禁要赞一下南方的早点——可以舒舒服服的坐下来要一份云吞或者米粉热干面什么的吃下去。大概是南方多雨,为了避免受天气影响生意,所以早餐点全都是有自己的临街铺面。而且也不是北京天津这样套一个塑料袋避免洗碗,用的是专门的一次性餐具,类似“来一桶”。

T15 临晨 5 点多就到了武昌,下车吃完早饭后马路上仍是冷冷清清。“我走在清晨六点/无人的街/带着一身疲倦”,我突然有预感,这次回家肯定会有和以往完全不同的感受....

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: 技术

火车票啊火车票

这几天常和人讨论起春运期间一票难求的事情,据一个小道消息说:西站全部都是票贩子,报价为硬卧加500,软卧加400

说实话我很是不理解为什么春运车票不涨价,一方面降低了票贩子的运营成本,理论上也会吸引更多的人加入贩票这项很有钱途的事业,另一方面严重违背市场规律,没有体现供需不平衡的矛盾。

和火车票一样的是汽车票,虽然大概没有汽车票贩子的存在,但只有汽车票涨价,才会吸引更多的客运汽车加入到春运物流里面去,这样乘客才能更方便的坐上车或者是获得更好更安全的服务;而且很明显春运期间客运的监管成本安全成本增加了,也需要涨价才能保证利润。

火车票黑市绝对是一个相当市场化的环境,我觉得票贩子的报价比铁道部的鸵鸟政策高明100倍,体现了车票的真实价格。为什么铁路部门就不能正视这个事实,以去年的黑市票价做参考来制定春运的票价政策呢?

如果政府真的希望老百姓能以低廉的价格买到火车票,比起狗屁的不降价政策,应该反其道而行之:

每张卧铺票的票面价格增加 2000,等旅客上车后查铺的时候,再给每张票返 2000。如果旅客觉得现金过多不安全,也可以给存有 2000 现金的卡。相应的财务流程、银行、保险、保安的成本由政府来负担。

而且这个政策的另一面,对政府和金融机构太有利了,从乘客购票再到返现金的几天之内(甚至是十几天之内),账面上会多出一大笔现金。当然这需要很好的现金流管理能力。

我就不相信,如果一张车票 2500 的话,还会有大量的票贩子来倒票。这样也提高了从不信任的个人/机构那里买票的风险,你会愿意花 2000 多从网上一个不认识的人那里买火车票吗?

从某些方面我还是很尊重票贩子的,是他们体现了市场经济的规律,他们就是那"看不见的手"。

Topic: 商业 社会
订阅 RSS - qyb的博客