<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>程式設計 遇上 小提琴 &#187; Open source</title>
	<atom:link href="http://blog.ez2learn.com/tag/open-source/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ez2learn.com</link>
	<description>Victor&#039;s個人部落格，關於程式設計與小提琴</description>
	<lastBuildDate>Tue, 07 Feb 2012 03:26:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>那些台灣軟體產業所缺少的 &#8211; 開放源始碼</title>
		<link>http://blog.ez2learn.com/2011/11/25/taiwan-software-lacking-of-open-source/</link>
		<comments>http://blog.ez2learn.com/2011/11/25/taiwan-software-lacking-of-open-source/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 15:43:19 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[中文文章]]></category>
		<category><![CDATA[作品]]></category>
		<category><![CDATA[嘴砲]]></category>
		<category><![CDATA[開源]]></category>
		<category><![CDATA[License]]></category>
		<category><![CDATA[Licensing]]></category>
		<category><![CDATA[Open source]]></category>
		<category><![CDATA[授權]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=1644</guid>
		<description><![CDATA[前面幾篇談到了台灣軟體產業界常見的毛病，除了工具以外，還有一項令我感到相當意外的，就是我發現台灣業界對於開放源始碼的認知真的很有問題，例如我曾有和別人討論過，跟他們你們可以使用open source的現成資源來減低成本，但是得到的回應很常是 那不是讓你用但之後就要付錢嗎? 從這類的回應就可以大略知道，其實有很多人對於開放源始碼都有一些錯誤的認知，到底什麼時候該付錢、什麼情況可以使用都搞不清楚，因此這回我大算介紹一下一些常見的開源授權的常識 免責聲明 在讀本文前我得先聲明，我不是律師，這不是提供專業的法律見解，只是試著用較易懂的方式解釋授權，以我自己的經驗來說明，其中多少可能會有錯誤，請自行判斷，也歡迎指出錯誤，如有需要請洽詢專業的法律諮詢，在本文末會提到 認識授權 (License) 首先要從授權(License)的概念開始談起，開放源始碼通常不是只是單純把程式碼公開出來，而是一般都會搭配某種授權，而授權的意思，以白話來說，就是寫了一份聲明，裡面這樣提到 此程式任何人可以免費使用，但是使用前你必需遵守以下條款&#8230;. 有了這樣的聲明，使用開源的人就可以放心使用，當然前提是要遵守授權所提出的條款，基本上因為已經授權出來，所以就算是原作者反悔，也沒辦法控告你什麼，除非你違反他當初訂出來的條款，而一般人看見落落長的條款項目可能就怕了，更何況是用英文寫的，但是別擔心，事實上要注意的要點只有幾樣，都大同小異，同一類條款的性質都很類似 散佈(Redistribute) 在理解授權之前，首先要理解散佈，這是授權裡面一定會提到的重要關鍵動作，那麼什麼是散佈呢？ 簡單的來說，就是將軟體轉交給其它人，不管你是以原始碼的形式，或是編成二進制執行檔後，只要是轉交給其它法人，就算是散佈，舉個例子 把原始碼上傳供人下載 把原始碼拿來販售 把原始碼編成執行檔供人下載 把原始碼編成執行檔販售 以上都算是散佈的行為，所有的授權條款裡面都會提到散佈開源程式時你應盡的義務，當然，也有很多行為是稱不上散佈的，例如 將原始碼交給公司內部某個單位 將原始碼編譯成執行檔自己使用 在伺服器上以開源程式執行提功服務給使用者 像這樣沒有法人的經手，都不算是散佈的行為，對於散佈的行為介定是很重要的，等一下會解釋 授權(License)的種類 授權有(License)非常多種，我們在此大略將其分成三大類，第一類是GPL，第二類為BSD，而第三類為商業授權，是較為特別且少見的，其中GPL最不自由，而BSD最自由 &#160; 在這裡自由與不自由主要是指你在使用這些開源軟體時所要盡的義務的多和少 GPL GNU General Public License主要是由Linux陣營的開源軟體開發者為主在使用的，它有幾個特色 散佈要連修改的部份一起開源 病毒的感染性 排它性 散佈與修改 如同我們前面提到的散佈，最重要的重點是，如果你改了程式，而又要散佈程式，那麼你在散佈的同時也要把你修改的部份也公開出來，例如 修改了原始碼後拿來販售 修改了原始碼後編成執行檔供別人使用 上列行為都扯到了散佈，因此如果你程式有修改，你不能只給別人執行檔，要連改的部份一起開源出來，這條款的目的主要是在於GNU的社群，希望強迫使用者能回饋社群，因為一但你改了程式，想拿來賣錢，就得公開出來，避免有人改進了程式，拿來販售，但沒有公開程式的問題 &#8230; <a href="http://blog.ez2learn.com/2011/11/25/taiwan-software-lacking-of-open-source/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>前面幾篇談到了台灣軟體產業界常見的毛病，除了工具以外，還有一項令我感到相當意外的，就是我發現台灣業界對於開放源始碼的認知真的很有問題，例如我曾有和別人討論過，跟他們你們可以使用open source的現成資源來減低成本，但是得到的回應很常是</p>
<blockquote><p>那不是讓你用但之後就要付錢嗎?</p></blockquote>
<p>從這類的回應就可以大略知道，其實有很多人對於開放源始碼都有一些錯誤的認知，到底什麼時候該付錢、什麼情況可以使用都搞不清楚，因此這回我大算介紹一下一些常見的開源授權的常識</p>
<h2>免責聲明</h2>
<p>在讀本文前我得先聲明，我不是律師，這不是提供專業的法律見解，只是試著用較易懂的方式解釋授權，以我自己的經驗來說明，其中多少可能會有錯誤，請自行判斷，也歡迎指出錯誤，如有需要請洽詢專業的法律諮詢，在本文末會提到</p>
<h2>認識授權 (License)</h2>
<p>首先要從授權(License)的概念開始談起，開放源始碼通常不是只是單純把程式碼公開出來，而是一般都會搭配某種授權，而授權的意思，以白話來說，就是寫了一份聲明，裡面這樣提到</p>
<blockquote><p>此程式任何人可以免費使用，但是使用前你必需遵守以下條款&#8230;.</p></blockquote>
<p>有了這樣的聲明，使用開源的人就可以放心使用，當然前提是要遵守授權所提出的條款，基本上因為已經授權出來，所以就算是原作者反悔，也沒辦法控告你什麼，除非你違反他當初訂出來的條款，而一般人看見落落長的條款項目可能就怕了，更何況是用英文寫的，但是別擔心，事實上要注意的要點只有幾樣，都大同小異，同一類條款的性質都很類似</p>
<h2>散佈(Redistribute)</h2>
<p>在理解授權之前，首先要理解散佈，這是授權裡面一定會提到的重要關鍵動作，那麼什麼是散佈呢？ 簡單的來說，就是將軟體轉交給其它人，不管你是以原始碼的形式，或是編成二進制執行檔後，只要是轉交給其它法人，就算是散佈，舉個例子</p>
<blockquote><p>把原始碼上傳供人下載</p>
<p>把原始碼拿來販售</p>
<p>把原始碼編成執行檔供人下載</p>
<p>把原始碼編成執行檔販售</p></blockquote>
<p>以上都算是散佈的行為，所有的授權條款裡面都會提到散佈開源程式時你應盡的義務，當然，也有很多行為是稱不上散佈的，例如</p>
<blockquote><p>將原始碼交給公司內部某個單位</p>
<p>將原始碼編譯成執行檔自己使用</p>
<p>在伺服器上以開源程式執行提功服務給使用者</p></blockquote>
<p>像這樣沒有法人的經手，都不算是散佈的行為，對於散佈的行為介定是很重要的，等一下會解釋</p>
<h2>授權(License)的種類</h2>
<p>授權有(License)非常多種，我們在此大略將其分成三大類，第一類是GPL，第二類為BSD，而第三類為商業授權，是較為特別且少見的，其中GPL最不自由，而BSD最自由</p>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2011/11/licensing.png"><img class="aligncenter size-full wp-image-1651" title="licensing" src="http://blog.ez2learn.com/wp-content/uploads/2011/11/licensing.png" alt="" width="466" height="281" /></a></p>
<p>&nbsp;</p>
<p>在這裡自由與不自由主要是指你在使用這些開源軟體時所要盡的義務的多和少</p>
<h2>GPL</h2>
<p>GNU General Public License主要是由Linux陣營的開源軟體開發者為主在使用的，它有幾個特色</p>
<ul>
<li>散佈要連修改的部份一起開源</li>
<li>病毒的感染性</li>
<li>排它性</li>
</ul>
<h3>散佈與修改</h3>
<p>如同我們前面提到的散佈，最重要的重點是，如果你改了程式，而又要散佈程式，那麼你在散佈的同時也要把你修改的部份也公開出來，例如</p>
<blockquote><p>修改了原始碼後拿來販售</p>
<p>修改了原始碼後編成執行檔供別人使用</p></blockquote>
<p>上列行為都扯到了散佈，因此如果你程式有修改，你不能只給別人執行檔，要連改的部份一起開源出來，這條款的目的主要是在於GNU的社群，希望強迫使用者能回饋社群，因為一但你改了程式，想拿來賣錢，就得公開出來，避免有人改進了程式，拿來販售，但沒有公開程式的問題</p>
<p>當然，如果你的程式只是自己使用，或是公司內部使用，那麼你修改了程式但因為沒有散佈的問題，所以修改的部份也不用因此公開，還有一種情況是，你使用GPL授權的程式放在伺服器上提供服務，因為這過程沒有重新散佈，所以也不會有問題</p>
<p>除了修改以外，還有一個特性，就是病毒的感染性，除了修改程式，如果GPL的原始碼是函式庫，而你的程式連結了GPL授權的程式，不管是靜態連結或動態連結，都會因此被GPL感染，一但你要散佈你的程式，因為用了GPL的函式庫，因此你的主程式也被感染，變成你要把你的主程式一起開源出來，就因為這特性替GPL贏得了「病毒授權」的美名，就跟T病毒一樣，被感染了就會變成殭屍</p>
<p>就因為這樣病毒的特性，讓很多人又愛又恨，很多商業軟體想用某些開源的函式庫，但因為那些函式庫如果是GPL授權，會導至他們的產品本身也受到感染，而因此無法使用，變成非GPL和GPL這兩種可能性，除此之外，有些廠商為了避免被GPL感染，會用一些比較特別的手法來避開</p>
<p>因為這樣感染的特性，加上如此不自由的特質，使得很多可以用上GPL的場合卻因為感染性而無法達成，為了能解決感染的問題，它有推出另一種弱化版的GPL，叫LGPL (Less Generic Public Licence)，這個授權大致上和GPL是一樣的，差別就在於上面提到的連結受感染的問題，連結LGPL的函式庫並不會受到感染，如此一來就算是商業軟體也能安心地使用LGPL的函式庫</p>
<p>接著還有它的排它性，因為授權有很多種，GPL規定它的授權條款不能被修改，這表示你修改了程式要散佈被強迫要開源的話，你也只能選擇GPL的授權，除非你是原作者</p>
<p>你覺得GPL很不自由嗎? 事實上他們覺得GPL還不夠嚴格，正因為GPL陣營的人認為像Google之流的廠商，用了GPL的程式提供服務，不用公佈修改的部份，因此覺得心癢癢的，為此甚至增加了AGPL，更加嚴格的GPL，他的重新散佈的定義，擴增為包括提供服務，因此即使你用了AGPL的程式提功服務，沒有轉交程式給他人，就AGPL的定義，這就算是重新散佈，然而使用AGPL授權的程式其實非常少，像是MongoDB就是使用AGPL授權，正因為LGPL/GPL/AGPL強烈的限制特性，反而使它成為商業軟件開源的最愛授權，對手要修改販授的話也得公開，不想公開的話就得買另外的授權，這就是常見的雙授權商業模式，因此我個人喜歡戲稱GPL為 "商業友善授權"</p>
<h2>類BSD</h2>
<p>如果說GPL是邪惡的病毒授權，那麼類BSD就是自由又開放的授權，相較於GPL相當害怕別人用了GPL的程式不回饋，類BSD就大方許多，它最主要的條款就是，當你散佈修改過的類BSD授權下的程式，一樣不管是二進制的執行檔或原始碼，你要盡的義務就只有記得要把類BSD的授權一起轉交給別人就可以了，包含原作的姓名你也得一併加進去，不能自行亂改</p>
<p>舉個例子，你改了一個BSD授權的應用程式，你想編譯好成執行檔放到網路上供人下載，可以，只要連著當初的BSD授權一起散佈即可，不必把你改的部份也公開出來，因此你可以安心的用BSD授權的函式庫來寫商業軟體</p>
<p>下面的例子都是不違反BSD授權的做法</p>
<blockquote><p>修改BSD授權的程式編譯成執行檔來賣，只提供執行檔而非原始碼給使用者，原始的BSD授權條款也得一併給使用者</p>
<p>連結BSD授權的函式庫，主程式只提供執行檔進行販售，原始的BSD授權條款也得交給使用者</p></blockquote>
<p>而下面這些例子可能會違反BSD授權</p>
<blockquote><p>重新散佈BSD授權的程式，竄改並宣稱自己才是原作者</p>
<p>散佈BSD授權的程式，但不附帶BSD授權條款</p></blockquote>
<p>那你可能會問附帶BSD授權條款是怎樣辦到，很簡單，通常都只是一個LICENSE.txt檔案夾在壓縮檔裡之類的即可</p>
<p>而類BSD在此只是通稱，因為有很多授權都有這類主要的特性，大約列出常見的，像是</p>
<ul>
<li>MIT</li>
<li>Apache</li>
<li>zlib</li>
</ul>
<p><span><span class="Apple-style-span" style="line-height: 24px;">其中zlib最為自由，只要求不能亂改作者，不能聲稱修改的版本才是原始版本，以及不能移除授權，也就是散佈時一樣要附帶zlib授權，除此之外還有很多非常多種的授權，這只是常見的幾種，只要你看見他有寫 "BSD-like"，通常就是指它的特色跟上面描述的差不多，有些專案會特別量身訂作他們自己的授權，但精神大多都會跟這些主流授權差不多</span></span></p>
<h2>商業授權和其它授權</h2>
<p>除了類BSD和GPL，其實還有很多授權，是一些基於商業考量定出來的授權，通常較為少見，所以不多做討論</p>
<h2>常見的謎思 &#8211; MySQL要錢嗎?</h2>
<p>前一陣子常見到很多台灣資訊業界的人瘋狂轉貼MySQL要開始收費的消息，如果懂得上面提到的授權條款就會覺得這很好笑，以MySQL的例子來說，它的程式碼已經用GPL的形式開放出來了，就像潑出來的水收不回去了，即使他們想收錢都沒辦法了，MySQL官網上的授權費用，還有授權說明，都說得不清不楚，即使你打過去問他們到底什麼情況要收錢，他們也只會給你閃爍不清的說法，其目的就只是要騙不懂開源授權的笨蛋去買他們的商用授權，如果你的公司真的有過多預算當做贊助他們是不錯，但都已經被Sun之後又被甲骨文買下來事實上他們也不缺錢了</p>
<p>有興趣可以參考<a href="http://antbsd.twbbs.org/~ant/wordpress/?p=2259"> 探討 MySQL 授權</a></p>
<h2>常見的謎思 &#8211; 開源軟體找不到商業支援</h2>
<p>很多人也有個想法就是開源軟體找不到商業支援，但事實上這是錯的，正因為開源軟體免費的特質，它很多的商業模式其實都是在提供商業支援，例如 <a href="http://www.percona.com/">Percona</a>，他們提功的是強化版的MySQL InnoDB引擎，因為MySQL的GPL授權，導致他們修改的部份也得開源，因此他們當然不可能靠賣軟體獲利，而是靠商業諮詢和技術支援、專業訊練等等項目</p>
<p>因此，事實上很多開源軟體的商業資源遠比商業軟體還來得豐富，因為商業軟體的支援就只有他們提供，他們不幫你你就沒折，然而開源軟體因為是開放的，反而很多人可以解決同樣的問題，最糟的情況不過是自己下海解決而已，至少還不是商業軟體的無解</p>
<p>關於開源軟體的商業模式其實是一個很有趣的議題，有空的話可以另外寫一篇來介紹</p>
<h2>免費的開源授權諮詢</h2>
<p>好吧，講了這麼多，如果你問我你們公司有X專案，要用到Y授權的Z套件是否可行? 請別問我，請問中研院的<a href="http://www.openfoundry.org/">自由軟體鑄造場</a>的<a href="http://www.openfoundry.org/legal-consulting-services">免費開源法律問題諮詢</a>吧，有免錢的程式可以用就算了，還有免錢的諮詢可以問，好諮詢，不問嗎?</p>
<p>除此之外還可以參考他們比我更專業一百倍的<a href="http://www.openfoundry.org/tw/law-and-licensing">法律源地</a>部落格</p>
<h2>小結</h2>
<p>常常看見很多單位都在花大錢買商用軟體，但是一看卻發現這些功能遠比不用錢的開源軟體還差，像是以資料庫為例，就有看見某間學校買了某家公司的資料庫，限制連線人數，功能殘缺不齊，連稱得上現代的資料庫都有困難，然而授權都動不動數十萬數百萬，就覺得很好笑，有免錢的不用，要花大錢去買垃圾來用，使用開源的軟體，並不只是省錢而已，用現成的函式庫與軟體兜出需要的系統更是提升競爭力與減少開發成本的關鍵，台灣如果不能掌握開源的相關知識會比現在更加落後世界的腳步</p>
<p>而授權雖然條款很多看起來很嚇人，實際理解了之後其實也不會太難懂，陣營也很清楚，如果要比喻的話，GPL陣營認為人性本惡，把大家都當成是會開發後就不想把東西公開，每人都是自私的，所以條款強制性很重，而BSD則是相反，要不要開放是你自己的決定，而我認為如果要開源就不怕別人用，怕別人用的話就別開源</p>
<p>最後，我們這裡談到的只是從使用層面來看開源授權而已，台灣大多廠商目前的狀況是連使用上的認知都有困難，更別說是貢獻開源，以後有機會再來寫一些相關的文章</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2011/11/25/taiwan-software-lacking-of-open-source/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>我的open source專案整理列表</title>
		<link>http://blog.ez2learn.com/2011/05/31/my-open-source-projects/</link>
		<comments>http://blog.ez2learn.com/2011/05/31/my-open-source-projects/#comments</comments>
		<pubDate>Tue, 31 May 2011 05:56:52 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[中文文章]]></category>
		<category><![CDATA[分享]]></category>
		<category><![CDATA[開源]]></category>
		<category><![CDATA[Open source]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=1279</guid>
		<description><![CDATA[從很久以前，我就覺得open source是一件很酷的事，覺得能夠免費讓大家用自己心血的結晶真的是件很了不起的事，因此我自己除了使用了不少的open source資源，也一直希望自己也能夠多少有點貢獻，所以在過去多年中確實也有寫了一些open source的專案，雖然都不大，但都很多都是我自己會用到的工具，雖然以前可能有寫過一些介紹，但其實還有不少是沒有介紹過的，會寫open source專案其實多少就是希望有人能使用，而隨著時間久了，我自己會在看到時才想起原來我有寫過這個專案，所以想說弄篇文章來整理一下我所做過的open source專案 Python HGE HGE以前是一款商用的2D遊戲引擎，後來開源，因為我覺得他的引擎挺簡單好用的，重點是有硬體加速，不像SDL純軟體算圖很慢，所以想說把它移植到Python，於是就用Boost.Python寫了一個專案，完成度大約7~8成，裡面有些比較難處理的部份還沒弄好，但主要功能大多都已經可以使用 專案網址: http://code.google.com/p/python-hge/ Gluttony Glottony是一個用來分析Python函式庫在PyPi上的相依情況，主要是有一次我安裝TurboGears時遇到其中一個package的伺服器似乎掛掉了，整個進度就因為那個檔案載不了而無法進行，因此我覺得或許這種相依的情況也是選工具時重要的考量，於是就寫了這樣的工具 專案網址: https://bitbucket.org/victorlin/gluttony Po translator 這是一個用來將.PO檔中的內容透過Google自動翻譯的工具，主要是因為我自己的網站有中文版，想翻成簡體中文，手動一個一個實在太花時間，於是就寫了一個這樣的工具，不過目前有個缺點是當送的量太多，會被Google擋掉一陣子的樣子 專案網址: https://bitbucket.org/victorlin/po_translate Apply firewall iptable幾乎是所有用Linux主機多少都會用到的服務，但是在重設iptable的過程中，難免有時會不小心擋掉自己，如果是遠端登入就麻煩大了，主機在美國也碰不到，只有遠端重開機一條路可走，為了解決這問題，我做這個小工具，可以讓設定iptable像是切換螢幕解析度一樣，會有一段時間讓你確認，沒反應的話會自動取回更動前的設定 專案網址: https://bitbucket.org/victorlin/apply_firewall Correct pycountry 這是一個pycountry的fork，主要是因為pycountry引用ISO裡的國家名稱，但大家都知道台灣的名稱被ISO亂訂，看了心情就不是很爽，所以就fork出一個專案然後改掉裡面的名稱部份 專案網址: https://bitbucket.org/victorlin/correct_pycountry Middleman Middleman是一個基於gevent的簡單網頁proxy，主要是我自己寫來抓論文用的，不過現在已經沒在使用，middleman的名稱主要是取自middleman attack 專案網址: https://bitbucket.org/victorlin/middleman/ Logy 一個簡易的中央日誌記錄用的網頁服務，目前沒有繼續開發的打算 專案網址: https://bitbucket.org/victorlin/logy Loso &#8230; <a href="http://blog.ez2learn.com/2011/05/31/my-open-source-projects/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>從很久以前，我就覺得open source是一件很酷的事，覺得能夠免費讓大家用自己心血的結晶真的是件很了不起的事，因此我自己除了使用了不少的open source資源，也一直希望自己也能夠多少有點貢獻，所以在過去多年中確實也有寫了一些open source的專案，雖然都不大，但都很多都是我自己會用到的工具，雖然以前可能有寫過一些介紹，但其實還有不少是沒有介紹過的，會寫open source專案其實多少就是希望有人能使用，而隨著時間久了，我自己會在看到時才想起原來我有寫過這個專案，所以想說弄篇文章來整理一下我所做過的open source專案</p>
<h2>Python HGE</h2>
<p><a href="http://hge.relishgames.com/">HGE</a>以前是一款商用的2D遊戲引擎，後來開源，因為我覺得他的引擎挺簡單好用的，重點是有硬體加速，不像SDL純軟體算圖很慢，所以想說把它移植到Python，於是就用Boost.Python寫了一個專案，完成度大約7~8成，裡面有些比較難處理的部份還沒弄好，但主要功能大多都已經可以使用</p>
<p>專案網址:</p>
<p><a href="http://code.google.com/p/python-hge/">http://code.google.com/p/python-hge/</a></p>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2011/05/t7.png"><img class="alignnone size-medium wp-image-1280" title="Python - HGE" src="http://blog.ez2learn.com/wp-content/uploads/2011/05/t7-300x235.png" alt="" width="300" height="235" /></a></p>
<h2>Gluttony</h2>
<p>Glottony是一個用來分析Python函式庫在<a href="http://pypi.python.org/pypi">PyPi</a>上的相依情況，主要是有一次我安裝TurboGears時遇到其中一個package的伺服器似乎掛掉了，整個進度就因為那個檔案載不了而無法進行，因此我覺得或許這種相依的情況也是選工具時重要的考量，於是就寫了這樣的工具</p>
<p>專案網址:</p>
<p><a href="https://bitbucket.org/victorlin/gluttony">https://bitbucket.org/victorlin/gluttony</a></p>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2011/05/sprox_dot.png"><img class="alignnone size-medium wp-image-1281" title="Gluttony" src="http://blog.ez2learn.com/wp-content/uploads/2011/05/sprox_dot-300x177.png" alt="" width="300" height="177" /></a></p>
<h2>Po translator</h2>
<p>這是一個用來將.PO檔中的內容透過Google自動翻譯的工具，主要是因為我自己的網站有中文版，想翻成簡體中文，手動一個一個實在太花時間，於是就寫了一個這樣的工具，不過目前有個缺點是當送的量太多，會被Google擋掉一陣子的樣子</p>
<p>專案網址:</p>
<p><a href="https://bitbucket.org/victorlin/po_translate">https://bitbucket.org/victorlin/po_translate</a></p>
<h2>Apply firewall</h2>
<p>iptable幾乎是所有用Linux主機多少都會用到的服務，但是在重設iptable的過程中，難免有時會不小心擋掉自己，如果是遠端登入就麻煩大了，主機在美國也碰不到，只有遠端重開機一條路可走，為了解決這問題，我做這個小工具，可以讓設定iptable像是切換螢幕解析度一樣，會有一段時間讓你確認，沒反應的話會自動取回更動前的設定</p>
<p>專案網址:</p>
<p><a href="https://bitbucket.org/victorlin/apply_firewall">https://bitbucket.org/victorlin/apply_firewall</a></p>
<h2>Correct pycountry</h2>
<p>這是一個pycountry的fork，主要是因為pycountry引用ISO裡的國家名稱，但大家都知道台灣的名稱被ISO亂訂，看了心情就不是很爽，所以就fork出一個專案然後改掉裡面的名稱部份</p>
<p>專案網址:</p>
<p><a href="https://bitbucket.org/victorlin/correct_pycountry">https://bitbucket.org/victorlin/correct_pycountry</a></p>
<h2>Middleman</h2>
<p>Middleman是一個基於gevent的簡單網頁proxy，主要是我自己寫來抓論文用的，不過現在已經沒在使用，middleman的名稱主要是取自middleman attack</p>
<p>專案網址:</p>
<p><a href="https://bitbucket.org/victorlin/middleman/">https://bitbucket.org/victorlin/middleman</a>/</p>
<h2>Logy</h2>
<p>一個簡易的中央日誌記錄用的網頁服務，目前沒有繼續開發的打算</p>
<p>專案網址:</p>
<p><a href="https://bitbucket.org/victorlin/logy">https://bitbucket.org/victorlin/logy</a></p>
<h2>Loso</h2>
<p>Loso主要是我替Plurk寫的一套中文斷詞系統，稍後有空我會寫篇文章來介紹這套系統</p>
<p>專案網址:</p>
<p><a href="https://github.com/victorlin/loso">https://github.com/victorlin/loso</a></p>
<h2>Avoid Disaster</h2>
<p>Avoid disaster是一套用來備份資料用的工具，這也是我會加入Plurk的原因，當時我替我的Now.in寫了備份資料庫的工具，剛好看見Amir也寫了一套，裡面有個做法我覺得很不錯，於是就把兩套合在一起，做了一個fork，Amir看了就邀請我加入Plurk，這套工具不只可以備份到Amazon S3去，只要新增不同的storage類別，例如FTP storage，就能改將資料備份到FTP去</p>
<p>專案網址:</p>
<p><a href="https://github.com/victorlin/avoid_disaster">https://github.com/victorlin/avoid_disaster</a></p>
<h1>License</h1>
<p>這裡的專案所有的License應該都是MIT，好像只有少數幾個BSD，為什麼選MIT呢? 一來是我覺得GPL那種病毒式的，修改了想散播就得強迫你加入的自由算哪門子的自由，其實這點反而讓它變成很多商業產品喜歡使用的授權，因為你改了要散播也得開放出來，對於競爭對手有所限制，但BSD like就沒這問題，我這些東西都沒有商業考量，我覺得要開放就是要做到你拿去做商業軟體散播也無所謂的地步，就像天元突破裡的一段，他們之所以想開源</p>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2011/05/gurren02.jpg"><img class="alignnone size-large wp-image-1282" title="gurren" src="http://blog.ez2learn.com/wp-content/uploads/2011/05/gurren02-1024x576.jpg" alt="" width="580" height="320" /></a></p>
<p>不過如果我也不是什麼聖人，或許哪天我的開源專案有了商業考量，或許我也會使用那病毒GPL來防止別人競爭吧，但是應該是不會，我覺得要開源就不怕別人用，就算用了GPL對方也不一定會照著規則走</p>
<p>第二個用MIT的理由，是因為MIT聽起來很酷!</p>
<p>第三，就是因為 MIT = Made in Taiwan :D</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2011/05/31/my-open-source-projects/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Logy &#8211; a central logging system for Python</title>
		<link>http://blog.ez2learn.com/2011/01/01/logy-a-central-logging-system-for-python/</link>
		<comments>http://blog.ez2learn.com/2011/01/01/logy-a-central-logging-system-for-python/#comments</comments>
		<pubDate>Sat, 01 Jan 2011 09:30:46 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[分享]]></category>
		<category><![CDATA[English Articles]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Open source]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=1174</guid>
		<description><![CDATA[I&#8217;m glad to announce my new open source project:Logy. Logy is a simple lightweight central logging system for Python. When do you need a central logging system?  Well, when you have many servers online, and they are running different python &#8230; <a href="http://blog.ez2learn.com/2011/01/01/logy-a-central-logging-system-for-python/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m glad to announce my new open source project:Logy.  Logy is a simple lightweight central logging system for Python. When do you need a central logging system?  Well, when you have many servers online, and they are running different python application, you will want to have a central logging system for making sure everything is going fine.  And you might ask, why not just use email for error reports? Well, following screenshot explains:</p>
<p><img class="alignnone size-medium wp-image-1175" title="error_reports" src="http://blog.ez2learn.com/wp-content/uploads/2011/01/error_reports-300x238.png" alt="" width="300" height="238" /></p>
<p>I use email as error logging report, but however, as you can see if there is something wrong with my servers in same time, network outage for instance, there will be so many error report mails come in my mailbox like crazy.  Therefore think a central log might be a good idea, then I decide to develop a simple central logging system for my own servers.  Here is a screenshot of the Logy web page.</p>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2011/01/logy_screenshot01.png"><img class="alignnone size-full wp-image-1178" title="logy_screenshot01" src="http://blog.ez2learn.com/wp-content/uploads/2011/01/logy_screenshot01.png" alt="" width="732" height="617" /></a></p>
<p>It categorizes your logging records by IP address automatically, and also, you can set a application name for different applications which are running in same box.  And one important feature is, it is base on Flask :)</p>
<p>It is super easy to write records to Logy, here is an example:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">logging</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> ex_loghandlers
&nbsp;
rootLogger = <span style="color: #dc143c;">logging</span>.<span style="color: black;">getLogger</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span><span style="color: black;">&#41;</span>
rootLogger.<span style="color: black;">setLevel</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">logging</span>.<span style="color: black;">DEBUG</span><span style="color: black;">&#41;</span>
&nbsp;
sream_handler = <span style="color: #dc143c;">logging</span>.<span style="color: black;">StreamHandler</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;"># set up the http handler which writes records to Logy server</span>
http_handler = ex_loghandlers.<span style="color: black;">ExHTTPHandler</span><span style="color: black;">&#40;</span>host=<span style="color: #483d8b;">'localhost:5000'</span>,
                                            url=<span style="color: #483d8b;">'/sink/TEST/myapp'</span>,
                                            method=<span style="color: #483d8b;">'POST'</span><span style="color: black;">&#41;</span>
rootLogger.<span style="color: black;">addHandler</span><span style="color: black;">&#40;</span>sream_handler<span style="color: black;">&#41;</span>
rootLogger.<span style="color: black;">addHandler</span><span style="color: black;">&#40;</span>http_handler<span style="color: black;">&#41;</span>
&nbsp;
logger1 = <span style="color: #dc143c;">logging</span>.<span style="color: black;">getLogger</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'myapp.area1'</span><span style="color: black;">&#41;</span>
logger2 = <span style="color: #dc143c;">logging</span>.<span style="color: black;">getLogger</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'myapp.area2'</span><span style="color: black;">&#41;</span>
&nbsp;
logger1.<span style="color: black;">debug</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Quick zephyrs blow, vexing daft Jim.'</span><span style="color: black;">&#41;</span>
logger1.<span style="color: black;">info</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'How quickly daft jumping zebras vex.'</span><span style="color: black;">&#41;</span>
logger2.<span style="color: black;">warning</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Jail zesty vixen who grabbed pay from quack.'</span><span style="color: black;">&#41;</span>
logger2.<span style="color: black;">error</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'The five boxing wizards jump quickly.'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">Exception</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Boom&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">except</span>:
    logger1.<span style="color: black;">fatal</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Huston, we've got a problem&quot;</span>, exc_info=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span> 
&nbsp;
logger1.<span style="color: black;">info</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Everything goes fine, now.'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>You need to install my module named ex_loghandlers before you can run this script, it contains an ExHTTPHandler which provides extra information for Logy.</p>
<p>Here are some more information of Logy:</p>
<p>PyPi page: <a href="http://pypi.python.org/pypi/logy">http://pypi.python.org/pypi/logy</a></p>
<p>Bitbucket: <a href="https://bitbucket.org/victorlin/logy/src">https://bitbucket.org/victorlin/logy/src</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2011/01/01/logy-a-central-logging-system-for-python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Python使用HGE引擎</title>
		<link>http://blog.ez2learn.com/2009/08/25/python-hge/</link>
		<comments>http://blog.ez2learn.com/2009/08/25/python-hge/#comments</comments>
		<pubDate>Tue, 25 Aug 2009 13:24:55 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[中文文章]]></category>
		<category><![CDATA[分享]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[遊戲設計]]></category>
		<category><![CDATA[設計]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[2D引擎]]></category>
		<category><![CDATA[2D硬體加速]]></category>
		<category><![CDATA[遊戲開發]]></category>
		<category><![CDATA[開源]]></category>
		<category><![CDATA[Game]]></category>
		<category><![CDATA[Game design]]></category>
		<category><![CDATA[HGE]]></category>
		<category><![CDATA[Open source]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=718</guid>
		<description><![CDATA[大家肯定都知道在Python下面寫2D遊戲有個眾所階知的選擇就是pygame，雖然它簡單好寫，對於簡單的遊戲來說已經足夠，但是他有一個致命的缺點，就是速度太慢了，在pygame的背後是SDL，用純軟體畫圖的函式庫，既然為純軟體繪圖，遇上旋轉、半透明等等需求，更顯得吃力和不切實際，所以該怎麼辦才好呢? 答案是用Haaf&#8217;s Game Engine，它是一款用DirectX做為backend的Open source遊戲函式庫，我在先前的文章裡已經有做簡單的介紹，就不再重覆，那這函式庫和Python又有什麼關聯呢? 他是用C++寫的，Python沒辦法用，正因為這樣，我一直一來想幫他寫一個python的binding，我一直想如果Python也能用HGE寫起來一定很開心，我試著找了一下有沒有已經存在這樣的專案，有找到一個，但是居然是在萬惡的GNU授權下的，讓我百思不得其解，那專案的作者到底在想什麼? 想讓大家寫Open source的Game嗎? 我們都知道GNU是大名頂頂的病毒授權，任何程式使用了用GNU的函式庫都會被感染，代表你的主程式一樣得變成GNU的開源授權，我個人非常討厭打著自由名義但是卻有強烈的強迫性質的GNU授權，況且HGE的授權是非常寬鬆的 zlib/libpng License，實在想不透為什麼一個binding可以用超嚴格的GNU，不過那是那作者的自由，我也管不著，在不能接受那惡心的授權，加上我看了一下他的專案似乎好像也沒有很完整的進度，於是我還是決定自己開了一個新的專案 Python HGE 在這樣的情況下，我前些天抽空開了一個新的Open source專案: Python-HGE，把一些最核心的程式碼都用boost.python包裝給Python使用，最核心的部份完成度很高，剩下的需要我在未來有空慢慢補上，License是MIT，如果你問我為什麼選MIT，我想答案應該是商業用途一樣也可以，不像GNU那種假腥腥的自由，還有一個重點就是，我覺得麻省理工這名字聽起來很酷，讓我想起每次在Discovery看到的東西 效能問題 我照著原本HGE的Tutorial7的程式寫了一個Python的版本，這個範例的目的就是在展示HGE的效能，純C++的版本速度當然是很快，而Python的版本FPS掉了不少，一開始讓我覺得有點失望，讓我開始懷疑如果效能掉很多的話，那用Python寫HGE還有價值嗎? 後來仔細思考了一下，對於一般的2D遊戲來說，要像這demo整畫面跑來跑去的圖片加透明效果的情況實在不多，就算有也很難到這樣上千張的圖片，再者我都還沒進行最佳化、跑profile等等，而且雖說FPS掉不少，但是那是和C++數百的FPS比起來，在60以上其實都是可以接受的，加上我測試的這台電腦已經有點年代，對現代的電腦和GUP來說情況只會更好，在如此的考量之下，Python HGE還是有搞頭的 python版的tutorial 7截圖 這個demo可以在這裡下載 目前狀況 目前雖然核心部份已經高度完成，不過我還沒有把編出來的pyd釋放的打算，如果想嘗鮮的話可以直接從那個demo裡面找pyd出來用，又或著自己check out原始碼進行編譯 參與開發 如果有興趣的話，歡迎參與專案的開發，如同我上面所提到的，我用的是boost.python，一款基於C++的python binding函式庫，如果你熟悉boost.python的話當然是最好，就算沒有也沒關系，因為其實大部份工作都是剪下貼上之類的，可以參考我已經寫好的部份，有些函數回傳例如指標之類的東西需要特別處理，除此之外都只是很簡單無腦工作]]></description>
			<content:encoded><![CDATA[<p>大家肯定都知道在Python下面寫2D遊戲有個眾所階知的選擇就是pygame，雖然它簡單好寫，對於簡單的遊戲來說已經足夠，但是他有一個致命的缺點，就是速度太慢了，在pygame的背後是SDL，用純軟體畫圖的函式庫，既然為純軟體繪圖，遇上旋轉、半透明等等需求，更顯得吃力和不切實際，所以該怎麼辦才好呢?</p>
<p>答案是用<a href="http://hge.relishgames.com/">Haaf&#8217;s Game Engine</a>，它是一款用DirectX做為backend的Open source遊戲函式庫，我在<a href="http://blog.ez2learn.com/2009/01/10/intro-to-hge/">先前的文章</a>裡已經有做簡單的介紹，就不再重覆，那這函式庫和Python又有什麼關聯呢? 他是用C++寫的，Python沒辦法用，正因為這樣，我一直一來想幫他寫一個python的binding，我一直想如果Python也能用HGE寫起來一定很開心，我試著找了一下有沒有已經存在這樣的專案，有找到一個，但是居然是在萬惡的GNU授權下的，讓我百思不得其解，那專案的作者到底在想什麼? 想讓大家寫Open source的Game嗎? 我們都知道GNU是大名頂頂的病毒授權，任何程式使用了用GNU的函式庫都會被感染，代表你的主程式一樣得變成GNU的開源授權，我個人非常討厭打著自由名義但是卻有強烈的強迫性質的GNU授權，況且HGE的授權是非常寬鬆的<a href="http://www.opensource.org/licenses/zlib-license.php" target="_blank"> zlib/libpng License</a>，實在想不透為什麼一個binding可以用超嚴格的GNU，不過那是那作者的自由，我也管不著，在不能接受那惡心的授權，加上我看了一下他的專案似乎好像也沒有很完整的進度，於是我還是決定自己開了一個新的專案<a href="http://www.opensource.org/licenses/zlib-license.php" target="_blank"></a></p>
<h2>Python HGE</h2>
<p>在這樣的情況下，我前些天抽空開了一個新的Open source專案: <a href="http://code.google.com/p/python-hge/">Python-HGE</a>，把一些最核心的程式碼都用boost.python包裝給Python使用，最核心的部份完成度很高，剩下的需要我在未來有空慢慢補上，License是MIT，如果你問我為什麼選MIT，我想答案應該是商業用途一樣也可以，不像GNU那種假腥腥的自由，還有一個重點就是，我覺得麻省理工這名字聽起來很酷，讓我想起每次在Discovery看到的東西</p>
<h2>效能問題</h2>
<p>我照著原本HGE的Tutorial7的程式寫了一個Python的版本，這個範例的目的就是在展示HGE的效能，純C++的版本速度當然是很快，而Python的版本FPS掉了不少，一開始讓我覺得有點失望，讓我開始懷疑如果效能掉很多的話，那用Python寫HGE還有價值嗎? 後來仔細思考了一下，對於一般的2D遊戲來說，要像這demo整畫面跑來跑去的圖片加透明效果的情況實在不多，就算有也很難到這樣上千張的圖片，再者我都還沒進行最佳化、跑profile等等，而且雖說FPS掉不少，但是那是和C++數百的FPS比起來，在60以上其實都是可以接受的，加上我測試的這台電腦已經有點年代，對現代的電腦和GUP來說情況只會更好，在如此的考量之下，Python HGE還是有搞頭的</p>
<p>python版的tutorial 7截圖</p>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2009/08/t7.png"><img class="alignnone size-medium wp-image-719" title="t7" src="http://blog.ez2learn.com/wp-content/uploads/2009/08/t7-300x235.png" alt="t7" width="300" height="235" /></a></p>
<p>這個demo可以在<a href="http://python-hge.googlecode.com/files/t7.zip">這裡下載</a></p>
<h2>目前狀況</h2>
<p>目前雖然核心部份已經高度完成，不過我還沒有把編出來的pyd釋放的打算，如果想嘗鮮的話可以直接從那個demo裡面找pyd出來用，又或著自己check out原始碼進行編譯</p>
<h2>參與開發</h2>
<p>如果有興趣的話，歡迎參與專案的開發，如同我上面所提到的，我用的是boost.python，一款基於C++的python binding函式庫，如果你熟悉boost.python的話當然是最好，就算沒有也沒關系，因為其實大部份工作都是剪下貼上之類的，可以參考我已經寫好的部份，有些函數回傳例如指標之類的東西需要特別處理，除此之外都只是很簡單無腦工作</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2009/08/25/python-hge/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>抓網頁的程式庫 : WebChuan</title>
		<link>http://blog.ez2learn.com/2008/10/20/python-module-for-getting-web-webchua/</link>
		<comments>http://blog.ez2learn.com/2008/10/20/python-module-for-getting-web-webchua/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 15:39:28 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[中文文章]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Open source]]></category>
		<category><![CDATA[抓取網頁]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=220</guid>
		<description><![CDATA[WebChuan 花了一些時間整理我先前提到設計下所寫出來的抓網頁模組，用Python寫基於Twisted和lxml，可以輕鬆地組織抓取網頁的流程，各種常用的功能都已經有了 我把它命名為WebChuan並且釋放成在MIT License下的Open source project http://webchuan.ez2learn.com/ 有興趣可以參考看看，目前還有很多事要做，包括生成文件、撰寫文件、測試等等，但是先前提到的基本功能都已經完備 http://webchuan.ez2learn.com/wiki/Examples/GetPageTitle 這裡有一個取得網頁標題的簡單程式可以執行看看]]></description>
			<content:encoded><![CDATA[<h1>WebChuan</h1>
<p>花了一些時間整理我先前提到設計下所寫出來的抓網頁模組，用Python寫基於Twisted和lxml，可以輕鬆地組織抓取網頁的流程，各種常用的功能都已經有了</p>
<p>我把它命名為WebChuan並且釋放成在MIT License下的Open source project</p>
<p><a href="http://webchuan.ez2learn.com/">http://webchuan.ez2learn.com/</a></p>
<p>有興趣可以參考看看，目前還有很多事要做，包括生成文件、撰寫文件、測試等等，但是先前提到的基本功能都已經完備</p>
<p><a href="http://webchuan.ez2learn.com/wiki/Examples/GetPageTitle">http://webchuan.ez2learn.com/wiki/Examples/GetPageTitle</a></p>
<p>這裡有一個取得網頁標題的簡單程式可以執行看看</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2008/10/20/python-module-for-getting-web-webchua/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>抓取網頁程式的架構設計</title>
		<link>http://blog.ez2learn.com/2008/10/11/design-of-web-grabing-program/</link>
		<comments>http://blog.ez2learn.com/2008/10/11/design-of-web-grabing-program/#comments</comments>
		<pubDate>Fri, 10 Oct 2008 17:24:54 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[中文文章]]></category>
		<category><![CDATA[設計]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Open source]]></category>
		<category><![CDATA[抓取網頁]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=138</guid>
		<description><![CDATA[截取網頁的架構設計 我們先前談到了抓取網頁用的工具，但是光有工具是不夠的，良好的設計也是必要的，這次我們就來談談設計 最早我寫一個抓取amazon.com商品資料的程式，當時沒仔細思考設計的問題，而且在一開始低估了問題的複雜程度，導至後來在修改時整個是一團混亂，我把抓取網頁的流程分成幾個部份，然而這些流程之間有著很多細小複雜的溝通和互相依賴的關係，到了後來我發現我哪裡在寫程式，這根本是一團義大利麵! 此時我終於深刻體會到什麼叫漣漪效應，當我修改一小部份程式，有很多依賴此的程式也跟著需要修改，間接依賴的程式片段一樣需要修改，程式的改變有如投入池子中的石子，修改在程式碼間散播開來，再也沒有比這個更糟的設計了，除了修改的問題，測試更是一個嚴重的問題，當我發現一個錯誤，我無法確定這個錯誤到底是屬於誰的，它們之間有這麼多關係，每個人都有嫌疑，我明白這程式繼續寫下去就只有死路一條，於是我開始思考怎樣的設計才是正確的 最明顯的錯誤 最明顯的錯誤就是，流程和流程之間有太多關係了，它們互相依賴，造成藕合度大大提升，牽一髮動全身，因此我意識到每個流程應該都要和其它任何流程沒有任何關係，它們只在乎它們的輸入，以及如何處理它們，於是我就聯想到了責任鏈設計模式，以及工廠的生產線，我想像資料進來，從最先的原料，進入一開始的工廠加工，接著被送到下一個工廠處理，每個工廠只知道如何對進入的產品加工，對於前一個工廠、後一個工廠，對所有工廠都一無所知，這才是將處理流程從藕合的關係中鬆綁的正確設計，於是我做出了設計上的修改，重新寫過了程式，我將幾個大流程分開成獨立的物件，並單獨做測試，確定每個流程都如預期般，有如預期的正確輸出，最後再將這些流程串起來，果然這樣的做法果然解決了問題，但是問題還沒有結束 一直有種強烈的直覺 很多時候沒辦法明白的說出來，但就是有些強烈的直覺，感覺到設計上可以做到某種程度，但卻還無法用言語表達，將每個流程分開程獨立的程式處理，雖然鬆綁藕合，但是卻沒有良好的重用性，到後來我發現Twisted，使用它的Deferred物件，從getPage的Deferred物件中增加parsing的callback，我意識到，不止一個大的流程，從抓取網頁、解析網頁、儲存資料，每一個步驟事實上應該都是獨立的，如果以一大流程做為單位，當我需要使用其它抓取網頁的機制，解析網頁的程式卻要從那個大流程中取出來，很明顯地，以大流程做為單位太大了，而且流程應該是由幾個小步驟組合而成，不應該把它們綁在一起，在這時我還沒有明確的想法，直到&#8230; 遇到GStreamer 為了寫某些程式的需要，我找到了一款Open source的影音串流處理的函式庫，我看到了它Pipeline的機制，此時我眼睛為之一亮，這不就是我想要的設計嗎? 由元素組成串在一起的pipeline，每個元素只有特定處理資料的方式，然後往後面的元素傳 引用自 : http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-intro-basics-bins.html#section-pipeline-img 我的設計 於是我開始構思我的網頁抓取的pipeline，起先我試著模仿它那種pipeline的設計方式，但是它的Element相當複雜，並不適合網頁抓取的pipeline，於是我把心思拉回處理網頁的每個單一步驟該有的特性，最後我做出了這樣的設計 在這其中，我除了考慮到藕合上的問題，同樣也考慮到效率等等的問題，Element本身只專注在於處理資料這件事，資料由input方法輸入，而handleData處理資料，當資料處理完成需要輸出使用outputEvent來通知外界資料處理完成，當資料都處理完成也輸出完成時，就用requestEvent通知外界可以輸入更多資料，然而如果在handleData的過程中發生問題，就使用failureEvent告知外界錯誤訊息，大至上的行為是如此，但在細節上還有一些問題沒想清楚 而Bin本身是一個Element的容器，負責接受來自Element的事件通知，然後做出對應的處理，Pipeline就是一個Bin的子類別，它負責轉送到對應的Element去，或是放入queue中等待request事件再送出，它都使用CallInThread來呼叫element的input方法，這表示，所有工作都是非同步進行的，不需要等一筆資料被處理完成後，才能接受新的資料，只要一個Element的資料處理完，可以馬上再處理下一筆，這是提升效率的方法之一 值得注意的是，Pipeline和Bin本身一樣也是一個Element，這表示它可以被當做Element和其它Element串在一起，或是加入其它Bin中，這讓設計上更有彈性 Retry裝飾者 有了這樣的概念確立後，我引進了更多設計上的應用，例如裝飾者設計樣式，我設計了一個Retry的裝飾者，可以把getPage等等可能會失敗的Element包裝起來，自動進行特定次數的重試，而不必為了getPage特地重寫重試的版本，有其它可能出錯的Element都可以用此裝飾者包裝起來 Dispatcher 然而，到目前為止我們的效能還是不夠好，因為同一個時間裡只有一條pipeline在運行，我們需要的是在同一個時間內可以有多條的pipeline運作，因此設計了一個Dispatcher的Bin，可以新增很多條Pipeline在其中，然後input資料就會自動分派給pipeline If判斷元素 只有這樣還不夠，考慮一下我們如果需要抓取分頁的網頁，我們一頁一頁往下抓，要判斷是否有下一頁，繼續網下抓取或是停止，為此我設計了If判斷用的Element，它會根據一個條件函數來決定輸出的port 當這一切組合在一起 到目前為止所有提到的都是Element，這表示他們可以被替換掉在任何以上的結構中，Dispatcher所分派的對象不一定要是Pipeline，也可以是其它Element，我為了我目前工作用這樣的東西重新組合重寫一次，組合起來像是這樣 而Dispatcher在外面將這個Pipeline重覆了幾次，因此同時可以執行很多個Pipeline，GetPage、Parser等等都是常用的Element，而只有Get book page detail等Element是我們自行設計的Element，這將重覆利用發揮到了極緻，有強大的彈性，你可以在裡面看到一個迴圈，事實上它只是串接著一個If的Element然後Link條件為真的Port和為假的Port到不同元素而已 我最早的設計是如上圖所示，但是後來考慮到Amazon網路書店的Review頁面，往往是商品資料頁面的好幾百倍和千倍，因此，到後來我將商品資料和Review資料的Pipeline分開，分別用Dispatcher包裝起來後串接在一起，Review的Pipeline數量應該要是商品資料的很多倍，如此一來才能更快消化完Review頁面的工作 未來 到此，相信已經可以感受到這樣設計的威力，我希望將我的程式整理成函式庫，釋放出來成為Open source的Project，專案的名字我還在想，目前考慮用中文字"川"或是DStreamer之類的名字，如果有任何想法，也歡迎提供給我 :P 除此之外，如果你有玩過GStreamer，應該知道它有一個用指令來播放串流媒體的功能，像這樣子 gst-launch -v &#8230; <a href="http://blog.ez2learn.com/2008/10/11/design-of-web-grabing-program/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h1>截取網頁的架構設計</h1>
<p>我們先前談到了抓取網頁用的工具，但是光有工具是不夠的，良好的設計也是必要的，這次我們就來談談設計</p>
<p><span id="more-138"></span></p>
<p>最早我寫一個抓取amazon.com商品資料的程式，當時沒仔細思考設計的問題，而且在一開始低估了問題的複雜程度，導至後來在修改時整個是一團混亂，我把抓取網頁的流程分成幾個部份，然而這些流程之間有著很多細小複雜的溝通和互相依賴的關係，到了後來我發現我哪裡在寫程式，這根本是一團義大利麵! 此時我終於深刻體會到什麼叫漣漪效應，當我修改一小部份程式，有很多依賴此的程式也跟著需要修改，間接依賴的程式片段一樣需要修改，程式的改變有如投入池子中的石子，修改在程式碼間散播開來，再也沒有比這個更糟的設計了，除了修改的問題，測試更是一個嚴重的問題，當我發現一個錯誤，我無法確定這個錯誤到底是屬於誰的，它們之間有這麼多關係，每個人都有嫌疑，我明白這程式繼續寫下去就只有死路一條，於是我開始思考怎樣的設計才是正確的</p>
<h2>最明顯的錯誤</h2>
<p>最明顯的錯誤就是，流程和流程之間有太多關係了，它們互相依賴，造成藕合度大大提升，牽一髮動全身，因此我意識到每個流程應該都要和其它任何流程沒有任何關係，它們只在乎它們的輸入，以及如何處理它們，於是我就聯想到了責任鏈設計模式，以及工廠的生產線，我想像資料進來，從最先的原料，進入一開始的工廠加工，接著被送到下一個工廠處理，每個工廠只知道如何對進入的產品加工，對於前一個工廠、後一個工廠，對所有工廠都一無所知，這才是將處理流程從藕合的關係中鬆綁的正確設計，於是我做出了設計上的修改，重新寫過了程式，我將幾個大流程分開成獨立的物件，並單獨做測試，確定每個流程都如預期般，有如預期的正確輸出，最後再將這些流程串起來，果然這樣的做法果然解決了問題，但是問題還沒有結束</p>
<h2>一直有種強烈的直覺</h2>
<p>很多時候沒辦法明白的說出來，但就是有些強烈的直覺，感覺到設計上可以做到某種程度，但卻還無法用言語表達，將每個流程分開程獨立的程式處理，雖然鬆綁藕合，但是卻沒有良好的重用性，到後來我發現Twisted，使用它的Deferred物件，從getPage的Deferred物件中增加parsing的callback，我意識到，不止一個大的流程，從抓取網頁、解析網頁、儲存資料，每一個步驟事實上應該都是獨立的，如果以一大流程做為單位，當我需要使用其它抓取網頁的機制，解析網頁的程式卻要從那個大流程中取出來，很明顯地，以大流程做為單位太大了，而且流程應該是由幾個小步驟組合而成，不應該把它們綁在一起，在這時我還沒有明確的想法，直到&#8230;</p>
<h2>遇到GStreamer</h2>
<p>為了寫某些程式的需要，我找到了一款Open source的影音串流處理的函式庫，我看到了它Pipeline的機制，此時我眼睛為之一亮，這不就是我想要的設計嗎? 由元素組成串在一起的pipeline，每個元素只有特定處理資料的方式，然後往後面的元素傳</p>
<div id="attachment_140" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.ez2learn.com/wp-content/uploads/2008/10/simple-player.png"><img class="size-medium wp-image-140" title="GStreamer的Pipeline" src="http://blog.ez2learn.com/wp-content/uploads/2008/10/simple-player-300x110.png" alt="GStreamer的Pipeline" width="300" height="110" /></a><p class="wp-caption-text">GStreamer的Pipeline</p></div>
<p>引用自 : <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-intro-basics-bins.html#section-pipeline-img">http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-intro-basics-bins.html#section-pipeline-img</a></p>
<h2>我的設計</h2>
<p>於是我開始構思我的網頁抓取的pipeline，起先我試著模仿它那種pipeline的設計方式，但是它的Element相當複雜，並不適合網頁抓取的pipeline，於是我把心思拉回處理網頁的每個單一步驟該有的特性，最後我做出了這樣的設計</p>
<div id="attachment_145" class="wp-caption alignnone" style="width: 278px"><a href="http://blog.ez2learn.com/wp-content/uploads/2008/10/element1.jpg"><img class="size-medium wp-image-145" title="Element 的UML設計圖" src="http://blog.ez2learn.com/wp-content/uploads/2008/10/element1-268x300.jpg" alt="Element 的UML設計圖" width="268" height="300" /></a><p class="wp-caption-text">Element 的UML設計圖</p></div>
<p>在這其中，我除了考慮到藕合上的問題，同樣也考慮到效率等等的問題，Element本身只專注在於處理資料這件事，資料由input方法輸入，而handleData處理資料，當資料處理完成需要輸出使用outputEvent來通知外界資料處理完成，當資料都處理完成也輸出完成時，就用requestEvent通知外界可以輸入更多資料，然而如果在handleData的過程中發生問題，就使用failureEvent告知外界錯誤訊息，大至上的行為是如此，但在細節上還有一些問題沒想清楚</p>
<p>而Bin本身是一個Element的容器，負責接受來自Element的事件通知，然後做出對應的處理，Pipeline就是一個Bin的子類別，它負責轉送到對應的Element去，或是放入queue中等待request事件再送出，它都使用CallInThread來呼叫element的input方法，這表示，所有工作都是非同步進行的，不需要等一筆資料被處理完成後，才能接受新的資料，只要一個Element的資料處理完，可以馬上再處理下一筆，這是提升效率的方法之一</p>
<p>值得注意的是，Pipeline和Bin本身一樣也是一個Element，這表示它可以被當做Element和其它Element串在一起，或是加入其它Bin中，這讓設計上更有彈性</p>
<h2>Retry裝飾者</h2>
<p>有了這樣的概念確立後，我引進了更多設計上的應用，例如裝飾者設計樣式，我設計了一個Retry的裝飾者，可以把getPage等等可能會失敗的Element包裝起來，自動進行特定次數的重試，而不必為了getPage特地重寫重試的版本，有其它可能出錯的Element都可以用此裝飾者包裝起來</p>
<h2>Dispatcher</h2>
<p>然而，到目前為止我們的效能還是不夠好，因為同一個時間裡只有一條pipeline在運行，我們需要的是在同一個時間內可以有多條的pipeline運作，因此設計了一個Dispatcher的Bin，可以新增很多條Pipeline在其中，然後input資料就會自動分派給pipeline</p>
<div id="attachment_147" class="wp-caption alignnone" style="width: 301px"><a href="http://blog.ez2learn.com/wp-content/uploads/2008/10/dispatcheractivity.jpg"><img class="size-medium wp-image-147" title="Dispatcher的活動示意圖" src="http://blog.ez2learn.com/wp-content/uploads/2008/10/dispatcheractivity-291x300.jpg" alt="Dispatcher的活動示意圖" width="291" height="300" /></a><p class="wp-caption-text">Dispatcher的活動示意圖</p></div>
<h2>If判斷元素</h2>
<p>只有這樣還不夠，考慮一下我們如果需要抓取分頁的網頁，我們一頁一頁往下抓，要判斷是否有下一頁，繼續網下抓取或是停止，為此我設計了If判斷用的Element，它會根據一個條件函數來決定輸出的port</p>
<h2>當這一切組合在一起</h2>
<p>到目前為止所有提到的都是Element，這表示他們可以被替換掉在任何以上的結構中，Dispatcher所分派的對象不一定要是Pipeline，也可以是其它Element，我為了我目前工作用這樣的東西重新組合重寫一次，組合起來像是這樣</p>
<div id="attachment_148" class="wp-caption alignnone" style="width: 193px"><a href="http://blog.ez2learn.com/wp-content/uploads/2008/10/activitydiagram1.jpg"><img class="size-medium wp-image-148" title="Amazon 活動圖" src="http://blog.ez2learn.com/wp-content/uploads/2008/10/activitydiagram1-183x300.jpg" alt="Amazon 活動圖" width="183" height="300" /></a><p class="wp-caption-text">Amazon 活動圖</p></div>
<p>而Dispatcher在外面將這個Pipeline重覆了幾次，因此同時可以執行很多個Pipeline，GetPage、Parser等等都是常用的Element，而只有Get book page detail等Element是我們自行設計的Element，這將重覆利用發揮到了極緻，有強大的彈性，你可以在裡面看到一個迴圈，事實上它只是串接著一個If的Element然後Link條件為真的Port和為假的Port到不同元素而已</p>
<p>我最早的設計是如上圖所示，但是後來考慮到Amazon網路書店的Review頁面，往往是商品資料頁面的好幾百倍和千倍，因此，到後來我將商品資料和Review資料的Pipeline分開，分別用Dispatcher包裝起來後串接在一起，Review的Pipeline數量應該要是商品資料的很多倍，如此一來才能更快消化完Review頁面的工作</p>
<h2>未來</h2>
<p>到此，相信已經可以感受到這樣設計的威力，我希望將我的程式整理成函式庫，釋放出來成為Open source的Project，專案的名字我還在想，目前考慮用中文字"川"或是DStreamer之類的名字，如果有任何想法，也歡迎提供給我 :P</p>
<p>除此之外，如果你有玩過GStreamer，應該知道它有一個用指令來播放串流媒體的功能，像這樣子</p>
<blockquote>
<pre class="programlisting">gst-launch -v filesrc location=sine.ogg ! oggdemux ! vorbisdec ! audioconvert ! alsasink</pre>
</blockquote>
<p>就可以播放ogg的音樂檔案，這只是簡單的例子，它還可以做更複雜的事，例如從麥克風讀取音訊即時壓縮成ogg或mp3格式，且同時播放出來之類的</p>
<p>除了Library，我同樣希望寫出一個像這樣的工具程式，讓某些抓網頁的程式可以被簡化成像這樣的指令，例如</p>
<blockquote><p>dst-launch GetPage url="http://www.google.com" ! RegexParser re="&lt;title&gt;(.*?)&lt;/title&gt;" output="$1&#8243; ! FileOutput filename="google_title.txt"</p></blockquote>
<p>像這樣簡單的指令就能抓取Google網頁的標題然後存成文字檔，除此之外，甚至是GUI介面來像UML那樣設計抓取網頁的流程</p>
<p>有興趣參與或有任何想法都歡迎給個評論，謝謝</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2008/10/11/design-of-web-grabing-program/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

