<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>Kavin Gray</title>
	<atom:link href="http://www.kavingray.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kavingray.com/blog</link>
	<description>Blog about life, inspiration and new ideas</description>
	<pubDate>Sun, 25 Jul 2010 12:27:40 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>It’s been a while..</title>
		<link>http://www.kavingray.com/blog/it%e2%80%99s-been-a-while/</link>
		<comments>http://www.kavingray.com/blog/it%e2%80%99s-been-a-while/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 12:27:40 +0000</pubDate>
		<dc:creator>Kavin</dc:creator>
		
		<category><![CDATA[Life]]></category>

		<category><![CDATA[internship]]></category>

		<guid isPermaLink="false">http://www.kavingray.com/blog/?p=826</guid>
		<description><![CDATA[
So scared of getting older.I&#8217;m only good at being young,so I play the numbers game to find away to say that life has just begun
Had a talk with my old man, said help me understand.He said turn 68, you&#8217;ll renegotiate
John, honestly&#8230;we&#8217;ll never stop this train

Song “Stop this train” by John Mayer.I’ve been listening to it [...]


No related posts.]]></description>
			<content:encoded><![CDATA[<blockquote><p>
<em>So scared of getting older.I&#8217;m only good at being young,so I play the numbers game to find away to say that life has just begun</p>
<p>Had a talk with my old man, said help me understand.He said turn 68, you&#8217;ll renegotiate</p>
<p>John, honestly&#8230;we&#8217;ll never stop this train</em>
</p></blockquote>
<p>Song “Stop this train” by John Mayer.I’ve been listening to it for a while.Pretty nice lyric,there&#8217;s something in it cuz usually I dont care about the lyrics while I&#8217;m listening songs.</p>
<p>So the internship has finally began.Actually It&#8217;s kinda like a short term training：two weeks of special training at school and that&#8217;s all.It is compulsory to attend this internship.Don&#8217;t ask me how is this happen.It&#8217;s a long story.</p>
<p>Now I am stuck by this school stuff and I don&#8217;t even know if I have time to get a full time internship of my own then.I&#8217;m going to graduate next year but now everything is still uncertain.</p>
<p>Wish I could stop the fucking time&#8230;which I couldn&#8217;t.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.kavingray.com/blog/it%e2%80%99s-been-a-while/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Della bot 2.0.1</title>
		<link>http://www.kavingray.com/blog/della-bot-201/</link>
		<comments>http://www.kavingray.com/blog/della-bot-201/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 15:20:01 +0000</pubDate>
		<dc:creator>Kavin</dc:creator>
		
		<category><![CDATA[Design]]></category>

		<category><![CDATA[bot]]></category>

		<category><![CDATA[Della]]></category>

		<category><![CDATA[gae]]></category>

		<category><![CDATA[Gtalk]]></category>

		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.kavingray.com/blog/?p=795</guid>
		<description><![CDATA[去年做的Della由于年久失修，各种查询已经失效了，而且当时做的gtalk版本是用xmpppy模块在本地运行实现，所以无法达到机器人24小时在线。所以最近抽空把Della的代码完全重构了一次，目前已经update至2.0.1版本，实现的查询功能是天气，股票，星座，词典。如果你对Della还不了解，可以看看去年的这篇日志。
上周也拿到新浪围脖的app key，说实话之前没想到围脖会开放api的，于是也顺手把Della移植到围脖上( @iDella )，同时加上GAE的xmpp功能完成了机器人24小时gt在线，新重构的Della无论在miniblog部分还是gt部分都依靠gae来跑了。Della 2.0.1在Twitter、围脖和Gtalk上都能使用，具体使用帮助可以参考这里。 
新版Della的代码也开源到新项目主页上了，十分欢迎各位为Della添加新的查询功能，具体程序结构开发事项可参考：http://code.google.com/p/della-bot/wiki/Development
源码下载(Della 2.0.1.rar) &#124; 项目Google Code主页(含源码)


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>去年做的Della由于年久失修，各种查询已经失效了，而且当时做的gtalk版本是用xmpppy模块在本地运行实现，所以无法达到机器人24小时在线。所以最近抽空把Della的代码完全重构了一次，目前已经update至2.0.1版本，实现的查询功能是天气，股票，星座，词典。如果你对Della还不了解，可以看看去年的这篇日志。</p>
<p>上周也拿到新浪围脖的app key，说实话之前没想到围脖会开放api的，于是也顺手把Della移植到围脖上( @iDella )，同时加上GAE的xmpp功能完成了机器人24小时gt在线，新重构的Della无论在miniblog部分还是gt部分都依靠gae来跑了。Della 2.0.1在Twitter、围脖和Gtalk上都能使用，具体使用帮助可以参考<a href="http://code.google.com/p/della-bot/wiki/Introduction">这里</a>。 </p>
<p>新版Della的代码也开源到新<a href="http://code.google.com/p/della-bot/">项目主页</a>上了，十分欢迎各位为Della添加新的查询功能，具体程序结构开发事项可参考：<a href="http://code.google.com/p/della-bot/wiki/Development ">http://code.google.com/p/della-bot/wiki/Development</a></p>
<div class="download"><a href="http://della-bot.googlecode.com/files/della%202.0.1.rar">源码下载(Della 2.0.1.rar)</a> | <a href="http://code.google.com/p/della-bot/">项目Google Code主页(含源码)</a></div>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.kavingray.com/blog/della-bot-201/feed/</wfw:commentRss>
		</item>
		<item>
		<title>又一年</title>
		<link>http://www.kavingray.com/blog/another-year/</link>
		<comments>http://www.kavingray.com/blog/another-year/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 07:00:43 +0000</pubDate>
		<dc:creator>Kavin</dc:creator>
		
		<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://www.kavingray.com/blog/?p=792</guid>
		<description><![CDATA[新年的时候憋着没写总结，其实也没时间好好总结。现在应酬玩乐基本结束，也开始好好回顾过去一年。
怎么说呢，过去一年还是有些进步，包括成长、专业上的一些东西，做了几个项目，信心也有所提升。但是，但是，这种进步没有我期待的那么大，过去一年我也犯了好多错误，错过了好多机会，很多都是因为犹豫和懒惰造成的，这一点是无论如何都不能原谅自己的。所以，这几天在回顾这过去一年的时候，更多的是遗憾和后悔，我知道我还能做的更好，时间已经越来越短，很快就毕业很快就要面对新的问题，我是否已经准备好了，思考了几天，答案是：not yet。
我也不想过多追究已经错过和发生的事儿，接下来两年毫无疑问是我人生一个最重要的时间段，梦想实现与否全看自己未来的表现，我相信我还有机会，我也相信人生如果没有拼尽全力而奋斗这个过程那也算是白过了。不管怎样，接下来我会尽力做到最好，至少，不会让任何机会再从我手上溜走了。


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>新年的时候憋着没写总结，其实也没时间好好总结。现在应酬玩乐基本结束，也开始好好回顾过去一年。</p>
<p>怎么说呢，过去一年还是有些进步，包括成长、专业上的一些东西，做了几个项目，信心也有所提升。但是，但是，这种进步没有我期待的那么大，过去一年我也犯了好多错误，错过了好多机会，很多都是因为犹豫和懒惰造成的，这一点是无论如何都不能原谅自己的。所以，这几天在回顾这过去一年的时候，更多的是遗憾和后悔，我知道我还能做的更好，时间已经越来越短，很快就毕业很快就要面对新的问题，我是否已经准备好了，思考了几天，答案是：not yet。</p>
<p>我也不想过多追究已经错过和发生的事儿，接下来两年毫无疑问是我人生一个最重要的时间段，梦想实现与否全看自己未来的表现，我相信我还有机会，我也相信人生如果没有拼尽全力而奋斗这个过程那也算是白过了。不管怎样，接下来我会尽力做到最好，至少，不会让任何机会再从我手上溜走了。</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.kavingray.com/blog/another-year/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Piece By Piece</title>
		<link>http://www.kavingray.com/blog/piece-by-piece/</link>
		<comments>http://www.kavingray.com/blog/piece-by-piece/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 16:22:23 +0000</pubDate>
		<dc:creator>Kavin</dc:creator>
		
		<category><![CDATA[Life]]></category>

		<category><![CDATA[Story]]></category>

		<guid isPermaLink="false">http://www.kavingray.com/blog/?p=772</guid>
		<description><![CDATA[讲一个故事，关于我的表哥，关于一个答案
表哥开始用电脑接触3DMax那个时候，我还是在读初中，他喜欢用3DMax做一些有趣的3D动画，我想这也成了当时他最大的兴趣之一吧，后来他成功拿着这些自己做的作品在一家公司找到了工作，后来又跳槽到我们当地一家比较知名的广告公司，他做过室内装饰设计，做过影视动画制作管理，这些事情都不是一蹴而就的，他的技术全部来自自学，我也听我妈说因为技术比别人出众，也是大概比较受重用的原因吧，所以公司很多小人都在有意排斥他，这样的环境真是难以置信，其中的艰辛我想只有他自己最明了，但他还是在这个公司做了下来，而且一做就是好几年。
再后来，酝酿了两三年，在时机成熟的情况下，在一些人怀疑和不解的眼光下，他终于开始自己创业，从自己一个白手打拼无固定员工的小工作室，发展现在有一个专业团队的广告公司，他用了短短不到两年，最近又扩充了公司的地点，可以说在渐渐步上正轨，当地电视报纸开始采访他，电视的广告越来越多出自他之手，现在他依然和当时一样拼命工作，和自己是员工时候一样，现在他28岁。
讲这个不是为了广告什么，一直有人在问怎么才是好的工作，怎样才是好的生活，怎么才能得到好的工作，I‘ve been there before。现在我渐渐觉得，这个故事已经是答案了。
你的想法，你的兴趣，你的细节、专注和冒险，足以让你忍受经历过程中的所有艰辛和挫折，足以决定你未来的进程。
这就是我的答案，在21岁开始的时候。


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>讲一个故事，关于我的表哥，关于一个答案</p>
<p>表哥开始用电脑接触3DMax那个时候，我还是在读初中，他喜欢用3DMax做一些有趣的3D动画，我想这也成了当时他最大的兴趣之一吧，后来他成功拿着这些自己做的作品在一家公司找到了工作，后来又跳槽到我们当地一家比较知名的广告公司，他做过室内装饰设计，做过影视动画制作管理，这些事情都不是一蹴而就的，他的技术全部来自自学，我也听我妈说因为技术比别人出众，也是大概比较受重用的原因吧，所以公司很多小人都在有意排斥他，这样的环境真是难以置信，其中的艰辛我想只有他自己最明了，但他还是在这个公司做了下来，而且一做就是好几年。</p>
<p>再后来，酝酿了两三年，在时机成熟的情况下，在一些人怀疑和不解的眼光下，他终于开始自己创业，从自己一个白手打拼无固定员工的小工作室，发展现在有一个专业团队的广告公司，他用了短短不到两年，最近又扩充了公司的地点，可以说在渐渐步上正轨，当地电视报纸开始采访他，电视的广告越来越多出自他之手，现在他依然和当时一样拼命工作，和自己是员工时候一样，现在他28岁。</p>
<p>讲这个不是为了广告什么，一直有人在问怎么才是好的工作，怎样才是好的生活，怎么才能得到好的工作，I‘ve been there before。现在我渐渐觉得，这个故事已经是答案了。</p>
<p>你的想法，你的兴趣，你的细节、专注和冒险，足以让你忍受经历过程中的所有艰辛和挫折，足以决定你未来的进程。</p>
<p>这就是我的答案，在21岁开始的时候。</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.kavingray.com/blog/piece-by-piece/feed/</wfw:commentRss>
		</item>
		<item>
		<title>喃喃自语的自在</title>
		<link>http://www.kavingray.com/blog/kellysweet/</link>
		<comments>http://www.kavingray.com/blog/kellysweet/#comments</comments>
		<pubDate>Sat, 24 Oct 2009 17:00:08 +0000</pubDate>
		<dc:creator>Kavin</dc:creator>
		
		<category><![CDATA[Music]]></category>

		<guid isPermaLink="false">http://www.kavingray.com/blog/?p=753</guid>
		<description><![CDATA[
这不是一张任何时候都适合听的专辑，但一个慵懒的午后，一杯红茶，反复循环的Raincost；在一个微醒的早晨，一首We Are One；在合适的时间，它就是一个世界。
Kelly Sweet，有人叫她甜心凯莉，07年处女专辑，《We Are One》。最喜欢Raincost，也是我听到的第一首歌，小Jazz，喃喃自语又慵懒的声音，温暖而收放自在。不觉得如有人所说的风格像早期MC（好吧，演唱时候范儿是有点像），倒觉得像早期的Hayley Westenra，同样以古典流行爵士作为专辑的主调，同样多语言歌曲自如演绎，而比之Hayley的声音，Kelly虽少了点古典却多了温暖。
几乎每首歌都十分出色，包括重新演绎的翻唱作品，配合Kelly温暖古典的唱腔，这样的专辑只能用美来形容。We Are One的安静，清柔和声，Dream on的平静冰洁，Je t&#8217;aime的哀伤倾诉，仅仅是一个新人，仅仅20岁，这在近年极为浮躁的乐坛特别少有，虽然现在评论是否为新生代天后还为时过早，但是Kelly确实拥有一般新人没有的气质和嗓音。
正如Kelly自己的评价，这张专辑的音乐不只是关于自己，也是关于人内在的灵魂。每首歌曲都是Kelly的自语，自在地诉说属于她的和大家的世界，快乐哀伤。


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.kavingray.com/images/blog/kelly.jpg" alt="" title="" class="img_border" /></p>
<p>这不是一张任何时候都适合听的专辑，但一个慵懒的午后，一杯红茶，反复循环的Raincost；在一个微醒的早晨，一首We Are One；在合适的时间，它就是一个世界。</p>
<p>Kelly Sweet，有人叫她甜心凯莉，07年处女专辑，《We Are One》。最喜欢Raincost，也是我听到的第一首歌，小Jazz，喃喃自语又慵懒的声音，温暖而收放自在。不觉得如有人所说的风格像早期MC（好吧，演唱时候范儿是有点像），倒觉得像早期的Hayley Westenra，同样以古典流行爵士作为专辑的主调，同样多语言歌曲自如演绎，而比之Hayley的声音，Kelly虽少了点古典却多了温暖。</p>
<p>几乎每首歌都十分出色，包括重新演绎的翻唱作品，配合Kelly温暖古典的唱腔，这样的专辑只能用美来形容。We Are One的安静，清柔和声，Dream on的平静冰洁，Je t&#8217;aime的哀伤倾诉，仅仅是一个新人，仅仅20岁，这在近年极为浮躁的乐坛特别少有，虽然现在评论是否为新生代天后还为时过早，但是Kelly确实拥有一般新人没有的气质和嗓音。</p>
<p>正如Kelly自己的评价，这张专辑的音乐不只是关于自己，也是关于人内在的灵魂。每首歌曲都是Kelly的自语，自在地诉说属于她的和大家的世界，快乐哀伤。</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.kavingray.com/blog/kellysweet/feed/</wfw:commentRss>
		</item>
		<item>
		<title>TwiTalker</title>
		<link>http://www.kavingray.com/blog/twitalker/</link>
		<comments>http://www.kavingray.com/blog/twitalker/#comments</comments>
		<pubDate>Thu, 08 Oct 2009 12:27:24 +0000</pubDate>
		<dc:creator>Kavin</dc:creator>
		
		<category><![CDATA[Design]]></category>

		<category><![CDATA[gae]]></category>

		<category><![CDATA[Gtalk]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[TwiTalker]]></category>

		<category><![CDATA[twitter]]></category>

		<category><![CDATA[XMPP]]></category>

		<guid isPermaLink="false">http://www.kavingray.com/blog/?p=637</guid>
		<description><![CDATA[
TwiTalker 是我九月初做的一个应用，提供推特Gtalk机器人服务，通过绑定添加TwiTalker 机器人可以在Gtalk上更新自己的推特和接收好友消息。代码花了两多周时间，9月19号开始公开测试，拖到现在才想到是时候总结下了，一方面是自己懒，一方面也是前段时间还一直在进行增加功能和后台优化。
和Della一样，这个应用也是基于Google App Engine。今年初开始就一直有传闻GAE将支持XMPP，自己盯着Google开放这个功能已经半年，终于在九月时候等到了。刚好饭否已经被那个啥了，转移到Twitter后发现它的官方Gtalk机器人已经失效多时，于是就想着要做这么一个应用，开始也只打算做着自己用的，后来觉得应该有人也需要这么个工具，于是干脆按多用户的结构去设计。


简介
TwiTalker和其他微博IM机器人一样，主要功能就是发推和接收消息。在此基础上你可以设置接收消息的模式，时间间隔；还有做一些基本的操作，如加删好友，收藏RT消息，发送DM等。目的也是尽可能让用户在IM上就可以基本使用Twitter，个人感觉功能增加改进到现在也已经差不多了。如果你想详细了解使用过程，建议你先访问帮助文档，或者看看这篇文章，写得挺详细的。

设计思路和结构
TwiTalker以Google App Engine为平台，主要用到它的XMPP模块、Cron Job和数据库。Twitter的API肯定是必不可少的，开发语言是Python
XMPP部分实现的是在Gtalk上的通讯，机器人接收用户消息以及发送消息给用户都依靠于它，强大的GAE已经把这个模块封装得特别傻瓜，直接看它的文档就可以很快上手运用到程序中。
同时利用Cron job来定时获取每个用户的最新消息和DM，并将它们发送给各个绑定Twitter的Gtalk用户。
数据库中保存的是每个用户唯一和Twitter关联的OAuth验证码和密钥，因为没有涉及用户密码等隐私信息，所以是相当安全的，还有一些设置信息，如接收消息设置模式和时间等。
当一个新用户向TwiTalker机器人发送验证信息时，程序在判断验证成功后就会把该用户添加到数据库中，此时用户就可以在Gtalk上发推，XMPP会自动接收用户发推的消息并在数据库中找出绑定用户，并把消息连同OAuth验证信息发送给Twitter进行更新。其他一些操作(加删好友，收藏RT) 也是这个原理。每隔一分钟，Cron job就会自动判断每个用户的接收消息时间是否已经到了（因为一些用户设置的是五分钟刷新），如果刷新时间到了，程序则通过Twitter的API获取每个用户的最新消息和DM并通过机器人帐号返回给用户。
Google App Engine的限制也是出了名的多，所以在开发时候要考虑把尽量多的功能和用户加到有限的服务器上也是颇为麻烦的一件事。由于GAE的CPU处理时间每次只有30秒，所以不可能一次性处理所有用户的消息接收更新问题；而且发现越频繁的Cron程序的出错率也越高；同时在获取Twitter消息时还偶尔有一些诡异的获取错误。综合以上的种种限制，同时为了最大保证程序的稳定，我把用户数的上限向下调了N次，并做了几次压力测试，最后确定一个机器人帐号，即是一个App最多容纳250名用户，满额的话再启用新的帐号（当时也没想到会有那么多人用这个，呵呵）。后台数据库设了10个表，每个表25个用户，10个Cron Job分别处理各自的数据库表，这是因为CPU30秒处理时间的限制，没法一次处理那么多用户，而且10个Cron也是GAE能设置的上限了

一些问题
TwiTalker推出后传播的速度比我想象的要快很多，在测试第一周里也增加也许多功能，解决了一些比较严重的Bugs，其间也进行了一次调查问卷，根据这些反馈也作出了一些更改。同时也发现一些用户还不是很清楚TwiTalker的一些功能，所以一并在这里简单说下。
关于延时问题，TwiTalker已经增加了可以自动设定接收消息时间的功能，最短1分钟刷新一次，这已经是GAE所能允许的最短时间了，最长5分钟刷新一次，需要注意的是，每次通过API抓取Twitter信息最多只能返回二十条消息，我测试的时候是这样的，所以如果好友更新消息数过多的话，设置较长的刷新时间可能会丢失一些好友消息，这也是把5分钟作为上限的原因。
关于RT问题，TwiTalker已经有了专门为方便RT收藏而设的消息附加ID模式，从而不需要手工RT，具体使用可以看帮助文档
至于消息接收很烦，你可以设置较长的刷新时间或者启动self模式，即只接收@你的消息和DM，这样不妨碍工作又不会错过重要消息。
现在TwiTalke主要工作放在后台找Bugs和保持程序稳定上。目前主要问题就是保持在用户数量增长的情况下程序仍能正常运行良好，这几周看来情况还是比较理想的，有时后会出现GAE短暂性抽风问题，或者一些命令无法执行，这种情况比较少见，但如果遇到的话，稍等片刻在试下应该就可以了。现在手头上有几个Project还在做，所以时间比较紧张，不过适当时候会推出英文版本，扩大下用户范围。


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.kavingray.com/images/blog/twitalker.jpg" alt="" title="" class="img_border" /></p>
<p><a href="http://twitalker.appspot.com/">TwiTalker</a> 是我九月初做的一个应用，提供推特Gtalk机器人服务，通过绑定添加TwiTalker 机器人可以在Gtalk上更新自己的推特和接收好友消息。代码花了两多周时间，9月19号开始公开测试，拖到现在才想到是时候总结下了，一方面是自己懒，一方面也是前段时间还一直在进行增加功能和后台优化。</p>
<p>和Della一样，这个应用也是基于Google App Engine。今年初开始就一直有传闻GAE将支持XMPP，自己盯着Google开放这个功能已经半年，终于在九月时候等到了。刚好饭否已经被那个啥了，转移到Twitter后发现它的官方Gtalk机器人已经失效多时，于是就想着要做这么一个应用，开始也只打算做着自己用的，后来觉得应该有人也需要这么个工具，于是干脆按多用户的结构去设计。</p>
<p><span id="more-637"></span></p>
<div class="newLine"></div>
<p><strong>简介</strong></p>
<p>TwiTalker和其他微博IM机器人一样，主要功能就是发推和接收消息。在此基础上你可以设置接收消息的模式，时间间隔；还有做一些基本的操作，如加删好友，收藏RT消息，发送DM等。目的也是尽可能让用户在IM上就可以基本使用Twitter，个人感觉功能增加改进到现在也已经差不多了。如果你想详细了解使用过程，建议你先访问<a href="http://twitalker.appspot.com/faq">帮助文档</a>，或者看看<a href="http://www.ineme.cn/2009/10/02/twitalker_using_gtalk_send_tweed_app.html">这篇文章</a>，写得挺详细的。</p>
<div class="newLine"></div>
<p><strong>设计思路和结构</strong></p>
<p>TwiTalker以Google App Engine为平台，主要用到它的XMPP模块、Cron Job和数据库。Twitter的API肯定是必不可少的，开发语言是Python</p>
<p><strong>XMPP部分</strong>实现的是在Gtalk上的通讯，机器人接收用户消息以及发送消息给用户都依靠于它，强大的GAE已经把这个模块封装得特别傻瓜，直接看它的文档就可以很快上手运用到程序中。</p>
<p>同时利用<strong>Cron job</strong>来定时获取每个用户的最新消息和DM，并将它们发送给各个绑定Twitter的Gtalk用户。</p>
<p><strong>数据库</strong>中保存的是每个用户唯一和Twitter关联的OAuth验证码和密钥，因为没有涉及用户密码等隐私信息，所以是相当安全的，还有一些设置信息，如接收消息设置模式和时间等。</p>
<p>当一个新用户向TwiTalker机器人发送验证信息时，程序在判断验证成功后就会把该用户添加到数据库中，此时用户就可以在Gtalk上发推，XMPP会自动接收用户发推的消息并在数据库中找出绑定用户，并把消息连同OAuth验证信息发送给Twitter进行更新。其他一些操作(加删好友，收藏RT) 也是这个原理。每隔一分钟，Cron job就会自动判断每个用户的接收消息时间是否已经到了（因为一些用户设置的是五分钟刷新），如果刷新时间到了，程序则通过Twitter的API获取每个用户的最新消息和DM并通过机器人帐号返回给用户。</p>
<p>Google App Engine的限制也是出了名的多，所以在开发时候要考虑把尽量多的功能和用户加到有限的服务器上也是颇为麻烦的一件事。由于GAE的CPU处理时间每次只有30秒，所以不可能一次性处理所有用户的消息接收更新问题；而且发现越频繁的Cron程序的出错率也越高；同时在获取Twitter消息时还偶尔有一些诡异的获取错误。综合以上的种种限制，同时为了最大保证程序的稳定，我把用户数的上限向下调了N次，并做了几次压力测试，最后确定一个机器人帐号，即是一个App最多容纳250名用户，满额的话再启用新的帐号（当时也没想到会有那么多人用这个，呵呵）。后台数据库设了10个表，每个表25个用户，10个Cron Job分别处理各自的数据库表，这是因为CPU30秒处理时间的限制，没法一次处理那么多用户，而且10个Cron也是GAE能设置的上限了</p>
<div class="newLine"></div>
<p><strong>一些问题</strong></p>
<p>TwiTalker推出后传播的速度比我想象的要快很多，在测试第一周里也增加也许多功能，解决了一些比较严重的Bugs，其间也进行了一次调查问卷，根据这些反馈也作出了一些更改。同时也发现一些用户还不是很清楚TwiTalker的一些功能，所以一并在这里简单说下。</p>
<p><strong>关于延时问题</strong>，TwiTalker已经增加了可以自动设定接收消息时间的功能，最短1分钟刷新一次，这已经是GAE所能允许的最短时间了，最长5分钟刷新一次，<strong>需要注意的是，</strong>每次通过API抓取Twitter信息最多只能返回二十条消息，我测试的时候是这样的，所以如果好友更新消息数过多的话，设置较长的刷新时间可能会丢失一些好友消息，这也是把5分钟作为上限的原因。</p>
<p><strong>关于RT问题，</strong>TwiTalker已经有了专门为方便RT收藏而设的消息附加ID模式，从而不需要手工RT，具体使用可以看<a href="http://twitalker.appspot.com/faq#6">帮助文档</a></p>
<p><strong>至于消息接收很烦，</strong>你可以设置较长的刷新时间或者启动self模式，即只接收@你的消息和DM，这样不妨碍工作又不会错过重要消息。</p>
<p>现在TwiTalke主要工作放在后台找Bugs和保持程序稳定上。目前主要问题就是保持在用户数量增长的情况下程序仍能正常运行良好，这几周看来情况还是比较理想的，有时后会出现GAE短暂性抽风问题，或者<strong>一些命令无法执行</strong>，这种情况比较少见，但如果遇到的话，稍等片刻在试下应该就可以了。现在手头上有几个Project还在做，所以时间比较紧张，不过适当时候会推出英文版本，扩大下用户范围。</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.kavingray.com/blog/twitalker/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Fantasia</title>
		<link>http://www.kavingray.com/blog/fantasia/</link>
		<comments>http://www.kavingray.com/blog/fantasia/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 16:52:35 +0000</pubDate>
		<dc:creator>Kavin</dc:creator>
		
		<category><![CDATA[Music]]></category>

		<category><![CDATA[Bassa Nova]]></category>

		<category><![CDATA[Jazz]]></category>

		<guid isPermaLink="false">http://www.kavingray.com/blog/?p=544</guid>
		<description><![CDATA[
我承认首先引起我注意的是她首张专辑的封面，一身短黑裙，步态曼妙，衬以黑白底色的街景，完全符合了我对一个爵士女歌手气质的所有想象。听过她的音乐之后，这种先入为主的好感变成了惊艳，毫无疑问这是我今年听过的最优雅的一把爵士女声了。
拉美本来就是Bossa Nova的发源地，这个地区的爵士歌手也都多多少少带有一点Bossa味道，但个人不是很感冒那种小野丽莎式软绵绵的风格，总觉得少了点什么，相比之下Gabriela Anders的作品都恰到好处，甚至有点老派Bossa歌手的影子，也许是文化背景的积淀和从小受传统古典和爵士音乐熏陶的影响吧，从唱腔和歌曲的风格上，她均演绎得如封面般优雅性感，如一杯上了年代的红酒，这是我第二次用这个比喻了，不过实在想不出其他更合适的词来形容这种状态。
一口气听完 Gabriela 四张专辑，包括今年为纪念Bossa Nova诞生50周年而推出的《Bossa Beleza》，重点推荐这一张和第一张专辑《Wanting》。Wanting 主要是爵士风格，Bossa Beleza 则全是Bossa和经典作品，两张都融入了 Gabriela 特有的风格，专辑的歌曲都相当的耐听，重点推荐 Wanting 里 Fire Of Love、Fantasia、Brasileira 。Bossa Beleza 则依然走流行爵士风格，尽管是翻唱作品，不过在 Gabriela 的重新演绎下都带上了浓厚的拉丁味道，在一些歌曲上甚至觉得比原唱来得纯正。
对于这些音乐，听不懂语言歌词已经变得不重要了，陌生的语言，爵士吉他，多重合音，每首歌都如一个异域故事。


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.kavingray.com/images/blog/GA.jpg" alt="" title="" class="img_border" /></p>
<p>我承认首先引起我注意的是她首张专辑的封面，一身短黑裙，步态曼妙，衬以黑白底色的街景，完全符合了我对一个爵士女歌手气质的所有想象。听过她的音乐之后，这种先入为主的好感变成了惊艳，毫无疑问这是我今年听过的最优雅的一把爵士女声了。</p>
<p>拉美本来就是Bossa Nova的发源地，这个地区的爵士歌手也都多多少少带有一点Bossa味道，但个人不是很感冒那种小野丽莎式软绵绵的风格，总觉得少了点什么，相比之下<a href="http://www.gabrielaanders.com/">Gabriela Anders</a>的作品都恰到好处，甚至有点老派Bossa歌手的影子，也许是文化背景的积淀和从小受传统古典和爵士音乐熏陶的影响吧，从唱腔和歌曲的风格上，她均演绎得如封面般优雅性感，如一杯上了年代的红酒，这是我第二次用这个比喻了，不过实在想不出其他更合适的词来形容这种状态。</p>
<p>一口气听完 Gabriela 四张专辑，包括今年为纪念Bossa Nova诞生50周年而推出的《Bossa Beleza》，重点推荐这一张和第一张专辑《Wanting》。Wanting 主要是爵士风格，Bossa Beleza 则全是Bossa和经典作品，两张都融入了 Gabriela 特有的风格，专辑的歌曲都相当的耐听，重点推荐 Wanting 里 Fire Of Love、Fantasia、Brasileira 。Bossa Beleza 则依然走流行爵士风格，尽管是翻唱作品，不过在 Gabriela 的重新演绎下都带上了浓厚的拉丁味道，在一些歌曲上甚至觉得比原唱来得纯正。</p>
<p>对于这些音乐，听不懂语言歌词已经变得不重要了，陌生的语言，爵士吉他，多重合音，每首歌都如一个异域故事。</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.kavingray.com/blog/fantasia/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Della解析(1)：在GAE上搭建miniblog查询机器人</title>
		<link>http://www.kavingray.com/blog/miniblog-bot/</link>
		<comments>http://www.kavingray.com/blog/miniblog-bot/#comments</comments>
		<pubDate>Sun, 30 Aug 2009 07:27:50 +0000</pubDate>
		<dc:creator>Kavin</dc:creator>
		
		<category><![CDATA[Python]]></category>

		<category><![CDATA[bot]]></category>

		<category><![CDATA[Della]]></category>

		<category><![CDATA[gae]]></category>

		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.kavingray.com/blog/?p=481</guid>
		<description><![CDATA[
今年三月完成了一个比较有趣的Project，Della查询机器人。半年了程序也断断续续更新，没什么气力去纠缠在这个上面了，所以也差不多是时候总结下，算是一个完整的结束吧，现在Della的版本已经是1.2，和刚开始的程序结构有了很大的变化，所以我想就直接把原理简单介绍下，也可以让自己没事回顾下。


Della1.1
不过在此之前，还是简单说说第一个版本的主要结构，如果你对此没兴趣而只是想知道怎么在GAE上搭建miniblog查询机器人的话，请直接忽视本段落以及下面一段，Della1.1是完全由python的第三方模块xmpppy实现的，XMPP是一种以XML为基础的开放式即时通讯协议，而GTalk所使用的消息传输协议与XMPP兼容，所以采用XMPP协议的一个开源Python实现xmpppy可以实现Gtalk在线操作查询功能，至于在饭否上实现查询，很简单，只要把饭否机器人加为Della机器人的好友，这样就等于绑定了饭否的信息，再根据从Gtalk上接受到的饭否信息来进行操作并返回结果，所以Della第一版是完全建立在Xmpppy上的程序，至于xmpppy具体原理我会在下一篇文章中比较详细的介绍，如果你需要详细了解Della1.1结构，也可以到Della的项目主页上下载1.1版本。

Della1.2
Della1.1在线的时间很不确定，因为没有服务器去放置基于xmpppy的Della1.1，所以只能利用闲暇时间在自己电脑上挂着，这样很不方便，所以在六月的时候抽着时间把Della的程序做了调整，原来的程序一分为二，饭否和Gtalk这两部分功能彻底分离了，也可以区别为在IM上查询和在miniblog上查询两部分，IM部分还是依据1.1的结构原理，miniblog部分则利用强大的GAE实现了24小时在线查询，这样也把Della成功移植到Twitter上了。本篇文章将简单说说怎么利用GAE实现在诸如饭否，twitter，叽歪等等miniblog上搭建自己的查询机器人：

在GAE上搭建miniblog查询机器人
言归正传，其实在GAE上搭建自己的机器人是很简单的，本例将以Della1.2的词典查询部分为例，我们将在twitter上建立一个小词典查询机器人，语言使用Python，首先你所需要准备的是：

一个Google帐号
一个Twitter帐号

然后申请一个Google app engine帐号，建立一个Application，Application名称随便取吧，这里我们姑且设置为cidian 。GAE有一个非常酷的cron功能，能实现程序定时运行，所以cidian的总体思路就是：

运行程序，查询GAE数据库中最新消息的id
利用twitter api获取此id为起始的所有消息
把信息逐条分析，符合查询格式的则把信息发送到dict.cn进行查询，并获取返回的结果
把结果再返回给twitter上的查询用户，把最近一条查询消息的id放到GAE数据库中
利用cron实现程序每分钟执行一次

程序分为三部分，主程序，封装Twitter一些功能的程序，还有查询程序，先贴Twitter部分的程序(twitter.py)：

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#coding:utf-8
import re
import base64
import httplib, urllib,urllib2
import time
from google.appengine.ext import db
&#160;
class Tiwdata&#40;db.Model&#41;:
    re_id=db.StringProperty&#40;&#41;
    re_date=db.StringProperty&#40;&#41;
&#160;
&#160;
class Twitter:
    &#34;&#34;&#34;Class to processing information from the twitter users&#34;&#34;&#34;
&#160;
    def __init__&#40; self &#41;:
        &#34;&#34;&#34;initializing the username and password&#34;&#34;&#34;
   [...]


No related posts.]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.kavingray.com/images/blog/gae.jpg" alt="" title="" class="img_border" /></p>
<p>今年三月完成了一个比较有趣的Project，<a href="http://www.kavingray.com/blog/della-gtalk-bot/">Della查询机器人</a>。半年了程序也断断续续更新，没什么气力去纠缠在这个上面了，所以也差不多是时候总结下，算是一个完整的结束吧，现在Della的版本已经是1.2，和刚开始的程序结构有了很大的变化，所以我想就直接把原理简单介绍下，也可以让自己没事回顾下。</p>
<p><span id="more-481"></span></p>
<div class="newLine"></div>
<p><strong>Della1.1</strong></p>
<p>不过在此之前，还是简单说说第一个版本的主要结构，如果你对此没兴趣而只是想知道怎么在GAE上搭建miniblog查询机器人的话，请直接忽视本段落以及下面一段，Della1.1是完全由python的第三方模块<a href="http://xmpppy.sourceforge.net/">xmpppy</a>实现的，XMPP是一种以XML为基础的开放式即时通讯协议，而GTalk所使用的消息传输协议与XMPP兼容，所以采用XMPP协议的一个开源Python实现xmpppy可以实现Gtalk在线操作查询功能，至于在饭否上实现查询，很简单，只要把饭否机器人加为Della机器人的好友，这样就等于绑定了饭否的信息，再根据从Gtalk上接受到的饭否信息来进行操作并返回结果，所以Della第一版是完全建立在Xmpppy上的程序，至于xmpppy具体原理我会在下一篇文章中比较详细的介绍，如果你需要详细了解Della1.1结构，也可以到Della的项目主页上<a href="http://code.google.com/p/della-gtalk-bot/downloads/list">下载</a>1.1版本。</p>
<div class="newLine"></div>
<p><strong>Della1.2</strong></p>
<p>Della1.1在线的时间很不确定，因为没有服务器去放置基于xmpppy的Della1.1，所以只能利用闲暇时间在自己电脑上挂着，这样很不方便，所以在六月的时候抽着时间把Della的程序做了调整，原来的程序一分为二，饭否和Gtalk这两部分功能彻底分离了，也可以区别为在IM上查询和在miniblog上查询两部分，IM部分还是依据1.1的结构原理，miniblog部分则利用强大的GAE实现了24小时在线查询，这样也把Della成功移植到Twitter上了。本篇文章将简单说说怎么利用GAE实现在诸如饭否，twitter，叽歪等等miniblog上搭建自己的查询机器人：</p>
<div class="newLine"></div>
<p><strong>在GAE上搭建miniblog查询机器人</strong></p>
<p>言归正传，其实在GAE上搭建自己的机器人是很简单的，本例将以Della1.2的词典查询部分为例，我们将在twitter上建立一个小词典查询机器人，语言使用Python，首先你所需要准备的是：</p>
<blockquote><p>
一个Google帐号<br />
一个Twitter帐号
</p></blockquote>
<p>然后申请一个Google app engine帐号，建立一个Application，Application名称随便取吧，这里我们姑且设置为cidian 。GAE有一个非常酷的cron功能，能实现程序定时运行，所以cidian的总体思路就是：</p>
<blockquote><p>
运行程序，查询GAE数据库中最新消息的id<br />
利用twitter api获取此id为起始的所有消息<br />
把信息逐条分析，符合查询格式的则把信息发送到dict.cn进行查询，并获取返回的结果<br />
把结果再返回给twitter上的查询用户，把最近一条查询消息的id放到GAE数据库中<br />
利用cron实现程序每分钟执行一次
</p></blockquote>
<p>程序分为三部分，主程序，封装Twitter一些功能的程序，还有查询程序，先贴Twitter部分的程序(twitter.py)：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#coding:utf-8</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">base64</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">httplib</span>, <span style="color: #dc143c;">urllib</span>,<span style="color: #dc143c;">urllib2</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
<span style="color: #ff7700;font-weight:bold;">from</span> google.<span style="color: black;">appengine</span>.<span style="color: black;">ext</span> <span style="color: #ff7700;font-weight:bold;">import</span> db
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Tiwdata<span style="color: black;">&#40;</span>db.<span style="color: black;">Model</span><span style="color: black;">&#41;</span>:
    re_id=db.<span style="color: black;">StringProperty</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    re_date=db.<span style="color: black;">StringProperty</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Twitter:
    <span style="color: #483d8b;">&quot;&quot;&quot;Class to processing information from the twitter users&quot;&quot;&quot;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span> <span style="color: #008000;">self</span> <span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;initializing the username and password&quot;&quot;&quot;</span>
        <span style="color: #008000;">self</span>.__username=<span style="color: #483d8b;">&quot;帐号名&quot;</span>
        <span style="color: #008000;">self</span>.__password=<span style="color: #483d8b;">&quot;密码&quot;</span>
        <span style="color: #008000;">self</span>.__since_id=<span style="color: #483d8b;">&quot;&quot;</span>
        <span style="color: #808080; font-style: italic;"># Twitter 采用的是base64验证</span>
        <span style="color: #008000;">self</span>.__authStr = <span style="color: #dc143c;">base64</span>.<span style="color: black;">b64encode</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.__username + <span style="color: #483d8b;">&quot;:&quot;</span> + <span style="color: #008000;">self</span>.__password<span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
&nbsp;
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> setMessage<span style="color: black;">&#40;</span> <span style="color: #008000;">self</span> , message <span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;function to set the message&quot;&quot;&quot;</span>
        regex=r<span style="color: #483d8b;">'^@帐号名 (.*)'</span>
        m=<span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>regex,message.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#提取其他用户查询消息</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> m
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> getMessage<span style="color: black;">&#40;</span> <span style="color: #008000;">self</span> <span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;function to return the message&quot;&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.__message
&nbsp;
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> parseMessage<span style="color: black;">&#40;</span> <span style="color: #008000;">self</span> <span style="color: black;">&#41;</span>:
&nbsp;
        since_id=<span style="color: #008000;">self</span>.<span style="color: black;">getSinceId</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#从数据库获取最新id  </span>
        <span style="color: #808080; font-style: italic;">#以since_id为参数，通过API读取新收到的所有消息</span>
        <span style="color: #ff7700;font-weight:bold;">if</span><span style="color: black;">&#40;</span>since_id<span style="color: #66cc66;">&lt;&gt;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span>:
            url=<span style="color: #483d8b;">&quot;https://twitter.com/statuses/mentions.xml?since_id=%s&quot;</span><span style="color: #66cc66;">%</span><span style="color: black;">&#40;</span>since_id<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            url=<span style="color: #483d8b;">&quot;https://twitter.com/statuses/mentions.xml&quot;</span>
        req = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">Request</span><span style="color: black;">&#40;</span>url<span style="color: black;">&#41;</span>
        req.<span style="color: black;">add_header</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Authorization&quot;</span>, <span style="color: #483d8b;">&quot;Basic &quot;</span> + <span style="color: #008000;">self</span>.__authStr<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            response = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>
            page=response.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> 
        <span style="color: #ff7700;font-weight:bold;">except</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
&nbsp;
&nbsp;
        matches = <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>
        r<span style="color: #483d8b;">&quot;&quot;&quot;(?sx)&lt;created_at&gt;(.*?)&lt;/created_at&gt;s*
        &lt;id&gt;(.*?)&lt;/id&gt;s*                              
        &lt;text&gt;(.*?)&lt;/text&gt;.*?                                
        &lt;screen_name&gt;(.*?)&lt;/screen_name&gt;.*?
        &lt;/status&gt;
        &quot;&quot;&quot;</span>,page<span style="color: black;">&#41;</span>
        <span style="color: #808080; font-style: italic;"># 并将最近一条消息的id放置到数据库中</span>
        <span style="color: #ff7700;font-weight:bold;">if</span><span style="color: black;">&#40;</span>matches<span style="color: #66cc66;">&lt;&gt;</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>:
            per=Tiwdata<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            per.<span style="color: black;">re_id</span>=matches<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span>1<span style="color: black;">&#93;</span>
            per.<span style="color: black;">re_date</span>=<span style="color: #008000;">self</span>.<span style="color: black;">parseTime</span><span style="color: black;">&#40;</span>matches<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
            per.<span style="color: black;">put</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>       
        <span style="color: #ff7700;font-weight:bold;">return</span> matches
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> parseTime<span style="color: black;">&#40;</span> <span style="color: #008000;">self</span>, time_str <span style="color: black;">&#41;</span>:
&nbsp;
        T=<span style="color: #483d8b;">&quot;%a %b %d %H:%M:%S +0000 %Y&quot;</span>
        t=<span style="color: #dc143c;">time</span>.<span style="color: black;">strptime</span><span style="color: black;">&#40;</span>time_str,T<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">time</span>.<span style="color: black;">strftime</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%Y-%m-%d-%H-%M-%S'</span>, t<span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> sentMessage<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, message<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;sent message to twitter&quot;&quot;&quot;</span>
        headers = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;Content-type&quot;</span>: <span style="color: #483d8b;">&quot;application/x-www-form-urlencoded&quot;</span>,
                <span style="color: #483d8b;">&quot;Accept&quot;</span>: <span style="color: #483d8b;">&quot;text/xml&quot;</span>,
                <span style="color: #483d8b;">&quot;Authorization&quot;</span>: <span style="color: #483d8b;">&quot;Basic &quot;</span> + <span style="color: #008000;">self</span>.__authStr<span style="color: black;">&#125;</span>
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            params = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlencode</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;status&quot;</span>: message<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
            req = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">Request</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;https://twitter.com/statuses/update.xml&quot;</span>, params, headers<span style="color: black;">&#41;</span>
            response = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span>:
            <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
&nbsp;
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> getSinceId<span style="color: black;">&#40;</span> <span style="color: #008000;">self</span> <span style="color: black;">&#41;</span>:
        msg=db.<span style="color: black;">GqlQuery</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SELECT * FROM Tiwdata ORDER BY re_date DESC&quot;</span><span style="color: black;">&#41;</span>
        x=msg.<span style="color: black;">count</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> x:
            <span style="color: #ff7700;font-weight:bold;">return</span> msg<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span>.<span style="color: black;">re_id</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;&quot;</span></pre></td></tr></table></div>

<p>详细功能见注释，twitter.py主要实现了获取以及提取最新消息，数据库id的更新，已经发送消息到twitter的功能</p>
<p>下面是词典查询功能(dict.py)：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #808080; font-style: italic;">#coding:utf-8</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib2</span>,<span style="color: #dc143c;">re</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Dict:
    <span style="color: #483d8b;">&quot;&quot;&quot;Class to get EN2CN &amp; CN2EN translation from dict.cn&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span> <span style="color: #008000;">self</span>, word=<span style="color: #483d8b;">&quot;Della&quot;</span> <span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;initializing the word and the url received&quot;&quot;&quot;</span>   
        <span style="color: #008000;">self</span>.<span style="color: black;">setWord</span><span style="color: black;">&#40;</span>word<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">setUrl</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> setWord<span style="color: black;">&#40;</span> <span style="color: #008000;">self</span>, word <span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;function to set the word&quot;&quot;&quot;</span>
        <span style="color: #008000;">self</span>.__word=word
&nbsp;
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> setUrl<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;function to set the url&quot;&quot;&quot;</span>
        <span style="color: #008000;">self</span>.__url=<span style="color: #483d8b;">&quot;http://dict.cn/ws.php?utf8=true&amp;q=%s&quot;</span><span style="color: #66cc66;">%</span><span style="color: #008000;">self</span>.__word
&nbsp;
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> getPage<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;function to get the content of the web page.return the string page content&quot;&quot;&quot;</span>        
        url=<span style="color: #008000;">self</span>.__url
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            page = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>url<span style="color: black;">&#41;</span>
            page_content = page.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            page.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> page_content
&nbsp;
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> getWord<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;function get the info what we needed from the web page.return a list reply&quot;&quot;&quot;</span>
        page_content=<span style="color: #008000;">self</span>.<span style="color: black;">getPage</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">replace</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>,<span style="color: #483d8b;">&quot; &quot;</span><span style="color: black;">&#41;</span>
        page_content=<span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span>page_content,<span style="color: #483d8b;">&quot;utf-8&quot;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># set the page content encoding to unicode</span>
        regex=r<span style="color: #483d8b;">'&lt;def&gt;(.*)&lt;/def&gt;'</span> 
        match=<span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span> regex , page_content <span style="color: black;">&#41;</span>     
        <span style="color: #ff7700;font-weight:bold;">return</span> match</pre></td></tr></table></div>

<p>这里利用Dict.cn的词典查询<a href="http://dict.cn/foot/help2.htm">api接口</a>，getWord()获取单词查询结果。</p>
<p>最后是主函数(cidian.py)：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#coding:utf-8</span>
<span style="color: #ff7700;font-weight:bold;">from</span> Twitter <span style="color: #ff7700;font-weight:bold;">import</span> Twitter
<span style="color: #ff7700;font-weight:bold;">from</span> Dict <span style="color: #ff7700;font-weight:bold;">import</span> Dict
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> getService<span style="color: black;">&#40;</span> match <span style="color: black;">&#41;</span>:
&nbsp;
    respons=<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        word=match<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">replace</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot; &quot;</span>,<span style="color: #483d8b;">&quot;%20&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">dict</span>=Dict<span style="color: black;">&#40;</span>word<span style="color: black;">&#41;</span>
        reply=<span style="color: #008000;">dict</span>.<span style="color: black;">getWord</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#获取查询结果</span>
    <span style="color: #ff7700;font-weight:bold;">except</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;服务端连接有误，请稍后再试&quot;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>reply==<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #008000;">cmp</span><span style="color: black;">&#40;</span>reply<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span>,<span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Not Found&quot;</span>,<span style="color: #483d8b;">&quot;utf-8&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>==0<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Oops,你查询的单词不存在或输入格式有误，请检查下或输入'词典'获取帮助&quot;</span><span style="color: black;">&#93;</span>
    reply<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>=<span style="color: #483d8b;">&quot;[&quot;</span>+match<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>+<span style="color: #483d8b;">&quot;] &quot;</span>+reply<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">encode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'utf-8'</span><span style="color: black;">&#41;</span>
    respons=reply
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> respons
&nbsp;
twitter=Twitter<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
receive=twitter.<span style="color: black;">parseMessage</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#获取所有查询信息</span>
<span style="color: #ff7700;font-weight:bold;">for</span> y <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">reversed</span><span style="color: black;">&#40;</span>receive<span style="color: black;">&#41;</span>:
    word=twitter.<span style="color: black;">setMessage</span><span style="color: black;">&#40;</span>y<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#提取用户查询消息</span>
    <span style="color: #ff7700;font-weight:bold;">if</span><span style="color: black;">&#40;</span>word<span style="color: #66cc66;">&lt;&gt;</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>:
        reply=getService<span style="color: black;">&#40;</span> word <span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># 交给Dict去处理</span>
        <span style="color: #ff7700;font-weight:bold;">if</span><span style="color: black;">&#40;</span>reply<span style="color: #66cc66;">&lt;&gt;</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">reversed</span><span style="color: black;">&#40;</span>reply<span style="color: black;">&#41;</span>:
                <span style="color: #ff7700;font-weight:bold;">if</span><span style="color: black;">&#40;</span>i<span style="color: #66cc66;">&lt;&gt;</span>None<span style="color: black;">&#41;</span>:
                    i=<span style="color: #483d8b;">&quot;@&quot;</span>+y<span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>+<span style="color: #483d8b;">&quot; &quot;</span>+i <span style="color: #808080; font-style: italic;">#y[3]为twitter上查询用户的帐号名</span>
                    twitter.<span style="color: black;">sentMessage</span><span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#将查询结果返回</span></pre></td></tr></table></div>

<p>以上就是程序的3个主要部分，最后所要做的就是让这个程序在GAE上定时运行，这样就等于不间断地处理twitter上的查询请求了，利用cron job可以很容易做到。<br />
上传到GAE的程序需要设置好app.yaml和cron.yaml文件，具体使用可以参考GAE的<a href="http://code.google.com/appengine/docs/python/overview.html">文档</a>，比如在此例中要实现程序每分钟运行一次，可以把app文件和cron文件设置如下：</p>
<blockquote><p>
application: cidian<br />
version: 1<br />
runtime: python<br />
api_version: 1<br />
handlers:<br />
- url: /cidian<br />
  script: cidian.py<br />
  secure: never
</p></blockquote>
<p>注意app文件中的application就是你在GAE上新建app的名称</p>
<blockquote><p>
cron:<br />
- description: daily job<br />
  url: /cidian<br />
  schedule: every 1 minutes<br />
  timezone: Asia/Shanghai
</p></blockquote>
<p>然后上传，大功告成:) 利用这种思路和网上各种应用功能遍布的api可以很容易做出一个像Della那样多功能的查询机器人，而只要有开发api的miniBlog，你就能为其制作一个机器人。</p>
<p>我前几天就又做了一个twitter机器人Twity，算是Della的姐妹机器人吧，呵呵，当是试手，实现了天气预报，股票查询，还有美剧节目单查询，Twity功能少，但查询的内容是全球性的，比如可以查询全球各个地方的天气~有兴趣的话可以<a href="http://www.kavingray.com/blog/twity-twitter-bot/">移步这里</a></p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.kavingray.com/blog/miniblog-bot/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Twity Twitter Bot</title>
		<link>http://www.kavingray.com/blog/twity-twitter-bot/</link>
		<comments>http://www.kavingray.com/blog/twity-twitter-bot/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 10:29:35 +0000</pubDate>
		<dc:creator>Kavin</dc:creator>
		
		<category><![CDATA[Design]]></category>

		<category><![CDATA[gae]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[twitter]]></category>

		<category><![CDATA[twitter bot]]></category>

		<category><![CDATA[twity]]></category>

		<guid isPermaLink="false">http://www.kavingray.com/blog/?p=395</guid>
		<description><![CDATA[
Well, I&#8217;ve developed a twitter bot, @Twity001, same as Della bot that provides with useful information.It&#8217;s an auto reply bot.So you have to send a direct reply message to this bot to get information.

The service Twity has provided so far including Weather Forecast, Stock Market and TV List. To get start, you have to follow [...]


No related posts.]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.kavingray.com/images/blog/twity001.jpg" alt="" title="" class="img_border" /></p>
<p>Well, I&#8217;ve developed a twitter bot, <a href="http://www.twitter.com/twity001">@Twity001</a>, same as <a href="http://www.kavingray.com/blog/della-gtalk-bot/">Della bot</a> that provides with useful information.It&#8217;s an auto reply bot.So you have to send a direct reply message to this bot to get information.</p>
<p><span id="more-395"></span></p>
<p>The service Twity has provided so far including <strong>Weather Forecast</strong>, <strong>Stock Market</strong> and <strong>TV List</strong>. To get start, you have to follow <a href="http://www.twitter.com/twity001">@Twity001</a>, then send it an @reply with the commands to get the info u need.</p>
<div class="newLine"></div>
<p>Here is a short commands manual for using Twity with correct formats.</p>
<div class="newLine"></div>
<p><strong>Getting Help</strong><br />
Simply tweet <font color="#015F92"><strong>@Twity001 ?</strong></font> or <font color="#015F92"><strong>@Twity001 help</strong></font> to get the help list</p>
<div class="newLine"></div>
<p><strong>Weather Forecast</strong><br />
<font color="#015F92"><strong>@Twity001 weather city</strong></font> or<br />
<font color="#015F92"><strong>@Twity001 weather city,country</strong></font> or<br />
<font color="#015F92"><strong>@Twity001 weather city country</strong></font></p>
<p>For example, if you want to know about the weather in Paris,send a @reply message with the format &#8220;@Twity001 weather Paris,France&#8221;.And Twity will reply u with the weather forecast of Paris in a few minutes.</p>
<p><img src="http://www.kavingray.com/images/blog/tw.jpg" width="490px" alt="" title="" class="img_border" /></p>
<div class="newLine"></div>
<p><strong>Stock Market</strong><br />
<font color="#015F92"><strong>@Twity001 stock Symbol</strong></font> or<br />
<font color="#015F92"><strong>@Twity001 stock Symbol Parameter</strong></font></p>
<p>For example, if you want to know about the stock info of Google company,send a @reply message with the format &#8220;@Twity001 stock GOOG&#8221;.(PS.GOOG is the symbol of Google company.Check out <a href="http://finance.yahoo.com/lookup">here</a> to find stock symbol) And Twity will reply u with the stock info of google company in a few minutes.</p>
<p><img src="http://www.kavingray.com/images/blog/ts2.jpg" width="490px" alt="" title="" class="img_border" /></p>
<p>Besides,you can leave a parameter behind the symbol to get more detail about the stock.</p>
<p><strong>Here is a lists of the parameter that can be used:</strong></p>
<blockquote><p>
price<br />
change<br />
volume<br />
avg_daily_volume or adv<br />
exchange<br />
market_cap or mc<br />
book_value or bv<br />
ebitda<br />
dividend_per_share or dps<br />
dividend_yield or dy<br />
earnings_per_share or eps<br />
52_week_high or 52wh<br />
52_week_low or 52wl<br />
50day_moving_avg or 50d<br />
200day_moving_avg or 200d<br />
price_earnings_ratio or per<br />
price_earnings_growth_ratio or pegr<br />
price_sales_ratio or psr<br />
price_book_ratio or pbr<br />
short_ratio or sr
</p></blockquote>
<p>For example,you can tweet &#8220;@Twity001 stock goog dps&#8221; or &#8220;@Twity001 stock goog dividend_per_share&#8221; to get the price sales ratio of Google stock</p>
<p><img src="http://www.kavingray.com/images/blog/ts1.jpg" width="490px" alt="" title="" class="img_border" /></p>
<div class="newLine"></div>
<p><strong>TV List</strong><br />
<font color="#015F92"><strong>@Twity001 TV</strong></font></p>
<p>Yes, tweet this message can you get the day&#8217;s TV Listings.Pretty easy,huh? Twity will according to your timezone in twitter and reply you the Listings.You can check or change your timezone in your twitter accout settings</p>
<div class="newLine"></div>
<p><strong>How it works?</strong><br />
Well,Twity is developed in Python.With the help of <a href="http://code.google.com/appengine/docs/python/config/cron.html">Cron job</a> of <a href="http://code.google.com/appengine/">GAE</a>(I upload this program to gae btw),the program get the latest reply messages from the bot&#8217;s twitter acount every minute.Analyzing these messages and fetching the info we need from other website.Then send the results back to the twitter.<br />
Here is the source code of Twity:</p>
<div class="download">
<a href="http://www.kavingray.com/file/twity001.rar">Source Code(Twity001.rar)</a></div>
<div class="newLine"></div>
<p>Feel free to leave a comment or <a href="http://twitter.com/kavin_gray">tweet me</a> if u have any suggestion:)</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.kavingray.com/blog/twity-twitter-bot/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Still breathing</title>
		<link>http://www.kavingray.com/blog/still-breathing/</link>
		<comments>http://www.kavingray.com/blog/still-breathing/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 16:57:59 +0000</pubDate>
		<dc:creator>Kavin</dc:creator>
		
		<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://www.kavingray.com/blog/?p=364</guid>
		<description><![CDATA[A tiny update to let you guys know I&#8217;m still alive.Kinda upset these days.The whole month of August is just a mess.Perfectionism killing me.And the truth is,things don&#8217;t always go the way you plan.
Keep learning javascript this week.I do have some small applications to be finishing up,and I have to take the driving licence exam [...]


No related posts.]]></description>
			<content:encoded><![CDATA[<p>A tiny update to let you guys know I&#8217;m still alive.Kinda upset these days.The whole month of August is just a mess.Perfectionism killing me.And the truth is,things don&#8217;t always go the way you plan.</p>
<p>Keep learning javascript this week.I do have some small applications to be finishing up,and I have to take the driving licence exam next week again,I failed last time btw.With the summer holiday drawing to a close,I will make a new plan for my new term,which means that more interesting projects are coming up.</p>
<p>Maybe things are getting better.I hope so.Shit happens all the time,I really need some luck.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.kavingray.com/blog/still-breathing/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
