<?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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>错落有致</title>
	<atom:link href="http://blog.cuoluo.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.cuoluo.net</link>
	<description>&#60;span class=&#34;lamengao&#34;&#62;Lamengao&#60;/span&#62;&#039;s weblog</description>
	<lastBuildDate>Thu, 10 Jun 2010 15:28:25 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>在App Engine上使用OpenID验证登陆</title>
		<link>http://blog.cuoluo.net/2010/06/using-openid-authentication-on-app-engine/</link>
		<comments>http://blog.cuoluo.net/2010/06/using-openid-authentication-on-app-engine/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 15:19:55 +0000</pubDate>
		<dc:creator>lamengao</dc:creator>
				<category><![CDATA[google app engine]]></category>
		<category><![CDATA[openid]]></category>

		<guid isPermaLink="false">http://blog.cuoluo.net/?p=197</guid>
		<description><![CDATA[Google App Engine最新发布的SDK 1.3.4提供了对OpenID的原生支持。下面我们就来演示在app engine上的应用如何使用OpenID来登陆。
首先你需要登陆到App Engine的管理控制台中，在你应用的"Application Settings"中选择"Authentication Options"为 "(Experimental) Federated Login"并保存。

一旦你设置好了上面这一步，App Engine的Users API就能够提供对OpenID的支持了。在使用Users API之前，我们先看看OpenID的登陆流程，我按照自己的理解画了一个示意图。


用户访问web app
web app返回一个登陆表单，提供OpenID identifier的输入框
用户输入OpenID identifier,提交表单
web app根据用户输入的OpenID identifier用create_login_url()函数生成并重定向到OpenID登陆页面
用户在OpenID provider处登陆，并授权web app获取用户的OpenID信息
OpenID provider把用户重定向到web app(重定向的url包含了用户的OpenID信息)
web app通过get_current_user()函数获取到用户信息，登陆完成

上面的流程省略掉了一些步骤和细节，比如web app和OpenID provider的交互，web app对重放攻击的处理等等。这些步骤和细节App Engine全都帮我们做了，所以对web开发者来说是透明的，我们不用去关心。我们需要做的就是第2，4，7步。
提供一个用户登陆页面
准备一个简单login.html文件内容如下，主要就是提供一个能够接收用户OpenID标识的表单。

&#60;html>
&#60;head>
  &#60;title>Log in with OpenID&#60;/title>
&#60;/head>
&#60;body>
  &#60;h1>Log in with OpenID&#60;/h1>
  &#60;form method="get" action="/testopenid">
    &#60;input type="text" name="openid" />
    &#60;input type="submit" [...]]]></description>
			<content:encoded><![CDATA[<p>Google App Engine最新发布的<a href="http://googleappengine.blogspot.com/2010/05/app-engine-at-google-io-2010.html">SDK 1.3.4</a>提供了对OpenID的原生支持。下面我们就来演示在app engine上的应用如何使用OpenID来登陆。</p>
<p>首先你需要登陆到App Engine的管理控制台中，在你应用的"Application Settings"中选择"Authentication Options"为 "(Experimental) Federated Login"并保存。</p>
<p><img src="http://lh6.ggpht.com/_23zDbjk-dKI/TAO4YHWyPgI/AAAAAAAABq8/WorsDE7Aa90/Picture%2013.png" alt="Authentication Options" /><br />
一旦你设置好了上面这一步，App Engine的<a href="http://code.google.com/appengine/docs/users.html">Users API</a>就能够提供对OpenID的支持了。在使用Users API之前，我们先看看OpenID的登陆流程，我按照自己的理解画了一个示意图。<br />
<img src="http://docs.google.com/drawings/pub?id=1SSwMcua1PvLEFngDVXMnXRBxINFiCPqoOHatJwm83_4&amp;w=648&amp;h=638"></p>
<ol>
<li>用户访问web app</li>
<li>web app返回一个登陆表单，提供OpenID identifier的输入框</li>
<li>用户输入OpenID identifier,提交表单</li>
<li style="font-weight:bold">web app根据用户输入的OpenID identifier用create_login_url()函数生成并重定向到OpenID登陆页面</li>
<li>用户在OpenID provider处登陆，并授权web app获取用户的OpenID信息</li>
<li>OpenID provider把用户重定向到web app(重定向的url包含了用户的OpenID信息)</li>
<li style="font-weight:bold">web app通过get_current_user()函数获取到用户信息，登陆完成</li>
</ol>
<p>上面的流程省略掉了一些步骤和细节，比如web app和OpenID provider的交互，web app对重放攻击的处理等等。这些步骤和细节App Engine全都帮我们做了，所以对web开发者来说是透明的，我们不用去关心。我们需要做的就是第2，4，7步。</p>
<p><strong>提供一个用户登陆页面</strong><br />
准备一个简单login.html文件内容如下，主要就是提供一个能够接收用户OpenID标识的表单。</p>
<pre class="prettyprint">
&lt;html>
&lt;head>
  &lt;title>Log in with OpenID&lt;/title>
&lt;/head>
&lt;body>
  &lt;h1>Log in with OpenID&lt;/h1>
  &lt;form method="get" action="/testopenid">
    &lt;input type="text" name="openid" />
    &lt;input type="submit" value="Log In" />
  &lt;/form>
&lt;/body>
&lt;/html>
</pre>
<p><br/><br />
修改app.yaml,让用户访问 http://your-app.appspot.com/testopenid 时能显示上面的login.html</p>
<pre class="prettyprint">
- url: /testopenid
  script: testopenid.py
</pre>
<p><br/><br />
添加testopenid.py文件，内容如下。</p>
<pre class="prettyprint">
import os

from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.api import users
from google.appengine.ext.webapp.util import run_wsgi_app

class UsersHandler(webapp.RequestHandler):
  def get(self):
    path = os.path.join(os.path.dirname(__file__), 'templates', 'login.html')
    self.response.out.write(template.render(path,{}))

application = webapp.WSGIApplication(
             [('/', MainPage),
             ('/testopenid',UsersHandler)],
             debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()
</pre>
<p><br/><br />
<strong>生成OpenID登陆url并重定向</strong><br />
当用户提交OpenID identifier后，我们用Users API中的create_login_url()函数生成需要跳转的url。具体的函数定义<a href="http://code.google.com/appengine/docs/python/users/functions.html">见这里</a>.<br />
修改testopenid.py中的UsersHandler类</p>
<pre class="prettyprint">
class UsersHandler(webapp.RequestHandler):
  def get(self):
    openid_url = self.request.GET.get('openid')
    if not openid_url:
      path = os.path.join(os.path.dirname(__file__), 'templates', 'login.html')
      self.response.out.write(template.render(path,{}))
    else:
      self.redirect(users.create_login_url('/testopenid', None, openid_url))
</pre>
<p><br/><br />
<strong>验证用户登陆，并取得OpenID信息</strong><br />
当用户在OpenID Provider处登陆并跳转到我们的web app时，我们用Users API中的get_current_user()函数验证用户是否登陆并返回一个User对象，这个对象中就保存着登陆用户的OpenID信息.<br />
继续修改我们的UsersHandler类</p>
<pre class="prettyprint">
class UsersHandler(webapp.RequestHandler):
  def get(self):
    user = users.get_current_user()
    openid_url = self.request.GET.get('openid')
    if user:
      greeting = ("Welcome, %s! %s(<a href=\"%s\">sign out</a>)" %
                    (user.__dict__, user.nickname(),
                     users.create_logout_url("/testopenid")))
      self.response.out.write(greeting)
    else:
      if not openid_url:
        path = os.path.join(os.path.dirname(__file__), 'templates', 'login.html')
        self.response.out.write(template.render(path,{}))
      else:
        self.redirect(users.create_login_url('/testopenid', None, openid_url))
</pre>
<p><br/><br />
到目前为止我们的web app已经能够支持OpenID登陆了。可以看到我们所需要做的工作非常简单，App Engine给我们处理了大量的细节,生活顿时变的非常美好。</p>
<p>还有一点需要注意。如果你在app.yaml中针对某个url设置成必须要先登录(login: required),那么当你未登录访问那个url时，App Engine会把你重定向到 http://your-app.appspot.com/_ah/login_required 对于这种情况你需要做的就是针对"/_ah/login_required"这个地址创建一个登陆页面。</p>
<p><a href="http://cuoluotest.appspot.com/testopenid">demo在这里</a></p>
<p><span style="font-size:14px;color:#ccc">参考文章 <a style="color:#ccc" href="http://blog.notdot.net/2010/05/Using-OpenID-authentication-on-App-Engine">Using OpenID authentication on App Engine</a></span></p>
<link href="http://blog.cuoluo.net/wp-content/themes/cuoluo/prettify/prettify.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="http://blog.cuoluo.net/wp-content/themes/cuoluo/prettify/prettify.js"></script><br />
<script type="text/javascript">prettyPrint();</script></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cuoluo.net/2010/06/using-openid-authentication-on-app-engine/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>没有距离的日子</title>
		<link>http://blog.cuoluo.net/2010/04/the-days-no-distance/</link>
		<comments>http://blog.cuoluo.net/2010/04/the-days-no-distance/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 13:12:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.cuoluo.net/?p=194</guid>
		<description><![CDATA[物理学家维纳曾说，在理论上人可以通过一根电线来传输。现在理论过去几百年早已成了现实。在我这个时代，所有的物质（包括生命体和非生命体）发生位移都是通过“电线”来完成，这里的电线当然与古代的有所不同，因为我是为了让你容易理解所以还是姑且称之为电线。简单的说，只要A、B两地都连入电网，并且都有一个传输终端（国人俗称此设备为“打炮”），那么任何物质都可以方便快捷的在两地间传输。
我还是简单地描述下我的世界。现在的地球上已经没有了公路铁路机场之类的交通设施，甚至连交通一词也变得陌生。原来的通用汽车成了玩具厂商，波音公司在80年前被NASA收购后跑到月亮上做航空设备去勒。现在世界500强企业第一名永远都是中国电网，理由显而易见：一是因为垄断，二是原来所谓的交通全部并入了电力公司的范围。
就拿我来说，本人在纽约上班，家住毛里求斯岛的火山岛上。每天都要从那个岛上通过电网传送到公司。以我百来斤的体重加上从毛里求斯岛到纽约的距离，每一次传送的费用大概是50美分（当然这是按照你们那个时代的物价水平估算的）。还好本人天生苗条，像我一个大胖子同事家到公司的距离没我远，但每个月的传输费却是我的三倍。正因为现在出门费用与体重挂钩，所以现在人们的身材普遍不错。这有点扯远了，关于打炮一事我还可以说得具体点：每天8点50我走出门，坐在门外的一个类似马桶的设备上，这个马桶就是传输终端。坐好后，我再把自己的目的地编号输入马桶前面两腿中间的仪器上（）。然后再在右手边的指纹识别器上按上自己的食指（按哪个指头随便你），要求对方的终端验证我的身份，要是不经过验证就能随便传送那这个世界就乱套啦。验证通过后，只要按一下start按钮我就变成了一堆信息，通过电线开始传输，然后在对方的终端组装起来。当然这些我是感觉不到的，唯一的感觉就是一阵酥麻，等我再次有意识的时候，我已经到了纽约的公司门口。整个过程大概2分钟。
不知道你注意到没有，我家的终端和公司的终端都是放在门外的。为什么不直接放在屋内呢，还省去了开门。这样做的原因主要是为了安全。曾经有黑客破译了终端的验证系统，结果就跑到别人家随便打炮去了。说到这个验证系统我还可以补充一下，前面我是通过指纹来验证，其实有很多种验证方式。如果你是残疾人没有手，你可以通过虹膜来验证----就是拿眼睛往一个小洞瞅瞅就行了。如果你既没手又没眼睛，你还可以通过血液的DNA来验证。如果你既没双手又没眼睛并且全身又没有一滴血，那你将会按照非生命体的标准来传输。比如我要把一瓶酒送到家住上海的女朋友家。我就要先把酒放在“马桶”上，输入girlfriend家的终端编号后再按一下分析按钮。这瓶酒就被打散成一堆信息，系统根据这堆信息算出一个标识这瓶酒的唯一编码然后发送给对方的终端。老婆在她终端上一看是瓶酒，就会按下allow按钮。最后这瓶酒就会在几秒钟内传送过去。
关于非生命体在终端上进行编码我再多说两句。这种编码类似在你们的计算机上用SHA算法计算一个文件的SHA值，一个SHA值可以唯一标识一个文件。同样的，对物质进行编码也有一种算法（好像学名叫lamengao算法）。通过这种算法计算出来的值也可以唯一标识一个物质。只不过这种算法比MD5算法复杂多了。当一个文件只要改动一比特，那么这个文件的SHA值就变了。但当物质有所改变时，lamengao算法计算出来的值不一定会改。比如我送给女朋友的那瓶酒，当我摸一下那瓶酒那么这瓶酒所带的信息肯定有所变化。如果用SHA算法的话，就会发生这种情况：当我老婆拿到这瓶酒时，这瓶酒就不再是我给她的那瓶了。如果这样，那所有的直销商店都可以关门了。
也许你会说，在你们这个时代不再有交通事故了吧。其实不然。如果我们的“交通”发生事故将会比古代更可怕。著名的911大灾难就是这样的一起事故。6年前的9月11号，某恐怖组织在下班的高峰期切断了纽约的部分电网，结果令5000多正在电网中传输的人瞬间灰飞烟灭。什么叫尸骨无存，这才叫真正的尸骨无存。还好我那天晚下班5分钟，不然我也将化为信息永远飘散在宇宙中。
我常常在想一个问题，打炮之前的我还是组装过后的我吗？
 。。。。。。。。。。。。。。。待续
]]></description>
			<content:encoded><![CDATA[<p>物理学家维纳曾说，在理论上人可以通过一根电线来传输。现在理论过去几百年早已成了现实。在我这个时代，所有的物质（包括生命体和非生命体）发生位移都是通过“电线”来完成，这里的电线当然与古代的有所不同，因为我是为了让你容易理解所以还是姑且称之为电线。简单的说，只要A、B两地都连入电网，并且都有一个传输终端（国人俗称此设备为“打炮”），那么任何物质都可以方便快捷的在两地间传输。</p>
<p>我还是简单地描述下我的世界。现在的地球上已经没有了公路铁路机场之类的交通设施，甚至连交通一词也变得陌生。原来的通用汽车成了玩具厂商，波音公司在80年前被NASA收购后跑到月亮上做航空设备去勒。现在世界500强企业第一名永远都是中国电网，理由显而易见：一是因为垄断，二是原来所谓的交通全部并入了电力公司的范围。</p>
<p>就拿我来说，本人在纽约上班，家住毛里求斯岛的火山岛上。每天都要从那个岛上通过电网传送到公司。以我百来斤的体重加上从毛里求斯岛到纽约的距离，每一次传送的费用大概是50美分（当然这是按照你们那个时代的物价水平估算的）。还好本人天生苗条，像我一个大胖子同事家到公司的距离没我远，但每个月的传输费却是我的三倍。正因为现在出门费用与体重挂钩，所以现在人们的身材普遍不错。这有点扯远了，关于打炮一事我还可以说得具体点：每天8点50我走出门，坐在门外的一个类似马桶的设备上，这个马桶就是传输终端。坐好后，我再把自己的目的地编号输入马桶前面两腿中间的仪器上（）。然后再在右手边的指纹识别器上按上自己的食指（按哪个指头随便你），要求对方的终端验证我的身份，要是不经过验证就能随便传送那这个世界就乱套啦。验证通过后，只要按一下start按钮我就变成了一堆信息，通过电线开始传输，然后在对方的终端组装起来。当然这些我是感觉不到的，唯一的感觉就是一阵酥麻，等我再次有意识的时候，我已经到了纽约的公司门口。整个过程大概2分钟。</p>
<p>不知道你注意到没有，我家的终端和公司的终端都是放在门外的。为什么不直接放在屋内呢，还省去了开门。这样做的原因主要是为了安全。曾经有黑客破译了终端的验证系统，结果就跑到别人家随便打炮去了。说到这个验证系统我还可以补充一下，前面我是通过指纹来验证，其实有很多种验证方式。如果你是残疾人没有手，你可以通过虹膜来验证----就是拿眼睛往一个小洞瞅瞅就行了。如果你既没手又没眼睛，你还可以通过血液的DNA来验证。如果你既没双手又没眼睛并且全身又没有一滴血，那你将会按照非生命体的标准来传输。比如我要把一瓶酒送到家住上海的女朋友家。我就要先把酒放在“马桶”上，输入girlfriend家的终端编号后再按一下分析按钮。这瓶酒就被打散成一堆信息，系统根据这堆信息算出一个标识这瓶酒的唯一编码然后发送给对方的终端。老婆在她终端上一看是瓶酒，就会按下allow按钮。最后这瓶酒就会在几秒钟内传送过去。</p>
<p>关于非生命体在终端上进行编码我再多说两句。这种编码类似在你们的计算机上用SHA算法计算一个文件的SHA值，一个SHA值可以唯一标识一个文件。同样的，对物质进行编码也有一种算法（好像学名叫lamengao算法）。通过这种算法计算出来的值也可以唯一标识一个物质。只不过这种算法比MD5算法复杂多了。当一个文件只要改动一比特，那么这个文件的SHA值就变了。但当物质有所改变时，lamengao算法计算出来的值不一定会改。比如我送给女朋友的那瓶酒，当我摸一下那瓶酒那么这瓶酒所带的信息肯定有所变化。如果用SHA算法的话，就会发生这种情况：当我老婆拿到这瓶酒时，这瓶酒就不再是我给她的那瓶了。如果这样，那所有的直销商店都可以关门了。</p>
<p>也许你会说，在你们这个时代不再有交通事故了吧。其实不然。如果我们的“交通”发生事故将会比古代更可怕。著名的911大灾难就是这样的一起事故。6年前的9月11号，某恐怖组织在下班的高峰期切断了纽约的部分电网，结果令5000多正在电网中传输的人瞬间灰飞烟灭。什么叫尸骨无存，这才叫真正的尸骨无存。还好我那天晚下班5分钟，不然我也将化为信息永远飘散在宇宙中。</p>
<p>我常常在想一个问题，打炮之前的我还是组装过后的我吗？<br />
 。。。。。。。。。。。。。。。待续</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cuoluo.net/2010/04/the-days-no-distance/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>把你的google电子表格打造成twitter客户端</title>
		<link>http://blog.cuoluo.net/2010/03/make-your-google-spreadsheet-to-twitter-client/</link>
		<comments>http://blog.cuoluo.net/2010/03/make-your-google-spreadsheet-to-twitter-client/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 13:25:07 +0000</pubDate>
		<dc:creator>lamengao</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.cuoluo.net/?p=176</guid>
		<description><![CDATA[前天学了一下Google Apps Script觉得这玩意儿很好玩儿(我很早以前就觉得google spreadsheet潜力很大),所以就想做点什么来练练手。经过短暂的思考，想到了一个点子--把google电子表格打造成twitter客户端。谁知google后发现早就有人想到这样做了，不由得有些小小的遗憾。不过继续搜索后发现，大家有的似乎都只是一个想法，我还没有找到一个真正可用的apps script.既然没有一个成型的脚本，那正好自己把它实现。
这里简单的介绍一下google apps script，它能让你用一种很简单的方式来自动处理电子表格中的数据。就像是office excel中的宏，但比宏强大很多倍。google apps script使用标准的javascript语言，提供相当直观的API,可以很容易就上手。最最重要的是，你写好的javascript脚本是在google的服务器上运行的，这为我们利用google电子表格来翻墙提供了可能,当然你要先保证自己的电子表格不被墙。比如我下面要介绍的这个脚本就能让你在不翻墙的情况下使用twitter(当然只是一部分内容：查看timeline和更新消息).
我的spreadsheet twitter client就是下面这个样子的。

你可以按照下面的步骤使用这个脚本：
1.登陆你的google文档
2.打开这个google电子表格(由于我的脚本很多都是硬编码，所以需要有一个模板)
3.点击菜单中的"File > Make a copy",然后输入你想保存的文件名，确定。
4.第一次打开你保存的这个电子表格后，你需要按照提示输入你的twitter用户名和密码.如果输入错误或者想更换twitter用户，你可以点击电子表格下面的"config"工作表，然后在里面更改。

5.如果想发推，你可以在"home"工作表左上角那个白色的大框框(就是cell A2)中输入内容,然后按回车确认输入完毕(输完内容后一定要按回车，这点很重要，不然脚本获取不到你的推)，然后点击菜单 "Twitter action > Update status."就可以了。
6.至于更新时间线，同样也是点击菜单"Twitter action"然后寻找相应的操作就可以了。
7.对了，不管是发推还是更新时间线，在你第一次运行脚本的时候电子表格会询问你是否同意脚本更改你的数据，你选择同意然后再次点击菜单运行就可以了。
好了，就是这么简单。如果你想Geek一把，尝试一下用电子表格浏览twitter吧。
如前所述，写这个脚本只是为了熟悉一下google apps script,所以这个电子表格客户端还很简陋，很多功能都没有。但也不排除那天有时间的话更新一些新功能。如果有了新功能你只需要打开这个文件重复上面的操作就可以了。当然，如果你对google apps script有兴趣，可以在"Tools > Scripts > Script editor..."查看源码，然后自行完善。
ps.在google 电子表格被墙的情况下可以试试用https打开。
]]></description>
			<content:encoded><![CDATA[<p>前天学了一下<a href="http://www.google.com/google-d-s/scripts/scripts.html">Google Apps Script</a>觉得这玩意儿很好玩儿(我很早以前就觉得<a href="http://blog.cuoluo.net/2008/12/from-google-spreadsheet-to-google-database/">google spreadsheet潜力很大</a>),所以就想做点什么来练练手。经过短暂的思考，想到了一个点子--把google电子表格打造成twitter客户端。谁知google后发现早就有人想到这样做了，不由得有些小小的遗憾。不过继续搜索后发现，大家有的似乎都只是一个想法，我还没有找到一个真正可用的apps script.既然没有一个成型的脚本，那正好自己把它实现。</p>
<p>这里简单的介绍一下google apps script，它能让你用一种很简单的方式来自动处理电子表格中的数据。就像是office excel中的宏，但比宏强大很多倍。google apps script使用标准的javascript语言，<a href="http://www.google.com/google-d-s/scripts/overview.html">提供相当直观的API</a>,可以很容易就上手。最最重要的是，你写好的javascript脚本是在google的服务器上运行的，这为我们利用google电子表格来翻墙提供了可能,当然你要先保证自己的电子表格不被墙。比如我下面要介绍的这个脚本就能让你在不翻墙的情况下使用twitter(当然只是一部分内容：查看timeline和更新消息).</p>
<p>我的spreadsheet twitter client就是下面这个样子的。<br />
<img src="http://bing-images.stor.sinaapp.com/photo_20100324200251.PNG" alt="spreadsheet twitter client" width="610" height="401" /></p>
<p>你可以按照下面的步骤使用这个脚本：<br />
1.登陆你的<a href="https://docs.google.com" target="_blank">google文档</a><br />
2.打开这个<a target="_blank" href="https://spreadsheets.google.com/ccc?key=0AvAcQwpJKwspdHktZTl4Wmt4VF9ZRFhHa3M2TWQ4M2c&#038;hl=en">google电子表格</a>(由于我的脚本很多都是硬编码，所以需要有一个模板)<br />
3.点击菜单中的"File > Make a copy",然后输入你想保存的文件名，确定。<br />
4.第一次打开你保存的这个电子表格后，你需要按照提示输入你的twitter用户名和密码.如果输入错误或者想更换twitter用户，你可以点击电子表格下面的"config"工作表，然后在里面更改。<br />
<img src="http://screensnapr.com/u/sa2l2m.png" alt="input twitter username" /><br />
5.如果想发推，你可以在"home"工作表左上角那个白色的大框框(就是cell A2)中输入内容,然后按回车确认输入完毕(输完内容后一定要按回车，这点很重要，不然脚本获取不到你的推)，然后点击菜单 "Twitter action > Update status."就可以了。<br />
6.至于更新时间线，同样也是点击菜单"Twitter action"然后寻找相应的操作就可以了。<br />
7.对了，不管是发推还是更新时间线，在你第一次运行脚本的时候电子表格会询问你是否同意脚本更改你的数据，你选择同意然后再次点击菜单运行就可以了。</p>
<p>好了，就是这么简单。如果你想Geek一把，尝试一下用电子表格浏览twitter吧。</p>
<p>如前所述，写这个脚本只是为了熟悉一下google apps script,所以这个电子表格客户端还很简陋，很多功能都没有。但也不排除那天有时间的话更新一些新功能。如果有了新功能你只需要打开<a target="_blank" href="https://spreadsheets.google.com/ccc?key=0AvAcQwpJKwspdHktZTl4Wmt4VF9ZRFhHa3M2TWQ4M2c&#038;hl=en">这个文件</a>重复上面的操作就可以了。当然，如果你对google apps script有兴趣，可以在"Tools > Scripts > Script editor..."查看源码，然后自行完善。</p>
<p>ps.在google 电子表格被墙的情况下可以试试用https打开。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cuoluo.net/2010/03/make-your-google-spreadsheet-to-twitter-client/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>How to send a private tweet</title>
		<link>http://blog.cuoluo.net/2010/03/how-to-send-a-private-tweet/</link>
		<comments>http://blog.cuoluo.net/2010/03/how-to-send-a-private-tweet/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 10:44:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.cuoluo.net/?p=167</guid>
		<description><![CDATA[习惯了用twitter记录自己的一些想法.但有时候想法很不成熟或者只想写下一些私事，所以并不是所有的tweets都适合公开。可是twitter并不支持private tweet,要么全部公开，要么全部私密。为了解决这个问题，我以前的做法是重新申请一个twitter账号，把tweets设为保护状态，然后所有不想公开的tweets就用那个账号发布。这样做起来并不方便，我只想用一个账号来保存我所有公开和不公开的tweets。于是便有了private tweet这个小工具。它的原理很简单，所谓的private tweet就是自己给自己发的私信，但是这在twitter的web页面上是无法做到的，只能通过api,所以我需要写一个小工具。如果有时间的话，下一步要完善的就是提供显示自己所有private tweets的功能.
update:花了一个多小时，view my private tweets功能已经完成。

http://privatetweet.appspot.com
]]></description>
			<content:encoded><![CDATA[<p>习惯了用twitter记录自己的一些想法.但有时候想法很不成熟或者只想写下一些私事，所以并不是所有的tweets都适合公开。可是twitter并不支持private tweet,要么全部公开，要么全部私密。为了解决这个问题，我以前的做法是重新申请一个twitter账号，把tweets设为保护状态，然后所有不想公开的tweets就用那个账号发布。这样做起来并不方便，我只想用一个账号来保存我所有公开和不公开的tweets。于是便有了<a href="http://privatetweet.appspot.com">private tweet</a>这个小工具。它的原理很简单，所谓的private tweet就是自己给自己发的私信，但是这在twitter的web页面上是无法做到的，只能通过api,所以我需要写一个小工具。如果有时间的话，下一步要完善的就是提供显示自己所有private tweets的功能.</p>
<p>update:花了一个多小时，view my private tweets功能已经完成。<br />
<img src="http://cuoluo.net/images/pts.jpg" alt="send private tweet" /><br />
<a href="http://privatetweet.appspot.com">http://privatetweet.appspot.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cuoluo.net/2010/03/how-to-send-a-private-tweet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>gmail style html editor</title>
		<link>http://blog.cuoluo.net/2010/01/gmail-style-html-editor/</link>
		<comments>http://blog.cuoluo.net/2010/01/gmail-style-html-editor/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 09:24:23 +0000</pubDate>
		<dc:creator>lamengao</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.cuoluo.net/?p=121</guid>
		<description><![CDATA[正在做一个google风格的web应用，前端需要用到富文本编辑器,于是在KindEditor的基础上山寨了一个gmail风格的html editor.山寨到了一半，Closure Library横空出世，有了官方的版本，我也就没有必要自己做了。不过我想也许有人用的着，还是贡献出来吧。下面就是这个做了一半的gmail html editor，代码都是开源的如需完善请自行修改。


demo
]]></description>
			<content:encoded><![CDATA[<p>正在做一个google风格的web应用，前端需要用到富文本编辑器,于是在<a href="http://www.kindsoft.net/" target="_blank">KindEditor</a>的基础上山寨了一个gmail风格的html editor.山寨到了一半，<a href="http://closure-library.googlecode.com/svn/trunk/closure/goog/docs/index.html" target="_blank">Closure Library</a>横空出世，有了官方的版本，我也就没有必要自己做了。不过我想也许有人用的着，还是贡献出来吧。下面就是这个做了一半的gmail html editor，代码都是开源的如需完善请自行修改。</p>
<p><img class="alignnone" title="gmail html editor" src="http://cuoluo.net/images/4321471659_49ae065f2c.jpg" alt="" width="500" height="285" /><br />
<a href="http://cuoluo.cn/demo/gmail-style-html-editor.html" target="_blank"><strong><strong></strong></strong></a></p>
<p><a href="http://cuoluo.net/demo/gmail-style-html-editor.html">demo</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cuoluo.net/2010/01/gmail-style-html-editor/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>在Linode VPS上安装pptp VPN</title>
		<link>http://blog.cuoluo.net/2009/12/install-pptp-vpn-in-linode-vps/</link>
		<comments>http://blog.cuoluo.net/2009/12/install-pptp-vpn-in-linode-vps/#comments</comments>
		<pubDate>Sat, 05 Dec 2009 21:03:25 +0000</pubDate>
		<dc:creator>lamengao</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.cuoluo.net/?p=108</guid>
		<description><![CDATA[pre{font-family: "ff-meta-web-pro-1", "ff-meta-web-pro-2", Helvetica, Arial, sans-serif;word-break:break-all;font-size:20px;}
应apple4.us之邀介绍一下如何在Linode VPS上安装VPN server.我自己的VPS装的是Ubuntu 9.10,所以以下操作全都是针对Ubuntu 9.10操作系统的。
首先，你要确保自己的vps已经按照Getting Started With Linode这篇文章做好了初步的准备工作。对安装VPN而言，需要注意的就是设置好更新源。编辑你的/etc/apt/sources.list文件，去掉"##universe repositories"之后所有行的注释，让文件变成和下面的一样。当然，这一步需要用sudo或者在root下来完成，后面所有的命令都是如此。
## main &#38; restricted repositories
deb http://us.archive.ubuntu.com/ubuntu/ karmic main restricted
deb-src http://us.archive.ubuntu.com/ubuntu/ karmic main restricted

deb http://security.ubuntu.com/ubuntu karmic-security main restricted
deb-src http://security.ubuntu.com/ubuntu karmic-security main restricted

## universe repositories
deb http://us.archive.ubuntu.com/ubuntu/ karmic universe
deb-src http://us.archive.ubuntu.com/ubuntu/ karmic universe
deb http://us.archive.ubuntu.com/ubuntu/ karmic-updates universe
deb-src http://us.archive.ubuntu.com/ubuntu/ karmic-updates universe

deb http://security.ubuntu.com/ubuntu karmic-security universe
deb-src http://security.ubuntu.com/ubuntu karmic-security universe
接着用下面的命令更新你的软件包数据库
apt-get update
现在我们可以正式安装VPN [...]]]></description>
			<content:encoded><![CDATA[<style>pre{font-family: "ff-meta-web-pro-1", "ff-meta-web-pro-2", Helvetica, Arial, sans-serif;word-break:break-all;font-size:20px;}</style>
<p>应<a href="http://apple4.us">apple4.us</a>之邀介绍一下如何在Linode VPS上安装VPN server.我自己的VPS装的是Ubuntu 9.10,所以以下操作全都是针对Ubuntu 9.10操作系统的。</p>
<p>首先，你要确保自己的vps已经按照<a href="http://library.linode.com/getting-started/" target="_blank">Getting Started With Linode</a>这篇文章做好了初步的准备工作。对安装VPN而言，需要注意的就是设置好更新源。编辑你的/etc/apt/sources.list文件，去掉"##universe repositories"之后所有行的注释，让文件变成和下面的一样。当然，这一步需要用sudo或者在root下来完成，后面所有的命令都是如此。</p>
<pre style="color: #101010; background-color: #f1f0e6; padding: 5px; border: 1px solid #a0a0a0;">## main &amp; restricted repositories
deb http://us.archive.ubuntu.com/ubuntu/ karmic main restricted
deb-src http://us.archive.ubuntu.com/ubuntu/ karmic main restricted

deb http://security.ubuntu.com/ubuntu karmic-security main restricted
deb-src http://security.ubuntu.com/ubuntu karmic-security main restricted

## universe repositories
deb http://us.archive.ubuntu.com/ubuntu/ karmic universe
deb-src http://us.archive.ubuntu.com/ubuntu/ karmic universe
deb http://us.archive.ubuntu.com/ubuntu/ karmic-updates universe
deb-src http://us.archive.ubuntu.com/ubuntu/ karmic-updates universe

deb http://security.ubuntu.com/ubuntu karmic-security universe
deb-src http://security.ubuntu.com/ubuntu karmic-security universe</pre>
<p>接着用下面的命令更新你的软件包数据库</p>
<pre style="color: #fbfbfb; background-color: #232323; padding: 5px; border: 1px solid #a0a0a0;">apt-get update</pre>
<p>现在我们可以正式安装VPN server了。这里我们选择pptp(vpn 协议的一种),因为简单，一条命令搞定。剩下的无非是一些配置。</p>
<pre style="color: #fbfbfb; background-color: #232323; padding: 5px; border: 1px solid #a0a0a0;">apt-get install pptpd</pre>
<p>pptpd安装完成后，编辑/etc/pptpd.conf文件，去掉下面两行的注释或者直接添加这两行(在文件的最后).这一步是配置ip地址的范围。</p>
<pre style="color: #101010; background-color: #f1f0e6; padding: 5px; border: 1px solid #a0a0a0;">localip 192.168.0.1
remoteip 192.168.0.234-238,192.168.0.245</pre>
<p>然后在/etc/ppp/chap-secrets文件中添加vpn用户，按照下面的格式,每个用户一行。</p>
<pre style="color: #101010; background-color: #f1f0e6; padding: 5px; border: 1px solid #a0a0a0;">username pptpd password *</pre>
<p>为了让你的用户连上VPN后能够正常地解析域名，我们需要手动设置DNS. 编辑/etc/ppp/options，找到ms-dns这一项，设置你的DNS.这里我推荐的是Google 最近发布的<a href="http://code.google.com/speed/public-dns/" target="_blank">Public DNS</a>,原因是因为好记。</p>
<pre style="color: #101010; background-color: #f1f0e6; padding: 5px; border: 1px solid #a0a0a0;">ms-dns 8.8.8.8
ms-dns 8.8.4.4</pre>
<p>编辑/etc/sysctl.conf文件，找到"net.ipv4.ip_forward=1"这一行，去掉前面的注释。</p>
<pre style="color: #101010; background-color: #f1f0e6; padding: 5px; border: 1px solid #a0a0a0;">net.ipv4.ip_forward=1</pre>
<p>运行下面的命令让配置生效。</p>
<pre style="color: #fbfbfb; background-color: #232323; padding: 5px; border: 1px solid #a0a0a0;">sysctl -p</pre>
<p>重启pptpd服务</p>
<pre style="color: #fbfbfb; background-color: #232323; padding: 5px; border: 1px solid #a0a0a0;">/etc/init.d/pptpd restart</pre>
<p>最后开启iptables转发</p>
<pre style="color: #fbfbfb; background-color: #232323; padding: 5px; border: 1px solid #a0a0a0;">/sbin/iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE</pre>
<p>ok,安装完毕。赶快用上你的VPN，让GFW见鬼去吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cuoluo.net/2009/12/install-pptp-vpn-in-linode-vps/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Search Tweets By Date Range</title>
		<link>http://blog.cuoluo.net/2009/11/search-tweets-by-date-range/</link>
		<comments>http://blog.cuoluo.net/2009/11/search-tweets-by-date-range/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 16:59:44 +0000</pubDate>
		<dc:creator>lamengao</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[分享发现]]></category>
		<category><![CDATA[创造]]></category>
		<category><![CDATA[爱生活]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://blog.cuoluo.net/?p=96</guid>
		<description><![CDATA[我在上一篇blog(似乎是很久很久以前的事了)中谈到，如果twitter想要当做云，能够记录各种log,那么首先要提供的一个功能就是特定时间段的信息搜索。但是twitter似乎并不想往这个方向努力，虽然提供了搜索服务但却不能满足那个小小的要求。你要是想查看某个话痨在上个月某一天的推，那要"more"的多么痛苦。
既然twitter不提供，那我们自己把他实现出来。这就是searchTweetsByDate.com的由来。目前功能还很有限并且必须要翻墙才能正常使用。下一步就是慢慢的完成这些todolist,如果有时间的话。
to do list

支持墙内用户使用
增大可搜索的时间范围(目前只支持从2009/11/02开始的范围内搜索)
支持用户home timeline的搜索(目前只支持用户的user timeline)
API
让可搜索的时间范围精确到秒
...

@Lamengao
]]></description>
			<content:encoded><![CDATA[<p>我在<a href="http://blog.cuoluo.cn/2009/06/14/89/">上一篇blog</a>(似乎是很久很久以前的事了)中谈到，如果twitter想要当做云，能够记录各种log,那么首先要提供的一个功能就是特定时间段的信息搜索。但是twitter似乎并不想往这个方向努力，虽然提供了搜索服务但却不能满足那个小小的要求。你要是想查看某个话痨在上个月某一天的推，那要"more"的多么痛苦。</p>
<p>既然twitter不提供，那我们自己把他实现出来。这就是<a href="http://searchtweetsbydate.com/" target="_blank">searchTweetsByDate.com</a>的由来。目前功能还很有限并且必须要翻墙才能正常使用。下一步就是慢慢的完成这些todolist,如果有时间的话。</p>
<p>to do list</p>
<ul>
<li>支持墙内用户使用</li>
<li>增大可搜索的时间范围(目前只支持从2009/11/02开始的范围内搜索)</li>
<li>支持用户home timeline的搜索(目前只支持用户的user timeline)</li>
<li>API</li>
<li>让可搜索的时间范围精确到秒</li>
<li>...</li>
</ul>
<div>@<a href="http://twitter.com/lamengao">Lamengao</a></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.cuoluo.net/2009/11/search-tweets-by-date-range/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>twitter发展的一种可能性</title>
		<link>http://blog.cuoluo.net/2009/06/twitter-way/</link>
		<comments>http://blog.cuoluo.net/2009/06/twitter-way/#comments</comments>
		<pubDate>Sat, 13 Jun 2009 19:48:47 +0000</pubDate>
		<dc:creator>lamengao</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[分享发现]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://blog.cuoluo.net/?p=89</guid>
		<description><![CDATA[我眼中的twitter就是一个半实时的动态信息发布和接收平台。从这个角度考虑,任何能够产生动态信息的地方都可以使用twitter。所以每一个twitter账号背后不一定是human，可以是服务器的系统日志，可以是个人交易的支付记录，当然也可以是blog的更新(只要你愿意，甚至可以把twitter当做rss阅读器。)。为如此众多的动态信息都创建一个twitter账号实在太麻烦。我希望twitter能够创建子账号，或者是给信息做标签，让信息能够更新到特定标签下。用户也可以只follow特定标签下的信息。这些概念都不新鲜，但如果twitter都实现出来潜力还是惊人的。
如果只要一个点击就能为任意一种动态信息创建一个twitter“账号”，那twitter的众多定义都将被改写。我可以创建自己网站的访问日志的twitter，我可以把自己商店的收银机连上twitter，让她记录我的每一笔营收。像这样把不同种类的信息集中放在twitter的好处在于，你可以在任意时间任意地点查看任意的一种记录,关键是你还可以分享出去还可以发布出去，只要你愿意。也许某一天FBI会要求twitter提供那个用户的账号信息来查看他是否偷税漏税。我就不相信twitter到了那一天还找不到自己的盈利模式。
twitter上的信息偏重于当前时间，而日历上的活动提醒之类的属于未来时间。如果twitter真要起到记录各种“日志”的作用，首先要提供的一个功能就是特定时间段的信息搜索。
我是个技术上的乐观主义者，什么服务都可以想得很美好，具体怎么走就看twitter自己了。
]]></description>
			<content:encoded><![CDATA[<p>我眼中的twitter就是一个半实时的动态信息发布和接收平台。从这个角度考虑,任何能够产生动态信息的地方都可以使用twitter。所以每一个twitter账号背后不一定是human，可以是服务器的系统日志，可以是个人交易的支付记录，当然也可以是blog的更新(只要你愿意，甚至可以把twitter当做rss阅读器。)。为如此众多的动态信息都创建一个twitter账号实在太麻烦。我希望twitter能够创建子账号，或者是给信息做标签，让信息能够更新到特定标签下。用户也可以只follow特定标签下的信息。这些概念都不新鲜，但如果twitter都实现出来潜力还是惊人的。</p>
<p>如果只要一个点击就能为任意一种动态信息创建一个twitter“账号”，那twitter的众多定义都将被改写。我可以创建自己网站的访问日志的twitter，我可以把自己商店的收银机连上twitter，让她记录我的每一笔营收。像这样把不同种类的信息集中放在twitter的好处在于，你可以在任意时间任意地点查看任意的一种记录,关键是你还可以分享出去还可以发布出去，只要你愿意。也许某一天FBI会要求twitter提供那个用户的账号信息来查看他是否偷税漏税。我就不相信twitter到了那一天还找不到自己的盈利模式。</p>
<p>twitter上的信息偏重于当前时间，而日历上的活动提醒之类的属于未来时间。如果twitter真要起到记录各种“日志”的作用，首先要提供的一个功能就是特定时间段的信息搜索。</p>
<p>我是个技术上的乐观主义者，什么服务都可以想得很美好，具体怎么走就看twitter自己了。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cuoluo.net/2009/06/twitter-way/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Fuck The GFW</title>
		<link>http://blog.cuoluo.net/2009/06/fuck-the-gfw/</link>
		<comments>http://blog.cuoluo.net/2009/06/fuck-the-gfw/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 19:21:26 +0000</pubDate>
		<dc:creator>lamengao</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[爱生活]]></category>

		<guid isPermaLink="false">http://blog.cuoluo.net/?p=83</guid>
		<description><![CDATA[昨天(6月2日),GFW相继屏蔽了twitter,live.com,bing.com,hotmail,flickr等一大批国外网站。为的是提醒我们那个快要到来的日子。生在这个局域网内，每天都在猜测下一个倒下的是谁，这种感觉很坏。面对互联网上众多优秀的免费的或不免费的服务，我们要么不能用，要么不敢用。我还能说什么呢？Fuck The GFW
我梦想有一天，国内能实现真正的言论自由。我梦想有一天，互联网能够真正的互联。
]]></description>
			<content:encoded><![CDATA[<p>昨天(6月2日),GFW相继屏蔽了twitter,live.com,bing.com,hotmail,flickr等一大批国外网站。为的是提醒我们那个快要到来的日子。生在这个局域网内，每天都在猜测下一个倒下的是谁，这种感觉很坏。面对互联网上众多优秀的免费的或不免费的服务，我们要么不能用，要么不敢用。我还能说什么呢？Fuck The GFW</p>
<p>我梦想有一天，国内能实现真正的言论自由。我梦想有一天，互联网能够真正的互联。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cuoluo.net/2009/06/fuck-the-gfw/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>oracle的tuning ppt下载</title>
		<link>http://blog.cuoluo.net/2009/04/oracle-tuning-ppt/</link>
		<comments>http://blog.cuoluo.net/2009/04/oracle-tuning-ppt/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 09:03:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[创造]]></category>

		<guid isPermaLink="false">http://blog.cuoluo.net/?p=80</guid>
		<description><![CDATA[以前oracle的工程师过来培训时的ppt,点击下面的"突然网址"下载.
http://toran.cn/jzcd
其实，我是想说toran.cn增加了文件上传功能。每天为这个小站添一砖加一瓦也自得其乐。
]]></description>
			<content:encoded><![CDATA[<p>以前oracle的工程师过来培训时的ppt,点击下面的"突然网址"下载.</p>
<p><a href="http://toran.cn/jzcd" target="_blank"><strong>http://toran.cn/jzcd</strong></a></p>
<p>其实，我是想说<a href="http://toran.cn" target="_blank">toran.cn</a>增加了文件上传功能。每天为这个小站添一砖加一瓦也自得其乐。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cuoluo.net/2009/04/oracle-tuning-ppt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
