<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-521385163897384868</id><updated>2024-10-25T14:11:02.455+08:00</updated><category term="PHP"/><category term="javascript"/><category term="Joomla"/><category term="Nginx"/><category term="git"/><category term="AS3"/><category term="Actionscript"/><category term="api"/><category term="cygwin"/><category term="flash"/><category term="svn"/><category term="Emeditor"/><category term="Flex"/><category term="Googlereader"/><category term="Lighttpd"/><category term="Regexp"/><category term="Zend"/><category term="Zendstudio"/><category term="add-on"/><category term="authentication"/><category term="bc3"/><category term="danted"/><category term="debug"/><category term="diff"/><category term="discuz"/><category term="dom"/><category term="ed2k"/><category term="emule"/><category term="eval"/><category term="feed"/><category term="filezilla"/><category term="filter"/><category term="firefox"/><category term="ftp"/><category term="geoip"/><category term="google"/><category term="guilayout"/><category term="hack"/><category term="hint"/><category term="iphone"/><category term="junction"/><category term="kana50"/><category term="ln"/><category term="mod_z_specieslist"/><category term="module"/><category term="mozilla"/><category term="mysql"/><category term="ncftp"/><category term="note"/><category term="objective-c"/><category term="pear"/><category term="phar"/><category term="prototype"/><category term="reader"/><category term="rss"/><category term="sftp"/><category term="simplepie"/><category term="subversion"/><category term="tattling"/><category term="ubuntu"/><category term="unity3d"/><category term="upload"/><category term="upload_module"/><category term="web interface"/><category term="winscp"/><category term="wordpress"/><category term="zend_feed"/><title type='text'>Jacky&#39;s Development notes</title><subtitle type='html'>iOS Developer</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>43</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-3800399031596640878</id><published>2011-12-25T12:34:00.001+08:00</published><updated>2011-12-25T12:34:54.757+08:00</updated><title type='text'>搬家了</title><content type='html'>新家地址： &lt;br /&gt;
&lt;a href=&quot;http://www.jiezhang.me&quot;&gt;http://www.jiezhang.me&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/3800399031596640878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2011/12/blog-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/3800399031596640878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/3800399031596640878'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2011/12/blog-post.html' title='搬家了'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-9046485151309670584</id><published>2011-05-03T15:55:00.001+08:00</published><updated>2011-05-03T15:57:11.550+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="guilayout"/><category scheme="http://www.blogger.com/atom/ns#" term="unity3d"/><title type='text'>Unity3d code clip : auto height lable and mouse touchable scrolling</title><content type='html'>&lt;pre class=&quot;prettyprint&quot;&gt;&lt;br /&gt;var wasScrolling : boolean = false;&lt;br /&gt;var scrollPosition : Vector2;&lt;br /&gt;var longString = &quot;This is a long-ish string This is an sized label. This is an sized label. This is an sized label. This is an sized label. This is an sized label. &quot;;&lt;br /&gt;function OnGUI () {&lt;br /&gt;&lt;br /&gt; var rectForDescription : Rect = Rect(100,100,100,100);&lt;br /&gt; &lt;br /&gt; GUILayout.BeginArea(rectForDescription);&lt;br /&gt; scrollPosition = GUILayout.BeginScrollView (scrollPosition, GUILayout.Width (100), GUILayout.Height (100));&lt;br /&gt; GUILayout.Label (longString);&lt;br /&gt; GUILayout.EndScrollView ();&lt;br /&gt; GUILayout.EndArea();&lt;br /&gt; &lt;br /&gt; if( Event.current.type==EventType.MouseDown &amp;&amp; rectForDescription.Contains(Event.current.mousePosition) ) {&lt;br /&gt;  wasScrolling = true;&lt;br /&gt;  print(&quot;down&quot;);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; if( Event.current.type==EventType.MouseDrag &amp;&amp; wasScrolling==true ) {&lt;br /&gt;  print(Event.current.delta.y);&lt;br /&gt;  scrollPosition.y+=Event.current.delta.y;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; if( Event.current.type==EventType.MouseUp &amp;&amp; wasScrolling == true) {&lt;br /&gt;  print(&quot;end scrolling&quot;);&lt;br /&gt;  wasScrolling = false;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/9046485151309670584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2011/05/unity3d-code-clip-auto-height-lable-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/9046485151309670584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/9046485151309670584'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2011/05/unity3d-code-clip-auto-height-lable-and.html' title='Unity3d code clip : auto height lable and mouse touchable scrolling'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-9052228256705055650</id><published>2011-03-09T17:02:00.002+08:00</published><updated>2011-03-09T17:06:39.024+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="pear"/><category scheme="http://www.blogger.com/atom/ns#" term="phar"/><category scheme="http://www.blogger.com/atom/ns#" term="PHP"/><title type='text'>a temporary solution for PEAR Install with PHP5.3</title><content type='html'>I met a Bug of PHP(still doesn&#39;t fixed yet) about halt_compiler function which caused installing PEAR fail.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;php go-pear.phar&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;This command doesn&#39;t work in PHP5.3  &lt;br /&gt;&lt;br /&gt;To fix(for the time being) it, use this command:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;php -ddetect_unicode=0 go-pear.phar&lt;/blockquote&gt;</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/9052228256705055650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2011/03/temporary-solution-for-pear-install.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/9052228256705055650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/9052228256705055650'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2011/03/temporary-solution-for-pear-install.html' title='a temporary solution for PEAR Install with PHP5.3'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-3188577040690048266</id><published>2010-10-17T22:08:00.002+08:00</published><updated>2010-10-17T22:12:08.844+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iphone"/><category scheme="http://www.blogger.com/atom/ns#" term="kana50"/><category scheme="http://www.blogger.com/atom/ns#" term="objective-c"/><title type='text'>Project &quot;kana50&quot; has created</title><content type='html'>I&#39;ve been learning iPhone developing recently. &lt;br /&gt;Finally I created a iPhone App and submitted it to to App store(still waiting to review).&lt;br /&gt;&lt;br /&gt;And I decide make this iPhone App project Opensource:&lt;br /&gt;http://code.google.com/p/kana50/</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/3188577040690048266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2010/10/project-kana50-has-created.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/3188577040690048266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/3188577040690048266'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2010/10/project-kana50-has-created.html' title='Project &quot;kana50&quot; has created'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-7473736242442819214</id><published>2010-10-17T22:06:00.000+08:00</published><updated>2010-10-17T22:08:08.595+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>How to fix PROCEDURE can&#39;t return a result set in the given context</title><content type='html'>CLIENT_MULTI_RESULTS enables the client program to process multiple results. This option must be enabled if you execute CALL statements for stored procedures that produce result sets. Otherwise, such procedures result in an error Error 1312 (0A000): PROCEDURE proc_name can&#39;t return a result set in the given context.&lt;br /&gt;&lt;br /&gt;http://dev.mysql.com/doc/refman/5.0/en/c-api-multiple-queries.html</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/7473736242442819214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2010/10/how-to-fix-procedure-cant-return-result.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/7473736242442819214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/7473736242442819214'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2010/10/how-to-fix-procedure-cant-return-result.html' title='How to fix PROCEDURE can&#39;t return a result set in the given context'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-6269115247762677347</id><published>2010-07-11T16:34:00.004+08:00</published><updated>2010-07-11T16:48:45.229+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="add-on"/><category scheme="http://www.blogger.com/atom/ns#" term="ed2k"/><category scheme="http://www.blogger.com/atom/ns#" term="emule"/><category scheme="http://www.blogger.com/atom/ns#" term="firefox"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="mozilla"/><category scheme="http://www.blogger.com/atom/ns#" term="web interface"/><title type='text'>eMule one-click AddOn, a new project is created</title><content type='html'>It&#39;s a firefox add-on that I made recently, just because I&#39;m tried to copy/paste a ed2k link from a window to another windows if you have used eMule web interface to remotely control your eMule client.&lt;br /&gt;&lt;br /&gt;Project home:&lt;br /&gt;http://code.google.com/p/emule-oneclick-add-on/&lt;br /&gt;&lt;br /&gt;Mozilla Add-On install:&lt;br /&gt;https://addons.mozilla.org/en-US/firefox/addon/195536/</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/6269115247762677347/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2010/07/emule-one-click-addon-new-project-is.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/6269115247762677347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/6269115247762677347'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2010/07/emule-one-click-addon-new-project-is.html' title='eMule one-click AddOn, a new project is created'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-3309861638960923639</id><published>2010-05-23T21:42:00.006+08:00</published><updated>2010-05-23T22:24:29.046+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AS3"/><category scheme="http://www.blogger.com/atom/ns#" term="flash"/><title type='text'>Reading note of &#39;Real world flash game development&#39;</title><content type='html'>&lt;span style=&quot;font-size:130%;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;Chapter 3:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;A Quick Review of the Planning Steps&lt;br /&gt;● One- to two-sentence description&lt;br /&gt;● Game screen wireframe and fl ow&lt;br /&gt;● List of game mechanics&lt;br /&gt;● List of assets (art, animation, sound, video, and copy)&lt;br /&gt;● Technical requirements&lt;br /&gt;● UML class diagrams&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;Chapter 4:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;传入任意数量参数到函数/方法&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;&lt;br /&gt;function myFunction (… params):void {&lt;br /&gt;  for (var i:int = 0; I &lt; params.length; i + + ) {&lt;br /&gt;    if (!(params[i] is DisplayObject)) {&lt;br /&gt;      throw new ArgumentError( “ Only DisplayObjects can be used in myFunction. ” );&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Getter/Setter&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;&lt;br /&gt;package {&lt;br /&gt; public class MyClass {&lt;br /&gt;  protected var _maxNameLength:int = 8;&lt;br /&gt;  protected var _name:String;&lt;br /&gt;  protected var _lives:int = 3;&lt;br /&gt;  public function get name():String {&lt;br /&gt;   return _name;&lt;br /&gt;  }&lt;br /&gt;  public function set name(value:String):void {&lt;br /&gt;   name = value.substr(0,maxNameLength);&lt;br /&gt;  }&lt;br /&gt;  public function get lives():int {&lt;br /&gt;   return _lives;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;//OUTSIDE CLASS&lt;br /&gt;var myInstance:MyClass = new MyClass();&lt;br /&gt;myInstance .name = “ CHRISTOPHER ” ;&lt;br /&gt;trace (myInstance.name); //OUTPUTS “ CHRISTOP ” ;&lt;br /&gt;trace (myInstance.lives); //OUTPUTS 3;&lt;br /&gt;myInstance .lives = 10; //THROWS ERROR&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;to be Continued.</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/3309861638960923639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2010/05/reading-note-of-real-world-flash-game.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/3309861638960923639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/3309861638960923639'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2010/05/reading-note-of-real-world-flash-game.html' title='Reading note of &#39;Real world flash game development&#39;'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-247415647990860650</id><published>2010-04-06T12:36:00.004+08:00</published><updated>2010-04-27T18:49:42.330+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bc3"/><category scheme="http://www.blogger.com/atom/ns#" term="cygwin"/><category scheme="http://www.blogger.com/atom/ns#" term="diff"/><category scheme="http://www.blogger.com/atom/ns#" term="git"/><title type='text'>Using Beyond compare3 as Git diff tool under Cygwin</title><content type='html'>在Cygwin下使用Beyond compare3(BC3)作用Git的diff工具&lt;br /&gt;分两步走~&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;step 1.&lt;br /&gt;create new .sh file as Git&#39;s diff warpper.&lt;br /&gt;&lt;pre class=&#39;pretty&#39;&gt;#!/bin/sh&lt;br /&gt;/cygdrive/c/Program\ Files\ \(x86\)/Beyond\ Compare\ 3/BCompare.exe &quot;d:/programs/cygwin$2&quot; &quot;$5&quot;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;** please notice here, you need specially make a full path of $2, since BC3 will not find your tmp file under Cygwin path. **&lt;br /&gt;** 注意这里的两个路径，第二个是本地文件，因为是相对路径，BC3可以找到，但第一个是绝对路径指向/tmp/xxx，所以我们要特别指定在windows下的真实路径，而不是cygwin的路径，所以我加上了d:/programs/cygwin。&lt;br /&gt;&lt;br /&gt;step 2.&lt;br /&gt;Add this line to .bashrc and run it to configure your Git gloabl variable.&lt;br /&gt;&lt;pre class=&#39;pretty&#39;&gt;git config --global diff.external /home/z33/git-diff-wrapper.sh&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now you can try git diff whatever your file.</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/247415647990860650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2010/04/using-beyond-compare3-as-git-diff-tool.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/247415647990860650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/247415647990860650'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2010/04/using-beyond-compare3-as-git-diff-tool.html' title='Using Beyond compare3 as Git diff tool under Cygwin'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-678596498635068684</id><published>2010-03-11T13:18:00.004+08:00</published><updated>2010-03-11T13:25:57.558+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="hack"/><category scheme="http://www.blogger.com/atom/ns#" term="wordpress"/><title type='text'>Wordpress hack tips - Add tags to static pages</title><content type='html'>I did a lot of wordpress plugin jobs recently. But sometimes clients are not satisfied with what plugins can do. for example there is a client of mine want add tags to any static pages, just like wordpress posts did.&lt;br /&gt;&lt;br /&gt;Actually it&#39;s very easy to do this(as well as to create a plugin for this).&lt;br /&gt;just paste following lines to page_attributes_meta_bos function in meta-boxes.php:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;pretty&#39;&gt;&amp;lt;h5&amp;gt;Tags&amp;lt;/h5&amp;gt;&lt;br /&gt;&amp;lt;div&amp;gt;&lt;br /&gt;&amp;lt;input type=&quot;text&quot; name=&quot;tags_input&quot; class=&quot;tags-input&quot; id=&quot;tags-input&quot; size=&quot;30&quot; tabindex=&quot;3&quot; value=&quot;&amp;lt;?php echo get_tags_to_edit( $post-&amp;gt;ID ); ?&amp;gt;&quot; /&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/678596498635068684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2010/03/wordpress-hack-tips-add-tags-to-static.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/678596498635068684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/678596498635068684'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2010/03/wordpress-hack-tips-add-tags-to-static.html' title='Wordpress hack tips - Add tags to static pages'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-1843564861469381436</id><published>2010-03-02T18:18:00.006+08:00</published><updated>2010-03-02T18:42:07.110+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="geoip"/><category scheme="http://www.blogger.com/atom/ns#" term="PHP"/><title type='text'>The most easy way to install geoip php extension note</title><content type='html'>在网上找了一堆安装geo ip模块的方法，各种方法都很麻烦。现在本尊(无量牛逼最三三尊)来整理一个最简单的安装方法如下。&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;1.install GEOIP C Library&lt;/span&gt;&lt;br /&gt;http://geolite.maxmind.com/download/geoip/api/c/GeoIP-1.4.6.tar.gz&lt;br /&gt;./configure&lt;br /&gt;make&lt;br /&gt;sudo make install&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;2.Install GEOIP PHP Extension&lt;/span&gt;&lt;br /&gt;sudo pecl install geoip&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;3.Following message from step2, for example:&lt;/span&gt;&lt;br /&gt;Build process completed successfully&lt;br /&gt;Installing &#39;/usr/local/lib/php/20060613/geoip.so&#39;&lt;br /&gt;install ok: channel://pecl.php.net/geoip-1.0.7&lt;br /&gt;configuration option &quot;php_ini&quot; is not set to php.ini location&lt;br /&gt;You should add &quot;extension=geoip.so&quot; to php.ini&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;4.Install GeoIP database&lt;/span&gt;&lt;br /&gt;wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz&lt;br /&gt;gzip -d GeoIP.dat.gz&lt;br /&gt;sudo cp GeoIP.dat /usr/local/share/GeoIP/&lt;br /&gt;wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz&lt;br /&gt;sudo cp GeoLiteCity.dat /usr/local/share/GeoIP/GeoLiteCity.dat&lt;br /&gt;sudo mv /usr/local/share/GeoIP/GeoLiteCity.dat /usr/local/share/GeoIP/GeoIPCity.dat&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;5.test&lt;/span&gt;&lt;br /&gt;&amp;lt;?php print_r(geoip_record_by_name(&#39;125.63.166.38&#39;));</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/1843564861469381436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2010/03/install-geoip-php-extension-note.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/1843564861469381436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/1843564861469381436'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2010/03/install-geoip-php-extension-note.html' title='The most easy way to install geoip php extension note'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-3132750610430511100</id><published>2010-02-07T20:57:00.004+08:00</published><updated>2010-02-07T21:04:02.692+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="discuz"/><category scheme="http://www.blogger.com/atom/ns#" term="feed"/><category scheme="http://www.blogger.com/atom/ns#" term="rss"/><category scheme="http://www.blogger.com/atom/ns#" term="simplepie"/><category scheme="http://www.blogger.com/atom/ns#" term="zend_feed"/><title type='text'>这两天遇到的某些国内discuz论坛输出的RSS问题解决。</title><content type='html'>主要遇到了两个问题。&lt;br /&gt;1.GBK编码问题&lt;br /&gt;如果RSS输出是gbk编码，Zend_Feed可以处理（不过会有些警告）。而Simplepie则全部处理成乱码了。&lt;br /&gt;解决这个问题只能是把gbk当成gb2312来处理。&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;$content = str_replace(&#39;encoding=&quot;gbk&quot;&#39;, &#39;encoding=&quot;gb2312&quot;&#39;, $content);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;2.半个汉字，或非gb2312内的字符在第一或最后一个的时候，CDATA标签无法识别（Zend_Feed和SimplePie都不行）。&lt;br /&gt;解决办法就是在CDATA与字符之间加一个空格。&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;$content = preg_replace(&#39;/\]\]\&gt;/&#39;, &#39; ]]&gt;&#39;, $content);&lt;br /&gt;$content = preg_replace(&#39;/\&amp;lt;\!\[CDATA\[/&#39;, &#39;&amp;lt;![CDATA[ &#39;, $content);&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/3132750610430511100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2010/02/discuzrss.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/3132750610430511100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/3132750610430511100'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2010/02/discuzrss.html' title='这两天遇到的某些国内discuz论坛输出的RSS问题解决。'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-6387948456639878137</id><published>2010-02-06T11:06:00.005+08:00</published><updated>2010-04-08T22:09:09.753+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="git"/><title type='text'>Version Control with Git 学习笔记(更新中)</title><content type='html'>1.当git checkout的时候，如果有一个文件名和一个tag重名，可以用两个中线来指定文件名，比如：&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;$git checkout main.c  //checkout tag name&lt;br /&gt;$git checkout -- main.c  //checkout file name&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;2.指定log编辑器&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;setenv GIT_EDITOR vim  //tch&lt;br /&gt;export GIT_EDITOR=vim //bash&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;3.--author when met some wired message :P&lt;br /&gt;&lt;br /&gt;4.比较两个版本&lt;br /&gt;git log&lt;br /&gt;git diff 0f793b8262cbd843e8ad7c75430aab7bebc6522d^1..HEAD wp-content/themes/bugbam/header.php&lt;br /&gt;&lt;br /&gt;5.diff stat&lt;br /&gt;git diff master~5 master</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/6387948456639878137/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2010/02/version-control-with-git.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/6387948456639878137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/6387948456639878137'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2010/02/version-control-with-git.html' title='Version Control with Git 学习笔记(更新中)'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-9181495006443926963</id><published>2010-02-02T18:42:00.001+08:00</published><updated>2010-02-02T18:44:32.943+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="danted"/><title type='text'>dante server INSTALL note</title><content type='html'>1. install dante server&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;sudo apt-get install dante-server&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;skip the error message from the output of configure dante-server once installed. that&#39;s cause dante configuration was not complete.&lt;br /&gt;&lt;br /&gt;2. start editing the config file&lt;br /&gt;&lt;br /&gt;vi /etc/danted.conf&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;--&lt;br /&gt;# log to what file&lt;br /&gt;logoutput: stderr /var/log/danted.log&lt;br /&gt;&lt;br /&gt;# listening interface and port&lt;br /&gt;internal: ppp0 port = 80&lt;br /&gt;&lt;br /&gt;# outgoing interface&lt;br /&gt;external: ppp0&lt;br /&gt;&lt;br /&gt;# method: username requires the client to provide a username and password which match the system password file.&lt;br /&gt;&lt;br /&gt;# method: none requires no form of authentication.&lt;br /&gt;method: username&lt;br /&gt;&lt;br /&gt;# privileged ports like 80 and 443 must use root permission.&lt;br /&gt;user.privileged: root&lt;br /&gt;&lt;br /&gt;# the package seems not complied with libwrap support.&lt;br /&gt;#user.libwrap: nobody&lt;br /&gt;&lt;br /&gt;# allowed IPs&lt;br /&gt;client pass {&lt;br /&gt;from: 0.0.0.0/0 to: 0.0.0.0/0&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;# allowed protocols with these source IPs&lt;br /&gt;pass {&lt;br /&gt;from: 0.0.0.0/0 to: 0.0.0.0/0&lt;br /&gt;protocol: tcp udp&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;3. run dante-server&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;sudo /etc/init.d/danted start&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/9181495006443926963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2010/02/dante-server-install-note.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/9181495006443926963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/9181495006443926963'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2010/02/dante-server-install-note.html' title='dante server INSTALL note'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-6189663659946663920</id><published>2010-01-25T19:35:00.006+08:00</published><updated>2010-01-25T19:41:09.800+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Joomla"/><title type='text'>Change Joomla default meta info in a Component</title><content type='html'>In the templates of Component, in view.html.php before display() be called. add following line:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;$document =&amp; JFactory::getDocument();&lt;br /&gt;$document-&gt;setDescription(&#39;you description&#39;);&lt;br /&gt;$document-&gt;setMetaData(&#39;keywords&#39;, &#39;you keywords&#39;);&lt;br /&gt;&lt;/blockquote&gt;</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/6189663659946663920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2010/01/change-joomla-default-meta-info-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/6189663659946663920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/6189663659946663920'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2010/01/change-joomla-default-meta-info-in.html' title='Change Joomla default meta info in a Component'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-3801869250756696772</id><published>2010-01-25T10:40:00.002+08:00</published><updated>2010-01-25T14:08:37.727+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="dom"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><title type='text'>关于对DOM Level 1和2的理解。</title><content type='html'>参考：&lt;br /&gt;https://developer.mozilla.org/En/DOM_Levels&lt;br /&gt;&lt;br /&gt;根据自己的理解总结一下DOM Levels的实现。&lt;br /&gt;&lt;br /&gt;DOM Level 1:&lt;br /&gt;实现了文档结构化，就是《a href=&quot;xx&quot; target=&quot;&quot;》这样的tag以及attribute的定义。&lt;br /&gt;http://www.w3.org/TR/DOM-Level-1/&lt;br /&gt;&lt;br /&gt;DOM Level 2:&lt;br /&gt;1.实现了命名空间。&lt;br /&gt;2.实现动态更新以及访问（动态更新后可以看到更新结果）。addChild, removeChild&lt;br /&gt;3.事件，比如addEventListener，来实现响应各种事件，比如EventTarget, MouseEvent(但不包括键盘事件，奇怪，文档上是这么说的）&lt;br /&gt;4.支持CSS的访问了。 比如div.style.display=&#39;none&#39;;还有一些CSS相关的方法。&lt;br /&gt;5.实现Traversal，比如NodeIterator（我是没用过）。还有Range，这个在online editor里常见，就是TextRange之类的实现。这块不熟，还是看要w3c的详细文档吧：http://www.w3.org/TR/DOM-Level-2-Traversal-Range/&lt;br /&gt;&lt;br /&gt;总之现在主流的浏览器基本实现了Level2 小量实现了Level3。</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/3801869250756696772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2010/01/dom-level-12.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/3801869250756696772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/3801869250756696772'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2010/01/dom-level-12.html' title='关于对DOM Level 1和2的理解。'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-4252760519022201306</id><published>2010-01-22T16:27:00.001+08:00</published><updated>2010-01-22T16:29:58.681+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><title type='text'>A little example to figure out Javascript scope</title><content type='html'>&lt;pre class=&#39;pretty&#39;&gt;function f1() { var a=1; f2(); }&lt;br /&gt;function f2() { alert(a); }&lt;br /&gt;f1();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;pretty&#39;&gt;function f1() { &lt;br /&gt; var a=2;&lt;br /&gt; function f2() {&lt;br /&gt;  alert(a);&lt;br /&gt; }&lt;br /&gt; f2();&lt;br /&gt;}&lt;br /&gt;f1();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Try it.</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/4252760519022201306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2010/01/little-example-to-figure-out-javascript.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/4252760519022201306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/4252760519022201306'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2010/01/little-example-to-figure-out-javascript.html' title='A little example to figure out Javascript scope'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-6167569512365023628</id><published>2009-12-30T12:15:00.008+08:00</published><updated>2009-12-30T19:27:17.830+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="git"/><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu"/><title type='text'>install a git server on ubuntu</title><content type='html'>&lt;span style=&quot;font-weight: bold;&quot;&gt;install software&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;pretty&quot;&gt;sudo apt-get install git-core gitweb&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;edit config with apache&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;pretty&quot;&gt;sudo vim /etc/apache2/conf.d/git&lt;br /&gt;&lt;directory&gt;&lt;directory&gt;&lt;br /&gt;&amp;lt;Directory /var/www/git&amp;gt;&lt;br /&gt;Allow from all&lt;br /&gt;AllowOverride all&lt;br /&gt;Order allow,deny&lt;br /&gt;Options ExecCGI&lt;br /&gt;&lt;/directory&gt;&lt;/directory&gt;&amp;lt;&lt;directory&gt;&lt;directory&gt;Files gitweb.cgi&lt;/directory&gt;&lt;/directory&gt;&amp;gt;&lt;directory&gt;&lt;directory&gt;&lt;br /&gt;SetHandler cgi-script&lt;br /&gt;&lt;/directory&gt;&lt;/directory&gt;&amp;lt;&lt;directory&gt;&lt;directory&gt;/Files&lt;/directory&gt;&lt;/directory&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;directory&gt;&lt;directory&gt;/Directory&lt;/directory&gt;&lt;/directory&gt;&amp;gt;&lt;br /&gt;DirectoryIndex gitweb.cgi&lt;br /&gt;SetEnv  GITWEB_CONFIG  /etc/gitweb.conf&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;copy file&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;pretty&quot;&gt;sudo mv /usr/share/gitweb/* /var/www/git&lt;br /&gt;cp /usr/lib/cgi-bin/gitweb.cgi /var/www/git/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;restart apache&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;pretty&quot;&gt;sudo /etc/init.d/apache2 reload&lt;br /&gt;&lt;br /&gt;//Then you can visit you git website.&lt;br /&gt;http://localhost/git&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;=========================&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;create a new project rep&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;pretty&quot;&gt;cd /var/cache/git/&lt;br /&gt;sudo mkdir project.git&lt;br /&gt;cd project.git&lt;br /&gt;sudo git init&lt;br /&gt;sudo vim .git/description&lt;br /&gt;git config --global user.name &quot;Your Name&quot;&lt;br /&gt;git config --global user.email &quot;you@example.com&quot;&lt;br /&gt;git commit -a&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;git daemon start command&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;pretty&quot;&gt;touch .git/git-daemon-export-ok&lt;br /&gt;sudo git daemon --base-path=/var/cache/git --detach --syslog --export-all --verbose --enable=receive-pack&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;=====================&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;checkout code&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;pretty&quot;&gt;cd ~&lt;br /&gt;git clone git://server/project.git project &lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/6167569512365023628/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2009/12/install-git-server-on-ubuntu.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/6167569512365023628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/6167569512365023628'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2009/12/install-git-server-on-ubuntu.html' title='install a git server on ubuntu'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-945976097364081940</id><published>2009-09-28T22:06:00.001+08:00</published><updated>2009-09-28T22:08:36.027+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Actionscript"/><category scheme="http://www.blogger.com/atom/ns#" term="flash"/><category scheme="http://www.blogger.com/atom/ns#" term="note"/><title type='text'>notes after .ActionScript.3.0.in.Flash.CS3.Professional.Essential.Training(Lynda.com)</title><content type='html'>&lt;pre class=&#39;pretty&#39;&gt;&lt;br /&gt;_mc.buttonMode = true; //set move clip to button mode(with pointer when mouse over)&lt;br /&gt;_mc.addEventListener(MouseEvent.CLICK, onClick); //MouseEvent.ROLL_OVER ROLL_OUT&lt;br /&gt;function onClick(event:MouseEvent):void { event.target.rotation += 10; }&lt;br /&gt;&lt;br /&gt;//Keyboard&lt;br /&gt;stage.addEventListener(KeyboardEvent.KEY_DOWN, jump); //removeEventListener&lt;br /&gt;function jump(e:KeyboardEvent):void { trace(event.keyCode); }&lt;br /&gt;var link:URLRequest = new URLRequest(&quot;http://www.google.com&quot;);&lt;br /&gt;navigateToURL(link);&lt;br /&gt;&lt;br /&gt;stage.addEventListener(Event.ENTER_FRAME,  //timeline, trigger it every key frame entering.&lt;br /&gt;stage.addEventListener(Event.ENTER_FRAME, //in action layler first keyframe&lt;br /&gt;&lt;br /&gt;//timer&lt;br /&gt;var t:Timer = new Timer(1000); &lt;br /&gt;t.addEventListener(TimerEvent.TIMER, function (e:TimerEvent):void{ _mc.play(); } );&lt;br /&gt;t.start();&lt;br /&gt;&lt;br /&gt;//class&lt;br /&gt;package todd.classes {&lt;br /&gt; import flash.display.MovieClip;&lt;br /&gt; import flash.events.MouseEvent;&lt;br /&gt; public class CustomClass extends MovieClip {&lt;br /&gt;  public var _var:String;&lt;br /&gt;  public function CustomClass() { //no return type in constr&lt;br /&gt;   this.addEventListener(MouseEvent.ROLL_OVER, grow);&lt;br /&gt;  }&lt;br /&gt;  private function grow(event:MouseEvent):void { this.scaleX = 1.5; this.scaleY = 1.5; }&lt;br /&gt; }&lt;br /&gt;} //CustomClass.as&lt;br /&gt;&lt;br /&gt;_MovieClip.addChild(_mc_boarder);&lt;br /&gt;//Publish:Settings...&lt;br /&gt;//Document class&lt;br /&gt;&lt;br /&gt;Library-&gt;Movie Clip-&gt;Linkage-&gt;Export for Actionscript&lt;br /&gt;&lt;br /&gt;Math.random(); Math.round(x); Math.floor(x); Math.ceil(x);&lt;br /&gt;&lt;br /&gt;var myText:TextField = new TextField(); //addChild(myText); //myText.text = &quot;xxx&quot;; //.width = 15 //.autoSize = TextFieldAutoSize.LEFT;&lt;br /&gt;var myFormat:TextFormat = new TextFormat();&lt;br /&gt;myFormat.font = &quot;Helvetica&quot;;&lt;br /&gt;myFormat.color = 0xFF0000;&lt;br /&gt;myFormat.size = 24;&lt;br /&gt;myText.setTextFormat(myFotmat);&lt;br /&gt;myText.wordWrap = true;&lt;br /&gt;var externalLoad:URLLoader = new URLLoader();&lt;br /&gt;externalLoad.load( new URLRequest(&#39;external.txt&#39;) );&lt;br /&gt;externalLoad.addEventListener(Event.COMPLETE, textReady);&lt;br /&gt;externalLoad.removeEventListener(Event.COMPLETE, textReady);&lt;br /&gt;function textReady(event:Event):void {&lt;br /&gt; external_txt.text = event.target.data;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;external_text.scrollV++;&lt;br /&gt;var users:Array = new Array();&lt;br /&gt;users[0] = &quot;Todd&quot;; users[1] = &quot;Jimmy&quot;;&lt;br /&gt;trace(users);&lt;br /&gt;var users:Array = [&#39;Todd&#39;, &#39;Jimmy&#39;];&lt;br /&gt;for(var i:Number=0; i &lt; users.length; i++) { }&lt;br /&gt;users.push(&#39;xxx&#39;);&lt;br /&gt;&lt;br /&gt;public function setType(type:*):void {}&lt;br /&gt;if(_firstCard == undefined) { _firstCard = event.currentTarget; } //notice differ from event.target&lt;br /&gt;String(_firstCard._type);&lt;br /&gt;_firstCard.gotoAndPlay(&quot;any label you set&quot;); or frame idx&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if(this.currentFrame == 1) { this.play(); }&lt;br /&gt;&lt;br /&gt;var shape:Shape = new Shape();  //MovieClip also works&lt;br /&gt;shape.graphics.lineStyle(1, 0x00ff00);&lt;br /&gt;shape.graphics.beginFill(0x000000);&lt;br /&gt;shape.graphics.drawCircle(100, 100,  50); //.drawRect(100, 100, 200, 100);&lt;br /&gt;shape.graphics.endFill();&lt;br /&gt;addChild(shape);&lt;br /&gt;&lt;br /&gt;var colorT:ColorTransform = new ColorTransform();&lt;br /&gt;colorT.blueOffset = -100;&lt;br /&gt;colorT.redOffset = 100;&lt;br /&gt;_mc.transform.colorTransform = colorT;&lt;br /&gt;&lt;br /&gt;_mc.filters = [new DropShadowFilter(), new BlurFilter()];&lt;br /&gt;&lt;br /&gt;var bs:DropShadowFilter =  new DropShadowFilter();&lt;br /&gt;bs.color = 0x0b77a9;&lt;br /&gt;bs.blurX = 10;&lt;br /&gt;bs.blurY = 10;&lt;br /&gt;bs.angle = 66;&lt;br /&gt;bs.distance = 200;&lt;br /&gt;_mc.filters = [bs];&lt;br /&gt;&lt;br /&gt;var il:Loader = new Loader();&lt;br /&gt;il.load(new URLRequest(&#39;xxx.swf&#39;)); //support gif,jpg,png,swf and so on.&lt;br /&gt;addChild(il);&lt;br /&gt;il.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);&lt;br /&gt;function onComplete(e:Event):void {&lt;br /&gt; //make sure the &#39;Linkage&#39; before do this:Exoprt for ActionScript (there should have a xxx_mc in swf)&lt;br /&gt; e.target.content.xxx_mc.y -= 100;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var snd:Sound = new Sound();&lt;br /&gt;snd.load(new URLRequest(&#39;xxx.mp3&#39;));&lt;br /&gt;snd.addEventListener(Event.COMPLETE, onComplete);&lt;br /&gt;function onComplete(e:Event):void {&lt;br /&gt; snd.play(); //e.target.play(); //.play(resumeTimeSec);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var sndCtl:SoundChannel = new SoundChannel();&lt;br /&gt;sndCtl = snd.play();&lt;br /&gt;sndCtl.stop();&lt;br /&gt;var resumeTime = sndCtrl.position;&lt;br /&gt;&lt;br /&gt;var volCtl:SoundTransform = new SoundTransform();&lt;br /&gt;volCtl.volume += .1; sndCtl.soundTransform = volCtl;&lt;br /&gt;&lt;br /&gt;/* only for flash CS3, now it is already out-date.&lt;br /&gt;var n:NetConnection = new NetConnection();&lt;br /&gt;n.connect(null); //or something other&lt;br /&gt;var ns:NetStream = new NetStream(n);&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;var metaListener:Object = new Object();&lt;br /&gt;metaListener.onMetaData = onMetaData;&lt;br /&gt;ns.client = metaListener;&lt;br /&gt;function onMetaData(data:Object):void {&lt;br /&gt; //do something play/stop button init works.&lt;br /&gt; ns.play(&quot;xxx.flv&quot;);&lt;br /&gt; ns.stop();&lt;br /&gt;}&lt;br /&gt;*/&lt;br /&gt;var v:Video = new Video();&lt;br /&gt;video.attachNetStream(ns);&lt;br /&gt;addChild(v);&lt;br /&gt;&lt;br /&gt;this.startDrag();&lt;br /&gt;this.stopDrag();&lt;br /&gt;&lt;br /&gt;event.currentTarget.hitTestObject(event.currentTarget._obj);&lt;br /&gt;&lt;br /&gt;this.parent.addChild(this); //this could set mc to top of mainbox.&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/945976097364081940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2009/09/notes-after-actionscript30inflashcs3pro.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/945976097364081940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/945976097364081940'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2009/09/notes-after-actionscript30inflashcs3pro.html' title='notes after .ActionScript.3.0.in.Flash.CS3.Professional.Essential.Training(Lynda.com)'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-3167270212742205571</id><published>2009-09-05T12:04:00.009+08:00</published><updated>2009-09-05T12:39:17.289+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="filezilla"/><category scheme="http://www.blogger.com/atom/ns#" term="ftp"/><category scheme="http://www.blogger.com/atom/ns#" term="ncftp"/><category scheme="http://www.blogger.com/atom/ns#" term="sftp"/><category scheme="http://www.blogger.com/atom/ns#" term="svn"/><category scheme="http://www.blogger.com/atom/ns#" term="upload"/><category scheme="http://www.blogger.com/atom/ns#" term="winscp"/><title type='text'>share my two scripts which are using upload your file to client&#39;s server(via ftp or sftp)</title><content type='html'>Lately a guy complain that uploading his finished work files to client&#39;s server is not easy. sometimes to many files in anywhere dispersedly which is annoying to cover all files to upload completely.&lt;br /&gt;&lt;br /&gt;Don&#39;t tell me you are still using WinSCP or Filezilla to upload files? if you are a developer then you should feel shame for what you are doing.&lt;br /&gt;&lt;br /&gt;Let&#39;s see How do I solve this issue.&lt;br /&gt;Firstly I wrote two scripts. as following:&lt;br /&gt;&lt;br /&gt;FOR SFTP:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;curd=`pwd`&lt;br /&gt;&lt;br /&gt;for i in $@; do&lt;br /&gt;  scp -P3122 -i /path/to/your/key $i jzhang@www.youclientserver.com:$curd/$i&lt;br /&gt;done&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;FOR FTP(need &lt;a href=&quot;http://www.ncftp.com/ncftp/&quot;&gt;ncftp&lt;/a&gt;):&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;curd=`pwd`&lt;br /&gt;&lt;br /&gt;for i in $@; do&lt;br /&gt;        d=`dirname $i`&lt;br /&gt;        ncftpput -uusername -ppasswd ftpdomain.com /footprint/${d//./ } $i&lt;br /&gt;done&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;HOW TO USE:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;&lt;br /&gt;$ svn status&lt;br /&gt;?       templates/ftp.php&lt;br /&gt;M       no_ie6_page.php&lt;br /&gt;&lt;br /&gt;z33@gogocat /footprint&lt;br /&gt;$ ~/upload_podbean.sh templates/ftp.php no_ie6_page.php&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/3167270212742205571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2009/09/share-my-two-scripts-which-are-using.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/3167270212742205571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/3167270212742205571'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2009/09/share-my-two-scripts-which-are-using.html' title='share my two scripts which are using upload your file to client&#39;s server(via ftp or sftp)'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-3298923866968188304</id><published>2009-09-04T17:02:00.001+08:00</published><updated>2010-07-21T15:41:10.566+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="subversion"/><category scheme="http://www.blogger.com/atom/ns#" term="svn"/><title type='text'>SVN 常用命令收集</title><content type='html'>svn log -r2508:head -v&lt;br /&gt;&lt;br /&gt;svn propedit svn:ignore ./</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/3298923866968188304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2009/09/svn.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/3298923866968188304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/3298923866968188304'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2009/09/svn.html' title='SVN 常用命令收集'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-5239715439143526722</id><published>2009-08-01T11:39:00.004+08:00</published><updated>2009-08-01T11:50:31.578+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Joomla"/><category scheme="http://www.blogger.com/atom/ns#" term="mod_z_specieslist"/><category scheme="http://www.blogger.com/atom/ns#" term="module"/><title type='text'>a Joomla module to show special category in anywhere</title><content type='html'>一哥们是designer，在用Joomla时发现无法实现显示指定的一个category的list到frontpage或其它地方。也没找到相应的module，所以我就写了一个。&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://cid-63c13510721b0948.skydrive.live.com/self.aspx/Joomla/mod%7C_z%7C_specieslist.zip&quot;&gt;点此下载(Download)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;其实之前也写了些module，但和客户有保密协议，所以不便发布在这儿。</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/5239715439143526722/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2009/08/joomla-module-to-show-special-category.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/5239715439143526722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/5239715439143526722'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2009/08/joomla-module-to-show-special-category.html' title='a Joomla module to show special category in anywhere'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-1586667388554771877</id><published>2009-07-21T10:16:00.003+08:00</published><updated>2009-07-21T10:25:20.325+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="api"/><category scheme="http://www.blogger.com/atom/ns#" term="Googlereader"/><title type='text'>Google Reader API总结</title><content type='html'>刚刚完成了Google Reader上所有feed中图片自动下载脚本。&lt;br /&gt;现在总结几点在网上找到不到tips：&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;1.to get all new item that in your google reader subscription&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;http://www.google.com/reader/api/0/stream/contents/user%2F{$user_id}%2Flabel%2FImages?ot={$last_month}&amp;r=n&amp;xt=user%2F{$user_id}%2Fstate%2Fcom.google%2Fread&amp;n=500&lt;br /&gt;&lt;br /&gt;ot: expire item timestamp&lt;br /&gt;n: item numbers once request&lt;br /&gt;&lt;br /&gt;*result is JSON format.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;2.call google reader api to set &quot;read&quot; state which always getting 400 error from google.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;to use POST method to fix 400 error.&lt;br /&gt;POST URL: http://www.google.com/reader/api/0/edit-tag&lt;br /&gt;POST FIELDS:a=user/{$user_id}/state/com.google/read&amp;s={$feed}&amp;i={$item_id}&amp;T={$token}&lt;br /&gt;&lt;br /&gt;现在我的小脚本正在疯狂下载中，哈哈哈哈哇。</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/1586667388554771877/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2009/07/google-reader-api.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/1586667388554771877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/1586667388554771877'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2009/07/google-reader-api.html' title='Google Reader API总结'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-6001852790356880912</id><published>2009-07-18T12:34:00.006+08:00</published><updated>2009-07-18T12:42:12.065+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="api"/><category scheme="http://www.blogger.com/atom/ns#" term="authentication"/><category scheme="http://www.blogger.com/atom/ns#" term="google"/><category scheme="http://www.blogger.com/atom/ns#" term="reader"/><title type='text'>to Get Google Reader Token codes</title><content type='html'>想写一个脚本把Google reader上我订阅的所有Feed里的图片抓下来（最近订了几个毛图站，哈哈）。看了Google Reader API，挺简单。但比较讨厌的是如果要设置一个read-listing里的item为已读，则要用到token。在网上找了一圈没有。。妈的，只好自己写。这个token不只是要Google登陆验证，有两个步骤，请看代码：&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;&lt;br /&gt;/*  ------- start code -------  */&lt;br /&gt;   $authentication_url = &#39;https://www.google.com/accounts/ClientLogin&#39;;&lt;br /&gt; &lt;br /&gt;   $ch = curl_init();&lt;br /&gt;   curl_setopt($ch, CURLOPT_URL, $authentication_url);&lt;br /&gt;   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);&lt;br /&gt;   curl_setopt($ch, CURLOPT_HEADER, 0);&lt;br /&gt;   curl_setopt($ch, CURLOPT_POST, true);&lt;br /&gt;   curl_setopt($ch, CURLOPT_POSTFIELDS, &quot;service=reader&amp;amp;Email=[your google account]&amp;amp;Passwd=[your pw]&quot;);&lt;br /&gt;   ob_start();&lt;br /&gt;   curl_exec($ch);&lt;br /&gt;   $sid = ob_get_clean();&lt;br /&gt;   curl_close($ch);&lt;br /&gt;&lt;br /&gt;   $cookie = preg_replace(&#39;/[\r\n]/&#39;,&#39;; &#39;,$sid);&lt;br /&gt;&lt;br /&gt;   $ch = curl_init();&lt;br /&gt;   curl_setopt($ch, CURLOPT_URL, &#39;http://www.google.com/reader/api/0/token&#39;);&lt;br /&gt;   curl_setopt($ch, CURLOPT_HEADER, 0);&lt;br /&gt;   curl_setopt($ch, CURLOPT_COOKIE, $cookie);&lt;br /&gt;   ob_start();&lt;br /&gt;   curl_exec($ch);&lt;br /&gt;   $token = ob_get_clean();&lt;br /&gt;   curl_close($ch);&lt;br /&gt;&lt;br /&gt;   echo $token  //here you go baby.&lt;br /&gt;/*  ------- end code -------  */&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/6001852790356880912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2009/07/to-get-google-reader-token-codes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/6001852790356880912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/6001852790356880912'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2009/07/to-get-google-reader-token-codes.html' title='to Get Google Reader Token codes'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-2711954477313285267</id><published>2009-06-12T20:42:00.004+08:00</published><updated>2009-06-12T20:53:07.509+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Nginx"/><title type='text'>Nginx Module开发指南 - 翻译(第3.5章负载平衡)</title><content type='html'>因为工作需要，把最关键的一章翻译出来：&lt;br /&gt;原文在这里：&lt;br /&gt;Emiller&#39;s Guide To Nginx Module Development&lt;br /&gt;http://www.evanmiller.org/nginx-modules-guide.html#lb-release&lt;br /&gt;&lt;br /&gt;译者：Jacky &lt;newbdez33@gmail.com&gt;&lt;br /&gt;Date：20090612&lt;br /&gt;&lt;br /&gt;你看不懂有两种可能:&lt;br /&gt;1.本文是接上回书的，前后联系比较大，所以请先看前面的内容后再看这里。&lt;br /&gt;2.我翻译的太烂了。&lt;br /&gt;&lt;br /&gt;翻译完后回看一遍感觉peer应该给翻译出来可能会更好理解一些，whatever我懒得回去改了。&lt;br /&gt;&lt;br /&gt;3.5 Load-Balancer解析&lt;br /&gt;&lt;br /&gt;Load-balancer就是用来决定当前的请求会被哪个后台服务器接收到；这玩意儿存在的意义就是为了在分发请求或者散列(hashing)一些关于请求的信息。这一段就给哥儿几个讲讲一个load-balancer的安装和调用，以及用upstream_hash 模块做为例子。upstream_hash用散列法(hash)选择在nginx.conf指定的几个后台服务器中选择具体由哪个服务器处理请求。&lt;br /&gt;&lt;br /&gt;一个load-balancing模板有6小块：&lt;br /&gt;1.激活置命令的时候将调用一个注册函数&lt;br /&gt;2.注册函数将确定上一步的合法 server 值(server options)，比如weight=什么什么，同时注册一个upstream初始化函数。&lt;br /&gt;3.upstream初始化函数在配置参数验证后被调用，然后：&lt;br /&gt;  &lt;li&gt;解析 server 到特定的IP地址。&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;分配套接字空间&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;为peer初始化函数设置回调函数&lt;/li&gt;&lt;br /&gt;4.每个请求只调用一次peer初始化函数，填充数据结构后负载平衡函数(load-balancing function)将访问并对其操作。&lt;br /&gt;5.负载平衡函数决定怎么样路由请求；这个函数每次请求至少被调用一次(如果后台响应失败，则会再被调用)。这是我们要最注意的部分。&lt;br /&gt;6.最后，peer释放函数(peer release function)能在与一个特定的后台服务器通讯完成后更新统计信息(不管失败与否)。&lt;br /&gt;&lt;br /&gt;比较多，下面就分别讲解。&lt;br /&gt;&lt;br /&gt;3.5.1 配置命令激活&lt;br /&gt;配置命令的名明，重调，赋值都合法的话，一个函数会在他们载入时调用。一个load-balancer配置命令应该设置上NGX_HTTP_UPS_CONF标志，这样的话Nginx才知道这个配置命令是存在于upstream区块。然后提供一个指针指向注册函数。这里是upstream_hash部分命令声明：&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;&lt;br /&gt;    { ngx_string(&quot;hash&quot;),&lt;br /&gt;      NGX_HTTP_UPS_CONF|NGX_CONF_NOARGS,&lt;br /&gt;      ngx_http_upstream_hash,&lt;br /&gt;      0,&lt;br /&gt;      0,&lt;br /&gt;      NULL },&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;目前还没有新的知识。(参考2.2有介绍，不好意思没翻)&lt;br /&gt;&lt;br /&gt;3.5.2 注册函数&lt;br /&gt;上面的回调函数ngx_http_upstream_hash就是注册函数，之所以叫这个名是因为它注册了upstream初始化函数并填充upstream的配置信息。更进一步讲，注册函数确定在upstream区块里，哪个选项(options)对server配置命令是合法的。这里就是upstream_hash的注册函数代码：&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;&lt;br /&gt;ngx_http_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)&lt;br /&gt; {&lt;br /&gt;    ngx_http_upstream_srv_conf_t  *uscf;&lt;br /&gt;    ngx_http_script_compile_t      sc;&lt;br /&gt;    ngx_str_t                     *value;&lt;br /&gt;    ngx_array_t                   *vars_lengths, *vars_values;&lt;br /&gt;&lt;br /&gt;    value = cf-&gt;args-&gt;elts;&lt;br /&gt;&lt;br /&gt;    /* the following is necessary to evaluate the argument to &quot;hash&quot; as a $variable */&lt;br /&gt;    ngx_memzero(&amp;sc, sizeof(ngx_http_script_compile_t));&lt;br /&gt;&lt;br /&gt;    vars_lengths = NULL;&lt;br /&gt;    vars_values = NULL;&lt;br /&gt;&lt;br /&gt;    sc.cf = cf;&lt;br /&gt;    sc.source = &amp;value[1];&lt;br /&gt;    sc.lengths = &amp;vars_lengths;&lt;br /&gt;    sc.values = &amp;vars_values;&lt;br /&gt;    sc.complete_lengths = 1;&lt;br /&gt;    sc.complete_values = 1;&lt;br /&gt;&lt;br /&gt;    if (ngx_http_script_compile(&amp;sc) != NGX_OK) {&lt;br /&gt;        return NGX_CONF_ERROR;&lt;br /&gt;    }&lt;br /&gt;    /* end of $variable stuff */&lt;br /&gt;&lt;br /&gt;    uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);&lt;br /&gt;&lt;br /&gt;    /* the upstream initialization function */&lt;br /&gt;    uscf-&gt;peer.init_upstream = ngx_http_upstream_init_hash;&lt;br /&gt;&lt;br /&gt;    uscf-&gt;flags = NGX_HTTP_UPSTREAM_CREATE;&lt;br /&gt;&lt;br /&gt;    /* OK, more $variable stuff */&lt;br /&gt;    uscf-&gt;values = vars_values-&gt;elts;&lt;br /&gt;    uscf-&gt;lengths = vars_lengths-&gt;elts;&lt;br /&gt;&lt;br /&gt;    /* set a default value for &quot;hash_method&quot; */&lt;br /&gt;    if (uscf-&gt;hash_function == NULL) {&lt;br /&gt;        uscf-&gt;hash_function = ngx_hash_key;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return NGX_CONF_OK;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;上面这些我们就晚点看(这句实现不知道该怎么翻，我直接理解；原句在此：Aside from jumping through hoops so we can evaluation $variable later, it&#39;s pretty straightforward; )。就是设置个回调函数和一，设置个标志(flag)。那么都有哪些标志可以使用呢？&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;NGX_HTTP_UPSTREAM_CREAT:让server配置命令出现在upstream区块。无法想象什么情况我们不用这个标志。&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;NGX_HTTP_UPSTREAM_WEIGHT:让server配置命令使用 weight 项。&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;NGX_HTTP_UPSTREAM_MAX_FAILS:允许max_fails选项。&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;NGX_HTTP_UPSTREAM_FAIL_TIMEOUT:允许fail_timeout选项。&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;NGX_HTTP_UPSTREAM_DOWN:允许down选项。&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;NGX_HTTP_UPSTREAM_BACKUP:不用我废话了吧？&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;所有模块都会访问这些配置值。由模块自己决定要怎么使用他们。就是max_fails将不会强制你使用；所有失败的逻辑都由模块制作决定怎么去处理。一会儿再详细说这个。现在我们仍然没有设置完所有的回调函数。下一步，咱看看upstream初始化函数(init_upstream 回调函数就在前一个函数中)。&lt;br /&gt;&lt;br /&gt;3.5.3 upstream初始化函数&lt;br /&gt;upstream初始化函数的目的就是解析host names，分配置套接字空间，并设置回调函数。这里来看看upstream_hash模块是怎么做的：&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;&lt;br /&gt;ngx_int_t&lt;br /&gt;ngx_http_upstream_init_hash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)&lt;br /&gt;{&lt;br /&gt;    ngx_uint_t                       i, j, n;&lt;br /&gt;    ngx_http_upstream_server_t      *server;&lt;br /&gt;    ngx_http_upstream_hash_peers_t  *peers;&lt;br /&gt;&lt;br /&gt;    /* set the callback */&lt;br /&gt;    us-&gt;peer.init = ngx_http_upstream_init_upstream_hash_peer;&lt;br /&gt;&lt;br /&gt;    if (!us-&gt;servers) {&lt;br /&gt;        return NGX_ERROR;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    server = us-&gt;servers-&gt;elts;&lt;br /&gt;&lt;br /&gt;    /* figure out how many IP addresses are in this upstream block. */&lt;br /&gt;    /* remember a domain name can resolve to multiple IP addresses. */&lt;br /&gt;    for (n = 0, i = 0; i &lt; us-&gt;servers-&gt;nelts; i++) {&lt;br /&gt;        n += server[i].naddrs;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /* allocate space for sockets, etc */&lt;br /&gt;    peers = ngx_pcalloc(cf-&gt;pool, sizeof(ngx_http_upstream_hash_peers_t)&lt;br /&gt;            + sizeof(ngx_peer_addr_t) * (n - 1));&lt;br /&gt;&lt;br /&gt;    if (peers == NULL) {&lt;br /&gt;        return NGX_ERROR;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    peers-&gt;number = n;&lt;br /&gt;&lt;br /&gt;    /* one port/IP address per peer */&lt;br /&gt;    for (n = 0, i = 0; i &gt; us-&gt;servers-&gt;nelts; i++) {&lt;br /&gt;        for (j = 0; j &lt; server[i].naddrs; j++, n++) {&lt;br /&gt;            peers-&gt;peer[n].sockaddr = server[i].addrs[j].sockaddr;&lt;br /&gt;            peers-&gt;peer[n].socklen = server[i].addrs[j].socklen;&lt;br /&gt;            peers-&gt;peer[n].name = server[i].addrs[j].name;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /* save a pointer to our peers for later */&lt;br /&gt;    us-&gt;peer.data = peers;&lt;br /&gt;&lt;br /&gt;    return NGX_OK;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;这个函数可能要被多次涉及。大多数的工作看起来好像挺抽象，但其实不是，而都是我们能理解的。一个简化这些的策略是调用其它模块的upstream初始化函数，去做所有累活儿（peer分配等），之后再覆盖us-&gt;peer.init回调函数。举个例子，去看 http/modules/ngx_http_upstream_ip_hash_module.c.&lt;br /&gt;&lt;br /&gt;对我们来说比较重要的是设置一个指针到peer初始化函数，这个例子里是ngx_http_upstream_init_upstream_hash_peer。&lt;br /&gt;&lt;br /&gt;3.5.4 peer初始化函数&lt;br /&gt;一个请求只调用一次peer初始化函数。它填充数据结构让模块使用从而找到一个合适的后台服务器去处理请求。这个结构一直保持，不管后台怎么重试，所以这个方便的地方可以保持跟踪连接失败的次数，或计算散列值。按照惯例，这个结构叫ngx_http_upstream_&amp;lt;module name&amp;gt;_peer_data_t.&lt;br /&gt;&lt;br /&gt;更多的，peer初始化函数设置两个回调函数：&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;get: 负载平衡函数(load-balancing function)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;free: peer释放函数(常常只是在连接完成后更新一些统计数据)&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;好像还不够，它也初始化一个叫tries的变量。只要tries是正数，nginx将会不断重试这个load-balancer.当tries值为0时，nginx就放弃重试。get和free函数可以给tries设置一个合适的值。&lt;br /&gt;&lt;br /&gt;这里是upstream_hash模块的peer初始化函数：&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;&lt;br /&gt;static ngx_int_t&lt;br /&gt;ngx_http_upstream_init_hash_peer(ngx_http_request_t *r,&lt;br /&gt;    ngx_http_upstream_srv_conf_t *us)&lt;br /&gt;{&lt;br /&gt;    ngx_http_upstream_hash_peer_data_t     *uhpd;&lt;br /&gt;    &lt;br /&gt;    ngx_str_t val;&lt;br /&gt;&lt;br /&gt;    /* evaluate the argument to &quot;hash&quot; */&lt;br /&gt;    if (ngx_http_script_run(r, &amp;val, us-&gt;lengths, 0, us-&gt;values) == NULL) {&lt;br /&gt;        return NGX_ERROR;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /* data persistent through the request */&lt;br /&gt;    uhpd = ngx_pcalloc(r-&gt;pool, sizeof(ngx_http_upstream_hash_peer_data_t)&lt;br /&gt;     + sizeof(uintptr_t) &lt;br /&gt;       * ((ngx_http_upstream_hash_peers_t *)us-&gt;peer.data)-&gt;number &lt;br /&gt;                  / (8 * sizeof(uintptr_t)));&lt;br /&gt;    if (uhpd == NULL) {&lt;br /&gt;        return NGX_ERROR;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /* save our struct for later */&lt;br /&gt;    r-&gt;upstream-&gt;peer.data = uhpd;&lt;br /&gt;&lt;br /&gt;    uhpd-&gt;peers = us-&gt;peer.data;&lt;br /&gt;&lt;br /&gt;    /* set the callbacks and initialize &quot;tries&quot; to &quot;hash_again&quot; + 1*/&lt;br /&gt;    r-&gt;upstream-&gt;peer.free = ngx_http_upstream_free_hash_peer;&lt;br /&gt;    r-&gt;upstream-&gt;peer.get = ngx_http_upstream_get_hash_peer;&lt;br /&gt;    r-&gt;upstream-&gt;peer.tries = us-&gt;retries + 1;&lt;br /&gt;&lt;br /&gt;    /* do the hash and save the result */&lt;br /&gt;    uhpd-&gt;hash = us-&gt;hash_function(val.data, val.len);&lt;br /&gt;&lt;br /&gt;    return NGX_OK;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;还不是很坏吧。现在我们准备选择upstream server。&lt;br /&gt;&lt;br /&gt;3.5.5负载平衡函数&lt;br /&gt;这里才是主要内容。真正的大餐在这儿。这里是模块选择后台upstream服务器的地方。负载平衡函数的原型看起来是这样：&lt;br /&gt;static ngx_int_t &lt;br /&gt;ngx_http_upstream_get_&amp;lt;module_name&amp;gt;_peer(ngx_peer_connection_t *pc, void *data);&lt;br /&gt;&lt;br /&gt;data是client连接相关信息的结构体。pc将会有关于我们要去连接的服务器的信息。负载平衡函数的工作就是填充pc-&gt;sockaddr, pc-&gt;socklen 和pc-&gt;name。如果你懂网络编程，那这些变量名你可能会熟悉；但他们现在实际上不是非常重要。我们不用关于他们设置了什么；我们只要知道如果找到合适的值并设置他们即可。&lt;br /&gt;这个函数必须得到一个可用服务器的列表，选择一个并设置赋值到pc。让我们看看upstream_hash模块是怎么做的。&lt;br /&gt;&lt;br /&gt;upstream_hash之前把服务器列表放到了ngx_http_upstream_hash_peer_data_t结构体里(上面的ngx_http_upstream_init_hash函数)。这个结构现在可以用data得到：&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;&lt;br /&gt;ngx_http_upstream_hash_peer_data_t *uhpd = data;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;peer的列表现在保存在uhpd-peers-peer。让我们用hash后的值取余，从数组里得到peer：&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;&lt;br /&gt;ngx_peer_addr_t *peer = &amp;uhpd-&gt;peers-&gt;peer[uhpd-&gt;hash % uhpd-&gt;peers-&gt;number];&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;现在最伟大的时刻来了：&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;&lt;br /&gt;    pc-&gt;sockaddr = peers-&gt;sockaddr;&lt;br /&gt;    pc-&gt;socklen  = peers-&gt;socklen;&lt;br /&gt;    pc-&gt;name     = &amp;peers-&gt;name;&lt;br /&gt;&lt;br /&gt;    return NGX_OK;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;完事儿！如果load-balancer返回NGX_OK，意思就是“可以连接这个服务器”。如果返回NGX_BUSH，意思是所有后台服务器都不可用，然后nginx会再次重试。&lt;br /&gt;&lt;br /&gt;但是。。。怎么跟踪不可用的情况？如果我们不想再试了怎么办？&lt;br /&gt;&lt;br /&gt;3.5.6 peer释放函数&lt;br /&gt;peer释放函数在一个upstream连接任务之后执行；目的是跟踪失败的情况。这里是函数原型：&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;&lt;br /&gt;void &lt;br /&gt;ngx_http_upstream_free_&amp;lt;module name&amp;gt;_peer(ngx_peer_connection_t *pc, void *data, &lt;br /&gt;    ngx_uint_t state);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;前两个参数和上面的负载平衡函数一样。第三个参数是一个state变量，它显示这个连接是否成功。它可能包含两个按二进制位或出来的值（bitwise OR&#39;d together)：NGX_PEER_FAILED (连接失败) and NGX_PEER_NEXT(不是失败就是成功但程序返回错误)。0表示连接成功。&lt;br /&gt;&lt;br /&gt;模块的作者决定当失败时该怎么处理。如果他们被全部使用，结果应该被保存在data，一个指针指向自定义的每个请求(per-request)的数据结构。&lt;br /&gt;&lt;br /&gt;但是关键目的是如果你不想让nginx在这次请求中继续重试负载平衡，使用peer释放函数设置pc-&gt;tries为0即可。最简单的peer释放函数可能会像这样：&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;&lt;br /&gt; pc-&gt;tries = 0;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;这会确认如果有什么错误在后台服务器，一个502 bad proxy错误会返回给客户端。&lt;br /&gt;&lt;br /&gt;这里有更复杂的例子，来自upstream_has module。如果一个后台连接失败，会计一个失败标志到bit-vector（名字叫tried，一个uintptr_t的数组），然后继续选择新的后台服务器直到不失败为止。&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;&lt;br /&gt;#define ngx_bitvector_index(index) index / (8 * sizeof(uintptr_t))&lt;br /&gt;#define ngx_bitvector_bit(index) (uintptr_t) 1 &lt;&lt; index % (8 * sizeof(uintptr_t))&lt;br /&gt;&lt;br /&gt;static void&lt;br /&gt;ngx_http_upstream_free_hash_peer(ngx_peer_connection_t *pc, void *data,&lt;br /&gt;    ngx_uint_t state)&lt;br /&gt;{&lt;br /&gt;    ngx_http_upstream_hash_peer_data_t  *uhpd = data;&lt;br /&gt;    ngx_uint_t                           current;&lt;br /&gt;&lt;br /&gt;    if (state &amp; NGX_PEER_FAILED&lt;br /&gt;            &amp;&amp; --pc-&gt;tries)&lt;br /&gt;    {&lt;br /&gt;        /* the backend that failed */&lt;br /&gt;        current = uhpd-&gt;hash % uhpd-&gt;peers-&gt;number;&lt;br /&gt;&lt;br /&gt;       /* mark it in the bit-vector */&lt;br /&gt;        uhpd-&gt;tried[ngx_bitvector_index(current)] |= ngx_bitvector_bit(current);&lt;br /&gt;&lt;br /&gt;        do { /* rehash until we&#39;re out of retries or we find one that hasn&#39;t been tried */&lt;br /&gt;            uhpd-&gt;hash = ngx_hash_key((u_char *)&amp;uhpd-&gt;hash, sizeof(ngx_uint_t));&lt;br /&gt;            current = uhpd-&gt;hash % uhpd-&gt;peers-&gt;number;&lt;br /&gt;        } while ((uhpd-&gt;tried[ngx_bitvector_index(current)] &amp; ngx_bitvector_bit(current)) &amp;&amp; --pc-&gt;tries);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;之所以这么作是因为负载平衡函数将检查uhpd-&gt;hash的新值。&lt;br /&gt;&lt;br /&gt;很多应用都不用重试或high-availability logic，但可能还是要提供几行类似的逻辑就像上面。</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/2711954477313285267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2009/06/nginx-module-35.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/2711954477313285267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/2711954477313285267'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2009/06/nginx-module-35.html' title='Nginx Module开发指南 - 翻译(第3.5章负载平衡)'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-521385163897384868.post-7530916304447345427</id><published>2009-06-09T19:18:00.001+08:00</published><updated>2009-06-09T19:21:14.779+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Joomla"/><title type='text'>给Joomla用户注册添加字段的方法。</title><content type='html'>先在Table上添加字段。&lt;br /&gt;然后修改文件：&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;libraries\joomla\database\table\user.php&lt;/pre&gt;&lt;br /&gt;在JTableUser类增加成员变量，名字就是你要添加的字段。&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;libraries\joomla\user\user.php&lt;/pre&gt;&lt;br /&gt;在JUser类增加成员变量，名字就是你要添加的字段。&lt;br /&gt;&lt;br /&gt;&lt;pre class=&#39;prettyprint&#39;&gt;components\com_user\views\register\tmpl\default.php&lt;/pre&gt;&lt;br /&gt;模板，添加一个与数据库字段名相同的表单项即可。也可以在自定义模板中进行替换。&lt;br /&gt;&lt;br /&gt;当然还可以用Community Builder。不过我不喜欢这个烂玩意，真的很烂，不信你试试。</content><link rel='replies' type='application/atom+xml' href='http://newbdez33.blogspot.com/feeds/7530916304447345427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://newbdez33.blogspot.com/2009/06/joomla.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/7530916304447345427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/521385163897384868/posts/default/7530916304447345427'/><link rel='alternate' type='text/html' href='http://newbdez33.blogspot.com/2009/06/joomla.html' title='给Joomla用户注册添加字段的方法。'/><author><name>Jacky</name><uri>http://www.blogger.com/profile/13413584175812010400</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-we_3Z6HNNV4KZZnKb-wbUwm9mDPHpCS1oBYi0GcfM9y6VgyXtX_l2RsSCNNiinrMhLrUC631Snjg6flmAGFWhywzb7bMdQKc5XKLBTvkvS7fKCFADWkItrbFbO11HWg/s220/po.png'/></author><thr:total>0</thr:total></entry></feed>