<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[蕲春人 - 软件开发]]></title>
  <link href="http://qichunren.github.com/atom.xml" rel="self"/>
  <link href="http://qichunren.github.com/"/>
  <updated>2012-05-17T15:09:17+08:00</updated>
  <id>http://qichunren.github.com/</id>
  <author>
    <name><![CDATA[qichunren]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[怎么样从git提交历史里永久删除一个文件?]]></title>
    <link href="http://qichunren.github.com/blog/2012/05/17/how-to-remove-a-file-from-git-history-forever/"/>
    <updated>2012-05-17T15:04:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2012/05/17/how-to-remove-a-file-from-git-history-forever</id>
    <content type="html"><![CDATA[<p>需要整理</p>

<h2>参考资料</h2>

<ul>
<li><a href="http://help.github.com/remove-sensitive-data/">Remove sensitive data</a></li>
<li><a href="http://stackoverflow.com/questions/872565/how-do-i-remove-sensitive-files-from-gits-history">How do I remove sensitive files from git&#8217;s history</a></li>
<li><a href="http://dound.com/2009/04/git-forever-remove-files-or-folders-from-history/">git: forever remove files or folders from history</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[通过update-rc.d来管理Ubuntu系统的自动启动程序]]></title>
    <link href="http://qichunren.github.com/blog/2012/03/14/how-to-managing-services-with-update-rc-dot-d/"/>
    <updated>2012-03-14T11:30:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2012/03/14/how-to-managing-services-with-update-rc-dot-d</id>
    <content type="html"><![CDATA[<p>转载, 并记下我的使用心得。</p>

<p>Linux services can be started, stopped and reloaded with the use of scripts stocked in /etc/init.d/.
However, during start up or when changing runlevel, those scripts are searched in /etc/rcX.d/ where X is the runlevel number.
This tutorial will explain how one can activate, deactivate or modify a service start up.
When installing a new service under debian, the default is to enable it. So for instance, if you just installed apache2 package, after you installed it, apache service will be started and so will it be upon the next reboots.
If you do not use apache all the time, you might want to disable this service from starting up upon boot up and simply start it manually when you actually need it by running this command:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>/etc/init.d/apache2 start</span></code></pre></td></tr></table></div></figure>


<p>You could either disable this service on boot up by removing any symbolic links in <strong><em>/etc/rcX.d/SYYapache2</em></strong> or by using <strong>update-rc.d</strong>.
The advantage of using update-rc.d is that it will take care of removing/adding any required links to /etc/init.d automatically.
Taking apache2 as an example, let&#8217;s examine how /etc/rcX.d is looking like:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># ls -l /etc/rc?.d/*apache2
</span><span class='line'>lrwxrwxrwx 1 root root 17 2007-07-05 22:51 /etc/rc0.d/K91apache2 -&gt; ../init.d/apache2
</span><span class='line'>lrwxrwxrwx 1 root root 17 2007-07-05 22:51 /etc/rc1.d/K91apache2 -&gt; ../init.d/apache2
</span><span class='line'>lrwxrwxrwx 1 root root 17 2007-07-05 22:51 /etc/rc2.d/S91apache2 -&gt; ../init.d/apache2
</span><span class='line'>lrwxrwxrwx 1 root root 17 2007-07-05 22:51 /etc/rc3.d/S91apache2 -&gt; ../init.d/apache2
</span><span class='line'>lrwxrwxrwx 1 root root 17 2007-07-05 22:51 /etc/rc4.d/S91apache2 -&gt; ../init.d/apache2
</span><span class='line'>lrwxrwxrwx 1 root root 17 2007-07-05 22:51 /etc/rc5.d/S91apache2 -&gt; ../init.d/apache2
</span><span class='line'>lrwxrwxrwx 1 root root 17 2007-07-05 22:51 /etc/rc6.d/K91apache2 -&gt; ../init.d/apache2</span></code></pre></td></tr></table></div></figure>


<p>As you can see, for runlevels 0, 1 and 6 there is a K at the beginning of the link, for runlevels 2, 3, 4 and 5, there is a S. Those two letters stands for Kill and Start.
On Debian and Ubuntu, runlevels 2, 3, 4 and 5 are multi-users runlevels.
Runlevel 0 is Halt.
Runlevel 1 is single user mode
Runlevel 6 is reboot</p>

<h3>1. Removing A Service</h3>

<p>If you want to totally disable apache2 service by hand, you would need to delete every single link in /etc/rcX.d/. Using <strong>update-rc.d</strong> it is as simple as:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>update-rc.d -f apache2 remove</span></code></pre></td></tr></table></div></figure>


<p>The use of <strong><em>-f</em></strong> is to force the removal of the symlinks even if there is still /etc/init.d/apache2.</p>

<pre><code>    Note: This command will only disable the service until next time the service is upgraded. If you want to make sure the service won't be re-enabled upon upgrade, you should also type the following:
    # update-rc.d apache2 stop 80 0 1 2 3 4 5 6 .
</code></pre>

<h3>2. Adding A Service</h3>

<h4>2.1. Default Priorities</h4>

<p>Now, if you want to re-add this service to be started on boot up, you can simply use:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># update-rc.d apache2 defaults
</span><span class='line'>Adding system startup for /etc/init.d/apache2 ...
</span><span class='line'>/etc/rc0.d/K20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc1.d/K20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc6.d/K20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc2.d/S20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc3.d/S20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc4.d/S20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc5.d/S20apache2 -&gt; ../init.d/apache2</span></code></pre></td></tr></table></div></figure>


<h4>2.2. Custom Priorities</h4>

<p>But as you can see, the default value is 20 which is pretty different than 91 &#8230; a S20 link is started before a S91 and and K91 is kill before K20.
To force apache2 to be started with priorities 91 for both Start and Kill, we need to use the following command:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># update-rc.d apache2 defaults 91
</span><span class='line'>Adding system startup for /etc/init.d/apache2 ...
</span><span class='line'>/etc/rc0.d/K91apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc1.d/K91apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc6.d/K91apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc2.d/S91apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc3.d/S91apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc4.d/S91apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc5.d/S91apache2 -&gt; ../init.d/apache2</span></code></pre></td></tr></table></div></figure>


<h3>2.3. Different Priorities For Start And Kill</h3>

<p> Alternatively, if you want to set different priorities for Start than for Kill, let say Start with 20 and Kill with 80, you will need to run:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># update-rc.d apache2 defaults 20 80
</span><span class='line'>Adding system startup for /etc/init.d/apache2 ...
</span><span class='line'>/etc/rc0.d/K80apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc1.d/K80apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc6.d/K80apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc2.d/S20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc3.d/S20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc4.d/S20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc5.d/S20apache2 -&gt; ../init.d/apache2</span></code></pre></td></tr></table></div></figure>


<h2>3. Specifying Custom Runlevels</h2>

<p>Finally, if you only want to Start and Kill on specific runlevels, like for instance starting apache with priority 20 on runlevels 2, 3, 4 and 5 and Kill with priority 80 on runlevels 0, 1 and 6:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># update-rc.d apache2 start 20 2 3 4 5 . stop 80 0 1 6 .
</span><span class='line'>Adding system startup for /etc/init.d/apache2 ...
</span><span class='line'>/etc/rc0.d/K80apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc1.d/K80apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc6.d/K80apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc2.d/S20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc3.d/S20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc4.d/S20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc5.d/S20apache2 -&gt; ../init.d/apache2</span></code></pre></td></tr></table></div></figure>


<p>Or, to start with priority 20 for runlevel 2, 3 and 4 and priority 30 for runlevel 5 and kill with priority 80 for runlevel 0, 1 and 6:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># update-rc.d apache2 start 20 2 3 4 . start 30 5 . stop 80 0 1 6 .
</span><span class='line'>Adding system startup for /etc/init.d/apache2 ...
</span><span class='line'>/etc/rc0.d/K80apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc1.d/K80apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc6.d/K80apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc2.d/S20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc3.d/S20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc4.d/S20apache2 -&gt; ../init.d/apache2
</span><span class='line'>/etc/rc5.d/S30apache2 -&gt; ../init.d/apache2</span></code></pre></td></tr></table></div></figure>


<h2>我的总结</h2>

<p>通过 update-rc.d 来管理Linux下开机自动运行，的确很方便，但是我在实际部署实践中，还是遇到了一些问题，导致开机后没有正常自动启动，但是手工通过service xxx start可以启动。我经过排查发现，原因是在Linux系统启动中，在执行/etc/init.d/中的脚本时，此时系统有可能没有加载好系统中的PATH变量，所以需要在init.d脚本中手工指定，对于使用Ruby脚本写的程序，需要GEM_HOME\GEM_PATH等环境变量，我这里是用RVM来管理Ruby的，这是我使用的：</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>PATH="/usr/local/rvm/gems/ruby-1.9.2-p290/bin:/usr/local/rvm/rubies/ruby-1.9.2-p290/bin:/usr/local/rvm/bin:/opt/node/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
</span><span class='line'>RUBY_VERSION="ruby-1.9.2-p290"
</span><span class='line'>GEM_HOME="/usr/local/rvm/gems/ruby-1.9.2-p290"
</span><span class='line'>GEM_PATH="/usr/local/rvm/gems/ruby-1.9.2-p290:/usr/local/rvm/gems/ruby-1.9.2-p290@global"
</span><span class='line'>export PATH=$PATH
</span><span class='line'>export RUBY_VERSION=$RUBY_VERSION
</span><span class='line'>export GEM_HOME=$GEM_HOME
</span><span class='line'>export GEM_PATH=$GEM_PATH</span></code></pre></td></tr></table></div></figure>


<p> 另外还有一些其它的变量（如果你的启动程序需要），也需要手工指定，如在Ruby 1.9中，就有可能需要指定，比如说unicorn启动脚本：</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>export LANG='en_US.UTF-8'</span></code></pre></td></tr></table></div></figure>


<p>最后附上一个常用的init.d启动脚本的样本：</p>

<figure class='code'><figcaption><span>/etc/init.d/ntgps  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c">#!/bin/sh</span>
</span><span class='line'><span class="c">### BEGIN INIT INFO</span>
</span><span class='line'><span class="c"># Provides:          gps</span>
</span><span class='line'><span class="c"># Required-Start:    $syslog $remote_fs $network</span>
</span><span class='line'><span class="c"># Required-Stop:     $syslog $remote_fs $network</span>
</span><span class='line'><span class="c"># Should-Start:      fam</span>
</span><span class='line'><span class="c"># Should-Stop:       fam</span>
</span><span class='line'><span class="c"># Default-Start:     2 3 4 5</span>
</span><span class='line'><span class="c"># Default-Stop:      0 1 6</span>
</span><span class='line'><span class="c"># Short-Description: Start the gps.</span>
</span><span class='line'><span class="c">### END INIT INFO</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="nv">PATH</span><span class="o">=</span>/usr/local/rvm/gems/ruby-1.9.2-p290/bin:/usr/local/rvm/gems/ruby-1.9.2-p290@global/bin:/usr/local/rvm/rubies/ruby-1.9.2-p290/bin:/usr/local/rvm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
</span><span class='line'><span class="nv">DAEMON</span><span class="o">=</span>/www/georgia/current/lib/gps/gps.rb
</span><span class='line'><span class="nv">NAME</span><span class="o">=</span>ntgps
</span><span class='line'><span class="nv">DESC</span><span class="o">=</span><span class="s2">&quot;ntgps daemon&quot;</span>
</span><span class='line'><span class="nv">PIDFILE</span><span class="o">=</span>/var/run/<span class="nv">$NAME</span>.pid
</span><span class='line'><span class="nv">SCRIPTNAME</span><span class="o">=</span>/etc/init.d/<span class="nv">$NAME</span>
</span><span class='line'>
</span><span class='line'><span class="nv">DAEMON_OPTS</span><span class="o">=</span><span class="s2">&quot;&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="nb">set</span> -e
</span><span class='line'>. /lib/lsb/init-functions
</span><span class='line'><span class="nb">export </span><span class="nv">LANG</span><span class="o">=</span><span class="s1">&#39;en_US.UTF-8&#39;</span>
</span><span class='line'><span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span><span class="nv">$PATH</span>
</span><span class='line'><span class="nb">export </span><span class="nv">GEM_HOME</span><span class="o">=</span>/usr/local/rvm/gems/ruby-1.9.2-p290
</span><span class='line'><span class="nb">export </span><span class="nv">GEM_PATH</span><span class="o">=</span>/usr/local/rvm/gems/ruby-1.9.2-p290:/usr/local/rvm/gems/ruby-1.9.2-p290@global
</span><span class='line'>
</span><span class='line'><span class="k">case</span> <span class="s2">&quot;$1&quot;</span> in
</span><span class='line'>    start<span class="o">)</span>
</span><span class='line'>        log_daemon_msg <span class="s2">&quot;Starting $DESC&quot;</span> <span class="nv">$NAME</span>
</span><span class='line'>        <span class="k">if</span> ! start-stop-daemon --start -m --background --oknodo --quiet --pidfile <span class="nv">$PIDFILE</span> --exec /usr/local/rvm/rubies/ruby-1.9.2-p290/bin/ruby <span class="nv">$DAEMON</span> -- <span class="nv">$DAEMON_OPTS</span>
</span><span class='line'>        <span class="k">then</span>
</span><span class='line'><span class="k">            </span>log_end_msg 1
</span><span class='line'>        <span class="k">else</span>
</span><span class='line'><span class="k">            </span>log_end_msg 0
</span><span class='line'>        <span class="k">fi</span>
</span><span class='line'>        ;;
</span><span class='line'>    stop<span class="o">)</span>
</span><span class='line'>        log_daemon_msg <span class="s2">&quot;Stopping $DESC&quot;</span> <span class="nv">$NAME</span>
</span><span class='line'>        <span class="k">if </span><span class="nb">kill</span>  -9 <span class="sb">`</span>cat <span class="nv">$PIDFILE</span><span class="sb">`</span>
</span><span class='line'>        <span class="k">then</span>
</span><span class='line'><span class="k">            </span>rm -f <span class="nv">$PIDFILE</span>
</span><span class='line'>            log_end_msg 0
</span><span class='line'>        <span class="k">else</span>
</span><span class='line'><span class="k">            </span>log_end_msg 1
</span><span class='line'>        <span class="k">fi</span>
</span><span class='line'>        ;;
</span><span class='line'>    restart<span class="o">)</span>
</span><span class='line'>        <span class="nv">$0</span> stop
</span><span class='line'>        <span class="nv">$0</span> start
</span><span class='line'>        ;;
</span><span class='line'>    status<span class="o">)</span>
</span><span class='line'>        status_of_proc -p <span class="s2">&quot;$PIDFILE&quot;</span> <span class="s2">&quot;$DAEMON&quot;</span> <span class="nv">$NAME</span> <span class="o">&amp;&amp;</span> <span class="nb">exit </span>0 <span class="o">||</span> <span class="nb">exit</span> <span class="nv">$?</span>
</span><span class='line'>        ;;
</span><span class='line'>    *<span class="o">)</span>
</span><span class='line'>        <span class="nb">echo</span> <span class="s2">&quot;Usage: $SCRIPTNAME {start|stop|restart|status}&quot;</span> &gt;&amp;2
</span><span class='line'>        <span class="nb">exit </span>1
</span><span class='line'>        ;;
</span><span class='line'><span class="k">esac</span>
</span><span class='line'>
</span><span class='line'><span class="nb">exit </span>0
</span></code></pre></td></tr></table></div></figure>


<h2>Resources:</h2>

<p><a href="http://www.debuntu.org/how-to-manage-services-with-update-rc.d">How-To: Managing services with update-rc.d</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Use Rubyencoder encrypt ruby code]]></title>
    <link href="http://qichunren.github.com/blog/2012/02/27/use-rubyencoder-encrypt-ruby-code/"/>
    <updated>2012-02-27T13:10:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2012/02/27/use-rubyencoder-encrypt-ruby-code</id>
    <content type="html"><![CDATA[<p>前些时候研究了一下ruby encoder的加密技术应用，在这里记录一下它的使用过程。</p>

<p><a href="http://rubyencoder.com/">Ruby Encoder</a>将ruby代码加密成不易阅读的格式，然后通过它提供的加载类型来载入ruby代码，从而达到加密的目的。它是一个付费软件，一个许可证要159美金，提供试用版，可以试用一个星期，支持Linux \ FreeBSD \ Mac OS X \ Windows系统。</p>

<p>首先在Ruby Encoder上注册一个帐号，登录进去后，我这里选择下载Mac OS X版的，RubyEncoder Trial for Mac OS X （RubyEncoder_1.3_Trial.dmg），下载后，将dmg中的程序拖到applications目录，就算安装好了。</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>qichunren:~ qichunren$ cd /Applications/RubyEncoder/
</span><span class='line'>qichunren:RubyEncoder qichunren$ ls
</span><span class='line'>Icon?             RubyEncoder_User_Manual.pdf bin/
</span><span class='line'>README                Start RubyEncoder.app*      rgloader/</span></code></pre></td></tr></table></div></figure>


<p>第一次使用的话，需要它的官方网站给你提供一个许可证文件(文件名为encode.lic),进行Ruby Encoder的bin目录,执行其中的rubyencoder文件, 它会输出一些它的软件声明信息，一直回车后几次后，阅读完许可声明，它还要求你输入&#8217;I AGREE&#8217;后，然后输出一个注册码（Reg Key）,要求你登录到它的网站中，在个人帐户里，在页面最下面的Available Licenses中填入注册码，然后下载它提供的encode.lic文件，放在Ruby Encoder的bin目录中，现在就可以使用Ruby Encoder了。</p>

<p>直接执行一下rubyencoder命令，可以先了解一下它的用法。</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>qichunren:bin qichunren$ ./rubyencoder 
</span><span class='line'>RubyEncoder 1.3 Evaluation (built: Aug 31 2010 11:55:25)
</span><span class='line'>Copyright (c) 2008-2010 rubyencoder.com
</span><span class='line'>Supports encoding for Ruby versions: 1.8.6,1.8.7,1.9.0,1.9.1,1.9.2
</span><span class='line'>
</span><span class='line'>Usage,    single file: rubyencoder [options] file.rb
</span><span class='line'>       multiple files: rubyencoder [options] file1.rb file2.rb file3.rb
</span><span class='line'>            file mask: rubyencoder [options] "*.rb"
</span><span class='line'>            file list: rubyencoder [options] @filelist
</span><span class='line'>
</span><span class='line'>  --ruby &lt;version x.y&gt;              Encode for Ruby ver (1.8 default and/or 1.9)
</span><span class='line'>* --expire &lt;dd/mm/yyyy&gt;             Set script expiration date
</span><span class='line'>* --days &lt;nn&gt;                       Set script expiration days (from today)
</span><span class='line'>* --domain &lt;domain&gt;                 Bind script to domain name
</span><span class='line'>* --domain-encrypt &lt;domain&gt;         Bind and encrypt to domain name (one only)
</span><span class='line'>* --ip &lt;x.x.x.x[/y.y.y.y]&gt;          Bind script to ip/mask
</span><span class='line'>* --ip-encrypt &lt;x.x.x.x[/y.y.y.y]&gt;  Bind and encrypt to ip/mask (one only)
</span><span class='line'>* --mac &lt;x:x:x:x:x:x&gt;               Bind script to mac address
</span><span class='line'>* --external &lt;filename&gt;             Script will require license file to run
</span><span class='line'>* --projid &lt;value&gt;                  Set project id (required for ext license)
</span><span class='line'>* --projkey &lt;value&gt;                 Set project key (required for ext license)
</span><span class='line'>* --time-server &lt;server,server,...&gt; Set time server (for expiration date check)
</span><span class='line'>* script locking options are disabled for evaluation version
</span><span class='line'>
</span><span class='line'>  --const name=value                Set custom defined constant
</span><span class='line'>  --catch err=function              Set custom error handler
</span><span class='line'>
</span><span class='line'>  -p "code"|@file  Prepend header code
</span><span class='line'>  -j "code"|@file  Change default loader error code
</span><span class='line'>  -b &lt;ext&gt;         Set file extension for backup files (bak is default)
</span><span class='line'>  -b-              Disable backup of source files (be careful!)
</span><span class='line'>  -r               Recurse subdirectories (use quotes for file masks)
</span><span class='line'>  -x "mask"|@list  Exclude files from encoding
</span><span class='line'>  -f "mask"|@list  Encode only these files
</span><span class='line'>  -o &lt;output_dir&gt;  Specify output directory for encoded scripts
</span><span class='line'>  -w               Wait for key press before exit
</span><span class='line'>  -q               Display settings and request confirmation
</span><span class='line'>  -v               Display version number
</span><span class='line'>  -l               Display license information
</span><span class='line'>  -h               Display this help</span></code></pre></td></tr></table></div></figure>


<p>像我给公司做的一个小项目，我只需要加密rails目录中的app目录就足够了，官方也建议只加密app目录就行了，可能是为了避免一些加密问题？</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>qichunren:bin qichunren$ ./rubyencoder --ruby 1.9 /Users/qichunren/code/menu/app/**/*.rb</span></code></pre></td></tr></table></div></figure>


<p>这样就完成了app目录中的rb代码加密，同时它还备份了原来的rb文件，是同名的后缀为bak的文件，在部署中应该将.bak文件都删除掉。还有一件事情要做，需要把Ruby Encoder的相当于解密的加载器文件复制到app目录中，也就是加密代码的上一级目录里面来，这样项目可以正常执行了。</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>qichunren:RubyEncoder qichunren$ pwd
</span><span class='line'>/Applications/RubyEncoder
</span><span class='line'>qichunren:RubyEncoder qichunren$ cp -r rgloader/ /Users/qichunren/code/menu/app/</span></code></pre></td></tr></table></div></figure>


<p>下面是我咨询的关于Ruby Encoder的许可证相关的几个问题的官方回复邮件。</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Hi,
</span><span class='line'>
</span><span class='line'>Thank you for your interest in RubyEncoder. Please find answers below.
</span><span class='line'>
</span><span class='line'>&gt; 0. After I paid $159 for RubyEncoder, do I have license to run rubyencoder on different machines for different systems(mac or linux). I have serval machines for development and deployment.
</span><span class='line'>RubyEncoder is licensed per-machine. One license lets you install and
</span><span class='line'>use the encoder to one physical or virtual machine. If you use multiple
</span><span class='line'>machines for development you may purchase additional licenses for $99
</span><span class='line'>each. Note, loaders that are required to run protected files are free.
</span><span class='line'>
</span><span class='line'>&gt; 1. I developed on Mac OSX system usually, then deploy my rails application on Linux (Ubuntu 11). This goes well currently. I want to know after encode my rails 3 application on mac, then will it goes well on my deployed Linux machine?
</span><span class='line'>Yes, you encode on your Mac and then install encoded files to your Linux
</span><span class='line'>machine as usual. To run protected files on Linux you need to install
</span><span class='line'>(copy a folder) RubyEncoder loaders for Linux to your rails root folder.
</span><span class='line'>With version 1.3 you can encode your application controllers, helpers
</span><span class='line'>and model rails files. Do not encode any other standard or configuration
</span><span class='line'>rails files. For non-rails Ruby files you may encode any code. Ruby
</span><span class='line'>verisons 1.8.6,1.8.7.1.9.0-1.9.3 are supported.
</span><span class='line'>
</span><span class='line'>&gt; 2. After I paid $159 for RubyEncoder, do I have to paid again for your update version? Can I get free follow-on support service and software update?
</span><span class='line'>Once you pay you get 1 year of free support and updates.
</span><span class='line'>
</span><span class='line'>&gt; 3. How long is a paid license?
</span><span class='line'>&gt;
</span><span class='line'>A license is time unlimited. Support is included for 1 year since the
</span><span class='line'>date of purchase. We do email support.
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>Feel free to contact me if you have any further questions.</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Create custom tags in Smarty 3]]></title>
    <link href="http://qichunren.github.com/blog/2012/02/26/create-custom-tags-in-smarty/"/>
    <updated>2012-02-26T14:21:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2012/02/26/create-custom-tags-in-smarty</id>
    <content type="html"><![CDATA[<p>接着上一篇，还是来说说PHP模板引擎Smarty。PHP的众多CMS框架，如DEDE CMS，对于前端展示都是有一套自己开发的标签，用于显示管理后台维护的数据。在DEDECMS中，如下的代码</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;h2&gt;最近新闻&lt;/h2&gt;
</span><span class='line'>&lt;ul&gt;
</span><span class='line'>    {dede:arclist typeid='1' row='10'}
</span><span class='line'>    &lt;li&gt;[field:textlink/]&lt;/li&gt;
</span><span class='line'>    {/dede:arclist}
</span><span class='line'>&lt;/ul&gt;</span></code></pre></td></tr></table></div></figure>


<p>就可以显示最近type id为1的10条新闻。在Smarty中创建属于自己的标签是很容易的，我之前在网络上搜索的关于创建smarty标签的内容大多数都是基于Smarty2的，我基于Smarty3中的plugins目录的代码了解到在Smarty3中创建自定义标签更为简单直观。</p>

<p>在smarty程序包的plugins目录中，可以看到有block \ function \ modifier 等几种前缀的php文件。像block前缀的php文件可以创建闭合的标签，就如上文提到的那个dede cms新闻标签的例子。现在我正是要创建这样类型的标签。</p>

<p>我结合CodeIgniter来说明，我现在创建一个用户列表的标签，可以显示最近注册的用户。
在smarty的plugins目录中创建的文件会自动被smarty加载而识别的，文件名和其中的function 名称需要特定的约定好的格式。
我现在想创建一个users标签,还有一个limit参数，用来显示取多少条数据</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>用户列表：
</span><span class='line'>&lt;ul&gt;
</span><span class='line'>    &lt;{users limit='3'}&gt;
</span><span class='line'>        &lt;li&gt;&lt;{$user-&gt;login}&gt;&lt;/li&gt;
</span><span class='line'>    &lt;{/users}&gt;
</span><span class='line'>&lt;/ul&gt;</span></code></pre></td></tr></table></div></figure>


<p>那么文件名就应该指定为block.users.php，然后function应该命名为smarty_block_users：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">function</span> <span class="nf">smarty_block_users</span><span class="p">(</span><span class="nv">$params</span><span class="p">,</span> <span class="nv">$content</span><span class="p">,</span> <span class="nv">$smarty</span><span class="p">,</span> <span class="o">&amp;</span><span class="nv">$repeat</span><span class="p">){</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="k">empty</span><span class="p">(</span><span class="nv">$content</span><span class="p">)){</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="k">empty</span><span class="p">(</span><span class="nv">$params</span><span class="p">[</span><span class="s1">&#39;limit&#39;</span><span class="p">]))</span> <span class="p">{</span>
</span><span class='line'>            <span class="nv">$limit</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>            <span class="nv">$limit</span> <span class="o">=</span> <span class="nv">$params</span><span class="p">[</span><span class="s1">&#39;limit&#39;</span><span class="p">];</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="nv">$CI</span> <span class="o">=&amp;</span> <span class="nx">get_instance</span><span class="p">();</span>
</span><span class='line'>        <span class="nv">$GLOBALS</span><span class="p">[</span><span class="s1">&#39;users&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$CI</span><span class="o">-&gt;</span><span class="na">db</span><span class="o">-&gt;</span><span class="na">query</span><span class="p">(</span><span class="s2">&quot;select * from users order by created_at desc limit </span><span class="si">$limit</span><span class="s2">&quot;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">result</span><span class="p">();</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="nb">isset</span><span class="p">(</span><span class="nv">$GLOBALS</span><span class="p">[</span><span class="s1">&#39;users&#39;</span><span class="p">])</span> <span class="o">!=</span> <span class="k">NULL</span> <span class="o">&amp;&amp;</span> <span class="nb">count</span><span class="p">(</span><span class="nv">$GLOBALS</span><span class="p">[</span><span class="s1">&#39;users&#39;</span><span class="p">])</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">){</span>
</span><span class='line'>        <span class="nv">$user</span> <span class="o">=</span> <span class="nb">array_shift</span><span class="p">(</span><span class="nv">$GLOBALS</span><span class="p">[</span><span class="s1">&#39;users&#39;</span><span class="p">]);</span>
</span><span class='line'>        <span class="nv">$smarty</span><span class="o">-&gt;</span><span class="na">assign</span><span class="p">(</span><span class="s1">&#39;user&#39;</span><span class="p">,</span> <span class="nv">$user</span><span class="p">);</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="nb">count</span><span class="p">(</span><span class="nv">$GLOBALS</span><span class="p">[</span><span class="s1">&#39;users&#39;</span><span class="p">])</span> <span class="o">==</span> <span class="mi">0</span><span class="p">){</span>
</span><span class='line'>            <span class="nb">unset</span><span class="p">(</span><span class="nv">$GLOBALS</span><span class="p">[</span><span class="s1">&#39;users&#39;</span><span class="p">]);</span>
</span><span class='line'>            <span class="nv">$repeat</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="nv">$repeat</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span><span class="k">else</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$repeat</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">return</span> <span class="nv">$content</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="cp">?&gt;</span><span class="x"></span>
</span></code></pre></td></tr></table></div></figure>


<p>这个function中有四个参数，$params参数存储的是标签中的属性信息，如上面的limit。$content是标签中间的内容，$smarty是smarty的实例对象，$repeat用于指定block是否重复执行。
解释完了function的参数，我想其中的执行原理应该很容易看明白了吧。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Use Smarty template in CodeIgniter]]></title>
    <link href="http://qichunren.github.com/blog/2012/02/11/use-smarty-template-in-codeigniter/"/>
    <updated>2012-02-11T16:57:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2012/02/11/use-smarty-template-in-codeigniter</id>
    <content type="html"><![CDATA[<p><a href="http://codeigniter.com/">CodeIgniter</a>是一个不错的PHP开发框架，很合我的口味，我做的一些PHP项目就是用的它。</p>

<p><a href="http://www.smarty.net/">Smarty</a>是目前业界最著名的PHP模板引擎之一。它分离了逻辑代码和外在的内容，提供了一种易于管理和使用的方法，用来将原本与HTML代码混杂在一起的PHP代码逻辑分离。</p>

<p>一般来说使用原生PHP作为视图会比使用模板引擎高效，一些简单的项目或者个人开发者可以直接使用PHP，如果是大一点的项目，再加上要和美工配合，使用模板引擎会是分工明确，合作高效一些。</p>

<p>在CodeIgniter使用Smarty模板引擎一点也不复杂，这是因为CodeIgniter提供了<a href="http://codeigniter.org.cn/user_guide/general/creating_libraries.html">创建类库</a>的方便方法。</p>

<p>我这里使用的CodeIgniter和Smarty都是最新版本,2.1.0和3.1.7</p>

<p>1: 将Smarty包下载后，解压后，放入CodeIgniter项目中的application/libraries目录.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>caojinhua:company caojinhua$ ls application/libraries/
</span><span class='line'>Smarty.php    index.html  smarty/
</span><span class='line'>caojinhua:company caojinhua$ ls application/libraries/smarty/
</span><span class='line'>Smarty.class.php  SmartyBC.class.php  debug.tpl       plugins/        sysplugins/</span></code></pre></td></tr></table></div></figure>


<p>2: 在application/libraries目录中创建Smarty.php文件。</p>

<figure class='code'><figcaption><span>application/libraries/Smarty.php  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span> <span class="k">if</span> <span class="p">(</span> <span class="o">!</span> <span class="nb">defined</span><span class="p">(</span><span class="s1">&#39;BASEPATH&#39;</span><span class="p">))</span> <span class="k">exit</span><span class="p">(</span><span class="s1">&#39;No direct script access allowed&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="k">require_once</span><span class="p">(</span><span class="s1">&#39;smarty/Smarty.class.php&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">CI_Smarty</span> <span class="k">extends</span> <span class="nx">Smarty</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">function</span> <span class="nf">__construct</span><span class="p">(){</span>
</span><span class='line'>          <span class="k">parent</span><span class="o">::</span><span class="na">__construct</span><span class="p">();</span>
</span><span class='line'>                <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">compile_dir</span> <span class="o">=</span> <span class="nx">FCPATH</span> <span class="o">.</span> <span class="s2">&quot;application/views/templates_c&quot;</span><span class="p">;</span>
</span><span class='line'>                <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">template_dir</span> <span class="o">=</span> <span class="nx">FCPATH</span> <span class="o">.</span> <span class="s2">&quot;application/views/templates&quot;</span><span class="p">;</span>
</span><span class='line'>                <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">cache_dir</span> <span class="o">=</span> <span class="nx">FCPATH</span> <span class="o">.</span> <span class="s2">&quot;application/views/cache&quot;</span><span class="p">;</span><span class="c1">//缓存目录</span>
</span><span class='line'>                <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">caching</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>                <span class="c1">//$this-&gt;cache_lifetime = 120; //缓存更新时间</span>
</span><span class='line'>                <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">debugging</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span>
</span><span class='line'>                <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">compile_check</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span> <span class="c1">// 检查当前的模板是否自上次编译后被更改；如果被更改了，它将重新编译该模板。</span>
</span><span class='line'>                <span class="c1">//$this-&gt;force_compile = true; // 强制重新编译模板</span>
</span><span class='line'>                <span class="c1">//$this-&gt;allow_php_templates= true; // 开启PHP模板</span>
</span><span class='line'>                <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">left_delimiter</span> <span class="o">=</span> <span class="s2">&quot;{&quot;</span><span class="p">;</span> <span class="c1">//左定界符</span>
</span><span class='line'>                <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">right_delimiter</span> <span class="o">=</span> <span class="s2">&quot;}&quot;</span><span class="p">;</span> <span class="c1">//右定界符</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="cp">?&gt;</span><span class="x"></span>
</span></code></pre></td></tr></table></div></figure>


<p>根据代码中的smarty目录配置，需要在application/views中建立templates_c\templates\cache三个目录.
这就算创建好了。</p>

<p>3: 使用方法。
控制器中的代码:</p>

<figure class='code'><figcaption><span>application/controllers/debug.php  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span> <span class="k">if</span> <span class="p">(</span> <span class="o">!</span> <span class="nb">defined</span><span class="p">(</span><span class="s1">&#39;BASEPATH&#39;</span><span class="p">))</span> <span class="k">exit</span><span class="p">(</span><span class="s1">&#39;No direct script access allowed&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">Debug</span> <span class="k">extends</span> <span class="nx">MY_Controller</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">function</span> <span class="nf">__construct</span><span class="p">()</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="k">parent</span><span class="o">::</span><span class="na">__construct</span><span class="p">();</span>
</span><span class='line'>    <span class="c1">// Write your own initialize code</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">function</span> <span class="nf">index</span><span class="p">(){</span>
</span><span class='line'>      <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">load</span><span class="o">-&gt;</span><span class="na">library</span><span class="p">(</span><span class="s1">&#39;smarty&#39;</span><span class="p">);</span>
</span><span class='line'>      <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">smarty</span><span class="o">-&gt;</span><span class="na">assign</span><span class="p">(</span><span class="s2">&quot;title&quot;</span><span class="p">,</span><span class="s2">&quot;smarty template&quot;</span><span class="p">);</span>
</span><span class='line'>      <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">smarty</span><span class="o">-&gt;</span><span class="na">assign</span><span class="p">(</span><span class="s2">&quot;body&quot;</span><span class="p">,</span><span class="s2">&quot;欢迎使用smarty模板引擎&quot;</span><span class="p">);</span>
</span><span class='line'>      <span class="nv">$arr</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="mi">1</span> <span class="o">=&gt;</span> <span class="s1">&#39;number 1&#39;</span><span class="p">,</span> <span class="mi">2</span> <span class="o">=&gt;</span> <span class="s1">&#39;number 2&#39;</span><span class="p">,</span> <span class="mi">3</span> <span class="o">=&gt;</span> <span class="s1">&#39;number 3&#39;</span><span class="p">);</span>
</span><span class='line'>      <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">smarty</span><span class="o">-&gt;</span><span class="na">assign</span><span class="p">(</span><span class="s2">&quot;myarray&quot;</span><span class="p">,</span> <span class="nv">$arr</span><span class="p">);</span>
</span><span class='line'>      <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">smarty</span><span class="o">-&gt;</span><span class="na">display</span><span class="p">(</span><span class="s1">&#39;index.html&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>模板代码:</p>

<figure class='code'><figcaption><span>application/views/templates/index.html  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="cp">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
</span><span class='line'><span class="nt">&lt;html</span> <span class="na">xmlns=</span><span class="s">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="nt">&gt;</span>
</span><span class='line'><span class="nt">&lt;head&gt;</span>
</span><span class='line'><span class="nt">&lt;meta</span> <span class="na">http-equiv=</span><span class="s">&quot;Content-Type&quot;</span> <span class="na">content=</span><span class="s">&quot;text/html; charset=utf-8&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'><span class="nt">&lt;title&gt;</span>smarty模板使用示例<span class="nt">&lt;/title&gt;</span>
</span><span class='line'><span class="nt">&lt;/head&gt;</span>
</span><span class='line'><span class="nt">&lt;body&gt;</span>
</span><span class='line'><span class="nt">&lt;h1&gt;</span>{$title}<span class="nt">&lt;/h1&gt;</span>
</span><span class='line'><span class="nt">&lt;p&gt;</span>{$body}<span class="nt">&lt;/p&gt;</span>
</span><span class='line'><span class="nt">&lt;ul&gt;</span>
</span><span class='line'>        {foreach from=$myarray item=v}
</span><span class='line'>        <span class="nt">&lt;li&gt;</span>{$v}<span class="nt">&lt;/li&gt;</span>
</span><span class='line'>       {/foreach}
</span><span class='line'><span class="nt">&lt;/ul&gt;</span>
</span><span class='line'><span class="nt">&lt;/body&gt;</span>
</span><span class='line'><span class="nt">&lt;/html&gt;</span>
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Customizing rails generator templates]]></title>
    <link href="http://qichunren.github.com/blog/2012/01/12/customizing-rails-generator-templates/"/>
    <updated>2012-01-12T13:49:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2012/01/12/customizing-rails-generator-templates</id>
    <content type="html"><![CDATA[<p>Rails framework and twitter bootstrap are good for your startup project, build-in generators generate source code by its way. It is  a good starting point.</p>

<p>But I often have to change default generted source code:</p>

<ul>
<li>Add <strong>encoding: utf-8</strong> into ruby file header, for Ruby 1.9.2 encoding.</li>
<li>Change scaffold view files to apply <a href="http://twitter.github.com/bootstrap/">bootstrap</a> css.</li>
<li>Other things you want to override default templates.</li>
</ul>


<p>Rails provides the mechanism to custom generator behavior.</p>

<p>I have already got it, and source code is on <a href="https://github.com/qichunren/rails_generator_override_templates">github</a>, follow README for usage.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to update a forked repository from original repository at github?]]></title>
    <link href="http://qichunren.github.com/blog/2012/01/09/update-forked-repository-from-original-repository-at-github/"/>
    <updated>2012-01-09T12:39:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2012/01/09/update-forked-repository-from-original-repository-at-github</id>
    <content type="html"><![CDATA[<p>If you use github, you can follow this.</p>

<p>I use <a href="https://github.com/huacnlee/ruby-china">huachlee/ruby-china</a> repository for example.</p>

<p>At huacnlee/ruby-china repository homepage, clicked &#8220;Fork&#8221; button, then after serval minutes, you will have you own forked repository copy.Then you clone to local.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git clone git@github.com:qichunren/ruby-china.git</span></code></pre></td></tr></table></div></figure>


<p>Then you commit your changes, and push to it.When you found the original repository has some updated feature,you can do as follow:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>cd ruby-china
</span><span class='line'>git remote add upstream git://github.com/huacnlee/ruby-china.git
</span><span class='line'>caojinhua:ruby-china caojinhua$ git fetch upstream
</span><span class='line'>remote: Counting objects: 345, done.
</span><span class='line'>remote: Compressing objects: 100% (164/164), done.
</span><span class='line'>remote: Total 266 (delta 196), reused 156 (delta 98)
</span><span class='line'>Receiving objects: 100% (266/266), 31.92 KiB | 25 KiB/s, done.
</span><span class='line'>Resolving deltas: 100% (196/196), completed with 67 local objects.
</span><span class='line'>From git://github.com/huacnlee/ruby-china
</span><span class='line'> * [new branch]      github_autocomplete -&gt; upstream/github_autocomplete
</span><span class='line'> * [new branch]      markdown   -&gt; upstream/markdown
</span><span class='line'> * [new branch]      master     -&gt; upstream/master
</span><span class='line'> * [new branch]      post       -&gt; upstream/post
</span><span class='line'>caojinhua:ruby-china caojinhua$ git merge upstream/master</span></code></pre></td></tr></table></div></figure>


<p>That is it.</p>

<h2>Resources:</h2>

<ul>
<li><a href="http://help.github.com/fork-a-repo/">Fork A Repo</a></li>
<li><a href="http://bradlyfeeley.com/2008/09/03/update-a-github-fork-from-the-original-repo/">Update a Github Fork from the Original Repo</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[在Rails3中使用ajax]]></title>
    <link href="http://qichunren.github.com/blog/2011/12/22/use-ajax-in-rails3-note/"/>
    <updated>2011-12-22T16:36:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2011/12/22/use-ajax-in-rails3-note</id>
    <content type="html"><![CDATA[<p>今天写代码的时候突然发现 我之前在Rails3中使用ajax的方式是不太正确的，我走了弯路。</p>

<p>我之前在Rails3项目中使用ajax是这样的：</p>

<p>如果是直接发送一个ajax请求，我就给标签加上:remote => true。如果我在此基础上还要做其它的操作，如ajax表单提交前要对表单字段验证，我之前以为那样UJS就不能搞定了，需要我自己写代码来处理。然后我就使用jquery中的相关ajax操作来处理。</p>

<p>今天我才了解到UJS的AJAX操作已经为我们提供了6个自定义事件方法：</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>ajax:before – right before ajax call
</span><span class='line'>ajax:loading – before ajax call, but after XmlHttpRequest object is created)
</span><span class='line'>ajax:success – successful ajax call
</span><span class='line'>ajax:failure – failed ajax call
</span><span class='line'>ajax:complete – completion of ajax call (after ajax:success and ajax:failure)
</span><span class='line'>ajax:after – after ajax call is sent (note: not after it returns)</span></code></pre></td></tr></table></div></figure>


<p>所以对于上面我说的那个事例，如果要对一个ajax表单在提交前作表单验证或者其它的一些检查，只需要写提交前的检查代码，然后通过事件绑定的方式，将余下的表单ajax提交让UJS来完成，这是多么地简单啊，我以前真是做了好多无用功。</p>

<figure class='code'><figcaption><span>sample code  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">ready</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#new_post_comment&quot;</span><span class="p">).</span><span class="nx">bind</span><span class="p">(</span><span class="s2">&quot;ajax:before&quot;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#post_comment_body&quot;</span><span class="p">).</span><span class="nx">val</span><span class="p">()</span><span class="o">==</span><span class="s2">&quot;&quot;</span><span class="p">){</span>
</span><span class='line'>      <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<h3>参考资料</h3>

<p><a href="http://net.tutsplus.com/tutorials/javascript-ajax/using-unobtrusive-javascript-and-ajax-with-rails-3/">Using Unobtrusive JavaScript and AJAX with Rails 3</a>
<a href="http://www.alfajango.com/blog/rails-3-remote-links-and-forms-data-type-with-jquery/">Rails 3 Remote Links and Forms Part 2: Data-type (with jQuery)</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[mongodb的可视化客户端工具:MongoHub]]></title>
    <link href="http://qichunren.github.com/blog/2011/12/20/mongodb-ui-client-mongohub/"/>
    <updated>2011-12-20T17:31:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2011/12/20/mongodb-ui-client-mongohub</id>
    <content type="html"><![CDATA[<p>最近在使用mongodb,经常要调试，然后找到了MongoHub这款工具，感觉很好。</p>

<p><a href="mongohub.todayclose.com/download">MongoHub网站</a></p>

<p><img src="http://qichunren.github.com/assets/posts/2011-12-20-mongohub.png" title="will_paginate bar" alt="MongoHub" /></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[近期iOS学习点]]></title>
    <link href="http://qichunren.github.com/blog/2011/12/18/ios-learn-note/"/>
    <updated>2011-12-18T20:44:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2011/12/18/ios-learn-note</id>
    <content type="html"><![CDATA[<p>虽然我业余在学iOS，但是感觉进步缓慢。为了使我的iOS开发的学习效率高一点，我决定先列一个简要的提纲，明确当前一个阶段的学习计划。</p>

<ol>
<li><p>iOS体系，了解清楚UI组件的体系</p></li>
<li><p>Objective-C中的基本数据结构使用</p></li>
<li><p>iOS中的基本的网络编程，主要是iOS客户端方的,如json,http交互等。</p></li>
</ol>


<p>先就这么多，每天要进步一点.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Shell学习小记录]]></title>
    <link href="http://qichunren.github.com/blog/2011/10/18/learning-shell-tip-note/"/>
    <updated>2011-10-18T00:00:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2011/10/18/learning-shell-tip-note</id>
    <content type="html"><![CDATA[<p>最近为了一些自动化的任务，要写一些脚本。可以使用Ruby脚本、Ruby的rake\thor等等，我为了简洁和性能，我了解了一下Shell，发现用Shell来做这个事情更合适。性能，命令行，管道，丰富的现有工具，基于Linux本身，Shell真是一个好东西。以前认为用Ruby来做这个事情是一个不错的选择，现在知道了，那是因为相比起Shell来，更熟悉Ruby，程序员总是喜欢自己熟悉的领域，而排斥自己不熟悉的领域。其实多了解一下其它方面的，更利用自己工作的开展，提高工作效率。</p>

<p>我随便总结一下几个知识点</p>

<h4>字符串</h4>

<p>声明一个字符串变量后，使用的时候，在变量名前面加一个$符号才能将其值取出来</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>DATA_FILE=data.tar.gz
</span><span class='line'>echo $DATA_FILE</span></code></pre></td></tr></table></div></figure>


<p>字符串拼接</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>DATA_DIR=/Users/caojinhua/code/
</span><span class='line'>DATA_FILE=data.tar.gz
</span><span class='line'>DATA_PATH=$DATA_DIR""$DATA_FILE</span></code></pre></td></tr></table></div></figure>


<p>将命令执行的结果保存在变量中</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sha1=`ls -al`</span></code></pre></td></tr></table></div></figure>


<h4>if语句结构</h4>

<p>if语句条件测试命令：</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>[ -d DIR ]   如果DIR存在并且是一个目录则为真
</span><span class='line'>[ -f FILE ]   如果FILE存在且是一个普通文件则为真
</span><span class='line'>[ -z STRING ] 如果STRING的长度为零则为真
</span><span class='line'>[ -n STRING ] 如果STRING的长度非零则为真
</span><span class='line'>[ STRING1 = STRING2 ] 如果两个字符串相同则为真
</span><span class='line'>[ STRING1 != STRING2 ]    如果字符串不相同则为真
</span><span class='line'>[ ARG1 OP ARG2 ]</span></code></pre></td></tr></table></div></figure>


<p>ARG1和ARG2应该是整数或者取值为整数的变量，OP是-eq（等于）-ne（不等于）-lt（小于）-le（小于等于）-gt（大于）-ge（大于等于）之中的一个</p>

<p>之前弄错好几次，中括号前后的空格不能少。</p>

<p>if语句的结构</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>if [ xxx ]
</span><span class='line'>then
</span><span class='line'>fi
</span><span class='line'>
</span><span class='line'>if [ xxx ]; then
</span><span class='line'>
</span><span class='line'>else
</span><span class='line'>
</span><span class='line'>fi
</span><span class='line'>
</span><span class='line'>if [ xxx ]; then
</span><span class='line'>
</span><span class='line'>elif [ ! xxx ]; then
</span><span class='line'>
</span><span class='line'>fi</span></code></pre></td></tr></table></div></figure>


<h4>时间格式化</h4>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>date  +%Y%m%d
</span><span class='line'>
</span><span class='line'>a=`date +%Y%m%d`
</span><span class='line'>echo $a</span></code></pre></td></tr></table></div></figure>


<h4>参考资料</h4>

<p><a href="http://learn.akae.cn/media/ch31s05.html">Shell脚本语法</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Fix problem annotate is broken with rails 3.1.1]]></title>
    <link href="http://qichunren.github.com/blog/2011/10/14/fix-annotate-gem-with-rails3-1-1/"/>
    <updated>2011-10-14T00:00:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2011/10/14/fix-annotate-gem-with-rails3-1-1</id>
    <content type="html"><![CDATA[<p>今天在做一个小工具，使用最新的Rails版本3.1.1, 在使用annotate(2.4.0)这个gem的时候出错了：</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>caojinhua:tts_cacher caojinhua$ annotate
</span><span class='line'>/Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.1/lib/active_record/railties/databases.rake:3:in `&lt;top (required)&gt;': undefined method `namespace' for main:Object (NoMethodError)
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.1/lib/active_record/railtie.rb:26:in `load'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.1.1/lib/active_record/railtie.rb:26:in `block in &lt;class:Railtie&gt;'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.1/lib/rails/railtie.rb:183:in `call'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.1/lib/rails/railtie.rb:183:in `block in load_tasks'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.1/lib/rails/railtie.rb:183:in `each'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.1/lib/rails/railtie.rb:183:in `load_tasks'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.1/lib/rails/engine.rb:396:in `block in load_tasks'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.1/lib/rails/application/railties.rb:8:in `each'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.1/lib/rails/application/railties.rb:8:in `all'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.1/lib/rails/engine.rb:396:in `load_tasks'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.1/lib/rails/application.rb:103:in `load_tasks'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.1/lib/rails/railtie/configurable.rb:30:in `method_missing'
</span><span class='line'>  from Rakefile:7:in `&lt;top (required)&gt;'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/annotate-2.4.0/lib/annotate.rb:17:in `load'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/annotate-2.4.0/lib/annotate.rb:17:in `load_tasks'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/gems/annotate-2.4.0/bin/annotate:66:in `&lt;top (required)&gt;'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/bin/annotate:19:in `load'
</span><span class='line'>  from /Users/caojinhua/.rvm/gems/ruby-1.9.2-p180/bin/annotate:19:in `&lt;main&gt;'</span></code></pre></td></tr></table></div></figure>


<p>然后在stackoverflow上找到了解决方法，就是使用最新的annotate.</p>

<figure class='code'><figcaption><span>Gemfile</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">gem</span> <span class="s1">&#39;annotate&#39;</span><span class="p">,</span> <span class="ss">:git</span> <span class="o">=&gt;</span> <span class="s1">&#39;git://github.com/ctran/annotate_models.git&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Resources:</h3>

<p><a href="http://stackoverflow.com/questions/7295505/annotate-gem-and-rails-3-1">annotate-gem-and-rails-3-1</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[网页截屏的方法]]></title>
    <link href="http://qichunren.github.com/blog/2011/10/12/capture-webpage/"/>
    <updated>2011-10-12T00:00:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2011/10/12/capture-webpage</id>
    <content type="html"><![CDATA[<p>曾经很想有这样一个app, 它可以将微博上用户的微博用图片的形式自动保存起来，留此存照。前几个月的那段时间，微博上很
网页截屏的基本原理就是通过取得webkit渲染（render）的数据来生成图片的，我经过一段时间研究，找到了两个方法来解决这个问题。</p>

<p>一个工具叫<a href="http://www.phantomjs.org/">phantomjs</a>，另一个工具叫<a href="http://cutycapt.sourceforge.net/">cutycapt</a></p>

<p>两个工具都不错，个人比较喜欢使用cutycapt这个工具，它是直接提供一个命令行来生成网页截图的，而前者是通过javascript来调用底层webkit接品(page.render方法)来实现的，两者的侧重点不一样。
并且cutycapt是将整个网截下来，phantomjs是将浏览器当前视区的一屏截下来。</p>

<p>Cutycapt的用法如下</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>qichunren@qichunren-desktop:~/github/cutycapt/CutyCapt$ ./CutyCapt 
</span><span class='line'> -----------------------------------------------------------------------------
</span><span class='line'> Usage: CutyCapt --url=http://www.example.org/ --out=localfile.png            
</span><span class='line'> -----------------------------------------------------------------------------
</span><span class='line'>  --help                         Print this help page and exit                
</span><span class='line'>  --url=&lt;url&gt;                    The URL to capture (http:...|file:...|...)   
</span><span class='line'>  --out=&lt;path&gt;                   The target file (.png|pdf|ps|svg|jpeg|...)   
</span><span class='line'>  --out-format=&lt;f&gt;               Like extension in --out, overrides heuristic 
</span><span class='line'>  --min-width=&lt;int&gt;              Minimal width for the image (default: 800)   
</span><span class='line'>  --min-height=&lt;int&gt;             Minimal height for the image (default: 600)  
</span><span class='line'>  --max-wait=&lt;ms&gt;                Don't wait more than (default: 90000, inf: 0)
</span><span class='line'>  --delay=&lt;ms&gt;                   After successful load, wait (default: 0)     
</span><span class='line'>  --user-style-path=&lt;path&gt;       Location of user style sheet file, if any    
</span><span class='line'>  --user-style-string=&lt;css&gt;      User style rules specified as text           
</span><span class='line'>  --header=&lt;name&gt;:&lt;value&gt;        request header; repeatable; some can't be set
</span><span class='line'>  --method=&lt;get|post|put&gt;        Specifies the request method (default: get)  
</span><span class='line'>  --body-string=&lt;string&gt;         Unencoded request body (default: none)       
</span><span class='line'>  --body-base64=&lt;base64&gt;         Base64-encoded request body (default: none)  
</span><span class='line'>  --app-name=&lt;name&gt;              appName used in User-Agent; default is none  
</span><span class='line'>  --app-version=&lt;version&gt;        appVers used in User-Agent; default is none  
</span><span class='line'>  --user-agent=&lt;string&gt;          Override the User-Agent header Qt would set  
</span><span class='line'>  --javascript=&lt;on|off&gt;          JavaScript execution (default: on)           
</span><span class='line'>  --java=&lt;on|off&gt;                Java execution (default: unknown)            
</span><span class='line'>  --plugins=&lt;on|off&gt;             Plugin execution (default: unknown)          
</span><span class='line'>  --private-browsing=&lt;on|off&gt;    Private browsing (default: unknown)          
</span><span class='line'>  --auto-load-images=&lt;on|off&gt;    Automatic image loading (default: on)        
</span><span class='line'>  --js-can-open-windows=&lt;on|off&gt; Script can open windows? (default: unknown)  
</span><span class='line'>  --js-can-access-clipboard=&lt;on|off&gt; Script clipboard privs (default: unknown)
</span><span class='line'>  --print-backgrounds=&lt;on|off&gt;   Backgrounds in PDF/PS output (default: off)  
</span><span class='line'>  --zoom-factor=&lt;float&gt;          Page zoom factor (default: no zooming)       
</span><span class='line'>  --zoom-text-only=&lt;on|off&gt;      Whether to zoom only the text (default: off) 
</span><span class='line'>  --http-proxy=&lt;url&gt;             Address for HTTP proxy server (default: none)
</span><span class='line'> -----------------------------------------------------------------------------
</span><span class='line'>  &lt;f&gt; is svg,ps,pdf,itext,html,rtree,png,jpeg,mng,tiff,gif,bmp,ppm,xbm,xpm    
</span><span class='line'> -----------------------------------------------------------------------------
</span><span class='line'> http://cutycapt.sf.net - (c) 2003-2010 Bjoern Hoehrmann - bjoern@hoehrmann.de
</span><span class='line'>qichunren@qichunren-desktop:~/github/cutycapt/CutyCapt$</span></code></pre></td></tr></table></div></figure>


<p>phantomjs截屏的用法如下：</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>qichunren@qichunren-desktop:~/github$ cd phantomjs/
</span><span class='line'>qichunren@qichunren-desktop:~/github/phantomjs$ ls
</span><span class='line'>bin         ChangeLog  ff.png     iteye.png    Makefile       python     src
</span><span class='line'>capture.js  examples   hello.png  LICENSE.BSD  phantomjs.pro  README.md           
</span><span class='line'>qichunren@qichunren-desktop:~/github/phantomjs$ ./bin/phantomjs examples/rasterize.js 
</span><span class='line'>Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat]
</span><span class='line'>  paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"
</span><span class='line'>qichunren@qichunren-desktop:~/github/phantomjs$ ./bin/phantomjs examples/rasterize.js http://www.iteye.com iteye.png
</span><span class='line'>qichunren@qichunren-desktop:~/github/phantomjs$</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[使用Jruby来部署Rails应用]]></title>
    <link href="http://qichunren.github.com/blog/2011/08/26/deploy-rails-project-with-jruby/"/>
    <updated>2011-08-26T00:00:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2011/08/26/deploy-rails-project-with-jruby</id>
    <content type="html"><![CDATA[<p>为了保护最近做的产品的源代码，需要将项目中的源代码进行保护起来。我目前了解到的方案有以下两种：</p>

<ol>
<li><p>使用代码混淆工具</p></li>
<li><p>使用JRuby将Ruby代码编译成java字节码文件（.class）</p></li>
</ol>


<hr />

<p>第一种方案，有一个名为<a href="http://rubyencoder.com">ruby encoder</a>的产品，我试用了一下，发现太重量级了，我个人只是一个可以将代码混淆一下的小工具而已，而ruby encoder有自己的运行加载机制，源代码二次编码，基于域名可以设置产品过期失效时间等等一系列功能，我不需要这些功能，另外它不是免费的，所以我没有采用这个方案。</p>

<p>第二种方安装就是使用JRuby。整体思路就是将Ruby项目的代码编译成java字节码文件，然后运行于Java环境中。</p>

<hr />

<p>将项目中的ruby文件编译成java的class文件不是一件容易的事情，所幸有一个名为warbler的gem可以帮助我们搞定这一切，它可以将项目打包(.war)，同时可以将ruby代码编译成class文件。然后你将生成好的.war文件放进JAVA应用服务器的应用目录中，如Tomcat的webapps中就可以了。</p>

<p>warbler提供若干个任务可供使用：</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>qichunren@qichunren-desktop:~/code/ntdeck$ warble -T
</span><span class='line'>warble compiled    # Feature: precompile all Ruby files
</span><span class='line'>warble config      # Generate a configuration file to customize your archive
</span><span class='line'>warble executable  # Feature: make an executable archive
</span><span class='line'>warble gemjar      # Feature: package gem repository inside a jar
</span><span class='line'>warble pluginize   # Install Warbler tasks in your Rails application
</span><span class='line'>warble version     # Display version of Warbler
</span><span class='line'>warble war         # Create the project war file
</span><span class='line'>warble war:clean   # Remove the project war file
</span><span class='line'>warble war:debug   # Dump diagnostic information</span></code></pre></td></tr></table></div></figure>


<p>平时最常用的就是warble war命令了，需要关注的是warble的配置文件，它的配置文件是通过warble config来生成的，在这个文件中有一系列的配置项可以设置，以下是我的配置文件：</p>

<figure class='code'><figcaption><span>config/warble.rb  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
<span class='line-number'>90</span>
<span class='line-number'>91</span>
<span class='line-number'>92</span>
<span class='line-number'>93</span>
<span class='line-number'>94</span>
<span class='line-number'>95</span>
<span class='line-number'>96</span>
<span class='line-number'>97</span>
<span class='line-number'>98</span>
<span class='line-number'>99</span>
<span class='line-number'>100</span>
<span class='line-number'>101</span>
<span class='line-number'>102</span>
<span class='line-number'>103</span>
<span class='line-number'>104</span>
<span class='line-number'>105</span>
<span class='line-number'>106</span>
<span class='line-number'>107</span>
<span class='line-number'>108</span>
<span class='line-number'>109</span>
<span class='line-number'>110</span>
<span class='line-number'>111</span>
<span class='line-number'>112</span>
<span class='line-number'>113</span>
<span class='line-number'>114</span>
<span class='line-number'>115</span>
<span class='line-number'>116</span>
<span class='line-number'>117</span>
<span class='line-number'>118</span>
<span class='line-number'>119</span>
<span class='line-number'>120</span>
<span class='line-number'>121</span>
<span class='line-number'>122</span>
<span class='line-number'>123</span>
<span class='line-number'>124</span>
<span class='line-number'>125</span>
<span class='line-number'>126</span>
<span class='line-number'>127</span>
<span class='line-number'>128</span>
<span class='line-number'>129</span>
<span class='line-number'>130</span>
<span class='line-number'>131</span>
<span class='line-number'>132</span>
<span class='line-number'>133</span>
<span class='line-number'>134</span>
<span class='line-number'>135</span>
<span class='line-number'>136</span>
<span class='line-number'>137</span>
<span class='line-number'>138</span>
<span class='line-number'>139</span>
<span class='line-number'>140</span>
<span class='line-number'>141</span>
<span class='line-number'>142</span>
<span class='line-number'>143</span>
<span class='line-number'>144</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># Disable Rake-environment-task framework detection by uncommenting/setting to false</span>
</span><span class='line'><span class="c1"># Warbler.framework_detection = false</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Warbler web application assembly configuration file</span>
</span><span class='line'><span class="no">Warbler</span><span class="o">::</span><span class="no">Config</span><span class="o">.</span><span class="n">new</span> <span class="k">do</span> <span class="o">|</span><span class="n">config</span><span class="o">|</span>
</span><span class='line'>  <span class="c1"># Features: additional options controlling how the jar is built.</span>
</span><span class='line'>  <span class="c1"># Currently the following features are supported:</span>
</span><span class='line'>  <span class="c1"># - gemjar: package the gem repository in a jar file in WEB-INF/lib</span>
</span><span class='line'>  <span class="c1"># - executable: embed a web server and make the war executable</span>
</span><span class='line'>  <span class="c1"># - compiled: compile .rb files to .class files</span>
</span><span class='line'>  <span class="n">config</span><span class="o">.</span><span class="n">features</span> <span class="o">=</span> <span class="sx">%w(executable compiled)</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Application directories to be included in the webapp.</span>
</span><span class='line'>  <span class="n">config</span><span class="o">.</span><span class="n">dirs</span> <span class="o">=</span> <span class="sx">%w(app config db lib log vendor tmp)</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Additional files/directories to include, above those in config.dirs</span>
</span><span class='line'>  <span class="c1"># config.includes = FileList[&quot;db&quot;]</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Additional files/directories to exclude</span>
</span><span class='line'>  <span class="c1"># config.excludes = FileList[&quot;lib/tasks/*&quot;]</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Additional Java .jar files to include.  Note that if .jar files are placed</span>
</span><span class='line'>  <span class="c1"># in lib (and not otherwise excluded) then they need not be mentioned here.</span>
</span><span class='line'>  <span class="c1"># JRuby and JRuby-Rack are pre-loaded in this list.  Be sure to include your</span>
</span><span class='line'>  <span class="c1"># own versions if you directly set the value</span>
</span><span class='line'>  <span class="c1"># config.java_libs += FileList[&quot;lib/java/*.jar&quot;]</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Loose Java classes and miscellaneous files to be included.</span>
</span><span class='line'>  <span class="c1"># config.java_classes = FileList[&quot;target/classes/**.*&quot;]</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># One or more pathmaps defining how the java classes should be copied into</span>
</span><span class='line'>  <span class="c1"># the archive. The example pathmap below accompanies the java_classes</span>
</span><span class='line'>  <span class="c1"># configuration above. See http://rake.rubyforge.org/classes/String.html#M000017</span>
</span><span class='line'>  <span class="c1"># for details of how to specify a pathmap.</span>
</span><span class='line'>  <span class="c1"># config.pathmaps.java_classes &lt;&lt; &quot;%{target/classes/,}p&quot;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Bundler support is built-in. If Warbler finds a Gemfile in the</span>
</span><span class='line'>  <span class="c1"># project directory, it will be used to collect the gems to bundle</span>
</span><span class='line'>  <span class="c1"># in your application. If you wish to explicitly disable this</span>
</span><span class='line'>  <span class="c1"># functionality, uncomment here.</span>
</span><span class='line'>  <span class="c1"># config.bundler = false</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># An array of Bundler groups to avoid including in the war file.</span>
</span><span class='line'>  <span class="c1"># Defaults to [&quot;development&quot;, &quot;test&quot;].</span>
</span><span class='line'>  <span class="c1"># config.bundle_without = []</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Other gems to be included. If you don&#39;t use Bundler or a gemspec</span>
</span><span class='line'>  <span class="c1"># file, you need to tell Warbler which gems your application needs</span>
</span><span class='line'>  <span class="c1"># so that they can be packaged in the archive.</span>
</span><span class='line'>  <span class="c1"># For Rails applications, the Rails gems are included by default</span>
</span><span class='line'>  <span class="c1"># unless the vendor/rails directory is present.</span>
</span><span class='line'>  <span class="c1"># config.gems += [&quot;activerecord-jdbcmysql-adapter&quot;, &quot;jruby-openssl&quot;]</span>
</span><span class='line'>  <span class="c1"># config.gems &lt;&lt; &quot;tzinfo&quot;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Uncomment this if you don&#39;t want to package rails gem.</span>
</span><span class='line'>  <span class="c1"># config.gems -= [&quot;rails&quot;]</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># The most recent versions of gems are used.</span>
</span><span class='line'>  <span class="c1"># You can specify versions of gems by using a hash assignment:</span>
</span><span class='line'>  <span class="c1"># config.gems[&quot;rails&quot;] = &quot;2.3.10&quot;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># You can also use regexps or Gem::Dependency objects for flexibility or</span>
</span><span class='line'>  <span class="c1"># finer-grained control.</span>
</span><span class='line'>  <span class="c1"># config.gems &lt;&lt; /^merb-/</span>
</span><span class='line'>  <span class="c1"># config.gems &lt;&lt; Gem::Dependency.new(&quot;merb-core&quot;, &quot;= 0.9.3&quot;)</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Include gem dependencies not mentioned specifically. Default is</span>
</span><span class='line'>  <span class="c1"># true, uncomment to turn off.</span>
</span><span class='line'>  <span class="c1"># config.gem_dependencies = false</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Array of regular expressions matching relative paths in gems to be</span>
</span><span class='line'>  <span class="c1"># excluded from the war. Defaults to empty, but you can set it like</span>
</span><span class='line'>  <span class="c1"># below, which excludes test files.</span>
</span><span class='line'>  <span class="c1"># config.gem_excludes = [/^(test|spec)\//]</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Pathmaps for controlling how application files are copied into the archive</span>
</span><span class='line'>  <span class="c1"># config.pathmaps.application = [&quot;WEB-INF/%p&quot;]</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Name of the archive (without the extension). Defaults to the basename</span>
</span><span class='line'>  <span class="c1"># of the project directory.</span>
</span><span class='line'>  <span class="n">config</span><span class="o">.</span><span class="n">jar_name</span> <span class="o">=</span> <span class="s2">&quot;ntdeck&quot;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Name of the MANIFEST.MF template for the war file. Defaults to a simple</span>
</span><span class='line'>  <span class="c1"># MANIFEST.MF that contains the version of Warbler used to create the war file.</span>
</span><span class='line'>  <span class="c1"># config.manifest_file = &quot;config/MANIFEST.MF&quot;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># When using the &#39;compiled&#39; feature and specified, only these Ruby</span>
</span><span class='line'>  <span class="c1"># files will be compiled. Default is to compile all \.rb files in</span>
</span><span class='line'>  <span class="c1"># the application.</span>
</span><span class='line'>  <span class="c1"># config.compiled_ruby_files = FileList[&#39;app/**/*.rb&#39;]</span>
</span><span class='line'>  <span class="n">compile_me</span> <span class="o">=</span> <span class="no">FileList</span><span class="o">[*</span><span class="n">config</span><span class="o">.</span><span class="n">dirs</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">x</span><span class="si">}</span><span class="s2">/**/*.rb&quot;</span><span class="p">}</span><span class="o">].</span><span class="n">exclude</span><span class="p">(</span><span class="s2">&quot;config/compass.rb&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="s2">&quot;lib/printer/*&quot;</span><span class="p">)</span>
</span><span class='line'>  <span class="n">config</span><span class="o">.</span><span class="n">compiled_ruby_files</span> <span class="o">=</span> <span class="n">compile_me</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># === War files only below here ===</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Path to the pre-bundled gem directory inside the war file. Default</span>
</span><span class='line'>  <span class="c1"># is &#39;WEB-INF/gems&#39;. Specify path if gems are already bundled</span>
</span><span class='line'>  <span class="c1"># before running Warbler. This also sets &#39;gem.path&#39; inside web.xml.</span>
</span><span class='line'>  <span class="c1"># config.gem_path = &quot;WEB-INF/vendor/bundler_gems&quot;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Files for WEB-INF directory (next to web.xml). This contains</span>
</span><span class='line'>  <span class="c1"># web.xml by default. If there is an .erb-File it will be processed</span>
</span><span class='line'>  <span class="c1"># with webxml-config. You may want to exclude this file via</span>
</span><span class='line'>  <span class="c1"># config.excludes.</span>
</span><span class='line'>  <span class="c1"># config.webinf_files += FileList[&quot;jboss-web.xml&quot;]</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Files to be included in the root of the webapp.  Note that files in public</span>
</span><span class='line'>  <span class="c1"># will have the leading &#39;public/&#39; part of the path stripped during staging.</span>
</span><span class='line'>  <span class="c1"># config.public_html = FileList[&quot;public/**/*&quot;, &quot;doc/**/*&quot;]</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Pathmaps for controlling how public HTML files are copied into the .war</span>
</span><span class='line'>  <span class="c1"># config.pathmaps.public_html = [&quot;%{public/,}p&quot;]</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Value of RAILS_ENV for the webapp -- default as shown below</span>
</span><span class='line'>  <span class="c1"># config.webxml.rails.env = ENV[&#39;RAILS_ENV&#39;] || &#39;production&#39;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Application booter to use, one of :rack, :rails, or :merb (autodetected by default)</span>
</span><span class='line'>  <span class="c1"># config.webxml.booter = :rails</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Set JRuby to run in 1.9 mode.</span>
</span><span class='line'>  <span class="c1"># config.webxml.jruby.compat.version = &quot;1.9&quot;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># When using the :rack booter, &quot;Rackup&quot; script to use.</span>
</span><span class='line'>  <span class="c1"># - For &#39;rackup.path&#39;, the value points to the location of the rackup</span>
</span><span class='line'>  <span class="c1"># script in the web archive file. You need to make sure this file</span>
</span><span class='line'>  <span class="c1"># gets included in the war, possibly by adding it to config.includes</span>
</span><span class='line'>  <span class="c1"># or config.webinf_files above.</span>
</span><span class='line'>  <span class="c1"># - For &#39;rackup&#39;, the rackup script you provide as an inline string</span>
</span><span class='line'>  <span class="c1">#   is simply embedded in web.xml.</span>
</span><span class='line'>  <span class="c1"># The script is evaluated in a Rack::Builder to load the application.</span>
</span><span class='line'>  <span class="c1"># Examples:</span>
</span><span class='line'>  <span class="c1"># config.webxml.rackup.path = &#39;WEB-INF/hello.ru&#39;</span>
</span><span class='line'>  <span class="c1"># config.webxml.rackup = %{require &#39;./lib/demo&#39;; run Rack::Adapter::Camping.new(Demo)}</span>
</span><span class='line'>  <span class="c1"># config.webxml.rackup = require &#39;cgi&#39; &amp;&amp; CGI::escapeHTML(File.read(&quot;config.ru&quot;))</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Control the pool of Rails runtimes. Leaving unspecified means</span>
</span><span class='line'>  <span class="c1"># the pool will grow as needed to service requests. It is recommended</span>
</span><span class='line'>  <span class="c1"># that you fix these values when running a production server!</span>
</span><span class='line'>  <span class="n">config</span><span class="o">.</span><span class="n">webxml</span><span class="o">.</span><span class="n">jruby</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">runtimes</span> <span class="o">=</span> <span class="mi">1</span>
</span><span class='line'>  <span class="n">config</span><span class="o">.</span><span class="n">webxml</span><span class="o">.</span><span class="n">jruby</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">runtimes</span> <span class="o">=</span> <span class="mi">1</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># JNDI data source name</span>
</span><span class='line'>  <span class="c1"># config.webxml.jndi = &#39;jdbc/rails&#39;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>需要注意的是config.features = %w(executable compiled)配置中，其中的compiled就是可以将ruby代码编译成class代码的。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Set proxy in server side to get crossing domain ajax request]]></title>
    <link href="http://qichunren.github.com/blog/2011/08/17/proxy-in-server-side-for-ajax-crossing-domain/"/>
    <updated>2011-08-17T00:00:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2011/08/17/proxy-in-server-side-for-ajax-crossing-domain</id>
    <content type="html"><![CDATA[

<figure class='code'><figcaption><span>proxy_controller.rb  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">ProxyController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># GET /proxy/:url</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">get_handle</span>
</span><span class='line'>    <span class="nb">require</span> <span class="s1">&#39;open-uri&#39;</span>
</span><span class='line'>    <span class="n">file</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:url</span><span class="o">]</span><span class="p">)</span>
</span><span class='line'>    <span class="n">contents</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="n">read</span>
</span><span class='line'>    <span class="n">render</span> <span class="ss">:text</span> <span class="o">=&gt;</span> <span class="n">contents</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>in config/routes.rb  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">get</span> <span class="s2">&quot;/proxy&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;proxy#get_handle&quot;</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>javascript useage  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="nx">$</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;/proxy?url=&quot;</span> <span class="o">+</span> <span class="nx">remote_url</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">){</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Install mongo on mac]]></title>
    <link href="http://qichunren.github.com/blog/2011/06/04/install-mongodb/"/>
    <updated>2011-06-04T00:00:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2011/06/04/install-mongodb</id>
    <content type="html"><![CDATA[<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>caojinhuamatoMacBook-Pro:code caojinhua$ brew install mongodb
</span><span class='line'>==&gt; Downloading http://fastdl.mongodb.org/osx/mongodb-osx-x86_64-1.8.1.tgz
</span><span class='line'>######################################################################## 100.0%
</span><span class='line'>==&gt; Caveats
</span><span class='line'>If this is your first install, automatically load on login with:
</span><span class='line'>    mkdir -p ~/Library/LaunchAgents
</span><span class='line'>    cp /usr/local/Cellar/mongodb/1.8.1-x86_64/org.mongodb.mongod.plist ~/Library/LaunchAgents/
</span><span class='line'>    launchctl load -w ~/Library/LaunchAgents/org.mongodb.mongod.plist
</span><span class='line'>
</span><span class='line'>If this is an upgrade and you already have the org.mongodb.mongod.plist loaded:
</span><span class='line'>    launchctl unload -w ~/Library/LaunchAgents/org.mongodb.mongod.plist
</span><span class='line'>    cp /usr/local/Cellar/mongodb/1.8.1-x86_64/org.mongodb.mongod.plist ~/Library/LaunchAgents/
</span><span class='line'>    launchctl load -w ~/Library/LaunchAgents/org.mongodb.mongod.plist
</span><span class='line'>
</span><span class='line'>Or start it manually:
</span><span class='line'>    mongod run --config /usr/local/Cellar/mongodb/1.8.1-x86_64/mongod.conf
</span><span class='line'>MongoDB 1.8+ includes a feature for Write Ahead Logging (Journaling), which has been enabled by default.
</span><span class='line'>This is not the default in production (Journaling is disabled); to disable journaling, use --nojournal.
</span><span class='line'>==&gt; Summary
</span><span class='line'>/usr/local/Cellar/mongodb/1.8.1-x86_64: 16 files, 93M, built in 2 seconds</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[去掉textmate源代码中的隐形空格]]></title>
    <link href="http://qichunren.github.com/blog/2011/05/16/remove-hidden-space-soure-code/"/>
    <updated>2011-05-16T00:00:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2011/05/16/remove-hidden-space-soure-code</id>
    <content type="html"><![CDATA[<p>有这个需要，主要是因为不想在git提交后的diff中无看到不有意思的diff显示。使用textmate的同学可以用<a href="https://github.com/glennr/uber-glory-tmbundle">这个工具</a>来解决这个小问题。</p>

<h3>安装方法</h3>

<figure class='code'><figcaption><span>install step  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd</span> ~/Library/Application<span class="se">\ </span>Support/TextMate/Bundles/
</span><span class='line'>git clone git://github.com/glennr/uber-glory-tmbundle.git Uber<span class="se">\ </span>Glory.tmbundle
</span><span class='line'><span class="nb">cd </span>Uber<span class="se">\ </span>Glory.tmbundle
</span><span class='line'>git submodule update --init
</span><span class='line'>osascript -e <span class="s1">&#39;tell app &quot;TextMate&quot; to reload bundles&#39;</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[学习和了解Redis]]></title>
    <link href="http://qichunren.github.com/blog/2011/05/13/learn-redis-db/"/>
    <updated>2011-05-13T00:00:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2011/05/13/learn-redis-db</id>
    <content type="html"><![CDATA[<p><a href="http://redis.io/">Redis</a>
<a href="https://github.com/ezmobius/redis-rb">redis-rb</a> gem install redis <br/>
<a href="https://github.com/nateware/redis-objects">redis-objects</a>是基于redis-rb的一个ruby对象与redis对象映射的gem</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[使用Unicorn]]></title>
    <link href="http://qichunren.github.com/blog/2011/05/12/use-unicorn-in-rails/"/>
    <updated>2011-05-12T00:00:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2011/05/12/use-unicorn-in-rails</id>
    <content type="html"><![CDATA[<h3>Install</h3>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>gem install unicorn</span></code></pre></td></tr></table></div></figure>


<p>Then add gem &#8216;unicorn&#8217; to Gemfile.
bundle exec unicorn_rails to start rails app at 8080 port.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>caojinhua:qichunren.github.com caojinhua$ unicorn_rails --help
</span><span class='line'>Usage: unicorn_rails [ruby options] [unicorn_rails options] [rackup config file]
</span><span class='line'>Ruby options:
</span><span class='line'>  -e, --eval LINE          evaluate a LINE of code
</span><span class='line'>  -d, --debug              set debugging flags (set $DEBUG to true)
</span><span class='line'>  -w, --warn               turn warnings on for your script
</span><span class='line'>  -I, --include PATH       specify $LOAD_PATH (may be used more than once)
</span><span class='line'>  -r, --require LIBRARY    require the library, before executing your script
</span><span class='line'>unicorn_rails options:
</span><span class='line'>  -o, --host HOST          listen on HOST (default: 0.0.0.0)
</span><span class='line'>  -p, --port PORT          use PORT (default: 8080)
</span><span class='line'>  -E, --env RAILS_ENV      use RAILS_ENV for defaults (default: development)
</span><span class='line'>  -D, --daemonize          run daemonized in the background
</span><span class='line'>  -l {HOST:PORT|PATH},     listen on HOST:PORT or PATH
</span><span class='line'>      --listen             this may be specified multiple times
</span><span class='line'>                           (default: 0.0.0.0:8080)
</span><span class='line'>  -c, --config-file FILE   Unicorn-specific config file
</span><span class='line'>
</span><span class='line'>      --path PATH          Runs Rails app mounted at a specific path.
</span><span class='line'>                           (default: /)
</span><span class='line'>Common options:
</span><span class='line'>  -h, --help               Show this message
</span><span class='line'>  -v, --version            Show version</span></code></pre></td></tr></table></div></figure>


<p>This is a smaple unicorn config file:</p>

<figure class='code'><figcaption><span>config/unicorn.conf.rb  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">worker_processes</span> <span class="mi">2</span>
</span><span class='line'><span class="n">working_directory</span> <span class="s2">&quot;/www/temp/ntmenu2/current&quot;</span>
</span><span class='line'><span class="n">listen</span> <span class="mi">3000</span><span class="p">,</span> <span class="ss">:tcp_nopush</span> <span class="o">=&gt;</span> <span class="kp">true</span>
</span><span class='line'><span class="n">timeout</span> <span class="mi">30</span>
</span><span class='line'><span class="n">pid</span> <span class="s2">&quot;/www/temp/ntmenu2/current/tmp/pids/unicorn.pid&quot;</span>
</span><span class='line'><span class="n">stderr_path</span> <span class="s2">&quot;/www/temp/unicorn.stderr.log&quot;</span>
</span><span class='line'><span class="n">stdout_path</span> <span class="s2">&quot;/www/temp/unicorn.stdout.log&quot;</span>
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[使用Juggernaut]]></title>
    <link href="http://qichunren.github.com/blog/2011/05/12/use-juggernaut-for-realtime-app/"/>
    <updated>2011-05-12T00:00:00+08:00</updated>
    <id>http://qichunren.github.com/blog/2011/05/12/use-juggernaut-for-realtime-app</id>
    <content type="html"><![CDATA[<p><a href="https://github.com/maccman/juggernaut">Juggernaut</a>是基于<a href="http://nodejs.org/">Node.js</a>的一个实时(Realtime)Web的解决方案。使用起来很方便。</p>

<h3>安装方法</h3>

<ol>
<li>安装Node.js: brew install node</li>
<li>安装<a href="http://code.google.com/p/redis">Redis</a>: brew install redis</li>
<li>安装<a href="http://npmjs.org/">NPM</a>: curl http://npmjs.org/install.sh | sh</li>
<li>安装Juggernaut: 这个会把Juggernaut安装到当前目录，所以我应该先进行项目的/vendor/third目录，然后执行 npm install juggernaut</li>
</ol>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>usermatoMacBook-Pro:third qichunren$ npm install juggernaut
</span><span class='line'>redis@0.5.11 ./node_modules/juggernaut/node_modules/redis
</span><span class='line'>node-static-maccman@0.5.3 ./node_modules/juggernaut/node_modules/node-static-maccman
</span><span class='line'>socket.io@0.6.17 ./node_modules/juggernaut/node_modules/socket.io
</span><span class='line'>juggernaut@2.0.4 ./node_modules/juggernaut
</span><span class='line'>usermatoMacBook-Pro:third qichunren$  </span></code></pre></td></tr></table></div></figure>


<ol>
<li>安装Juggernaut gem:</li>
</ol>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>gem install juggernaut</span></code></pre></td></tr></table></div></figure>


<h3>使用方法</h3>

<p>我们在自己的项目中只需要引入http://localhost:8080/application.js 这个js文件即可。
然后在页面中可以这样接收服务器端的消息：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span> <span class="na">charset=</span><span class="s">&quot;utf-8&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">jug</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Juggernaut</span><span class="p">;</span>
</span><span class='line'>  <span class="nx">jug</span><span class="p">.</span><span class="nx">subscribe</span><span class="p">(</span><span class="s2">&quot;channel1&quot;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">){</span>
</span><span class='line'>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Got data: &quot;</span> <span class="o">+</span> <span class="nx">data</span><span class="p">);</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="nt">&lt;/script&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>服务器端直接发消息：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s2">&quot;juggernaut&quot;</span>
</span><span class='line'><span class="no">Juggernaut</span><span class="o">.</span><span class="n">publish</span><span class="p">(</span><span class="s2">&quot;channel1&quot;</span><span class="p">,</span> <span class="s2">&quot;Some data&quot;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>另外在启动了Juggernaut后，它默认在8080端口上有一个Helloword的应用，可以了解一下。</p>
]]></content>
  </entry>
  
</feed>

