<?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>草客天下——{{caokee}}</title>
	<atom:link href="http://blog.caokee.com/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.caokee.com</link>
	<description>上帝说要有光，于是就有了光</description>
	<lastBuildDate>Sun, 20 May 2012 06:25:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Nginx + uWSGI + web.py 搭建示例</title>
		<link>http://blog.caokee.com/2012/05/nginx-uwsgi-webpy.html</link>
		<comments>http://blog.caokee.com/2012/05/nginx-uwsgi-webpy.html#comments</comments>
		<pubDate>Sun, 20 May 2012 06:24:09 +0000</pubDate>
		<dc:creator>soone</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[uwsgi]]></category>

		<guid isPermaLink="false">http://blog.caokee.com/?p=149</guid>
		<description><![CDATA[废话少说，直接书写详细搭建过程，以作记录。 (1)安装Nginx 1.1 下载nginx-1.0.5.tar.gz并解压 1.2 ./configure (也可以增加&#8211;prefix= path指定安装路径) 此时有可能会提示缺少pcre支持，如果要安装pcre的话可以通过 yum install pcre-devel 来实现安装 1.3 make 1.4 make install (2)安装uWSGI 2.1 下载uwsgi-0.9.8.2.tar.gz并解压 2.2 make 在安装uWSGI的时候有可能提示说是libxml2不存在，针对此情况，建议通过 yum install libxml2-devel来解决 (3)安装web.py 可以通过easy_install web.py来安装最新版，不过我在安装0.36的时候出错，而且是语法错误，所以最终回退到0.35版 (4)以一个简单的webpy程序作为示例。以下代码是一个完整的webpy程序(webpytest.py) import web urls = (     '/(.*)', 'hello'     ) app &#8230; <a href="http://blog.caokee.com/2012/05/nginx-uwsgi-webpy.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
		<wfw:commentRss>http://blog.caokee.com/2012/05/nginx-uwsgi-webpy.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>redmine+mongrel+nginx+ssl</title>
		<link>http://blog.caokee.com/2012/05/redmine-mongrel-nginx-ssl.html</link>
		<comments>http://blog.caokee.com/2012/05/redmine-mongrel-nginx-ssl.html#comments</comments>
		<pubDate>Fri, 18 May 2012 17:12:09 +0000</pubDate>
		<dc:creator>soone</dc:creator>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[mongrel]]></category>
		<category><![CDATA[redmine]]></category>

		<guid isPermaLink="false">http://blog.caokee.com/?p=146</guid>
		<description><![CDATA[最近在新公司使用了redmine来进行项目流程和问题管理以及代码的管控。由于boss等需要在外网访问到redmine服务，所以需要将redmine所在服务器映射到外网，为了安全起见使用了ssl，提供客户端证书，通过双向认证的机制来限制访问。 关于redmine的安装，可以参考这里，需要注意的一点是不同的redmine版本对各种组件的需求在版本上要求比较严格，还有ruby推荐使用1.8的，如果使用最新的ruby，目前是1.9版本，则会有mysql中文问题，后来我直接使用了sqlite3作为数据库了。 在安装mongrel的过程中，总是遇到编译错误啊，后来参考了这里才顺利的安装上。不过在nginx+mongrel的模式中，我使用的是redmine-1.4的版本，会出现一个无法登陆的状况，后来在官网看到了解决方法，这个需要打一个补丁，可以参考这里。 关于ssl证书如何创建和使用，大家可以google一下，网上有很多相关的介绍说明。这里主要说下我遇到的https协议无法在外网使用的问题。公司内网使用的是飞鱼星路由，我将redmine主机映射到外网，主要是使用了路由的端口映射功能，比如我把外网访问的端口18888映射到内网redmine主机的443端口上，这样当访问公司的出口ip，就必须使用https协议并提供相应的证书才能访问到redmine服务，nginx的配置是这样的：   server { listen 443; server_name redmine.ename.cn; root /usr/local/nginx/www/redmine-1.4; index index.html index.htm; ssl on; ssl_certificate /usr/local/nginx/conf/keys2/server.crt; ssl_certificate_key /usr/local/nginx/conf/keys2/server.key; ssl_client_certificate /usr/local/nginx/conf/keys2/ca.crt; ssl_session_timeout 5m; ssl_verify_client on; ssl_verify_depth 10; ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL; ssl_prefer_server_ciphers on; location / { proxy_pass http://mongrel; proxy_redirect &#8230; <a href="http://blog.caokee.com/2012/05/redmine-mongrel-nginx-ssl.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
		<wfw:commentRss>http://blog.caokee.com/2012/05/redmine-mongrel-nginx-ssl.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>命令行下查看php函数说明的好工具——pman</title>
		<link>http://blog.caokee.com/2012/04/php-pman-tool.html</link>
		<comments>http://blog.caokee.com/2012/04/php-pman-tool.html#comments</comments>
		<pubDate>Thu, 19 Apr 2012 00:53:16 +0000</pubDate>
		<dc:creator>soone</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[pman]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://blog.caokee.com/?p=143</guid>
		<description><![CDATA[在pear上面有这样一个工具，叫pman，它实现了可以直接在命令行下使用类似于man ls这样的查看命令，来了解php的一些函数使用说明和例子。 首先从pear上面安装： pear install doc.php.net/pman 安装成功后，我们就可以使用这样到命令来查看相关的php函数使用说明了 pman substr 有了这个工具后，对于我们在类unix系统下编写php的人来说，简直是太有用了，直接省略掉了从终端和手册或者浏览器之间的不断切换的过程。对于经常使用vim的，那就有福了，我们可以把这个工具映射到某个按键上，在vim编辑php文件的时候，如果遇到需要查看了解的函数，直接按该按键，就可以直接看到该函数的详细说明了。我在.vimrc里面是这样配置的 autocmd FileType php setlocal keywordprg=pman “设置pman手册（只对vim哦，vi不行的，亲要注意） pman被映射到了K字母上，只要按K就可以调用并显示。 ps:人生就是各种懒啊，，，懒人是推动科技进步的重要因素。。。^=^ &#160;]]></description>
		<wfw:commentRss>http://blog.caokee.com/2012/04/php-pman-tool.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP输入流php://input</title>
		<link>http://blog.caokee.com/2012/03/php-input.html</link>
		<comments>http://blog.caokee.com/2012/03/php-input.html#comments</comments>
		<pubDate>Tue, 13 Mar 2012 03:35:36 +0000</pubDate>
		<dc:creator>soone</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[input]]></category>
		<category><![CDATA[stream]]></category>

		<guid isPermaLink="false">http://blog.caokee.com/?p=138</guid>
		<description><![CDATA[在使用xml-rpc的时候，server端获取client数据，主要是通过php输入流input，而不是$_POST数组。所以，这里主要探讨php输入流php://input 对一php://input介绍，PHP官方手册文档有一段话对它进行了很明确地概述。 “php://input allows you to read raw POST data. It is a less memory intensive alternative to $HTTP_RAW_POST_DATA and does not need any special php.ini directives. php://input is not available with enctype=”multipart/form-data”. 翻译过来，是这样： “php://input可以读取没有处理过的POST数据。相较于$HTTP_RAW_POST_DATA而言，它给内存带来的压力较小，并且不需要特殊的php.ini设置。php://input不能用于enctype=multipart/form-data” 我们应该怎么去理解这段概述呢?!我把它划分为三部分，逐步去理解。 读取POST数据 不能用于multipart/form-data类型 php://input VS $HTTP_RAW_POST_DATA 读取POST数据 PHPer们一定很熟悉$_POST这个内置变量。$_POST与php://input存在哪些关联与区别呢?另外，客户端向服务端交互数据，最常用的方法除了POST之外，还有GET。既然php://input作为PHP输入流，它能读取GET数据吗？这二个问题正是我们这节需要探讨的主要内容。 经验告诉我们，从测试与观察中总结，会是一个很凑效的方法。这里，我写了几个脚本来帮助我们测试。 @file 192.168.0.6:/phpinput_server.php 打印出接收到的数据 @file &#8230; <a href="http://blog.caokee.com/2012/03/php-input.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
		<wfw:commentRss>http://blog.caokee.com/2012/03/php-input.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>木头，木头，请告诉我时间是什么？？</title>
		<link>http://blog.caokee.com/2012/02/wood-clock.html</link>
		<comments>http://blog.caokee.com/2012/02/wood-clock.html#comments</comments>
		<pubDate>Mon, 20 Feb 2012 15:39:24 +0000</pubDate>
		<dc:creator>soone</dc:creator>
				<category><![CDATA[极客屋]]></category>
		<category><![CDATA[LED]]></category>
		<category><![CDATA[时钟]]></category>

		<guid isPermaLink="false">http://blog.caokee.com/?p=125</guid>
		<description><![CDATA[关于木头总是有很多的故事，而且故事本身总是和时间离不开关系。苍天巨树，它的年轮告诉我们时间的流逝，告诉我们生命的轮回，那一轮一轮的圆圈，虽然静止无语，却似乎在跟我们诉说着无尽的关于时间的故事。。。 今天我们家木头很兴奋，似乎它也对我手上的这个新玩意很感兴趣，一个木质的LED时钟，从外观上看似乎就是一块普通的木头，其实里面大有玄机：1、它能告诉你日期和时间，这是必须的。2、它能告诉你当前温度，这个有点高级。3、它能感应声音自动休眠和唤醒。我把它放在卧室的书桌上，装上三节AA电池，调整当前时间，顺带的调整一下闹钟，soone总是无休止的赖床，必须用这个治一治。下面上上这个LED时钟的真面目 想和soone一样拥有一个？soone是在这里淘的，赶紧去淘一个吧。 &#160;]]></description>
		<wfw:commentRss>http://blog.caokee.com/2012/02/wood-clock.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转载]Python 的虛擬環境及多版本開發利器─Virtualenv 與 Pythonbrew</title>
		<link>http://blog.caokee.com/2012/02/pythons-virtual-environment-and-multi-version-programming-tools-virtualenv-and-pythonbrew.html</link>
		<comments>http://blog.caokee.com/2012/02/pythons-virtual-environment-and-multi-version-programming-tools-virtualenv-and-pythonbrew.html#comments</comments>
		<pubDate>Fri, 17 Feb 2012 08:05:34 +0000</pubDate>
		<dc:creator>soone</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[pythonbrew]]></category>
		<category><![CDATA[virtualenv]]></category>

		<guid isPermaLink="false">http://blog.caokee.com/?p=115</guid>
		<description><![CDATA[Virtualenv 和 Pythonbrew 都是可以創造虛擬（獨立）Python 環境的工具，只是虛擬（獨立）標的不同。 Virtualenv 可以隔離函數庫需求不同的專案，讓它們不會互相影響。在建立並啟動虛擬環境後，透過 pip 安裝的套件會被放在虛擬環境中，專案就可以擁有一個獨立的環境。 簡而言之，Virtualenv 可以幫你做到： 在沒有權限的情況下安裝新套件 不同專案可以使用不同版本的相同套件 套件版本升級時不會影響其他專案 Pythonbrew 則可以在家目錄中安裝多個 Python，並迅速地切換版本；也可以在指定的 Python 版本下批次測試你的 Python 程式；另外更整合了 Virtualenv。 這篇文章會詳細介紹這兩個工具，讓你在多人開發及多版本開發的環境中更得心應手。 &#160; 事前準備 Python 的 package 通常會上傳至 PyPI，有很多工具都可以從 PyPI 安裝 package。下面會使用easy_install 這個工具（由 setuptools 提供）來安裝 Virtualenv 和 Pythonbrew。 01. Linux 如果不知道 easy_install 或還沒安裝 setuptools，在 Debian/Ubuntu 可以用下列指令安裝： $ sudo apt-get &#8230; <a href="http://blog.caokee.com/2012/02/pythons-virtual-environment-and-multi-version-programming-tools-virtualenv-and-pythonbrew.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
		<wfw:commentRss>http://blog.caokee.com/2012/02/pythons-virtual-environment-and-multi-version-programming-tools-virtualenv-and-pythonbrew.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>functools模块</title>
		<link>http://blog.caokee.com/2012/02/functools-module.html</link>
		<comments>http://blog.caokee.com/2012/02/functools-module.html#comments</comments>
		<pubDate>Wed, 15 Feb 2012 03:50:01 +0000</pubDate>
		<dc:creator>soone</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[functools]]></category>
		<category><![CDATA[tornado]]></category>

		<guid isPermaLink="false">http://blog.caokee.com/?p=111</guid>
		<description><![CDATA[在看tornado的源代码的时候发现了functools模块，google一下，发现这里有相关的介绍，很简单，稍微摘录了一下 functools模块提供了两个装饰器。这个模块是Python 2.5后新增的 wraps(wrapped[, assigned][, updated]) total_ordering(cls) wraps(wrapped[, assigned][, updated]) 这是一个很有用的装饰器。python函数是有几个特殊属性比如函数名，在被装饰后，原来的函数名如：foo会变成包装函数的名字如：wrapper，如果你希望使用反射，可能会导致意外的结果。这个装饰器可以解决这个问题，它能将装饰过的函数的特殊属性保留。 import time import functools def timeit(func): @functools.wraps(func) def wrapper(): start = time.clock() func() end = time.clock() print 'used:', end - start return wrapper @timeit def foo(): print 'in foo()' &#8230; <a href="http://blog.caokee.com/2012/02/functools-module.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
		<wfw:commentRss>http://blog.caokee.com/2012/02/functools-module.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]Python:os模块的进程管理</title>
		<link>http://blog.caokee.com/2012/02/python-os-process.html</link>
		<comments>http://blog.caokee.com/2012/02/python-os-process.html#comments</comments>
		<pubDate>Wed, 15 Feb 2012 02:11:24 +0000</pubDate>
		<dc:creator>soone</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[os]]></category>
		<category><![CDATA[process]]></category>

		<guid isPermaLink="false">http://blog.caokee.com/?p=93</guid>
		<description><![CDATA[有两种方式来实现并发性，一种方式是让每个“任务”或“进程”在单独的内在空间中工作，每个都有自已的工作内存区域。不过，虽然进程可在单独的内存空间中执行，但除非这些进程在单独的处理器上执行，否则，实际并不是“同时”运行的。是由操作系统把处理器的时间片分配给一个进程，用完时间片后就需退出处理器等待另一个时间片的到来。另一种方式是在在程序中指定多个“执行线程”，让它们在相同的内存空间中工作。这称为“多线程处理”。线程比进程更有效，因为操作系统不必为每个线程创建单独的内存空间。 新建进程用os.fork函数。但它只在POSIX系统上可用，在windows版的python中，os模块没有定义os.fork函数。相反，windows程序员用多线程编程技术来完成并发任务。 os.fork函数创建进程的过程是这样的。程序每次执行时，操作系统都会创建一个新进程来运行程序指令。进程还可调用os.fork，要求操作系统新建一个进程。父进程是调用os.fork函数的进程。父进程所创建的进程叫子进程。每个进程都有一个不重复的进程ID号。或称pid，它对进程进行标识。子进程与父进程完全相同，子进程从父进程继承了多个值的拷贝，如全局变量和环境变量。两个进程的唯一区别是fork的返回值。子进程接收返回值0，而父进程接收子进程的pid作为返回值。 用os.fork创建的子进程和父进程作为异步的并发进程而单独执行。异步是指它们各行其是，相互间不进行同步；并发是指它们可同时执行。所以我们无法知道子进程和父进程的相对速度。 os.wait函数用于等待子进程结束(只适用于UNIX兼容系统)。该函数返回包含两个元素的元组，包括已完成的子进程号pid，以及子进程的退出状态，返回状态为0，表明子进程成功完成。返回状态为正整数表明子进程终止时出错。如没有子进程，会引发OSError错误。os.wait要求父进程等待它的任何一个子进程结束执行，然后唤醒父进程。 要指示父进程等候一个指定的子进程终止，可在父进程中使用os.waitpid函数(只适用于unix兼容系统)。它可等候一个指定进程结束，然后返回一个双元素元组，其中包括子进程的pid和子进程的退出状态。函数调用将pid作为第一个参数传递，并将一个选项作为第二个选项，如果第一个参数大于0，则waitpid会等待该pid结束，如果第一个参数是-1，则会等候所有子进程，也就和os.wait一样。 用os.system 和 os.exec函数族来执行系统命令和其它程序。os.system使用shell来执行系统命令，然后在命令结束之后把控制权返回给原始进程；os.exec函数族在执行完命令后不将控制权返回给调用进程。它会接管python进程，pid不变。这两个函数支持unix和windows平台。 os.popen()函数可执行命令，并获得命令的stdout流。函数要取得两个参数，一个是要执行的命令，另一个是调用函数所用的模式，如“r”只读模式。os.popen2()函数执行命令，并获得命令的stdout流和stdin流。函数返回一个元组，其中包含有两个文件对象，一个对象对应stdin流，一个对象对应stdout流。 进程使用IPC机制在进程间传递信息，一种IPC机制是“管道”，它是一种类似于文件的对象，提供单向通信渠道。父进程可打开一个管道，再分支一个子进程。父进程使用管道将信息写入(发送到)子进程，而子进程使用管道从父进程读取信息。在python中使用os.pipe函数创建管道。 os._exit()类似于sys.exit()，但它不执行任何的清除工作(例如刷新缓冲区)。所以os._exit()尤其适用于退出子进程。如果程序使用sys.exit()，操作系统会回收父进程或其它子进程可能仍然需要的资源。传给os._exit()函数的参数必须是进程的退出状态。退出状态为0，表示正常终止。 进程也可用信号进行通信。所谓“信号”，是操作系统采取异步方式传给程序的消息。如CTRL+C会传递一个“中断信号”，通常该信号导致程序中止。然而程序完全可以指定用不同的行动来响应任何一个信号。在信号处理中，程序要接收信号，并根据那个信号采取一项行动。错误(例如向已关闭管道写入)、事件(例如计时器变成0)以及用户输入(例如按ctrl+c)都会产生信号。 针对每个信号，每个python程序都有一个默认的信号处理程序。例如，假定python解释器收到一个信号，该信号指出程序试图向已关闭的管道写入，或者用户敲入一个键盘中断，python就会引发一个异常。发生异常后，程序既可使用默认处理程序，也可使用自定义处理程序。 signal.signal函数为中断信号注册一个信号处理程序。函数要获得两个参数：一个信号和一个对应于信号处理程序的函数。 在unix/linux系统中，子进程终止后，会保留在进程表中，让父进程知道子进程是否正常终止。如果创建大量子进程，但在终止后没有从进程表中移除它们，进程表便会积累越来越多的死进程，这些进程称为“zombies”(僵尸进程)，消除僵尸进程的操作称为“reaping”，这是通过os.wait和os.waitpid函数实现的。 转发地址：http://hi.baidu.com/giftangellong/blog/item/fe5dc630a749f410ebc4afa2.html]]></description>
		<wfw:commentRss>http://blog.caokee.com/2012/02/python-os-process.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>gf3在天安门附近试拍</title>
		<link>http://blog.caokee.com/2012/02/try-gf3.html</link>
		<comments>http://blog.caokee.com/2012/02/try-gf3.html#comments</comments>
		<pubDate>Tue, 14 Feb 2012 15:27:59 +0000</pubDate>
		<dc:creator>soone</dc:creator>
				<category><![CDATA[心语]]></category>
		<category><![CDATA[gf3]]></category>
		<category><![CDATA[photo]]></category>
		<category><![CDATA[摄影]]></category>

		<guid isPermaLink="false">http://blog.caokee.com/?p=75</guid>
		<description><![CDATA[幸福路人 王府井小吃街 钟楼 看起来很忧郁的狮子 仰望的角度 老北京布鞋 同仁堂 热闹的电话亭 这里缺少一个人 无题 老宅第 铺首 小溪 白椅 狮头 华表]]></description>
		<wfw:commentRss>http://blog.caokee.com/2012/02/try-gf3.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[翻译]关于python的“with”声明</title>
		<link>http://blog.caokee.com/2012/02/python-with-statement.html</link>
		<comments>http://blog.caokee.com/2012/02/python-with-statement.html#comments</comments>
		<pubDate>Tue, 14 Feb 2012 10:20:59 +0000</pubDate>
		<dc:creator>soone</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[with]]></category>

		<guid isPermaLink="false">http://blog.caokee.com/?p=68</guid>
		<description><![CDATA[从com.lang.python以及其他的一些论坛上看来，一些有经验的python开发者对于在2.5版本新增加的with似乎有一点迷惑。 如同Python的其他方面一样，一旦你了解了with是用来试图解决哪些问题的时候，你会发现其实它很简单。 看看下面的代码片段： set things up try:     do something finally:     tear things down 在这里，”set things up” 可以是打开一个文件或者获得一些外部资源，而”tear things down”可能是相对应的关闭打开的文件或者释放或移除一些资源。try-finally结构保证了就算”do something”代码没有真正执行完成，”tear thigs down”部分也总是会被执行。 如果你经常如上面那样编写一些代码，那么将“set things up”和”tear things down“这些代码放到库函数里以便重用是比较方便的。你可以如下面那样作： def controlled_execution(callback):     set things up     &#8230; <a href="http://blog.caokee.com/2012/02/python-with-statement.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
		<wfw:commentRss>http://blog.caokee.com/2012/02/python-with-statement.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

