<?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>Fred 学习小站</title>
	<atom:link href="http://fredzhu.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://fredzhu.com</link>
	<description>程序员的道路上一路走来 所思、所想、所悟</description>
	<lastBuildDate>Sat, 12 May 2012 15:06:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Java WebSocket 开发 Webbit</title>
		<link>http://fredzhu.com/2012/05/java-websocket-dev-webbit/</link>
		<comments>http://fredzhu.com/2012/05/java-websocket-dev-webbit/#comments</comments>
		<pubDate>Sat, 12 May 2012 14:51:55 +0000</pubDate>
		<dc:creator>fred</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[修炼之旅]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[netty]]></category>
		<category><![CDATA[webbit]]></category>
		<category><![CDATA[websocket]]></category>

		<guid isPermaLink="false">http://fredzhu.com/?p=300218</guid>
		<description><![CDATA[<p>webbit是基于netty扩展的websocket工具。可以大大简化websocket开发。 项目地址：https://github.com/webbit/webbit 使用说明：https://github.com/webbit/webbit/blob/master/README.md 本文权当翻译，高手直接进上面链接。 一些题外话： websocket和我一开始想象的TCP应用不同。websocket和传统意义上的socket通信不一样。本质上还是HTTP的扩展。 websocket协议目前还没有定稿。目前主要有3个版本的协议在使用。且都是草案。webbit都实现了3个草案。具体参阅维基http://en.wikipedia.org/wiki/WebSocket 快速开始 Maven配置  配置端口8080.并配置websocket路径/socket的handler  编写/socket handler 到此为止。基本代码已经都好了。感觉更写个servlet一样方便。 下面是客户端代码： 到此为止。websocket基本功能都已经实现。 &#160; &#160;</p>
 ]]></description>
			<content:encoded><![CDATA[<div style="clear:both; margin-top:5px; margin-bottom:5px;"></div><p>webbit是基于netty扩展的websocket工具。可以大大简化websocket开发。</p>
<p>项目地址：<a title="https://github.com/webbit/webbit" href="https://github.com/webbit/webbit">https://github.com/webbit/webbit</a></p>
<p>使用说明：<a title="https://github.com/webbit/webbit/blob/master/README.md" href="https://github.com/webbit/webbit/blob/master/README.md">https://github.com/webbit/webbit/blob/master/README.md</a></p>
<p>本文权当翻译，<span style="color: #800000;">高手直接进上面链接</span>。</p>
<p>一些题外话：</p>
<ol>
<li>websocket和我一开始想象的TCP应用不同。websocket和传统意义上的socket通信不一样。本质上还是HTTP的扩展。</li>
<li>websocket协议目前还没有定稿。目前主要有3个版本的协议在使用。且都是草案。webbit都实现了3个草案。具体参阅维基<a title="http://en.wikipedia.org/wiki/WebSocket" href="http://en.wikipedia.org/wiki/WebSocket">http://en.wikipedia.org/wiki/WebSocket</a></li>
</ol>
<h2>快速开始</h2>
<p><strong>Maven配置</strong></p><pre class="crayon-plain-tag">&amp;lt;dependency&amp;gt;
	&amp;lt;groupId&amp;gt;org.webbitserver&amp;lt;/groupId&amp;gt;
	&amp;lt;artifactId&amp;gt;webbit&amp;lt;/artifactId&amp;gt;
	&amp;lt;version&amp;gt;0.4.7&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;</pre><p><strong> 配置端口8080.并配置websocket路径/socket的handler</strong></p><pre class="crayon-plain-tag">public class WebSocketServer{

	public static void main(String[] args) {
		WebServer webServer = WebServers.createWebServer(8080)
	    .add(new StaticFileHandler(&quot;/socket&quot;));
		webServer.start();
	}

}</pre><p><strong> 编写/socket handler</strong></p><pre class="crayon-plain-tag">public class WebSocketHandler  extends BaseWebSocketHandler{

    private int connectionCount;

    public void onOpen(WebSocketConnection connection) {
        connection.send(&quot;Hello! There are &quot; + connectionCount + &quot; other connections active&quot;);
        connectionCount++;
    }

    public void onClose(WebSocketConnection connection) {
        connectionCount--;
    }

    public void onMessage(WebSocketConnection connection, String message) {
        connection.send(message.toUpperCase()); // echo back message in upper case
    }

}</pre><p>到此为止。基本代码已经都好了。感觉更写个servlet一样方便。</p>
<p>下面是客户端代码：</p><pre class="crayon-plain-tag">&amp;lt;html&amp;gt;
  &amp;lt;body&amp;gt;

    &amp;lt;!-- Send text to websocket --&amp;gt;
    &amp;lt;input id=&quot;userInput&quot; type=&quot;text&quot;&amp;gt;
    &amp;lt;button onclick=&quot;ws.send(document.getElementById('userInput').value)&quot;&amp;gt;Send&amp;lt;/button&amp;gt;

    &amp;lt;!-- Results --&amp;gt;
    &amp;lt;div id=&quot;message&quot;&amp;gt;&amp;lt;/div&amp;gt;

    &amp;lt;script&amp;gt;
      function showMessage(text) {
        document.getElementById('message').innerHTML = text;
      }

      var ws = new WebSocket('ws://' + document.location.host + '/hellowebsocket');
      showMessage('Connecting...');
      ws.onopen = function() { showMessage('Connected!'); };
      ws.onclose = function() { showMessage('Lost connection'); };
      ws.onmessage = function(msg) { showMessage(msg.data); };
    &amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;</pre><p>到此为止。websocket基本功能都已经实现。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div style="float:left"><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><div style="clear:both; margin-top:5px; margin-bottom:5px;"></div>]]></content:encoded>
			<wfw:commentRss>http://fredzhu.com/2012/05/java-websocket-dev-webbit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>netty+flash xmlsocket 在线聊天室</title>
		<link>http://fredzhu.com/2012/04/nettyflash-xmlsocket-online-chatrom/</link>
		<comments>http://fredzhu.com/2012/04/nettyflash-xmlsocket-online-chatrom/#comments</comments>
		<pubDate>Fri, 27 Apr 2012 14:09:01 +0000</pubDate>
		<dc:creator>fred</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[修炼之旅]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[netty]]></category>
		<category><![CDATA[聊天室]]></category>

		<guid isPermaLink="false">http://fredzhu.com/?p=300196</guid>
		<description><![CDATA[<p>这几天公司做了个简单的web im聊天室。麦包包晒包频道 右下角的“包打听”。 采用netty 做socket server + flash client. 通讯采用自定义的JSON文本。 在线IM初步的探索，现阶段做的比较简单。 目前就部署1台服务器。没有考虑多机通信。没有涉及通信队列。 总共代码不到1000行。netty的确强大。 关键代码分享： 无话可说的代码,netty通用设置。 由于采用JSON协议。 上行通道： DelimiterBasedFrameDecoder 读取缓存时,已\0\r\n 为中止符 StringDecoder 二进制转字符串进行UTF-8解码 StringEncoder 字符串UTF-8编码 下行通道： MessageHandler 业务逻辑处理 MessageEncoder JSON转字节流打入下行通道 netty没有提供\0截取。不过重写部分代码即可。 逻辑处理： 处理flash 的policy file request 处理业务逻辑 &#160; 具体业务在    MessageDispatchHandler &#8230;
<p class="read-more"><a href="http://fredzhu.com/2012/04/nettyflash-xmlsocket-online-chatrom/">继续阅读 &#187;</a></p>
 ]]></description>
			<content:encoded><![CDATA[<div style="clear:both; margin-top:5px; margin-bottom:5px;"></div><p>这几天公司做了个简单的web im聊天室。<a href="http://mkts.mbaobao.com/active/showbag.php">麦包包晒包频道</a> 右下角的“包打听”。</p>
<p>采用netty 做socket server + flash client. 通讯采用自定义的JSON文本。</p>
<p>在线IM初步的探索，现阶段做的比较简单。</p>
<p>目前就部署1台服务器。没有考虑多机通信。没有涉及通信队列。</p>
<p>总共代码不到1000行。netty的确强大。</p>
<p>关键代码分享：</p>
<p>无话可说的代码,netty通用设置。</p><pre class="crayon-plain-tag">public class ChatRoomNioServer {

	private static final Logger		logger		= Logger.getLogger(ChatRoomNioServer.class);

	private static final Integer	SERVER_PORT	= Integer.parseInt(PropertiesHelp
													.getProperty(&quot;chat.server.port&quot;));
	public void start() {
		logger.info(&quot;chatroom init...&quot;);
		ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(
			Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
		bootstrap.setPipelineFactory(new ChatRoomServerPipelineFactory());

		bootstrap.setOption(&quot;child.tcpNoDelay&quot;, true);
		bootstrap.setOption(&quot;child.keepAlive&quot;, true);
		bootstrap.setOption(&quot;reuseAddress&quot;, true);
		bootstrap.bind(new InetSocketAddress(SERVER_PORT));
		logger.info(&quot;chatroom running...&quot;);
	}

}</pre><p>由于采用JSON协议。</p>
<p>上行通道：</p>
<ol>
<li>DelimiterBasedFrameDecoder 读取缓存时,已\0\r\n 为中止符</li>
<li>StringDecoder 二进制转字符串进行UTF-8解码</li>
<li>StringEncoder 字符串UTF-8编码</li>
</ol>
<p>下行通道：</p>
<ol>
<li>MessageHandler 业务逻辑处理</li>
<li>MessageEncoder JSON转字节流打入下行通道</li>
</ol>
<p></p><pre class="crayon-plain-tag">public class ChatRoomServerPipelineFactory implements ChannelPipelineFactory {

	@Override
	public ChannelPipeline getPipeline() throws Exception {
		ChannelPipeline pipeline = Channels.pipeline();
		pipeline
			.addLast(&quot;framer&quot;, new DelimiterBasedFrameDecoder(8192, Delimiters.zeroDelimiter()));
		pipeline.addLast(&quot;stringDecoder&quot;, new StringDecoder(CharsetUtil.UTF_8));
		pipeline.addLast(&quot;stringEncoder&quot;, new StringEncoder(CharsetUtil.UTF_8));
		pipeline.addLast(&quot;messageHandler&quot;, new MessageHandler());
		pipeline.addLast(&quot;encoder&quot;, new MessageEncoder());
		return pipeline;
	}

}</pre><p>netty没有提供\0截取。不过重写部分代码即可。</p><pre class="crayon-plain-tag">public class Delimiters {

	public static ChannelBuffer[] zeroDelimiter() {
		return new ChannelBuffer[] { ChannelBuffers.wrappedBuffer(new byte[] { '\0' }),
				ChannelBuffers.wrappedBuffer(new byte[] { '\r', '\n' }) };
	}

	private Delimiters() {

	}
}</pre><p>逻辑处理：</p>
<ol>
<li>处理flash 的policy file request</li>
<li>处理业务逻辑</li>
</ol>
<p></p><pre class="crayon-plain-tag">public class MessageHandler extends SimpleChannelUpstreamHandler {

	private static final Logger	logger			= Logger.getLogger(MessageHandler.class);

	private static final String	POLICY_REQUEST	= &quot;&amp;lt;policy-file-request/&amp;gt;&quot;;

	private static final String	POLICY_XML		= &quot;&amp;lt;?xml version=\&quot;1.0\&quot;?&amp;gt;&amp;lt;cross-domain-policy&amp;gt;&amp;lt;site-control permitted-cross-domain-policies=\&quot;master-only\&quot;/&amp;gt;&amp;lt;allow-access-from domain=\&quot;*\&quot; to-ports=\&quot;*\&quot; /&amp;gt;&amp;lt;/cross-domain-policy&amp;gt;&quot;;

	@Override
	public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
		super.channelConnected(ctx, e);
		ChatService.initConnection(e.getChannel());
		logger.info(&quot;one user connection server, left &quot; + ChatUserService.getOnlineUserCount()
					+ &quot; users&quot;);
	}

	@Override
	public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
		super.channelConnected(ctx, e);
		ChatService.closedConnection(e.getChannel());
		logger
			.info(&quot;one user left server, left &quot; + ChatUserService.getOnlineUserCount() + &quot; users&quot;);
	}

	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
		String msg = (String) e.getMessage();
		if (msg.equalsIgnoreCase(POLICY_REQUEST)) {
			e.getChannel().write(POLICY_XML + &quot;\0&quot;);
			e.getChannel().close();
		} else {
			try {
				MessageDispatchHandler messageDispatchHandler = new MessageDispatchHandler(e);
				messageDispatchHandler.setListener(new ChatRoomListenerImpl());
				messageDispatchHandler.dispatch();
			} catch (Exception ex) {
				logger.error(&quot;message handler error&quot;, ex);
			}
		}
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
		logger.warn(&quot;Unexpected exception from downstream.&quot;, e.getCause());
		e.getChannel().close();
	}
}</pre><p>&nbsp;</p>
<p>具体业务在    <span style="color: #ff0000;">MessageDispatchHandler</span> 处理一些业务逻辑即可。</p>
<p><span style="color: #ff8000;">总结下遇到的问题：</span></p>
<ol>
<li>flash socket通讯格式。每个协议请求都会\0作为消息结尾。因此netty接收消息也必须以\0为截止符读取消息。</li>
<li>flash 安全策略。flash夸域访问服务器时,会自动发&lt;policy-file-request/&gt; ，服务端收到消息后，必须响应对应策略文件。<br />
<pre class="crayon-plain-tag">&amp;lt;cross-domain-policy&amp;gt;
  &amp;lt;allow-access-from domain=&quot;*&quot; to-ports=&quot;80-9000&quot; /&amp;gt;
&amp;lt;/cross-domain-policy&amp;gt;</pre>
</li>
<li>SQL注入。Socket和Http相比。只是通讯的层次发生了改变。应用本身的漏洞仍旧没变。处理SQL的时候需要特别注意。不过用一些成熟的ORM框架可以很好的避免这类问题。<br />
<span style="color: #ff0000;"><strong>注：</strong></span><span style="color: #0000ff;">这里使用的是比较低级的JSON字符串作为消息载体，较为普遍和靠谱的做法是采用head+body的方式，但前提需要对格式有严格的约定。JSON灵活性较大，因此采用。</span></li>
</ol>
<div style="float:left"><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><div style="clear:both; margin-top:5px; margin-bottom:5px;"></div>]]></content:encoded>
			<wfw:commentRss>http://fredzhu.com/2012/04/nettyflash-xmlsocket-online-chatrom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>哎</title>
		<link>http://fredzhu.com/2012/04/ai/</link>
		<comments>http://fredzhu.com/2012/04/ai/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 12:55:52 +0000</pubDate>
		<dc:creator>fred</dc:creator>
				<category><![CDATA[心情宣泄]]></category>

		<guid isPermaLink="false">http://fredzhu.com/?p=300189</guid>
		<description><![CDATA[<p>哎</p>
 ]]></description>
			<content:encoded><![CDATA[<div style="clear:both; margin-top:5px; margin-bottom:5px;"></div><p>哎</p>
<div style="float:left"><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><div style="clear:both; margin-top:5px; margin-bottom:5px;"></div>]]></content:encoded>
			<wfw:commentRss>http://fredzhu.com/2012/04/ai/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>python模拟飞信(模拟webim)</title>
		<link>http://fredzhu.com/2012/01/python-fetion-mock/</link>
		<comments>http://fredzhu.com/2012/01/python-fetion-mock/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 14:37:03 +0000</pubDate>
		<dc:creator>fred</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://fredzhu.com/?p=300163</guid>
		<description><![CDATA[<p>之前写过一点飞信相关的小程序。很久没关心了。发现现在飞信协议都改掉了。强制了验证码。基本上原来的第三方库都不能使用了。 下面就是现在的飞信验证码。看上去破解难度不大。就一根干扰线。有哪位可以破解的网友贡献下代码to me&#60;me[???]fengsage.com&#62; 替换[???]你懂得。 废话不多说，开始进入正文。 最近发现飞信官网出了webim版的飞信。而且因为年底工作不多。有点无聊。花了几周无聊时间写写代码。给自己发发短信神马的。没多大意义。 项目地址：http://code.google.com/p/fetionim/ 值得注意的地方： 这个程序不是api库。如果验证码能破解则可以作为API库。 这个程序需要不关机环境。因为要保持和飞信server的心跳连接。一旦关机需要重新登录。 很多未知bug 目前实现的功能： 简单的cron表达式。目前只支持 month day hour minute 四个区间. 支持一个*通配符。一般用用够了。举例：[* * * *]表示每分钟执行到。[* * 20 00]表示每天20点执行。[* 20 * *] 表示每月20日的每一分钟执行到。[12 20 20 1]表示12月20日20点1分执行到。 只支持2种定时任务。即天气预报(只支持嘉兴.因为我住这)和任意短信。 未来要实现的功能： 天气预报各地支持。这块实现起来很简单。但打算重新设计下任务模块和cron模块。到时候一起改。 开放一些api。方便其他程序连接。比如宏机短信&#8230;&#8230; 做个wordpress插件。方便博友直接通过短信联系作者。  一些废话： 本来不打算发布这个。个人感觉这玩意不能算是什么好的作品。不过以我个性，如果不发布这玩意。估计后面也懒得去维护了。索性发布。代码写的不好。看到的朋友请口水少喷。多提点实在点的意见。 java和ruby都有基于webim的类似实现。 &#8230;
<p class="read-more"><a href="http://fredzhu.com/2012/01/python-fetion-mock/">继续阅读 &#187;</a></p>
 ]]></description>
			<content:encoded><![CDATA[<div style="clear:both; margin-top:5px; margin-bottom:5px;"></div><p>之前写过一点飞信相关的小程序。很久没关心了。发现现在飞信协议都改掉了。强制了验证码。基本上原来的第三方库都不能使用了。</p>
<p>下面就是现在的飞信验证码。看上去破解难度不大。就一根干扰线。有哪位可以破解的网友贡献下代码to me&lt;me[???]fengsage.com&gt; 替换[???]你懂得。<br />
<img class="size-full wp-image-300164" title="飞信验证码" src="http://fredzhu.com/wp-content/uploads/2012/01/fetion-vcode20120125220537.jpg" alt="飞信验证码" width="101" height="38" /></p>
<p>废话不多说，开始进入正文。</p>
<p>最近发现飞信官网出了<a href="https://webim.feixin.10086.cn/login.aspx">webim</a>版的飞信。而且因为年底工作不多。有点无聊。花了几周无聊时间写写代码。给自己发发短信神马的。没多大意义。</p>
<p>项目地址：<a href="http://code.google.com/p/fetionim/" target="_blank">http://code.google.com/p/fetionim/</a></p>
<p><span style="color: #800000;">值得注意的地方：</span></p>
<ol>
<li>这个程序不是api库。如果验证码能破解则可以作为API库。</li>
<li>这个程序需要不关机环境。因为要保持和飞信server的心跳连接。一旦关机需要重新登录。</li>
<li>很多未知bug</li>
</ol>
<p><span style="color: #800000;">目前实现的功能：</span></p>
<ol>
<li>简单的cron表达式。目前只支持 month day hour minute 四个区间. 支持一个*通配符。一般用用够了。举例：[* * * *]表示每分钟执行到。[* * 20 00]表示每天20点执行。[* 20 * *] 表示每月20日的每一分钟执行到。[12 20 20 1]表示12月20日20点1分执行到。</li>
<li>只支持2种定时任务。即天气预报(只支持嘉兴.因为我住这)和任意短信。</li>
</ol>
<p><span style="color: #800000;">未来要实现的功能：</span></p>
<ol>
<li>天气预报各地支持。这块实现起来很简单。但打算重新设计下任务模块和cron模块。到时候一起改。</li>
<li>开放一些api。方便其他程序连接。比如宏机短信&#8230;&#8230;</li>
<li>做个wordpress插件。方便博友直接通过短信联系作者。</li>
</ol>
<p><a href="http://fredzhu.com/wp-content/uploads/2012/01/python-fetion-login.jpg" rel="lightbox[300163]" title="python-fetion-login"><img class="alignnone size-medium wp-image-300165" title="python-fetion-login" src="http://fredzhu.com/wp-content/uploads/2012/01/python-fetion-login-300x125.jpg" alt="" width="300" height="125" /></a></p>
<p><a href="http://fredzhu.com/wp-content/uploads/2012/01/python-fetion-task.jpg" rel="lightbox[300163]" title="python-fetion-task"><img class="alignnone size-medium wp-image-300167" title="python-fetion-task" src="http://fredzhu.com/wp-content/uploads/2012/01/python-fetion-task-300x162.jpg" alt="" width="300" height="162" /></a></p>
<p><a href="http://fredzhu.com/wp-content/uploads/2012/01/python-fetion-xintiao.jpg" rel="lightbox[300163]" title="python-fetion-xintiao"><img class="alignnone size-medium wp-image-300173" title="python-fetion-xintiao" src="http://fredzhu.com/wp-content/uploads/2012/01/python-fetion-xintiao-300x227.jpg" alt="" width="300" height="227" /></a></p>
<h1> 一些废话：</h1>
<p>本来不打算发布这个。个人感觉这玩意不能算是什么好的作品。不过以我个性，如果不发布这玩意。估计后面也懒得去维护了。索性发布。代码写的不好。看到的朋友请口水少喷。多提点实在点的意见。</p>
<p>java和ruby都有基于webim的类似实现。</p>
<p>java参见：<a href="http://code.google.com/p/litefetion/" target="_blank">litefetion</a><br />
ruby参见：<a href="http://methodmissing.iteye.com/blog/824993" target="_blank">fetion-robot</a></p>
<p>python的应该算是独一无二的。我没看过这些现有的代码是如何实现的。纯粹自己编写边想。思路和方式和他们应该都存在较多的不同。算是给python初学者提供一些例子吧。</p>
<p>&nbsp;</p>
<div style="float:left"><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><div style="clear:both; margin-top:5px; margin-bottom:5px;"></div>]]></content:encoded>
			<wfw:commentRss>http://fredzhu.com/2012/01/python-fetion-mock/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>总结2011</title>
		<link>http://fredzhu.com/2012/01/summary-me-2011/</link>
		<comments>http://fredzhu.com/2012/01/summary-me-2011/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 13:34:19 +0000</pubDate>
		<dc:creator>fred</dc:creator>
				<category><![CDATA[心情宣泄]]></category>
		<category><![CDATA[2011]]></category>
		<category><![CDATA[总结]]></category>

		<guid isPermaLink="false">http://fredzhu.com/?p=300131</guid>
		<description><![CDATA[<p>每年都给自己写个总结。写给将来的自己看。 不太会写文章，分几个方面总结下2011过去的一年。 生活 离开了生活了5年多的杭州。其实说是5年。但里面有3年大学生活，只有2年的工作。虽然是爸妈的意思，但我知道，其实是我自己的软弱。我害怕孤单的一直生活下去。每天上班下班。不知道前面的路在哪里。回嘉兴的这一年来感觉非常的放松，再也没有了那种漂泊孤单感觉，有着家人的关爱，重新滋润了我那干枯的心床。我不后悔！感谢小龚老师、小王老师、老蒋童鞋。曾经的照顾和关怀~ 工作 告别了曾经共同奋斗过得同事们，告别了我最尊敬的王总。感谢你2年前给我一个走出大学的学生机会，让我不至于在茫茫的毕业潮中失去方向。在公司的这段日子是我毕生难忘的日子。你教会了我如何学习，如何沟通，如何写文档&#8230;&#8230;感谢震宇，我的好兄弟，好朋友。感谢所有曾经给我过帮助的同事朋友们。 这1年找了2份工作，这在我以前看来是十分反常的。我很反感经常换工作的人，频繁的换工作即是对公司的不负责任也是对自己的懈怠。然而我犯了这个错误。 回嘉兴的第一份工作是在浙江衣派网络科技公司，一家不上进的公司。从刚开始给人一种勃勃生机的兴奋，到最后给人一种日落黄昏的伤感。不想过于主观的评价一家公司，这里感谢强哥，老陆，小朱，老吴，小彭。感谢技术部同事们给我的帮助和照顾。感谢你们包容我的缺点，祝愿新的一年，你们在各自的岗位上取得新的成就。 第二家公司就是现在的嘉兴麦包包网络科技公司。说实话我刚回嘉兴之前从来没听说过。虽然麦包包在电商领域已经较有名气。来麦包包的理由就简单，一是上一家公司的确经营不善，面临裁员的风险，其次就是这里有我非常感兴趣的项目，搭建自己的支付系统。前面这半年，基本快打磨掉我的积极性，整天准点下班，做些没有挑战的事情。人都懒散了。然而这个项目给了我兴奋的感觉。我太渴望有所提升。感谢我的胖师傅银鲨，二师弟银鲈.(呵呵，麦包包的企业文化的确做得不错,有意思的花名文化,虽然山寨但不错)。你们给了我太多太多的帮助。银鲨师傅的“苛刻”灭了偷懒的借口，重新点燃了我的斗志。银鲈童鞋的固执，坚持，避免了我很多bug的出现。然而好事多磨，年前的1个月，银鲨师傅的突然离职，让我感到希望的破灭，没有领路人的感觉真的不好受。随后项目的暂停和转移，让我有了离开麦包包的想法。12月被安排到日本项目组，我有种被打入冷宫的感觉。为了总监给我的希望，坚持了1个月。回头想来这1个月同样精彩。跟新的同事打了交道，虽然已经来了2个多月，但是除了跟银鲨和银鲈，没有和太多的同事沟通，想来有点可悲。感谢滕枣童鞋，很高兴与你的合作。这个月是轻松愉快的。感谢下糯米同学，你是我见过最有才华和实力的应届毕业生了。希望你在新一年里，新的公司取得更多的成就。年初之际总监重启了支付项目，今年这个将是我努力的目标和方向。 感谢下卷丹童鞋、木虱童鞋、戎麦童鞋、巴叶童鞋、灵猫童鞋、角蒿童鞋、银鲈童鞋、章木童鞋、腾枣童鞋、铁阕童鞋、青柠童鞋、戟天童鞋、白鱼童鞋、翠雀童鞋、戎草童鞋、海椒童鞋、蜂虎童鞋、蝎虎童鞋、龙猫童鞋、简草童鞋、洋姜童鞋、白鲩童鞋、蓝天童鞋、白苏童鞋、西柚童鞋、毛尖童鞋&#8230;..(排名按我座位的远近,方便我回想。并且在职的同事。保佑我都记全了) 感情 感情方面一直是我的弱项，25年来就没真正谈过一场恋爱。大学里我不想谈，更不敢谈。承担不起责任的我，没资格谈恋爱。所以我不后悔。这方面今年是可悲一年。一是曾经很喜欢的女生结婚了,我从头到尾都没有勇气去追求过，伤悔。二是好不容易相亲到一个比较中意的女生，准备踏踏实实一起走下去。但对方一句从来没有喜欢过我，把我打落了谷底。我不怪她，如果我能多关心关心她，也许结局会不一样。感情方面一直都是我很回避的方面，但2012年我会改正这一点。遇到喜欢的就尽力去追，&#8221;放开&#8221;的去追。不想以后来了有后悔。 财产 左边是全年的支出图，总体感觉每一笔钱都是有价值的。 理财方面非常的糟糕。今年基本亏损10%左右。还在坚持定存的习惯，投入财产的资金不多。总体亏损在1-2K之前。但和我2011年初制定的理财计划已经相差太多了。2011理财计划。感觉今年的亏损主要原因还是投机心太重，没有真正的肯去学习理财知识。以为读几本理财方面的书，就能理到财。其次今年全球的经济的确不景气。黄金大大起大落，给人当年中国股市崩盘的感觉。 &#160; 2012的展望 工作上，把东西做好，做漂亮。努力工作，早日升值加薪。 生活上，多做点力所能及的事情，少让爸妈操心。周末多学点菜，为将来做准备。 感情上，希望今年能找到心仪的女朋友，早日踏上婚姻的&#8221;坟墓&#8221;。 理财上，有空，踏踏实实学点经济常识，少点投机心，多点主观意念。 学习上，今年要好好学好英语。踏踏实实。把阅读和听力提升一个台阶。 身体上，有时间好好锻炼下自己，瘦巴巴的，像柴火一样。我是女人也不会喜欢。 2012欢迎我吧~</p>
 ]]></description>
			<content:encoded><![CDATA[<div style="clear:both; margin-top:5px; margin-bottom:5px;"></div><p>每年都给自己写个总结。写给将来的自己看。</p>
<p>不太会写文章，分几个方面总结下2011过去的一年。</p>
<p><strong>生活</strong></p>
<p>离开了生活了5年多的杭州。其实说是5年。但里面有3年大学生活，只有2年的工作。虽然是爸妈的意思，但我知道，其实是我自己的软弱。我害怕孤单的一直生活下去。每天上班下班。不知道前面的路在哪里。回嘉兴的这一年来感觉非常的放松，再也没有了那种漂泊孤单感觉，有着家人的关爱，重新滋润了我那干枯的心床。我不后悔！感谢小龚老师、小王老师、老蒋童鞋。曾经的照顾和关怀~</p>
<p><strong>工作</strong></p>
<p>告别了曾经共同奋斗过得同事们，告别了我最尊敬的王总。感谢你2年前给我一个走出大学的学生机会，让我不至于在茫茫的毕业潮中失去方向。在公司的这段日子是我毕生难忘的日子。你教会了我如何学习，如何沟通，如何写文档&#8230;&#8230;感谢震宇，我的好兄弟，好朋友。感谢所有曾经给我过帮助的同事朋友们。<br />
这1年找了2份工作，这在我以前看来是十分反常的。我很反感经常换工作的人，频繁的换工作即是对公司的不负责任也是对自己的懈怠。然而我犯了这个错误。<br />
回嘉兴的第一份工作是在浙江衣派网络科技公司，一家不上进的公司。从刚开始给人一种勃勃生机的兴奋，到最后给人一种日落黄昏的伤感。不想过于主观的评价一家公司，这里感谢强哥，老陆，小朱，老吴，小彭。感谢技术部同事们给我的帮助和照顾。感谢你们包容我的缺点，祝愿新的一年，你们在各自的岗位上取得新的成就。<br />
第二家公司就是现在的嘉兴麦包包网络科技公司。说实话我刚回嘉兴之前从来没听说过。虽然麦包包在电商领域已经较有名气。来麦包包的理由就简单，一是上一家公司的确经营不善，面临裁员的风险，其次就是这里有我非常感兴趣的项目，搭建自己的支付系统。前面这半年，基本快打磨掉我的积极性，整天准点下班，做些没有挑战的事情。人都懒散了。然而这个项目给了我兴奋的感觉。我太渴望有所提升。感谢我的胖师傅银鲨，二师弟银鲈.(呵呵，麦包包的企业文化的确做得不错,有意思的花名文化,虽然山寨但不错)。你们给了我太多太多的帮助。银鲨师傅的“苛刻”灭了偷懒的借口，重新点燃了我的斗志。银鲈童鞋的固执，坚持，避免了我很多bug的出现。然而好事多磨，年前的1个月，银鲨师傅的突然离职，让我感到希望的破灭，没有领路人的感觉真的不好受。随后项目的暂停和转移，让我有了离开麦包包的想法。12月被安排到日本项目组，我有种被打入冷宫的感觉。为了总监给我的希望，坚持了1个月。回头想来这1个月同样精彩。跟新的同事打了交道，虽然已经来了2个多月，但是除了跟银鲨和银鲈，没有和太多的同事沟通，想来有点可悲。感谢滕枣童鞋，很高兴与你的合作。这个月是轻松愉快的。感谢下糯米同学，你是我见过最有才华和实力的应届毕业生了。希望你在新一年里，新的公司取得更多的成就。年初之际总监重启了支付项目，今年这个将是我努力的目标和方向。<br />
感谢下卷丹童鞋、木虱童鞋、戎麦童鞋、巴叶童鞋、灵猫童鞋、角蒿童鞋、银鲈童鞋、章木童鞋、腾枣童鞋、铁阕童鞋、青柠童鞋、戟天童鞋、白鱼童鞋、翠雀童鞋、戎草童鞋、海椒童鞋、蜂虎童鞋、蝎虎童鞋、龙猫童鞋、简草童鞋、洋姜童鞋、白鲩童鞋、蓝天童鞋、白苏童鞋、西柚童鞋、毛尖童鞋&#8230;..(排名按我座位的远近,方便我回想。并且在职的同事。保佑我都记全了)</p>
<p><strong>感情<br />
</strong></p>
<p>感情方面一直是我的弱项，25年来就没真正谈过一场恋爱。大学里我不想谈，更不敢谈。承担不起责任的我，没资格谈恋爱。所以我不后悔。这方面今年是可悲一年。一是曾经很喜欢的女生结婚了,我从头到尾都没有勇气去追求过，伤悔。二是好不容易相亲到一个比较中意的女生，准备踏踏实实一起走下去。但对方一句从来没有喜欢过我，把我打落了谷底。我不怪她，如果我能多关心关心她，也许结局会不一样。感情方面一直都是我很回避的方面，但2012年我会改正这一点。遇到喜欢的就尽力去追，&#8221;放开&#8221;的去追。不想以后来了有后悔。</p>
<p><strong>财产</strong></p>
<p><a href="http://fredzhu.com/wp-content/uploads/2012/01/20120108212029.jpg" rel="lightbox[300131]" title="2011全年支出"><img class="alignleft size-medium wp-image-300136" title="2011全年支出" src="http://fredzhu.com/wp-content/uploads/2012/01/20120108212029-300x183.jpg" alt="" width="300" height="183" /></a>左边是全年的支出图，总体感觉每一笔钱都是有价值的。<br />
理财方面非常的糟糕。今年基本亏损10%左右。还在坚持定存的习惯，投入财产的资金不多。总体亏损在1-2K之前。但和我2011年初制定的理财计划已经相差太多了。<a href="fredzhu.com/2011/02/2011-financial-pla/">2011理财计划</a>。感觉今年的亏损主要原因还是投机心太重，没有真正的肯去学习理财知识。以为读几本理财方面的书，就能理到财。其次今年全球的经济的确不景气。黄金大大起大落，给人当年中国股市崩盘的感觉。</p>
<p>&nbsp;</p>
<p><strong>2012的展望</strong></p>
<p>工作上，把东西做好，做漂亮。努力工作，早日升值加薪。<br />
生活上，多做点力所能及的事情，少让爸妈操心。周末多学点菜，为将来做准备。<br />
感情上，希望今年能找到心仪的女朋友，早日踏上婚姻的&#8221;坟墓&#8221;。<br />
理财上，有空，踏踏实实学点经济常识，少点投机心，多点主观意念。<br />
学习上，今年要好好学好英语。踏踏实实。把阅读和听力提升一个台阶。<br />
身体上，有时间好好锻炼下自己，瘦巴巴的，像柴火一样。我是女人也不会喜欢。</p>
<h1><strong>2012欢迎我吧~</strong></h1>
<p><a href="http://fredzhu.com/wp-content/uploads/2012/01/maibao.jpg" rel="lightbox[300131]" title="麦宝"><img class="alignnone size-full wp-image-300137" title="麦宝" src="http://fredzhu.com/wp-content/uploads/2012/01/maibao.jpg" alt="" width="199" height="261" /></a></p>
<div style="float:left"><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><div style="clear:both; margin-top:5px; margin-bottom:5px;"></div>]]></content:encoded>
			<wfw:commentRss>http://fredzhu.com/2012/01/summary-me-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>wordpress图片搬家脚本</title>
		<link>http://fredzhu.com/2011/12/wordpress-move-picture/</link>
		<comments>http://fredzhu.com/2011/12/wordpress-move-picture/#comments</comments>
		<pubDate>Sun, 25 Dec 2011 10:58:12 +0000</pubDate>
		<dc:creator>fred</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://fredzhu.info/?p=300111</guid>
		<description><![CDATA[<p>历经几次换域名,以及从GAE-wordpress造成不少历史遗留的图片分布在不同域名或gae目录下。 主要分布 http://oldres.fengsage.com http://www.fengsage.com http://fensageblog.appspot.com 原来使用代码实现图片代理访问。但自己越看越不爽。索性写个脚本一次性把原来的图片下载到wordpress本地。并且更新数据库。主要是圣诞节闲的蛋疼。 代码有不少问题： 不用php,因为懒得看wordpress插件制作。 因为是python脚本,所以必须是有执行python的权限 没有生成wordpress media记录。不能后台编辑多媒体 wordpress插件实现： http://wordpress.org/extend/plugins/velvet-blues-update-urls/  等发现的时候脚本已经写好了。悲哀～～ 脚本笔记简单。分享下。</p>
 ]]></description>
			<content:encoded><![CDATA[<div style="clear:both; margin-top:5px; margin-bottom:5px;"></div><p>历经几次换域名,以及从GAE-wordpress造成不少历史遗留的图片分布在不同域名或gae目录下。</p>
<p>主要分布<br />
<span style="color: #993300;">http://oldres.fengsage.com</span><br />
<span style="color: #993300;"> http://www.fengsage.com</span><br />
<span style="color: #993300;"> http://fensageblog.appspot.com</span></p>
<p>原来使用代码实现图片代理访问。但自己越看越不爽。索性写个脚本一次性把原来的图片下载到wordpress本地。并且更新数据库。主要是圣诞节闲的蛋疼。</p>
<p>代码有不少问题：</p>
<ol>
<li>不用php,因为懒得看wordpress插件制作。</li>
<li>因为是python脚本,所以必须是有执行python的权限</li>
<li>没有生成wordpress media记录。不能后台编辑多媒体</li>
</ol>
<p>wordpress插件实现：</p>
<p><a href="http://wordpress.org/extend/plugins/velvet-blues-update-urls/">http://wordpress.org/extend/plugins/velvet-blues-update-urls/</a>  等发现的时候脚本已经写好了。悲哀～～</p>
<p>脚本笔记简单。分享下。</p><pre class="crayon-plain-tag">#!/usr/bin/env python
# --*-- encoding:utf-8 --*--
'''
Created on 2011-12-25
@author: fred &lt;fredzhu.info&gt;
'''

import MySQLdb
import re
import urllib
import time
import os

WP_POST_CONTENT = u&quot;wp_posts&quot;
SIMPLE_IMG_URL = r'&lt;img[^/]*src=&quot;([^&quot;]*)&quot;[^/]*/&gt;' 
NEW_IMG_URL = u''
DOWNLOAD_PATH = u'wp-content/uploads/%s'%(time.strftime('%m/%d', time.localtime(time.time())))

REPLACE_LIST = ['http://oldres.fengsage.com','../media','http://www.fengsage.com']

conn = MySQLdb.connect(host=&quot;localhost&quot;,
                         user=&quot;root&quot;,
                         passwd=&quot;zhufeng&quot;,
                         db=&quot;wordpress&quot;,
                         charset='utf8')


def get_post_list():
    cursor = conn.cursor()
    cursor.execute(&quot;SET NAMES utf8&quot;)
    cursor.execute(&quot;select * from %s&quot;%WP_POST_CONTENT);
    return cursor.fetchall()

def find_img_urls(str):
    pattern = re.compile(SIMPLE_IMG_URL) 
    match = pattern.findall(str)
    if match:
        return match
    return None

def process_imgs(img_urls,replace):
    result = {}
    for img in img_urls:
        for rp in replace:
            if img.find(rp)&gt;=0:
                print &quot;\tdownload picture&quot;
                new_img_ath = download_img(img)
                result.update({img:new_img_ath})
    return result
                
def download_img(img_url):
    IMG_NAME_REG = r'([^./]*).(png|jpg|gif|jpeg|bmp)'
    m = re.findall(IMG_NAME_REG, img_url)
    if m:
        name,suf = m[0]
        if os.path.isdir(DOWNLOAD_PATH) == False:
            os.makedirs(DOWNLOAD_PATH)
        file_path = u'%s/%s.%s'%(DOWNLOAD_PATH,name,suf)
        downloaded_image = file(file_path.encode('utf-8'), &quot;wb&quot;)
        try:
            image_on_web = urllib.urlopen(img_url.encode('utf-8'))
            while True:
                buf = image_on_web.read(65536)
                if len(buf) == 0:
                    break
                downloaded_image.write(buf)
            downloaded_image.close()
            image_on_web.close()
            return file_path
        except:
            print '\tdownload img failture:%s'%img_url

def refresh_content(post_content,result):
    for k in result.keys():
        post_content = post_content.replace(k,'%s/%s'%(NEW_IMG_URL,result[k]))
    return post_content

def update_content(post_id,post_content):
    sql = &quot;update &quot;+WP_POST_CONTENT+&quot; set post_content=%s where ID=%s&quot;
    cursor = conn.cursor()
    cursor.execute(&quot;SET NAMES utf8&quot;)
    cursor.execute(sql,(post_content,post_id))
    
    
def go():
    post_list = get_post_list()
    for post in post_list:
        post_id = post[0]
        post_content = post[4]
        post_title = post[5]
        if post_id and post_content and post_title:
            print &quot;process article ID:%s&quot;%(post_id)
            img_urls = find_img_urls(post_content)
            if img_urls:
                result = process_imgs(img_urls,REPLACE_LIST)
                if result and len(result)&gt;0:
                    post_content = refresh_content(post_content,result)
                    try:
                        update_content(post_id,post_content)
                    except Exception, e:
                        print 'update database failture:%s'%e
                        

if __name__ == '__main__': 
    print go()</pre><p></p>
<div style="float:left"><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><div style="clear:both; margin-top:5px; margin-bottom:5px;"></div>]]></content:encoded>
			<wfw:commentRss>http://fredzhu.com/2011/12/wordpress-move-picture/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>javascript实用模板引擎</title>
		<link>http://fredzhu.com/2011/12/javascript-micro-templating/</link>
		<comments>http://fredzhu.com/2011/12/javascript-micro-templating/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 13:39:19 +0000</pubDate>
		<dc:creator>fred</dc:creator>
				<category><![CDATA[修炼之旅]]></category>
		<category><![CDATA[算法介绍]]></category>
		<category><![CDATA[转载]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[模板]]></category>

		<guid isPermaLink="false">http://www.fengsage.com/?p=300094</guid>
		<description><![CDATA[<p>John Resig 开发的一个简易模板引擎,配合json非常的实用。 很少的一点代码。但功能非常实用。 准备json和一个模板即可</p>
 ]]></description>
			<content:encoded><![CDATA[<div style="clear:both; margin-top:5px; margin-bottom:5px;"></div><p><a href="http://ejohn.org/blog/javascript-micro-templating/">John Resig</a> 开发的一个简易模板引擎,配合json非常的实用。</p><pre class="crayon-plain-tag">// Simple JavaScript Templating
// John Resig - http://ejohn.org/ - MIT Licensed
(function(){
  var cache = {};
 
  this.tmpl = function tmpl(str, data){
    // Figure out if we're getting a template, or if we need to
    // load the template - and be sure to cache the result.
    var fn = !/\W/.test(str) ?
      cache[str] = cache[str] ||
        tmpl(document.getElementById(str).innerHTML) :
     
      // Generate a reusable function that will serve as a template
      // generator (and which will be cached).
      new Function(&quot;obj&quot;,
        &quot;var p=[],print=function(){p.push.apply(p,arguments);};&quot; +
       
        // Introduce the data as local variables using with(){}
        &quot;with(obj){p.push('&quot; +
       
        // Convert the template into pure JavaScript
        str
          .replace(/[\r\t\n]/g, &quot; &quot;)
          .split(&quot;&lt;%&quot;).join(&quot;\t&quot;)
          .replace(/((^|%&gt;)[^\t]*)'/g, &quot;$1\r&quot;)
          .replace(/\t=(.*?)%&gt;/g, &quot;',$1,'&quot;)
          .split(&quot;\t&quot;).join(&quot;');&quot;)
          .split(&quot;%&gt;&quot;).join(&quot;p.push('&quot;)
          .split(&quot;\r&quot;).join(&quot;\\'&quot;)
      + &quot;');}return p.join('');&quot;);
   
    // Provide some basic currying to the user
    return data ? fn( data ) : fn;
  };
})();</pre><p>很少的一点代码。但功能非常实用。</p>
<p>准备json和一个模板即可</p><pre class="crayon-plain-tag">&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js&quot;&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot;&gt;// &lt;![CDATA[
$(document).ready(function(){
	var json = 
		{
			&quot;key&quot;:&quot;1&quot;,
			&quot;datas&quot;:
				[{&quot;k&quot;:&quot;v1&quot;,&quot;k2&quot;:&quot;v2&quot;}],
			&quot;test_if&quot;:true,
			&quot;test_for_datas&quot;:[1,2,3,4,5,6,7,8,9,10]
		};
	var tmp = 	'key:&lt;%=key%&gt;&lt;/br&gt;'+
				'datas:
&lt;ul&gt;
	&lt;li&gt;&lt;%=datas[0].k%&gt;&lt;/li&gt;
	&lt;li&gt;&lt;%=datas[0].k2%&gt;&lt;/li&gt;
&lt;/ul&gt;
'+
				'test_if:'+
				'&lt;%if(test_if){%&gt;'+
				'成立'+
				'&lt;%}else{%&gt;'+
				'失败'+
				'&lt;%}%&gt;'+
				'&lt;/br&gt;'+
				'循环:'+
				'&lt;%for(var i=0;i&lt;test_for_datas.length;i++){%&gt;'+
					'&lt;%=test_for_datas[i]%&gt;'+
				'&lt;%}%&gt;';

	$(&quot;#conent&quot;).html(tmpl(tmp,json));
});
// ]]&gt;&lt;/script&gt;</pre><p></p>
<div id="conent"></div>
<p><a href="/wp-content/uploads/12/25/TM截图未命名.png" rel="lightbox[300094]" title="jquery simple template demo"><img class="alignnone size-full wp-image-300096" title="jquery simple template demo" src="/wp-content/uploads/12/25/TM截图未命名.png" alt="jquery simple template demo" width="230" height="180" /></a></p>
<div style="float:left"><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><div style="clear:both; margin-top:5px; margin-bottom:5px;"></div>]]></content:encoded>
			<wfw:commentRss>http://fredzhu.com/2011/12/javascript-micro-templating/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>zookeeper资料汇集</title>
		<link>http://fredzhu.com/2011/12/zookeeper-article-list/</link>
		<comments>http://fredzhu.com/2011/12/zookeeper-article-list/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 01:07:03 +0000</pubDate>
		<dc:creator>fred</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[修炼之旅]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[paxos]]></category>
		<category><![CDATA[zookeeper]]></category>

		<guid isPermaLink="false">http://www.fengsage.com/?p=300084</guid>
		<description><![CDATA[<p>这几天看了下zookeeper的东西。收获多多。感谢国人的分享精神。使得这一产品能被更多人了解。 zookeeper基础配置与入门：http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/ agapple学习笔记系列：http://agapple.iteye.com/blog/1292473 taobao通用产品团队：http://rdc.taobao.com/team/jm/archives/448 Paxos算法：http://zh.wikipedia.org/zh/Paxos%E7%AE%97%E6%B3%95 工具：https://github.com/killme2008/node-zk-browser 淘宝团队开发的一个zookeeper节点管理工具。nodejs开发。功能简单。基本实现了zookeeper命令行的功能。 文档是最佳的知识沉淀呀~ &#160; &#160;</p>
 ]]></description>
			<content:encoded><![CDATA[<div style="clear:both; margin-top:5px; margin-bottom:5px;"></div><p>这几天看了下zookeeper的东西。收获多多。感谢国人的分享精神。使得这一产品能被更多人了解。</p>
<p>zookeeper基础配置与入门：<a href="http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/">http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/</a></p>
<p>agapple学习笔记系列：<a href="http://agapple.iteye.com/blog/1292473">http://agapple.iteye.com/blog/1292473</a></p>
<p>taobao通用产品团队：<a href="http://rdc.taobao.com/team/jm/archives/448">http://rdc.taobao.com/team/jm/archives/448</a></p>
<p>Paxos算法：<a href="http://zh.wikipedia.org/zh/Paxos%E7%AE%97%E6%B3%95">http://zh.wikipedia.org/zh/Paxos%E7%AE%97%E6%B3%95</a></p>
<p>工具：<a href="https://github.com/killme2008/node-zk-browser">https://github.com/killme2008/node-zk-browser</a> 淘宝团队开发的一个zookeeper节点管理工具。nodejs开发。功能简单。基本实现了zookeeper命令行的功能。</p>
<p>文档是最佳的知识沉淀呀~</p>
<div class="wp-caption alignnone" style="width: 89px"><img title="zookeeper" src="http://zookeeper.apache.org/images/zookeeper_small.gif" alt="apache zookeeper" width="79" height="112" /><p class="wp-caption-text"> zookeeper</p></div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div style="float:left"><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><div style="clear:both; margin-top:5px; margin-bottom:5px;"></div>]]></content:encoded>
			<wfw:commentRss>http://fredzhu.com/2011/12/zookeeper-article-list/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jmock2学习笔记-续</title>
		<link>http://fredzhu.com/2011/12/jmock2-notes-2/</link>
		<comments>http://fredzhu.com/2011/12/jmock2-notes-2/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 15:11:26 +0000</pubDate>
		<dc:creator>fred</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jmock]]></category>

		<guid isPermaLink="false">http://www.fengsage.com/?p=300075</guid>
		<description><![CDATA[<p>总结下这几天初步学习mock的心得. 文中大部分内容来自官网文档. 创建Mock对象 创建Mock Expections expections 这里指的是jmock在不同情况下的预期值。expections 是jmcok的最重要部分之一。可以模拟用户在不同情况下返回不同的结果。 &#60;expections block&#62;这里是可以设置多个expections 。 Expectations expections的结构如下： 上面是一个通用的结构。所有expecions都采用相同或更简洁的结构。 invocation-count mock调用频率。oneOf表示调用一次后这个expections即失效。 mock-object mock对象。即上面Mockery创建的对象。 method 用mock代替实现接口的一个方法。所以mock必须使用接口编程。 argument-constraints mock参数条件。即mock指定方法的参数。 when &#8230; will&#8230;then &#8230; 类似于if .. else&#8230; 这样的语句。简单的条件表达式 action mock符合条件后,执行操作。一般是返回结果。或者抛出异常 state-machine 条件表达式。 下面详细讲解下expectations各个部分。 Invocation Count oneOf 只执行一次 exactly(n).of &#8230;
<p class="read-more"><a href="http://fredzhu.com/2011/12/jmock2-notes-2/">继续阅读 &#187;</a></p>
 ]]></description>
			<content:encoded><![CDATA[<div style="clear:both; margin-top:5px; margin-bottom:5px;"></div><p>总结下这几天初步学习mock的心得. 文中大部分内容来自官网文档.</p>
<h2>创建Mock对象</h2>
<p></p><pre class="crayon-plain-tag">Mockery context = new Mockery();
Turtle turtle = context.mock(Turtle.class);
Turtle turtle2 = context.mock(Turtle.class, &quot;turtle2&quot;);</pre><p></p>
<h2>创建Mock Expections</h2>
<p></p><pre class="crayon-plain-tag">... create mock objects ...
public void testSomeAction() {
    ... set up ...
    context.checking(new Expectations() {{
        ... &amp;lt;expections block&amp;gt; ...
    }});
   ... call code being tested ...
}</pre><p>expections 这里指的是jmock在不同情况下的预期值。expections 是jmcok的最重要部分之一。可以模拟用户在不同情况下返回不同的结果。</p>
<p><span style="color: #ff0000;">&lt;expections block&gt;</span>这里是可以设置多个expections 。</p>
<h2>Expectations</h2>
<p>expections的结构如下：</p><pre class="crayon-plain-tag">invocation-count (mock-object).method(argument-constraints);
    inSequence(sequence-name);
    when(state-machine.is(state-name));
    will(action);
    then(state-machine.is(new-state-name));</pre><p>上面是一个通用的结构。所有expecions都采用相同或更简洁的结构。</p>
<table>
<tbody>
<tr>
<td>invocation-count</td>
<td>mock调用频率。oneOf表示调用一次后这个expections即失效。</td>
</tr>
<tr>
<td>mock-object</td>
<td>mock对象。即上面Mockery创建的对象。</td>
</tr>
<tr>
<td>method</td>
<td>用mock代替实现接口的一个方法。所以mock必须使用接口编程。</td>
</tr>
<tr>
<td>argument-constraints</td>
<td>mock参数条件。即mock指定方法的参数。</td>
</tr>
<tr>
<td>when &#8230; will&#8230;then &#8230;</td>
<td>类似于if .. else&#8230; 这样的语句。简单的条件表达式</td>
</tr>
<tr>
<td>action</td>
<td>mock符合条件后,执行操作。一般是返回结果。或者抛出异常</td>
</tr>
<tr>
<td>state-machine</td>
<td>条件表达式。</td>
</tr>
</tbody>
</table>
<p>下面详细讲解下expectations各个部分。</p>
<h3>Invocation Count</h3>
<table>
<tbody>
<tr>
<td>oneOf</td>
<td>只执行一次</td>
</tr>
<tr>
<td>exactly(<var>n</var>).of</td>
<td>执行指定n次</td>
</tr>
<tr>
<td>atLeast(<var>n</var>).of</td>
<td>至少执行n次</td>
</tr>
<tr>
<td>atMost(<var>n</var>).of</td>
<td>最多执行n次</td>
</tr>
<tr>
<td>between(<var>min</var>,<var>max</var>).of</td>
<td>可以执行min-max次</td>
</tr>
<tr>
<td>allowing</td>
<td>允许执行,不受限制</td>
</tr>
<tr>
<td>ignoring</td>
<td>功能同allowing类似。这里主要字面上区分allowing</td>
</tr>
<tr>
<td>never</td>
<td>不允许执行</td>
</tr>
</tbody>
</table>
<h3>Actions</h3>
<table>
<tbody>
<tr>
<td>will(returnValue(<var>v</var>))</td>
<td>返回一个值。Object类型任意。集合类型不建议这里返回。虽然也可以</td>
</tr>
<tr>
<td>will(returnIterator(<var>c</var>))</td>
<td>返回一个集合类型的值。</td>
</tr>
<tr>
<td>will(returnIterator(<var>v<sub>1</sub></var>, <var>v<sub>2</sub></var>, &#8230;, <var>v<sub>n</sub></var>))</td>
<td>返回一个集合类型的值。可以用多个,来分隔。</td>
</tr>
<tr>
<td>will(throwException(<var>e</var>))</td>
<td>抛出一个异常。</td>
</tr>
<tr>
<td>will(doAll(<var>a<sub>1</sub></var>, <var>a<sub>2</sub></var>, &#8230;, <var>a<sub>n</sub></var>))</td>
<td>嵌套执行多个actoin。不常用。</td>
</tr>
</tbody>
</table>
<h3>Sequences</h3>
<p>设定mock方法调用的顺序。简单的看下面代码片段。<br />
定义了先save后countUser。调用的时候也必须找这个顺序。否则用例失败。</p><pre class="crayon-plain-tag">public void testCountUserSequences() {
                final Sequence testSequence = mockery.sequence(&quot;testSequence&quot;);

                final User _user = genUser();

                mockery.checking(new Expectations() {
                        {
                                oneOf(userDao).save(_user);
                                inSequence(testSequence);
                                will(returnValue(_user));

                                oneOf(userDao).countUser();
                                inSequence(testSequence);
                                will(returnValue(1));
                        }
                });

                assertEquals(userService.save(_user).getUsername(), &quot;fengsage&quot;);
                assertEquals(userService.countUser(), 1);
        }</pre><p></p>
<div style="float:left"><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><div style="clear:both; margin-top:5px; margin-bottom:5px;"></div>]]></content:encoded>
			<wfw:commentRss>http://fredzhu.com/2011/12/jmock2-notes-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>jmock2学习笔记</title>
		<link>http://fredzhu.com/2011/12/jmock-nodes-1/</link>
		<comments>http://fredzhu.com/2011/12/jmock-nodes-1/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 14:07:03 +0000</pubDate>
		<dc:creator>fred</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jmock]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.fengsage.com/?p=300064</guid>
		<description><![CDATA[<p>目前晚上学习jmock。 Issue: spring+annotations使用jmock 遇到了这个场景。stackoverflow上有人问过这个问题,这里贴一下。 http://stackoverflow.com/questions/1638911/mock-object-and-spring-annotations 关键是使用ReflectionTestUtils的方法。这个方法在spring-test工程的相关jar包。 Issue:入参对象时。mock表达式传入对象必须和实际传入对象为同一句柄。 共用一个_user句柄。否则报错。 Issues:jmock一个异常错误 推荐链接：http://superleo.iteye.com/blog/143493 相关:jmock2学习笔记-续</p>
 ]]></description>
			<content:encoded><![CDATA[<div style="clear:both; margin-top:5px; margin-bottom:5px;"></div><p>目前晚上学习jmock。</p>
<p><strong>Issue:</strong> <span style="color: #ff0000;">spring+annotations使用jmock</span></p>
<p>遇到了这个场景。stackoverflow上有人问过这个问题,这里贴一下。</p>
<p><a href="http://stackoverflow.com/questions/1638911/mock-object-and-spring-annotations">http://stackoverflow.com/questions/1638911/mock-object-and-spring-annotations</a></p>
<p>关键是使用ReflectionTestUtils的方法。这个方法在spring-test工程的相关jar包。</p><pre class="crayon-plain-tag">...
    @Autowired
    private UserService	userService;
    private UserDao	userDao	= null;
    ...
    ReflectionTestUtils.setField(userService, &quot;userDao&quot;, userDao, UserDao.class);
    ...</pre><p><strong>Issue:</strong><span style="color: #ff0000;">入参对象时。mock表达式传入对象必须和实际传入对象为同一句柄。</span></p><pre class="crayon-plain-tag">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;
    final User _user = genUser();

    mockery.checking(new Expectations() {
        {
            one(userDao).queryUser(_user);
            List&amp;lt;User&amp;gt; userList = new ArrayList&amp;lt;User&amp;gt;();
            userList.add(genUser());
            userList.add(genUser());
            will(returnValue(userList));
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}
    });

    List&amp;lt;User&amp;gt; users = userService.queryUser(_user);</pre><p>共用一个_user句柄。否则报错。</p>
<p><strong>Issues:</strong><span style="color: #ff0000;">jmock一个异常错误</span></p><pre class="crayon-plain-tag">will(throwException(new RuntimeException(&quot;test exception&quot;)));</pre><p>推荐链接：<a href="http://superleo.iteye.com/blog/143493">http://superleo.iteye.com/blog/143493</a></p>
<p>相关:<a href="http://fredzhu.info/2011/12/jmock2-notes-2/" target="_blank">jmock2学习笔记-续</a></p>
<div style="float:left"><!-- JiaThis Button BEGIN -->
<div id="jiathis_style_32x32">
	<a class="jiathis_button_qzone"></a>
	<a class="jiathis_button_tsina"></a>
	<a class="jiathis_button_tqq"></a>
	<a class="jiathis_button_renren"></a>
	<a class="jiathis_button_kaixin001"></a>
	<a href="http://www.jiathis.com/share/" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END --></div><div style="clear:both; margin-top:5px; margin-bottom:5px;"></div>]]></content:encoded>
			<wfw:commentRss>http://fredzhu.com/2011/12/jmock-nodes-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

