我不喜欢 Google Buzz

google-buzz-icon.png9、10 号的时候从 Twitter 上看到有人说 Google Buzz,简单的了解了一下,说是 Google 的微博服务,与 Gmail 集成的。我那时候还没有见到过 Buzz 的页面,只是从 Twitter 上看别人在讨论。有人说他不会用 Buzz,有人说可以把 Twitter 同步到 Buzz 上云云。

10 号晚些时候,我进 Gmail 的时候,发现 Buzz 也开通了。上来先“假惺惺”的问我要不要开通,这种免费的新鲜服务还有选不开通的吗?开通了之后,印象里第一步就是选 follow 的人。Google 通过通讯录里的信息,筛选出同样开通了 Buzz 的人让我选。我忘了之前的选择是什么了,反正有些比较有名的人物,比如月光、keso 等我都选了。或者是我当时就觉得我在近期不大会用 Buzz,所以就把人物都选中了,话多的也没什么影响。

不过没用一会,我就感觉:我不会喜欢 Buzz。

上来后发现的第一个问题就是所谓的“话唠”。这话唠和 Twitter 上的不同,Twitter 上是一个人呼哧呼哧的说,而在 Buzz 上,如果一个人的通讯录比较发达,默认 follow 他的就有很多人。经常是他随便在 Buzz 上说点话,就有一大群人跟着回复。而且这种回复不是那种论坛中探讨问题的回复,而是不折不扣的“唠嗑”,闲话家常那种。但这又不像是真正的闲聊,很多人都不认识,没有聊天的气氛,更重要的是,没有上下文、不了解谈话的背景,很容易几个人就一个鸡毛蒜皮的小问题就争论起来了。没意义,看着也烦。别说中国人挺含蓄,在网上可一点都不含蓄,我估计也是日常憋得。我刚刚和一位同学在 Buzz 上说话,就看到有个陌生人插了一句“路过”。要不是之前没发现,Buzz 好像也不能回复中间的条目,我真想像王小峰那样说一句“路你妈屄过”。试想你和朋友说话的时候有陌生人在旁边说句“路过”你什么感觉,我一直认为“互联网即生活”,互联网上的活动应该反映人们的日常生活,所以这种情况我是不喜欢发生的。我印象里上来就 mute 了月光的一条,忘了是什么内容了,反正已经把我的 Buzz 页面拖得老长了。还有 keso 的也是,都不是原张贴者的问题,都是留言太多导致的。尤其是可能是因为 Buzz 刚开通,人们都有好奇心,什么都想试一试。这一试就水了很多楼层。

前几天无论是在 Twitter 上还是在 Buzz 上,有很多人说 Buzz 像这个像那个。我当时就问了一句:“难道没有人觉得 Buzz 像 Plurk 的吗?”当时确实是没看到有任何 Buzz 和 Plurk 相像的说法,不过我觉得两者太像了,Buzz 就像是未完工的 Plurk,当然这也符合 Google 一贯的 beta 风格。

我在之前写文章讨论过 Twitter 和 Plurk 对于信息管理方式的优缺点。Twitter 是朴素的线性,而 Plurk 则是树形。两者之间那种好,我在那篇文章里已经讨论过了。那篇文章的结论,现在我感觉同样适用于 Buzz。比如说用 Buzz 的时候,我想过好几次,如果能只显式我 follow 的人的条目就好了,把那些条目的回复都折叠起来,看上去就很清晰。Plurk 默认是这么做的,而 Buzz 不是。看上去 Buzz 里面“一片繁荣”,但实际上有用的没有多少,用户还是被淹没在了信息洪潮当中。所以我觉得 Buzz 是未完工的 Plurk。

但 Buzz 在这一点上又有比 Plurk 更好的地方,虽然这个好可能不是 Google 主动做到的。那就是 Buzz 条目的字数限制很宽。刚才我测试了一下,把我目前 Blog 首页的所有正文文字复制下来粘帖到 Buzz 的发布框中,Buzz 倒也都能吞下,但点击了发布按钮之后会提示错误,但也不说明是为什么出错。然后我只复制了上一篇文章的文字,贴了上去,就成功了。我上一篇文章有 2000 多字,远远超过了 Plurk 的 140 个字的限制。这样的好处就是想说一句话的时候,可以尽情的说,而不用绞尽脑汁删减字数。在 Twitter 上,我有时候因为实在删减不了了,只好发两条的情况。这在 Twitter 上无所谓,因为条目是线性显式的,所有东西都堆在一堆,回复了也不知道是针对哪条回复的。而在 Plurk 上如果这样做,回复的时候就要考虑一下,“我到底是要回复第一条呢?还是第二条呢?”。如果回复了第一条,就导致对话的逻辑混乱;如果回复了最后一条,旁观者又可能会看不明白两者的“对牛弹琴”,因为要回复的重点在另外一条里呢。当然,这种情况下,Plurk 用户可以自己回复自己,应该也算是一种解决方法。Google Buzz 的这种“超级”条目,自然就没有这种问题了。谁一句话要 2000 多字还解释不完,那可要重新去小学里“回炉”了。

而这种情况,在 Twitter 同步下就成了悲剧了。就在刚才,我发现我之前在 Twitter 上发的一句话分成两条的条目,在同步到了 Buzz 上,被显式成了两个不同的条目。结果导致我的朋友回复了其中一条而没有把两条关联起来看。我问他为什么,他说同步过来的条目都乱序了,他也不容易分清楚。我目前常用(确切的说是“唯一使用”)的微博工具就是 Twitter,其它的地方,能同步的话我就同步过去,毕竟也算是扩大影响力吧。但这也带来了一个情况,就是别人在 Buzz 上回复我,回复的是我在 Twitter 同步过去的条目,我几天上一次 Buzz 的情况看,我经常会没有及时回复别人的回复,这也导致了讨论的断层。

另外,关于条目的长度,我一直觉得对于中文来说,Twitter 的 140 个字的限制是“神来之笔”。至于英文,可能是我的驾驭能力不够吧,经常说着说着就说超了。对于中文来说,绝大多数情况下,对于绝大多数完成了中等教育的中国人来说,是绝对的够用了。Buzz 目前可以说是不限制字数,反而会有人网上贴长文的情况。不过目前已经可以把 Blog 的文章同步到 Buzz 上了,这样也说不上好不好。好处是浏览者不需要跳转过去看 blog 了,坏处是我担心会分流留言,导致回复不及时。

最后一点,还是用户使用习惯的问题。如果 Buzz 做的很优秀也就罢了,但目前这种程度的产品,想要和 Twitter 分流用户,我觉得很难。我在 Twitter 上 follow 的人都是我认识的,这些人当中只有一个人选择了同步 Twitter 到 Buzz。他们多数人日常都使用 Gmail,但 Buzz 的使用量则少的可怜。我个人也觉得人们目前阶段用 Buzz 也只是玩玩而已,而不会真正的转向使用 Buzz。换句话说,我觉得 Buzz 其实就是另一个 Google Wave。Wave 发布的时候,我感觉很惊艳,写了篇文章来总结它的优点。但 Wave 是邀请机制的,而且与日常使用的产品(Gmail)不挂钩,再加上 Wave 本身的效率问题,在公开几天后,出乎我意料的是 Wave 并没有火起来。很多人四面八方的讨要来一个邀请,注册之后,新鲜了几天,就荒废了,这也是我虽然有邀请,但拒绝给任何人的原因。我觉得如果 Wave 不需要邀请注册,再跟 Gmail 联系起来的话,估计也就是 Buzz 的水平。

基于以上几点,我在使用 Buzz 的第一天就感觉,就觉得 Buzz 应该不适合我,至少我觉得 UI 方面的表示层应该要重新设计,否则使用起来会非常的不方便,难受。其它的一些小问题也值得重新思考一下。说到这里,我觉得 Buzz 应该是几个人一时间的冲动,我不觉得在这个产品的设计方面有很多精深的思考,只是把 Twitter 的思想与 Google 的一贯模式浅层的结合一下而已。也就是说,我觉得 Buzz 还不成熟,在将来应该也会有很大的变动,因此我在近期里是不会重点使用 Buzz 的。

谢谢饭否

fanfou.jpg昨天在查看blog的流量统计时,翻到了之前写的一篇文章。那时饭否刚刚开始自己停止了服务,官方上的说法还是几天后会重开。那个时候我也觉得饭否想避过那时的风头,等着过几天会重新开放,但没想到饭否会一直死到今天。

我在那篇文章里说,同样是无法访问,饭否是主动封锁,用户用什么方法都无法登录,而Twitter是被动封锁,只要能翻墙,还是可以使用的。当时我没有想到饭否会一直无法恢复,因此心里也没有现在这么肯定,也一直在担心。担心的点是Twitter在长期被封锁下,会导致中国用户的离开。我在Twitter上follow用户的原则是只follow我认识的,其它的一些名人什么的一概不管。确实名人们的Twitter会有丰富的信息,但也会让我的信息负载加重,反而影响了我对需要信息的获取。这个原则让我的follow列表长度保持在20之内,也就是说我经常交流的Twitter用户只限于不倒20人。而里面经常发言的又更少了。如果这些人之中有人离开了Twitter,我的交流渠道就会大大减少。

新浪微博发布时,我觉得可能会是一个冲击,不过并不十分担心。因为我一直觉得新浪对于blog、微博这些东西掌握的不好,做出来的东西华而不实,不会吸引Twitter用户,而国内微博服务的用户的去留与我无关。另外,新浪微博的封闭性也阻塞了它的流传。除了API方面的种种之外,首当其冲的是其封闭注册的性质。而更过分的是,不注册却无法浏览别人的页面(最近好像有改善),这直接阻止了我对其进行评估,也断掉了我使用的可能。而且邀请注册的吸引人的前提是别无分号的东西,gmail邀请的时期其成功是因为没有免费的1G邮箱,Google Wave邀请的抢手也是如此(顺便说一句,手里还有19个邀请,不过我谁也不给,哈哈)。新浪微博在这种情况下弄个邀请,如果除了对自己的服务确实没有信心,那就纯是在装逼作秀了。

真正让我担心的,其实还是像饭否这种国内的专注于微博服务的公司。首先是它们有口碑,对人的吸引力更大;其次是它们的服务,对于普通用户来说,确实也能与Twitter一拼,而且像客户端什么的也都挺火爆的。所以我那一阵子是挺怕那些公司把Twitter上的用户吸引过去的。不过它们自己本身也有问题,最大的问题是天生就有的。“合则力强、分则力弱”,本来在国内还算小众的微博用户群,被几家给瓜分了,就更加难与Twitter抗衡了。Twitter不像电子邮件,目前使用者被固定在一个公司的服务中,就很难和别的服务互通。什么时候这个问题被真正解决了(嘀咕那种的迂回同步不算真正解决问题),国内微博才有能力真正和Twitter一拼。不过就算这样,我也不希望我follow的Twitter用户离开。

而饭否的关闭,则帮了我一个忙。

首先是饭否用实际行动证明了微博服务在国内的不可控性。你的发言,可以在任何情况下,仅仅因为一个理由,就全都消失一空,朋友之间的联系也因此而丧失。饭否是国内微博服务的佼佼者,口碑数一数二,由“老大哥”来做示范确实很有效果。而且,饭否在这么长时间之后都没有兑现当初说的十几天之后恢复的承诺,反而积极删贴的新浪微博倒还好好的,这也告诉了用户──除非饭否做到新浪那个份上,否则饭否则很难继续下去。这也让用户知道了,真正能体验微博服务,只能找国外的公司,也就是Twitter。所以现在,尽管我的follow列表里在国内的同学都无法正常发推,但总有工具可以帮助他们和我完成Twitter上的交流,而且他们的发言频率也并没有因此而减少。

所以我昨天看到了之前写的文章,不由的觉得应该对饭否说声谢谢──你给国内的微博用户上了宝贵的一课。

另外,今天看到月光贴了篇文章,说百度发布了自己的微博产品──i贴吧。我过去看了一看,里面也有一些名人的头像。我点进去看看,感觉就像是一个论坛上的某位用户的发帖列表,里面没有几篇发言。不过每一篇下面的用户回复则几乎全是“沙发”、“留名”之类的东西,我于是知道了什么是中国特色,同时也完成了对于i贴吧这个产品的定位,并对Twitter的稳固地位更加放心了。

还是我们的文化作祟

Herock的blog可能出了点问题,我今天在Google Reader里面看到了他的blog又有了更新提示,但明显都是旧文章,他的blog首页链接也坏掉了。不过这样一来,我又重看了一次他上个月的文章《能不能别摸雅虎的咪咪了》,又有了新的感触。

文章大意是很多中国人用一些色情图片占据了Yahoo Meme的popular的排行榜,并导致了Yahoo Meme开始删除一些用户的发言。因为文中也提到了Meme和Twitter的规模问题,所以当时我看了文章以后,在文章后面留言说,当Twitter有了Obama、O'Neal等人之后,其它的模仿者就做不到同样的规模了。Yahoo Meme作为一个新兴服务,功能并没有超出Twitter很多,因此也不会有多大的作为。因为用户惰性的道理,人们很少会愿意变更自己的微博服务,一是因为带不走过去发布的内容,二是有很多朋友还在用老服务,这样联系就断了。名人也一样如此,这样加上跟风效应,用户对一个新兴的服务只能是抱着玩玩的态度,而不会把它作为主要的工具来深入使用。

今天再读一遍,又想到了一点新的东西。Herock在文章中说道:

把meme叫成咪咪的人中,可能有一部分不知道meme应该读成/ˈmiːm/,也拥有一些听起来没那么引人遐思的拗口的名字:米姆、模因、弥母等,在牛津英语词典中的定义是"文化的基本单位,通过非遗传的方式,特别是模仿而得到传递。"用来指代"在诸如语言、观念、信仰、行为方式等的传递过程中与基因在生物进化过程中所起的作用相类似的那个东西。"

Herock是从正面宽容的角度来论述的:因为国人不知道meme作为英文单词的含义,因此一厢情愿的把它念成“咪咪”,并加上了许多香艳的含义,但实际上却用行动亵渎了“文化”这一层意思,让别人认为国人没有内涵。而我是从负面来想的:不论国人是否知道meme的英文含义,这种行为就是在像外界宣示我们的文化。也就是说,并不是国人因为语言不通而“闹笑话”,而是国人的文化本身就是如此。

“性”在经历了中国两千年的封建统治后,已经成为了一种见不得人的东西。但其本身美好,又容易让人津津乐道。在这两种矛盾的情况下,人们对待“性”的态度,就成了表面上据其千里,私底下却又非常向往。古语“满嘴的仁义道德,一肚子男盗女娼”就有这个意味。而这种难以表述的意味,在长时间里已经融入了我们的文化中,无时不刻都会从我们的“文化的基本单位”中体现出来。

所以,当人们有了在Yahoo Meme上的机会时,在上面发一些裸照之类的,就显得相当正常了。之所以Twitter上没有,一是因为它无法直接显式照片,更是因为它太正式,用户多,关系也复杂,让别人知道了会“影响不好”。Yahoo Meme上的用户本身就少,而且已经有别人的先例,自己再发就没有那种干坏事的不安感,毕竟自己不是“首恶”,这倒是普适的心理学的研究范畴。

归根结底,还是我们的文化不能正视“性”所导致的。

我讨厌Twitter的一个地方

先明确一下,标题里说的Twitter指的是狭义的Twitter──Twitter网页

Twitter网页上最近加了一个功能,就是在页面代码里加上了几个javascript,来捕捉快捷键。这样一来,当我在Firefox里按control+d键的时候,页面就会自动跳到了direct message部分,当我按control+p的时候,就会自动跳到我的页面上去,当我按control+f的时候,就会自动跳到favorites页面上去。

为什么说我讨厌这个设计呢?因为设计快捷键的大忌就是与其它快捷键相冲突。作为一个Emacs用户,control+d可不是普通的快捷键,它相当与普通键盘上的delete键,也就是删除光标后面的字符。而control+p和control+f分别是把光标移到上一行和把光标往右移一位。

首先,在我的MacBook上没有delete键(键盘上的delete键相当于普通键盘的backspace键),因此我要用普通方式删除光标后面的字符,只好把光标右移一位,然后再按delete键。control+f和control+p由于Twitter的性质则应用的较少。其次,就算是有普通办法,我也不愿用它,毕竟Emacs的用法已经深入人心了,把手移开键盘去点右下角的方向键,是件多么痛苦的事情啊。

我相信Twitter团队是想方便人们的使用,但与快捷键冲突,尤其是传统快捷键冲突,反而会帮倒忙。现在Twitter是火了,很多人都用它而不只是geek,但毕竟在早期还是由这些用户给捧起来的。而且我怀疑有多少人会使用这些快捷键,毕竟每天direct大量的人是少数,要从home跳到profile的也是少数,每天去看自己加星的记录更是少之又少。而从编辑框里编辑tweet的内容要发布的是多少啊。更何况,Twitter关注的应该是“What are you doing”,而不应该是“What have you done”或“What are you directing”。从这一点看来,Twitter也更应该把编辑框弄的更舒服放在首要考虑的事情。而且它们还不止是快捷键这么简单,当跳转到错误的页面后,用浏览器的上一页功能回来后,在输入框里的文字就全丢失了,这一点是让我想喊“Shit”的地方。

同样的问题,Wikipedia也有。我有的时候会在上面翻译一些感兴趣的条目,但它的编辑框就有一些快捷键,也是和Emacs的相冲突。不过它的问题较轻,因为我常碰到的一个键好像是刷新预览界面,倒是不影响编辑的文字。因此我还能忍受,所以也没有检查能不能关掉那几个快捷键。

目前Twitter画蛇添足加了这么几个快捷键,看似实用,反而添乱。更让我火大的是,这个功能竟然无法从设置里面关闭。我是希望Twitter团队能早日解决这个问题。

简论《Twitter 大脑》

这篇文章停留在我的浏览器中已经很久了,当第一遍看的时候就想写点什么,但由于忙一直没有总结出来。思路也不怎么清晰,不知道该怎么总结。到今天看到它还在浏览器中,遂决定不等了,脑中想到什么就写什么吧。

我在今年四月份,写了一篇文章《母体外的人》。文章来源于Kevin Kelly在TED的演讲,在web存在了5000天的时候,预测web在5000天之后的样子。我在看到《Twitter 大脑》这篇文章之后,马上就想到了我的那篇文章。

Kevin Kelly在演讲中的观点是,在5000天之后,我们只需要一台电脑。这台电脑是最稳定的,我们用的掌上设备,不过是这台电脑的一个终端,这台机器的操作系统就是网络。而从我们的角度上看来,这台电脑大约可以等同与我们的大脑。我们大脑由神经元组成,由神经连接,而网络由网页组成,由链接来链接起来。但不同的是,我们的大脑不会每年扩充一倍。也就是说,假以时日,我们的网络会在计算量和存储量上超越我们的想象。我们几乎就生活在这台电脑里,就像在电影《Matrix》一样。我们忘了朋友的手机号,我们不去找备忘录,只要在搜索引擎上搜索朋友就可以了。Kevin Kelly也讨论了连接Data而不是Page,这一点主要由HTML的创始人Tim Berners-Lee来讲述的,他为之起名Linked Data。

我在自己的blog上搜索了一下之前写过的此方面的文章,还找到了不少,比如这篇。也讲述了同样的道理。与apple4us上的文章一样,这些演讲讲的道理是同一个:当基数无限增大时,似乎一切的问题都将解决。《Twitter 大脑》上说,根据Twitter发展的速度,在2013年,Twitter网络就可以形成一个发育中的婴儿大脑了。

这是令人兴奋的。虽然靠基数来解决问题,有点作弊的感觉。但在我们无法在技术上再进一步的情况下,这也似乎是我们唯一的途径。不过我对由Twitter来完成这一个任务抱有怀疑,因为Twitter上几乎没有机器可以识别的Data可言,让机器来达到能提取Data的程度,又需要我们前面说的网络。这似乎是一个永动机一样的东西,是不可能完成的。不过这毕竟为我们的计算领域提供了希望。

少写Twitter多写博

Twitter无疑是互联网界的一大革新。从几年前它推出一来,这两年它的如火如荼的发展,让我们都承认──Twitter革了blog的命。不过,Twitter革命的不彻底。在我看来,它在形式上让群众参与互联网有了新的等级;但在结果上,则不那么尽如人意。当然,我们都热爱Twitter,想尽量的把自己展示在Twitter上与大家交流,但我还是觉得,我们应该多分一点时间在blog上面。

这个想法是我在上周日突然明确的出现在我脑中的。我的同学ZH打算总结一下常见的(荒谬的)大众想法,于是就开始一条一条的把他的想法推了上去。我当时看到了他总结了有六条之多,虽然语言上不是那么完美,但也已经让我觉得惊喜,挺有价值的。当时我就想到,这么好的东西,过不了几天就被新的tweets给挤到后面去了,几乎无法再挖掘出来。而Twitter的服务器不保存/公开早先的tweets,也就是说,一段时间之后,他在周日总结的想法就彻底的消失了。

这是多么可惜的啊,不过目前的Twitter也只能做到这种程度了。我在过去手写程序保存自己的tweets的目的之一就是想解决这个问题,但也只能是某种程度上的。

而我近一年对blog的看法,也相对过去有了改变。我觉得blog不一定要搞的那么正式,你日常生活中的一些小事,只要对你有意义,就可以把它写下来。人脑的记忆是有限的,很少人能记得一年前的一天发生的一些事情。我就经常想到在过去的某一天做了什么事,但具体事情是怎么发生的,我怎么想也回想不起来了。而这时,如果有了当时写的一篇文章来刺激,事情就会容易的多了。我每次浏览我过去的blog文章时,都有深刻的这种感觉──要不是当时写了这么篇文章,我说不定一辈子都难以回想起这么多细节来了。

刚才蔡智浩发布了一篇文章《我的電子記憶》,讲了他是如何克服自己对过去发生的某件事情的遗忘的。蔡智浩使用了Twitter、GPS 軌跡記錄器、數位相機、相片定位和智慧型手機来帮助自己记录每日发生的事情的细节,在将来回顾起来就有了依据。其实我觉得可以再加上一条──常写blog。我没有蔡智浩的那些数码定位设施,但通过写blog,就能在未来或多或少的回顾今天发生的事情。

当然,我也知道在今天,很多人都放弃了常常更新blog,我过去就发现一些人都不更新或很少更新了(比如[1]|[2])。据我猜测的原因有几条:一是到了一定的年纪,可能就不大写blog了,网上写blog的人是我的晚辈,我不大知道而已;二是有很多的东西可以分散想法,让你难以把它留在脑中“发酵”并在合适的时间整理成文章。

比如说我,在2007年开始用Twitter后,对blog的更新就少了。从我的blog的月份archive上看,有的月竟然没有一篇文章,那就是我的一些观点都用来更新了Twitter了。写在了Twitter上,就不想再在blog上写一次了。我有一段时间怀疑,现在有了Twitter,我的这个blog还有没有存在的必要,甚至有段时间我想把blog做成静态的HTML网页,反正写的也少,也没有什么评论。现在我对那种想法已经不以为然了。我的Twitter现在有了8500多条,中间肯定有一点好的idea,现在也早已被其它的废话给湮没了。如果我当时能把它们抽时间整理成文章,现在都可以很好的保存。

有的时候坚持写blog确实不容易。我身边的很多人在几年前也顺应潮流开通了blog,现在也早就停了。我依稀记得从王建硕那里看到他说,坚持写blog是个习惯问题。养成了习惯后,就会自然而然了。有人说平时太忙,没有时间写。但我觉得,现在再忙,挤出一点时间来把自己的想法总结归纳一下,在将来就会产生大用途。现在我的学业也特别忙,但也在时常找时间写。至于现在我养成习惯了没有,我还不清楚。不过我相信我现在比别人写了更多的blog,在将来一定会有收获的。原因很简单,因为两年前写的文章,已经让今天的我有所收获了。

Twitter备份的代码

我前天写过文章,说写了一个保存Twitter记录的工具。今天把代码整理了一下,上传到了网上

目前我只完成了数据获取的部分,至于报表生成的部分我还没有写。写个cgi来输出HTML表格,我上学期学过,应该不难。

程序中用到了sqlite3-ruby和twitter4r这两个库,它们都可以通过RubyGems来安装。

对数据库的操作,我用了最直接的方法,没有进行任何优化。一是考虑到这个程序对速度的要求不高,二是我这学期才开始学数据库,对于SQL语句的优化还没有什么概念。

最后,说一下Ruby中的YAML配置。考虑到不管是数据库的初始化还是更新数据库,都需要Twitter的用户名和密码,而且我也想把一次抓取多少条tweet这个变量也提取出来。本来想的是在程序的开头设置变量,但这样会让程序的使用变得麻烦──修改Twitter的用户名和密码后,需要在两个程序里做出改动。因此写个配置文件就是比较必要的了。过去我一直觉得写一个带配置文件的程序是比较困难的,因为需要自己解析。但Ruby中的YAML让一切变得非常简单。正好借这个机会,学习一些YAML的解析。

中文网页很少,我没有搜到什么结果。最后从一个外国blog上看到了例子,才知道Ruby中用YAML原来是这样的简单。想看的同学自己去看看就会用了。

Twitter备份

自从上次开始,我就想写一个工具,可以像Google搜索历史那样,把Twitter的历史记录下来。思考了几天后,今天开始动手写。

我简单的找了一下,没看到有很合适的工具,也不知道有什么好办法,就用最简单粗暴的方式,写个定时运行的程序,保存tweets到sqlite数据库中,然后从数据库中获取数据,得到列表。

前几天看了Ruby的书,就用Ruby来练一下。并找到了Twitter4r库,能比较方便的获取一定数量的tweet记录。然后结合sqlite3 api接口,在解决了下述几个问题后,程序运行成功。代码我还没有整理好,等以后再上传吧。以下是当中遇到的几个问题。

一是Ruby正则表达式替换的处理,以及sqlite对于转义字符的处理问题。Tweets上经常会有引号,这样在写SQL语句的时候就有了转义的问题。我在程序中是用单引号来包含字符串的,中间一度怎么也搞不定单引号的转义问题──要么把引号弄没了,要么生成不了正确的的结果。看了一下Ruby书,似乎在Ruby正则表达式中,\'和\有特殊的含义,不能直接转义。经过几次尝试,最后用gsub(/'/, '\'\'')解决了问题。具体是什么原理,我没研究过Ruby书,因此没有深究。

二是写好程序后上传到Dreamhost服务器上,sqlite总提示出错。似乎是用了IF EXISTS和IF NOT EXISTS就不行。后来经过搜索才知道,sqlite从3.3.4之后才支持EXISTS关键字。而Dreamhost上的版本不够,于是造成了这个问题。在检查了代码后,觉得虽然不如加了EXISTS保险一些(如果有人工干预操作数据库就可能出错),但也不是非要不可,把EXISTS删除就好了。

第三是当终于能运行了后,却又发现在Dreamhost上生成的数据库在合并的时候会出现每条tweet都存了两遍的情况。为了这个我检查了将近半下午,最后才发现是时区问题。我的表中有个DATETIME字段,存了tweet发布的时间。在我这里时区是GMT-5,而在Dreamhost服务器所在的地方,时区是GMT-7。把建立数据库的程序在服务器上运行一遍后就算解决了问题。

以上是写程序中遇到的三个问题,已经解决了。但在最后我又遇到了一个最大的问题。我准备在Dreamhost上用crontab来每天运行更新程序,但Dreamhost默认没有安装twitter4r,我是通过gem安装的。而似乎crontab运行程序的用户组不是普通用户,导致找不到twitter4r库,结果程序无法运行。当然这些只是我的推测,希望可以尽快解决吧。还有就是生成报告的程序,应该不难,但要在这个的基础上写。

I Wanna My Tweet Archive

twitter-screenshot.png回来这边已经几天了。比两年前的第一次出国的激动紧张相比,有点更加怀念在国内的日子。说来也怪,在国内的时候没有感觉到什么,反而觉得不如在国外舒服。现在倒是经常能回味在国内生活的点滴,如果有机会可以选择是要国外的生活还是国内的,我可能会选择国内的吧。

经常时不时有一些小片段浮现在我脑中,比如在北京的饭店里因为时差原因,很早就醒了,然后躺在床上看电视;还有在北京的饭店时,为了更新Twitter方便,自己写了一个中转网页,不断调试;还有去烟台的路上听到车载收音机里说军人节日什么的,才想到那天是8月1日……所以我突然有了一个想法,把回国时的日程记录到日历上,以便回顾更精细的细节。

这时我第一个想到的就是Twitter。虽然在国内上Twitter不方便,但像我之流的人还是想尽各种办法来更新Twitter。于是Twitter的记录就成为了一个很好的回忆的方法。但当我打开Twitter页面的时候,我就觉得Twitter很可能无法帮助我完成这个任务了。

首先就是Twitter页面最下方的翻页按钮变成了more。虽然说从原先的GET换成AJAX应该是一个进步,但这样的副作用就是用户无法跨越页面来翻阅,而只能一页一页的点more。这样的搜索历史记录就非常的缓慢了。

其次就是当我点了不知道多少遍more后,我发现那个more按钮竟然没有了。最旧的一条记录是8月9日的一条。我当时就有点崩溃,因为我想的是找到7月23日左右之后的记录。

在令我大失所望之后,我找到了一个折衷方法,就是放弃和朋友交谈的记录,只从我的Twitter页面上来寻找,果然找到了我要的记录,虽然并不是我想要的完整对话。

所以这就是我一直想让Twitter改进的地方。虽然现在人们对Twitter的减法赞不绝口,而我想要的archive功能其实算是个加法。但没有了archive,Twitter就只是人们的日常对话而已,过了一天就消逝的无影无踪;而有了archive,Twitter的实用性就变得丰满了起来。

我简略的从网上找了一下,想找一个Twitter API写就的工具,来帮助人们整理过去的tweet记录。结果找到了TweetScan。它有办法帮助你把你的记录保存成TiddlyWiki的形式,打包让你下载。不过它的功能太简略,没有按照时间线来区分,而且保存的似乎也不是我所有的tweet。我现在在考虑是不是自己写一个工具来做这事。

写这篇文章的时候,我想到,如果Twitter被卖给了Google,这项功能是不是就有了。现在Google的搜索记录已经可以查询了,是按日历的形式展现的。而Twitter的形式和Google的搜索记录是非常类似的,只要有足够的资源,达到这个目标应该不难。只是我比较怀疑Twitter的实例就是了。

Twitter不能访问时的更新方法

今天早上,看到Twitter上的同学说Twitter不能访问了,后来从另外的同学那里得到了确认。当时我的第一个想法就是想个办法来让国内的同学可以更新Twitter。

办法很简单,就是让国外的同学来帮忙代发,只要国外的同学得知了国内同学要发布的消息就帮忙发送到Twitter上就OK了。另外,国外的同学可以帮忙代取Twitter上的消息,让国内的同学看到,也算解决了浏览的问题。Twitter开放API,很容一就可以写一个完成这种操作的小脚本,放到cron里面自动运行。小规模操作起来应该没有危险,而如果单单发布的话,就算是已经被墙了的国外主机也可以完成。

当时没有仔细考虑这个问题,只是在Twitter上说了几句。结果同学回复我说月光已经总结了好几种方法。我看了一下都挺不错的,在国内少也没想到用别的网站做中介的方法,不过基本原理也是一样的。

我为什么这么想找到解决方法呢?因为微博和聊天工具一样,虽然几千条的更新有一定粘性,但长时间这么搞下去,用户总会越来越少。要是有一天我在Twitter上的好友都去了饭否之类的网站,我也没办法。虽然不一定会用饭否,但可能要写个小脚本来同步更新了。

虽然现在听说网上有点怨声载道的感觉,不过我觉得也只能这样了。我希望负责此事的人等风头过去后别忘了再恢复回来,一直这样子就不好玩了。

停止使用Plurk

其实这篇文章应该一个星期前就写下的。不过上一个星期都非常忙碌,于是拖到现在。从七天前开始,我就下决心不在更新我的Plurk帐户了。

网络上功能相同的应用是最让人头疼的事情了。自从几年前由Twitter引领起来的微博,在短短的几年里,就出现了很多复制品。其中很多我都试用过,不过多数情况下都是用了几天后就不用了,我在正式使用Twitter前,就做过类似的事情考察Twitter、饭否、和叽歪de三家微博服务,最终确定了Twitter作为我的微博工具。我算是比较有环保意识的,我之后不再用的网络服务,如果可以删除帐号,我多数情况下会选择删除了这个帐号。我有些朋友就会觉得多个帐号不压人,反正不要钱,就任由那个帐号荒废掉。我的想法是在不用服务的时候注销帐号,不仅为别人提供了资源,更重要的是,可以让生活更加融入网络中,结果是网络不再像从前一样,只是一种免费的娱乐器械。有些网络服务供应商可能觉得提供给用户注销帐号的选择,会导致用户的流失。可我从一个用户的角度来看,提供注销帐号的提供商,不仅显得大气,还显得他们的服务更成熟。在我的那篇比较三种微博服务的文章里,叽歪de让不让删除帐号我忘了,饭否是不行,Twitter有这个功能。结果最后我还是选择了Twitter。而我在饭否上的那个帐号上的更新不超过一页,以后有想用liufeng作为用户名的人也无法再使用这个帐号了,不能不让人觉得很垃圾。

我最早听说Plurk这个东西,是因为看了Plurk在中国大陆境内无法访问的相关文章,才知道Plurk是另一个微博服务,当时没对它有太大的兴趣。后来得知有很多台湾人都用Plurk,很多耳熟能详的台湾blogger都在侧栏上加上了Plurk的挂件,这就引起了我的好奇心。于是在有一天看凯洛的部落格时,点了她的Plurk挂件,糊里糊涂的注册了Plurk。Plurk让我体验了这么长的时间,无疑是有它吸引我的地方的。我曾经写了一篇文章来分析Plurk的优点和缺点,里面总结的很多优点都比其它的一些Twitter模仿者好上太多了。Plurk自然有其缺点,不过我决心不再使用Plurk不是因为那篇文章里提到的缺点,而是因为Plurk的“原罪”。

所谓“原罪”,就是指不是从Plurk本身的技术上来看,而是从Plurk的存在价值来看的。微博这个东西,有点脱离blog,而偏向IM,其作用就是让人快速交流的。当你有朋友分布与各种不同的微博工具时,你就要同时维护不同种微博服务上的帐号。有一句话想对所有的朋友说,你就要在每个微博服务上都发布一遍,或者一劳永逸的委托给一个同步工具。这一步看上去还好,但如果你的几个朋友想一起讨论意见事情,而他们都分散在不同的微博服务上,这样就成了灾难了。我们解决的方案,大概有两种:一种是像blog那样,发明一种类似Trackback的东西并制定成标准,来把不同的微博服务联系起来;二是只使用单一的一个微博服务。目前在微博之间联络的标准尚未出炉(现在是连谱都没有)的时候,我的选择是只维护一个Twitter(好在我的朋友都在Twitter上)。不过我还是希望未来我说的第一种解决方案可以实现,因为你不知道那一天那个微博服务会出什么岔子。一旦这种联络技术普及,我们可以放心的把微博服务架在自己的主机上,这样就不怕不怕啦。

另外,让我尝试了这么长时间Plurk的原因还有就是我又一次陷入了用户等级的陷阱中了,好在这次比较轻微。我在2007年四月写过一篇文章《网络程序的用户为什么要设定等级》,提到一些网络服务的注册用户会有一个评级,你在这个服务上花费越多的时间,你的级别就越高,你就会获得相应的权限。Plurk恰好有这么个功能──Karma。Karma是一个0到100的两位小数的浮点数值,你在Plurk上玩的越多(发消息、邀请朋友注册、和别人交朋友……),你的Karma就越高;你一天不更新,你的Karma值就会下降。当你的Karma突破20,你就可以用更多的表情;突破了更多,你就可以自定义页面的形态……理性的思考一下Karma,我觉得它和QQ等级之类的一样无聊,它的作用无非是吸引用户在上面投入更多的时间,但它的缺点就是让人觉得这个服务的娱乐性多于生活性。配合Plurk的华丽的界面,我更觉得Plurk是用来抽时间上来娱乐的,而Twitter的朴实让我觉得我可以把我的生活放在上面。当然,如果我堕落到成天到晚娱乐,可能也会觉得Plurk很亲切吧。想明白了这一点,更加让我决心和Plurk说拜拜了。

写了这篇文章后,我正式删除了我的Plurk帐号

Plurk的优点和缺点

自从我开始使用Plurk以来,对比我一直在使用的Twitter,有了一些感想,写在这里。

首先我要说:“生子当如孙仲谋”这句话,我一直在找一种形式来用在Plurk上。与之相对的是我们熟知的一些Twitter复制品,如饭否、唧歪de之类的。同样是继承了Twitter开创的微博服务,Plurk就能比它们更有创新。这也是我今天讲到的Plurk的优点。

Twitter的用户tweet列表的方法,是一种对用户的tweet的简单组织。按照时间顺序,用户可以非常方便的知道用户最近做了什么。它的缺点是对于用户的交流无法体现出来。在Twitter上几个不同的话题被同时讨论时,用户的回复就常常被误解:到底这条回复是针对哪一条tweet?这种方式一直被饭否、唧歪de简单的继承着。而Plurk独辟蹊径的用了按照线程排序的组织方式,这样一来所有用户的交流过程就被很直观地表现了出来。Plurk改用横向的时间显示方式,同一条信息的交流用纵向来表示。Twitter用户初次接触Plurk时会感到页面挺乱,不过熟悉后就能发觉这样非常有效率。通过鼠标滚轮来横向滚动也比在Twitter上不断的点“more”键翻页来得快。

事情似乎总是一体两面的,Plurk的优点同时又成为了它的缺点。举例来说,我在Plurk上是“棉花糖”的粉丝,棉花糖的每条信息有了更新后Plurk就会提醒我。而这里所谓的“信息有了更新”不仅是指棉花糖的信息列表有了新的内容,而是信息列表有新的内容并且已有的信息有了新的回复。而像棉花糖这种用户交流频繁的用户,他们的交流特别频繁。而一旦有了新的更新,Plurk就会有提示,而这类的更新往往并不是我们想获得的信息。

打个比方说,台湾时间今天早上,棉花糖说了“大家早安”和“希望大家要記得吃早餐唷!!!我們是棉花糖...祝大家有個快樂了一天”。对于棉花糖的粉丝们来说,知道小球或者圣哲至少其中的一个人已经起床了就够了。但有很多的用户会回复这两条消息来给他们致早安,而他们的回复是我不关心的。而我刚才的一个小时之内常常被提醒有了新的回复,察看后才发现只是对这两条消息的回复。

其实我觉得这种缺点是可以通过技术避免的。我用Plurk的时间还短,不知道有没有相关的设置,不过刚才翻了一下“我的帐户”页面没有找到。我的理想状态是:默认情况下只跟踪选定用户的信息,然后看到感兴趣的后,有选项可以让我把它加入到我的跟踪列表里面去,这样其他用户有了对于这些信息的回复后才提醒我。微博的最大不足就是无法从碎碎念的小消息里找到需要的消息,解决了这个问题,微博才会成为更有用的交流工具。

不管怎样,Plurk还是我相当喜爱的工具。优点也好、缺点也罢,总比不加改进就复制别人要好很多。

我的Plurk的使用感受与想法

说起来,我得知Plurk还是因为它在中国被封锁的新闻。当时我上去看了一下别人的页面,觉得不过是又一个Twitter的复制品,因此也没有再关心。后来我在这几天看了不少台湾人的blog,发现Plurk这个东西在台湾挺火的,很多人的blog侧栏上都加了Plurk的gadget。特别是传奇的“Twitter女王”林凯洛blog侧栏上同时摆了Twitter和Plurk的gadget。林凯洛的Twitter数目比我多了大约20000条,我当时就觉得在Twitter上有了27000+条记录的人要同时用Twitter和Plurk两个,于是就点了她blog上的Plurk注册按钮,注册了一个帐号。

与其它的仿Twitter微博不同,Plurk给我的感受就是界面做得相当精美。整个页面分成两部分。上半部分是更新的条目。与传统微博不同的是条目按照时间先后横向排列,可以动态的显式出更新的顺序。用鼠标滚轮可以使线条左右滚动。另外交互线程也比Twitter有了改进,可以清楚的显示出来一个条目的回复过程。这部分也支持一些快捷键,比如V浏览、U更新之类的。页面下半部分是发送更新与用户信息区域。与传统微博一样,Plurk每条信息也是140个字符。信息前面可以在下拉菜单里选择动词,比如“想”、“说”、“觉得”什么的,这样发出的信息就成了“liufeng 说 XXX”这样的话。信息框右侧也有下拉菜单可以选择条目的表情。

Plurk支持机器人,可以通过Google Talk(但不支持Google Apps)、MSN等IM来更新。也支持绑定移动设备,不过我绑定手机后还不知道怎么用。Plurk支持把信息同步更新到Friendster、Facebook、Twitter和Multiply上。我只用了同步到Twitter上这一个功能,是单向同步的。Twitter上从Plurk得到的每条tweet的后面加上了Plurk里相关信息的链接,用了Plurk自己的tinyurl格式。

其它的引起我注意的几点就是Plurk支持包括简繁中文的32种文字。从这个页面了解到,Plurk似乎是通过网友支持翻译的。目前简繁中文的翻译进度都是100%。Twitter的首页显示Twitter目前只支持英文和日文。不过jaycybird提醒我,可能就是因为Plurk有中文界面才被封锁的这么快,因此Twitter没有中文界面未必不是一件好事。另一个在信息区里比较显著的东西是Karma评分。Plurk通过某种算法,给用户评价了0到100的分数,算是鼓励用户使用的一种手段。我在其他用户的Karma这一块下方看到了有的有几个徽章,显式这个用户有什么“丰功伟绩”,比如有的人邀请了多于10个用户、有的人有多于50个粉丝等等。还有就是Karma的用户关系有“好友”和“粉丝”两种,好友指的是两个人互相follow,粉丝是别人但方向follow你,和Twitter里的follow一样。

总体下来,我感觉Plurk的外观像一个非常优秀的Twitter的Web客户端。从信息发布的角度来说,Plurk胜过Twitter;从信息浏览的角度,Plurk和Twitter各擅胜场。Twitter上有大量用户,Plurk的用户体验又优于Twitter。但目前的情况是Plurk上也积累了大量的新用户,比如5月1日刚发行新专辑《小飞行》的棉花糖就有三个Plurk帐号。这种琐碎信息只有在有了一定的用户基数后才能产生实用价值,网上有太多的微博而且底层互不联通我觉得不是一件好事情。我刚才在外面散步的时候就想如果Plurk单单做成一个Twitter客户端会是什么效果,有没有商业价值?不过Plurk目前赚钱的消息还没有听过。

Blog在我的身边没落了

今天清晰的感到我周围的人不爱写blog了。

意识到这一点已经很长时间了,但今天真正让我感到详细的感慨。起因是我看到了“憂鬱馬戲團”的一篇Movable Type教学文章《Blogrolling 使用教學》。Blogroll我一直以为就是blog页面上的友情链接,给blogger们建立关系用的。而Movable Type貌似没有默认提供这个功能,所以要花一点功夫自己来修改模板。看到了文章后,我就在想我要不要也弄一个,然后才意识到我不用Blogroll好久了。

两年前,不管我是在BSP上写blog,还是在独立空间上写,总会记得把身边好友的blog链接加上去,这似乎是建立blog后的第一件事。那时blog在国内还很热,所以当有同学知道我也有blog后,就赶紧要跟我交换友情链接,就像两个人热衷于交换QQ号一样。尽管有的blog以我当时的眼光来看没有任何用处,纯属幼稚的垃圾,但毕竟是一层关系,我也就加了。不过我那时在网上认识的人不多,因此友情链接固定后就没再怎么变化。这种情形似乎持续到上次我的空间被攻击。那时我的空间上的东西都丢失了,因此我的blog也是重新开始的。似乎从那次我就没再怎么设置过友情链接。有几个我是直接能默写出来地址的,我就直接给加上去了。

这次换了Blog系统,Movable Type的设置里一直没有这个功能,我也就一直给忽略了。今天想起来后,想了一下,发现我根本就不必加友情链接了:要加的那些几乎很早就不更新了。也许是因为Twitter的冲击,blog这种东西在我的身边没落了!

我不禁有些伤感,细想原因:一是大家都忙了,可能平时没有精力再在网上维护自己的那一亩三分地;二是新鲜工具的冲击,Twitter把大家的写作欲望都一点一滴的化解掉了,而目前blog这种东西上的文章毕竟不如在校内上发一篇流传的快。不过从“大局”来看,这未尝不是一件好事:有些人的blog本来就不是因为他想有一个表达的渠道而建立的。大概三、四年前,由方兴东起头,国内开始炒作blog。炒作本身就是把一件事物的价值过分抬高,因此导致在那时你要是没有一个blog就是落伍的表现。很多人注册了帐号,更换了模板之后才发现根本不知道要写什么,于是结果有二:好的一点就是不管它,任由那个帐号荒废;不好的一点就是去网上别人的blog上搜刮,把文章搬到自己的空间上,满足一下自己的虚荣心。而我一些同学不在关注blog,把精力放在更有用的地方,也不会对blog圈带来不好的影响,应该是一件好事啊。

可能是由于环境的原因,我一直觉得blog在我身边算是“精英”文化,而不是新浪鼓吹的“草根”。身边屈指可数的blogger就体现了这一点,而真正写出点有用的东西的则少之又少。反正到现在,我身边一直没出现过大面积开始写blog的情况。可能跟我们这一代与blog热潮相遇的时间点有点关系:blog火的时候,大家忙于学业,没有心思写blog;而到大家上了大学,有了点时间,校内就基本上取代了blog。因此我反而觉得blog是“精英”,校内才是“草根”。

这与我在国外的感觉也很相似。我的加拿大同学很少有写正式blog的。虽然也有很多人没听说过Twitter,但有些我觉得应该写blog的都去Twitter了。另外就是Facebook非常盛行,基本上是大学生必备配备,直有“民间学生证”的感觉。反正国外的新奇玩意远比国内丰富,老外不愁找不到blog的替代品。

放眼国内外,我能想到的blogger们都属于精英型的,国内的比较知名的三表、徐宥之流,都是在相关领域有一定影响力的,其它的一些驻于新浪之类的blogger的声音都很微弱,形不成气势。总之,我感觉blog热潮算是过去了,经过“草根”群众的实践,blog这种东西并不能帮助他们表达生活琐事,于是纷纷投入SNS网络,而blog则成了“精英”的表达工具。

:本文中“草根”的解释参考新浪,“精英”指的是一直坚持blog写作的人们。由于找不到合适的词,只好用低俗解释来代替。

又:刚刚看到了“老白说真话”上的一篇文章《丧失了表达欲》,里面的一段话让我相当认同:

某个人之所以写独立的blog,最真实的目的是想贡献出一些别处没有的思想、观点、看法。而且,这些是发自内心的。

为什么独立blogger不容易荒废?很有启发。

从Twitter更新校内状态成功!

继续上篇文章,紧天吃午饭的时候觉得那里说的两种方向都不太容易解决。Python的那个最诡异,实在不知道是哪里的问题,而且Python那个脚本,用了几个库,好像我目前手上能用的虚拟主机上(Dreamhost和SDF)都没有;Bash的那个,我实在是不想把目前的宝贵时间花在学习一门新语言上。然后就想到了我过去最喜欢的Perl,既然它被称为是一门“粘合语言”,应该在里面可以直接调用yegle写的wget语句,而且前两天用Perl写过海词客户端简化版,里面就用了正则表达式来处理了HTML。相对与海词的那个排版混乱的HTML输出,Twitter给的XML可简单清晰多了。

我不知道Perl里怎么解析XML,不过Twitter的XML很简单,我几下就弄出了需要的最新的tweet文本和那一条tweet的时间。然后用yegle的wget语句提交,一下子就成功了。然后就发现了一个困扰了我长时间的问题:如果tweet里面是中文,就无法提交(实际上是提交了一个空信息)。然后让程序打印初那条tweet的文字,发现都成了写这样的东西,然后就到处研究怎么把它转换成正常的文字。后来从这里知道了需要用HTML::Entities来处理(代码里第38行)。做了这一步后那些wget语句就又好使了。

结下来就是隔一段时间就运行一下这个程序了。cron似乎是我第一个想到的。还有一个方法就是在Perl脚本里用循环,不过这样似乎有点不妥(具体怎么不妥我没有自习琢磨)。我的MacBook虽然基本上保持开机状态,不过把它放在24小时运行的网上的虚拟主机上似乎更不错。我目前有两个虚拟主机帐号,一个是Dreamhost,一个是SDF。结果两个都有问题:Dreamhost上的wget版本太老,不支持命令行里的那些session、cookies功能;SDF则不让我用cron。SDF的问题不大好办,似乎cron是它们专门的用户帐号才能做的,我目前的ARPA帐号不在此范围。我只好试着下载wget的代码在Dreamhost上编译。结果出乎我意料,居然编译成功了!我过去在不是本地的主机上编译软件通常是以失败而告终的。用了新版本的wget,程序就运行正常了。设定好了cron(我让程序2分钟运行一次,查看了Dreamhost的wiki上关于cron的说明,没有提到有什么限制),程序运行OK。

这时还有最后一个问题没解决:如果让这段代码隔一段时间就自动运行,那么如果在这段时间里面没有更新Twitter,那么校内的状态会被不断用同一条tweet刷新。这也是我要保存最新tweet的发布时间的目的。我用的方法是把这一条tweet的发布时间写到一个磁盘文件中去,然后下一次运行的时候比较两个时间,如果两个时间不同,就运行发布的wget命令,然后更新磁盘文件,否则就退出程序。我不知道有没有更好的解决方案,不过我的方法目前还可行。

最后就是把代码贴出来了。我整理了一下,把用户名、帐号、磁盘文件、还有wget程序的地址都弄成了变量,放在代码最前面以方便设定。完事后看起来还不错。

01 #!/usr/bin/perl -w
02
03 # Twitter -> Xiaonei status sync tool.
04 # Author: Feng Liu <liufeng@cnliufeng.com>
05 # Version: 1.0
06 # Date: Tue Apr 21 23:06:40 +0000 2009
07
08 use utf8;
09 use Encode;
10 use LWP::Simple;
11 use HTML::Entities;
12
13 ####################### Settings starts here #######################
14 # Set your base account information here. Don't show this to others!
15 my $twitter_account = '';
16 my $xiaonei_email = '';
17 my $xiaonei_passwd = '';
18
19 # some machine's wget is too old, so you may need to rebuild a newer
20 # version and indicate the path of your own wget here.
21 my $wget_cmd = 'wget';
22
23 # The program needs a log file for keeping the time of your last
24 # tweet. Otherwise you may get your xiaonei status updated to a same
25 # tweet. So please keep this file!
26 my $logfile = '/tmp/twxn.log';
27 ######################## Settings ends here ########################
28
29 my $twitter_url = 'http://twitter.com/statuses/user_timeline/' . $twitter_account . '.xml';
30 my $statuses = get($twitter_url);
31 my @lines = split /\n/, $statuses;
32 my $latest_text = $lines[5];
33 my $latest_time = $lines[3];
34
35 if ($latest_text =~ /<text>(.*)<\/text>/) {
36     $status = $1;
37 };
38 $text = decode_entities($status);
39
40 # If the log file doesn't exist, create a new one.
41 if (!(-e $logfile)) {
42     open LOG,"> /tmp/twxn.log" or die "ERROR: Cannot create log file.";
43     close LOG;
44     print "Created a new log file: $logfile\n";
45 }
46
47 open LOG, "< $logfile" || die "ERROR: Cannot open log file!";
48 $last_time = <LOG>;
49 close LOG;
50
51 if ($last_time ne $latest_time) {
52
53     my $login_cmd = $wget_cmd . ' --no-proxy -O xiaoneilogin.log --post-data="email=' . $xiaonei_email . '&password=' . $xiaonei_passwd . '&autoLogin=true"  --keep-session-cookies --save-cookies=xiaoneicookie http://login.xiaonei.com/Login.do';
54
55     my $post_cmd = $wget_cmd . ' --no-proxy -O xiaoneipost.log --post-data="c=' . $text . '"  --keep-session-cookies --load-cookies=xiaoneicookie http://status.xiaonei.com/doing/update.do --referer=http://status.xiaonei.com/getdoing.do';
56
57     system($login_cmd);
58     system($post_cmd);
59    
60     open LOG, "> $logfile" || die "ERROR: Cannot open log file!";
61     print LOG $latest_time;
62     close LOG;
63 }

最后,感谢半瓶墨水yegle的指教与启发!

校内状态更新有进展

不愧是水木的Linux版主,yegle直接用wget就能成功的修改了校内的状态。不过话说wget、curl这种看似不起眼的命令行工具还真是牛屄,man了一下yegle的代码里面wget的参数,感觉我过去只把wget当成一个下载软件只是大材小用了。

我测试了他的代码。刚开始的时候一直不能成功,后来经yegle在Twitter上指点后也成功了。只是不会更新“目前”的状态,而是修改的“目前”的上一条状态。换句话说,目前的状态显式“什么都没做”,但从个人主页上可以显式状态被修改的历史。

这已经相当程度的解决了问题了。我对用shell处理xml还不熟悉,不能做到一直在后台更新Twitter的消息,有待以后研究。或者再继续修改那个Python脚本。要么就干脆结合Python和Bash,也可以解决问题。

另外,关于上一篇文章中的问题,我昨天回家就给python-twitter发了issue,今天早上看到有人回复,原来从今年四月8日开始,Twitter就不在http header里面支持since参数了,真是很奇怪。另外,发芽网的半瓶墨水回复了我的邮件,给我了一篇“鼓励性”的邮件……

被Python字符串弄崩溃了

受发芽网上的一段“校内网发帖机”的启发,最近想修改那段代码,让它可以部分的实现Twitter状态和校内网同步。之所以说“部分的”是因为我不知道怎么样让它像Facebook的Twitter插件那样Twitter的消息发送完毕后几乎同时(相差不到10秒钟)把Facebook的状态一并更新。另外一点很惭愧,就是我对HTTP编程不熟悉,目前还找不初修改校内的状态要提交的代码,只能修改一下原来的代码,在写日志上面做文章。

就算这样,也还是遇到了不少问题。我目前的打算是像过去WordPress上用过的一个插件,名字大概叫twitter-post那样,总结一天的Twitter消息,成为一篇文章,发送到校内上去。我开始用的是python-twitter这个包,很方便的就能弄到Twitter的消息。不过在它的GetUserTimeline()方法的说明中说到里面有一个since参数,提交一个“HTTP-formatted time”,就可以获得从那个时间点以后的消息。我觉得它应该能让我获得前一整天的所有消息,虽然需要做点处理,删除今天的消息。但这个“HTTP-formatted time”我实在是不知道是什么东西。昨天下午几乎找遍了我能从网上找到的所有表示时间的格式,怎么测试,它都只给我默认的最近20条的消息。可笑的是,python-twitter的代码里有test可以运行,而里面测试since参数的用例里用得Twitter帐号居然总共才不到10条tweets,这样GetUserTime()返回了所有的tweets,当然都是他要的时间段的啦。没办法,我只好去它的Google Groups里发问,结果今天居然找不到我提交的帖子了,难道是开发者觉得我是捣乱的?!!

既然这样不行,只好退一步先把能获得的最近20条tweets一并发上去,先看看效果再花功夫自己来解析前一天的所有tweets。结果很快写出了代码,但测试的时候却不行了。那段代码,我在程序里输入什么样的文字都可以正常发送,但自己从Twitter那里获得的文字就无法发送。Python一点提示都没有。我不光试验了python-twitter API给出的结果,还自己抓取了Twitter给出的XML文件自己parse,得到的结果也无法发送。我让两个程序在提交前输出提交的字符自己来比对,基本上都是一种格式的。简直快疯掉了。

接下来该怎么办?我目前只想到:

  • 继续骚扰python-twitter,谁让他给出的测试用例中有问题呢?

  • 像那段发布“校内网发帖机”的半瓶墨水虚心请教。

  • 昨天晚上yegle在Twitter上对那段代码表示了兴趣,如果我没猜错的话,他应该就是某个BBS的Linux版版主之一,大概Python功力比我这种菜鸟强很多,说不定他能“一语惊醒梦中人”……

我目前的代码如下,它还不能工作。这个是我自己parse Twitter的XML版本,用python-twitter的版本前半部分简洁一些,不过差别不大,两者都有同样的问题。

01 #!/usr/bin/env python
02 # -*- coding: utf-8 -*-
03
04 from xml.dom import minidom
05
06 # 需要先运行wget http://twitter.com/statuses/user_timeline/liufeng.xml
07 tw_url = 'http://twitter.com/statuses/user_timeline/liufeng.xml'
08 xmldoc = minidom.parse('liufeng.xml')
09
10 status = xmldoc.firstChild
11 tweet = status.childNodes[1]
12
13 output = ""
14 count = 1
15 flag = 0
16 for tweet in status.childNodes:
17     if flag == 1:
18         created_at = tweet.childNodes[1].firstChild.toxml()
19         text = tweet.childNodes[5].firstChild.toxml()
20         output += str(count) + " " + text + " " + created_at + "\n"
21         count += 1
22         flag = 0
23     else:
24         flag = 1
25
26
27 import cookielib
28 import urllib2
29 import urllib
30 import time
31
32 cj = cookielib.CookieJar()
33 opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
34 exheaders = [("User-Agent", "Mozilla/4.0 (compatible; MSIE 7.1; Windows NT 5.1; SV1)"),]
35 opener.addheaders = exheaders
36 url_login = 'http://xiaonei.com/Login.do'
37 body = (('email', '*******@gmail.com'), ('password', '*******'))
38 req1 = opener.open(url_login, urllib.urlencode(body))
39 print "Login should be successful.\n"
40
41 body = {'relative_optype':'publisher', 'blogControl':'1'}
42 url_post = 'http://blog.xiaonei.com/NewEntry.do'
43 title = '最近我(说了/做了/想了)什么 %s' % time.asctime()
44 #xt = text.encode('utf-8')
45 print output
46 output = output.encode('utf-8')
47 print " fucked\n\n" + output
48 body['title'] = title
49 body['body'] = output
50 req2 = opener.open(url_post, urllib.urlencode(body))
51
52 #print urllib.urlencode(body)

Twitter上follow谁?

Twitter上follow谁?今天看了月光在Google Reader上分享了一篇来自”望月的博客”的文章《45+或许你想follow的twitter帐号》后,突然有了明确表述的想法。当然,我不是Twitter专业用户,讲得都是我自己的想法,并不客观。

首先我想说一下”微博”的作用以及由于作用所带来的它的性质。与传统网站、新兴的论坛、blog一样,微博的作用同样是发布信息的媒体。他们之间的区别是成本不同:传统的静态网页需要发布者有编辑的权利,而论坛、blog则只需要一个帐号。Twitter则把这种成本进一步降低,可以说是使成本无限接近与一个标准。这里的”标准”,被我不严谨的描述为”越接近这个标准,人们越有意于发布一篇文章/帖子/信息…”。

Twitter之前的媒体的成本,大约在标准之上。因此尽管通过论坛、blog发布信息越来越容易了,还是有人不会这样做。原因无非就是他们的信息太无关紧要了,根本不值得发布;或者他们虽然有值得发布的信息,但由于太懒,不愿把它整理成一篇文章。而Twitter几乎把成本降低到了无限接近这个标准的程度,因此像”我的猫…了”这种信息,大家也乐于发布到Twitter上。Twitter的140个字的限制,很大程度上促进了成本的降低。

正是Twitter的这种作用,它的一个性质是:上面的许多信息都不正式。如果你是普通人,那么喜欢读这些非常琐碎的日常信息的人,基本上都是你的亲友。与你越不熟的人,越对这些信息没有兴趣。当这种兴趣无限降低时,你的信息则对对方造成了骚扰。我有一次用twitterfeed把用last.fm记录的我目前在听的音乐信息同步到我的Twitter帐号上,不一会儿就有人在Twitter上让我停止。当时我第一个想法是这种责任在于订阅者而不在发布者,也就是说我有权利发布任何我想发布的信息,如果你不喜欢,要么不要follow我,要么闭嘴。不过考虑到我的行为其实属于滥用,因此就关掉了。

这就是微博的问题。因为发布信息的成本极低,因此Twitter上必然产生”无聊”的信息。而且只要你想,你几乎可以产生无限多的这种信息。当然,如果你要刻意的研究一个人,这种信息越多越好,反之,你的日常工作会被这些信息淹没。在Pownce关门前,我曾经做过实验:在Pownce上不断添加好友,不管我认识还是不认识(事实上,这些人我现实生活中一个都不认识)。实验的目的是体验一下”与社团融入”的感觉。结果是我很快就不在用Pownce了。

后来我想到,在Twitter上要follow的人,一定要是你在日常生活中认识的人。哪怕是不曾见过,也一定要说过话。否则一旦follow的人多了,而那些人又都是更新频繁的”Twitter大户”(其实只要飞猪一人就要你命了),几乎肯定会被骚扰。

因此,或许你会想follow那45+个Twitter帐号,不过还是希望你三思。

PS,这篇文章还隐含的涉及到一个有争议的问题:”真正的Twitter使用者”。简单的讨论一下:如果你不是真正的Twitter使用者,你或许不会用客户端软件来即时获取Twitter上的信息,而只通过浏览器来主动查看Twitter上的信息时,被大量信息骚扰的可能性就很低了;另一方面,当你用客户端时,你大概算是Twitter的日常用户,但这样一来,当你follow了会频繁更新的人时,你的工作就经常会被骚扰到。不过这个问题并没有定论。

母体外的人

还有半小时计算机伦理课就要开始了,这次我想写写我们这门课老师的一个特点。我相信他的这个特点蛮普遍的,就是:活在母体(matrix)之外。

对于我们这一代来说,把互联网形容成电影《Matrix》里面的matrix再适合不过了。虽然程度上并不是那么强大,但现今的互联网上总能或多或少的找到某个人的某些信息。Google的发展壮大固然是一个很大的因素,但更重要的是我们心态上的变化。开放的社会环境使得我们比过去更加不惧怕在网上公开自己的信息,Twitter、Facebook、校内网的壮大就是依赖于我们的这种心态。

2007年,Kevin Kelly在TED上作了题目为“预测5,000日之后的互联网”的演讲,里面根据从互联网诞生的那一天到Kelly演讲时的总共大约5,000天中互联网的发展趋势,Kelly估计了从那时开始再过5,000天后互联网的情形。其中他说道,那时人们的信息都在互联网上,当你忘了你朋友的电话号码时,上Google搜索就出来了。Kevin Kelly是电影《Matrix》的顾问,因此他的预计这么像Matrix里的剧情就不足为奇了。

人们的资料都公开,对我来讲很难说是好是坏。但我们的老师就不喜欢这种“科技带来的进步”。

描述一下他的行为吧:他是大学计算机系的老师,却没有所有权属于自己的电脑;工作时不随身带手机(鉴于他的教师职位,这点可以接受);他回家后就把手机关机,拒绝被任何工作上的事情打扰;他注册了Facebook帐号,却没有一个好友,只是用Facebook帐号去看别人的页面;他对我们宣称自己为了体验,注册了Twitter帐号,但不管我们如何软磨硬泡,他就是不告诉我们他的Twitter的用户名……

他并不强烈反对这些技术,也不觉得这些技术不好,但对于自己使用这些技术感到有点空洞的不妥。他也说不上来具体如何不妥,但就是觉得“隐隐”不对。说白了就是钻牛角尖吧:)

这种人似乎并不少见。我简单的想了一下,似乎我们的上一代人都不是对这些技术很感冒。不说社会性网络、微博这类新鲜事务,有些人对于个人网页都不是很赞同。很难解释这方面的原因。

今天正好看keso共享了译言翻译的一篇文章“从Facebook到Twitter:‘数字化亲密’的美丽新世界”。里面“环境知觉”这一段里本·哈雷的例子我感觉很有趣:经过尝试,他习惯甚至沉迷于Twitter当中。文章中是这样解释的:

这就是环境知觉的悖论。每条小的更新,每一条单独的社交信息,本身都是微不足道的,甚至是十分平庸的。但若假以时日,当它们汇集起来,这些小片段就渐渐接合成一幅细致得惊人的、描绘你朋友或家人生活的画卷,就像成千上万个点构成的一幅点描派画作。这在过去是绝无可能的,因为在现实世界中,没有朋友会专程打电话给你描述她吃的三明治是什么样子。用哈雷自己的话说,这些环境信息就好比“一种超感知觉”,一种弥漫在我们日常生活中的看不见的存在。

这段话是否正确,我无法判断。这类拒绝母体的人是否落后于时代,同样无法判断。我只知道:从我们这一代起,人们会越来越依赖网络。不过就像电影里面描绘的那样,生活在母体里的人们看上去被当作机器的能源,但与Neo这群人相比,究竟谁更幸福,还真是难说。

虽然不能得到具体的结论,不过在我脑袋里想了将近一个学期的问题,终于被我写了下来,也算欣慰了。

失败

最近经历了一连串失败。

主要是围绕着blog来的。首先是想恢复因为Twitter而松懈下来的blog。本来很久没更新就放在了那里苟延残喘,后来服务器受攻击,结果我的目录下的东西都没了。恢复后放了一个首页,加个Twitter Badge和几篇垃圾论文凑合着。想想也挺可惜,就想把blog恢复了。

然后就是最近看了些敏捷开发的东西,想借这个机会试试Ruby on Rails或者基于Python的Django。用它们来开发一个blog也是件挺酷的事情。况且最近新进了MacBook,TextMate,对RoR的支持不错,就找了几篇文档来看。结果实践下来,总是有这样那样的错误无法解决,最后终于气馁。恰值WordPress 2.5发布,之前用着也挺顺,就用它凑合了。

过去也攒了不少文章,虽说不是那么好,但也想把它用来充数。虚拟主机被攻击后,数据丢失。本来已经想通了放弃,但合租的“协调人”后来发邮件告诉我找回了一部分数据。我看了一下,有数据库的sql文件备份,于是就试着导入。当时还不想直接导入到这个帐号里,因为过去用Twitter-tools在blog的侧栏上显示Twitter更新,后来发现Twitter-tools在我的数据库里面记录了所有的Twitter更新,这次就不想留它们。于是就先导入到过去英文blog的数据库里面。中间出现了写问题,我解决了一些,然后又出现一些。而且这个文件有10M多,压缩了上传就直接出错,不压缩直接传除了一开始有提示错误外,其它基本上没完成过。传到刚才,决定放弃了。

几次失败,不算学业、生活上的大事,也够无趣的,恰和这个blog的标题。至于为什么把原先的Feng's Style改成这个名字,等以后再说吧。

Find recent content on the main index or look in the archives to find all content.