<?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:georss='http://www.georss.org/georss' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-35201715</id><updated>2010-07-30T17:21:53.131-05:00</updated><title type='text'>Wensheng</title><subtitle type='html'>Wensheng Wang's journal on web, Linux, programming, and more.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.wensheng.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default?start-index=26&amp;max-results=25'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>45</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-35201715.post-201053980881350397</id><published>2010-05-16T01:52:00.011-05:00</published><updated>2010-05-16T03:49:03.127-05:00</updated><title type='text'>Creating ooxml  word docx file with python and XSLT</title><content type='html'>The idea is taking an existing Word document, making it a template, and using it with external data to create a new Word document.&lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;If you're dealing with 'doc' file (word2003 and before), you can use &lt;a href="http://sourceforge.net/projects/pywin32/"&gt;Pywin32&lt;/a&gt;.  There are good information in the Chapter 10 of "Python Programming on Win32" book, in a section called "Automating Word".&lt;br /&gt;But 'doc' file is on the way out.  Staring from version 2007, Word is using the new 'docx' format. The good news is that 'docx' use OOXML (Office Open XML), an open industry standard. This means we can, in theory anyway, create Word DOCX file without using Windows.  In practice, there's currently no good library that facilitate creating a docx file from xml data from scratch.  It's tedious to do so without a good library.  Hopefully someone will create one soon.&lt;br /&gt;&lt;br /&gt;A short-cut exists though, i.e. create a template docx, create XSLT from it, then use XSLT to transform xml data into a new docx file.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://openxmldeveloper.com/archive/2009/03/16/4283.aspx"&gt;Here's a post&lt;/a&gt; that describes this process using CSharp.  My code is based on ideas and codes in this post.&lt;br /&gt;&lt;br /&gt;Here's how to do it in Python (using the excellent &lt;a href="http://codespeak.net/lxml/"&gt;lxml module&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt;1, Create a template docx file&lt;br /&gt; Just create a regular docx file with Word (example.docx)&lt;br /&gt;&lt;br /&gt;2, Create xslt file from docx file.&lt;br /&gt; A docx file is a zip file. You can get "word/document.xml" file by unzip the docx file.  But the resulting file has no line breaks.  It's very hard to edit it using regular text editor like VIM.  (you can use xml editor, but there ain't good one that's free).  I have a python program that does this (getxslt.py).  All it does is getting 'word/document.xml', prettifying it(adding linebreaks), and adding XSLT header and footer.&lt;br /&gt; We need to use the docx file later, but without 'word/document.xml' file (python's zipfile module can't do file replacement in zip). You can achieve this by "open archive" the docx file with '7-zip' on windows, then delete 'word/document.xml'.&lt;br /&gt;&lt;br /&gt;3, Modify xslt file.&lt;br /&gt;  Determine where you need to change the data, add things like:&lt;br /&gt;  &amp;lt;xsl:value-of  select="..."/&amp;gt;&lt;br /&gt; and&lt;br /&gt;  &amp;lt;xsl:for-each  select="..."&amp;gt;&lt;br /&gt;   ...&lt;br /&gt;  &amp;lt;/xsl:for-each&amp;gt;&lt;br /&gt; You need to study a little bit xslt to do this, it's not too hard.&lt;br /&gt;&lt;br /&gt;4, Do XSLT transform to convert xml data to 'word/document.xml' and add it to new docx file.&lt;br /&gt;&lt;blockquote&gt;import shutil&lt;br /&gt;import zipfile&lt;br /&gt;from lxml import etree&lt;br /&gt;&lt;br /&gt;xsl = etree.XSLT(etree.parse("xslt1.xml"))&lt;br /&gt;xml = etree.parse("cddata.xml")&lt;br /&gt;newxml=xsl(xml)&lt;br /&gt;&lt;br /&gt;#nodocxml.docx is original docx file without word\document.xml&lt;br /&gt;shutil.copyfile("nodocxml.docx","mycds.docx")&lt;br /&gt;&lt;br /&gt;mycds = zipfile.ZipFile("mycds.docx",'a',zipfile.ZIP_DEFLATED)&lt;br /&gt;mycds.writestr('word/document.xml',str(newxml))&lt;br /&gt;mycds.close()&lt;/blockquote&gt;&lt;br /&gt;explanation: &lt;br /&gt;  'xslt1.xml' is the modified xslt file from the step 3; &lt;br /&gt;  'cddata.xml' is xml data file (source: &lt;a href="http://www.w3schools.com/xsl/tryxslt.asp?xmlfile=cdcatalog&amp;xsltfile=tryxsl_sort"&gt;w3schools xslt tutorial&lt;/a&gt; ); &lt;br /&gt;  newxml is the result xml tree of xslt transformation; &lt;br /&gt;  'nodocxml.docx' is the same as example.docx, the original docx file, except it doesn't have 'word/document.xml'; &lt;br /&gt;  'mycds.docx' is our final product.&lt;br /&gt;&lt;br /&gt;The example files can be downloaded from here: &lt;a href="http://bitbucket.org/wensheng/pydocx/downloads/pydocxml.zip"&gt;http://bitbucket.org/wensheng/pydocx/downloads/pydocxml.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The example does very few transformation.  If you want to more advanced stuff like adding images, you have to be more familiar with OOXML. (Add image to media directory, change relationships xml file, add relationship anchor to document.xml etc.)&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-201053980881350397?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/201053980881350397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=201053980881350397' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/201053980881350397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/201053980881350397'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2010/05/creating-ooxml-word-docx-file-with.html' title='Creating ooxml  word docx file with python and XSLT'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-5162566035041983263</id><published>2010-04-13T00:40:00.005-05:00</published><updated>2010-04-13T01:13:37.824-05:00</updated><title type='text'>Getting back data from lvm on raid1 on a single disk</title><content type='html'>One of my servers died.  The only thing I have left is a hard-drive from that server.  But I have important data I need to recover from this disk.&lt;br /&gt;&lt;br /&gt;The disk was part of RAID1 (software-raid) disks.  It's not boot-able, and only contains LVM volumes.&lt;br /&gt;&lt;br /&gt;Here's how I get my data back:&lt;br /&gt;&lt;br /&gt;1, Connect the hard-drive to my PC.  I used a USB docking station.&lt;br /&gt;&lt;br /&gt;2, My OS (Fedora) assigned it to /dev/sdd. It can not mount it since it's raid.&lt;br /&gt;&lt;br /&gt;3, make raid node, and attach the partition&lt;br /&gt;  mknod /dev/md0 b 9 3&lt;br /&gt;  mdadm --create /dev/md0 --level=raid1 --name=0 --auto=md --raid-disks=1 -f /dev/sdd1&lt;br /&gt;"-f" switch is needed to force creating raid1 with only 1 disk.&lt;br /&gt;&lt;br /&gt;4, now if I do pvscan, vgscan, and lvscan, it shows my vg (vg1) and lvm's:&lt;br /&gt;  pvscan #it shows PV /dev/md0 VG vg1&lt;br /&gt;but I still can not mount them, because no volume group actually existed.  Do this:&lt;br /&gt;  vgchange -a y vg1&lt;br /&gt;Now  /dev/vg1 is activated.&lt;br /&gt;&lt;br /&gt;5, Do the mount as usual&lt;br /&gt;  mount /dev/vg1/wensheng /mnt&lt;br /&gt;&lt;br /&gt;After I got back all my data, I disassemble the hard-drive to get the magnets, and throw the rest to trash.   Why? because of this:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_uMM6sJPJ1ug/S8QKBUrO8sI/AAAAAAAAAZQ/-98rc-kfbfA/s1600/Screenshot-SMART+Data.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 284px;" src="http://2.bp.blogspot.com/_uMM6sJPJ1ug/S8QKBUrO8sI/AAAAAAAAAZQ/-98rc-kfbfA/s320/Screenshot-SMART+Data.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5459499666126074562" /&gt;&lt;/a&gt;&lt;br /&gt;from my experience, this drive will die soon anyway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-5162566035041983263?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/5162566035041983263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=5162566035041983263' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/5162566035041983263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/5162566035041983263'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2010/04/getting-back-data-from-lvm-on-raid1-on.html' title='Getting back data from lvm on raid1 on a single disk'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_uMM6sJPJ1ug/S8QKBUrO8sI/AAAAAAAAAZQ/-98rc-kfbfA/s72-c/Screenshot-SMART+Data.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-3936704664216645821</id><published>2009-11-26T00:38:00.003-06:00</published><updated>2009-11-26T01:27:22.941-06:00</updated><title type='text'>IGot24 - a javascript game for calculate 24, hosted on AppEngine</title><content type='html'>I wrote a small game in the last few days.  The game is called IGot24.&lt;br /&gt;The idea is to use 4 basic arithmetic operations to get result 24 from 4 randomly drawn cards.  I talked about the algorithm and python implementation in &lt;a href="http://blog.wensheng.com/2006/06/calculate-24-python-implementation-24.html"&gt;an old post&lt;/a&gt;.  In fact, it's currently the first result on Google for "calculate 24".&lt;br /&gt;&lt;br /&gt;The game is at:&lt;br /&gt;  &lt;a href="http://calculate24.appspot.com/"&gt;http://calculate24.appspot.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I first wrote the game using pure JavaScript.  Later I thought whoever play it may want to get solutions.  So I created the backend with &lt;a href="http://code.google.com/appengine/"&gt;Google AppEngine&lt;/a&gt; that supply cards and solutions.  Then I added a few more options, like getting only solvable cards, disabling timer, calculate 42 instead of 24, etc.&lt;br /&gt;&lt;br /&gt;The heart of the JavaScript code is a finite state machine.  At first I just coded away thinking it'll be simple, then gradually realized there're more states.  I then drew a state diagram and found out there were 21 states!  They are all branches, there's no loopback, so I don't think they can be optimized. (Maybe they can, but I don't want to re-read my circuit design book from ages ago to find out)&lt;br /&gt;&lt;br /&gt;I think the game can be easily re-done in flash using Flex, since JavaScript can be ported to AS3.  It can be ported to IPhone too but it will be waste of time and money (to buy a mac to do iphone dev) because I found a "calculating 24" iphone app got downloaded a whopping 12 times.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-3936704664216645821?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/3936704664216645821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=3936704664216645821' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/3936704664216645821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/3936704664216645821'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2009/11/igot24-javascript-game-for-calculate-24.html' title='IGot24 - a javascript game for calculate 24, hosted on AppEngine'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-9096603344666264459</id><published>2009-11-21T23:55:00.000-06:00</published><updated>2009-11-22T02:15:55.714-06:00</updated><title type='text'>Chrome OS on Xen HVM</title><content type='html'>Google &lt;a href="http://googleblog.blogspot.com/2009/11/releasing-chromium-os-open-source.html"&gt;announced open-source Chromium OS&lt;/a&gt; 2 days ago. today I tried to build it on a Ubuntu virtual machine. But I failed, had numerous problems I won't elaborate. I will try again sometime later.&lt;br /&gt;&lt;br /&gt;I searched web and found a VMWare virtual disk of ChromeOS &lt;a href="http://gdgt.com/google/chrome-os/download/"&gt;here&lt;/a&gt;. So I downloaded it.&lt;br /&gt;&lt;br /&gt;Not wanting to install VMWare, I converted it to a raw disk image and loaded it to XEN with HVM, it worked.  But it basically unusable for me mainly because of mouse movement was too slow.  I will try with a different vnc client later to see if it improves.&lt;br /&gt;&lt;br /&gt;Here's how to convert vmdk image to raw:&lt;br /&gt;$qemu-img convert -f vmdk chrome-os-0.4.22.8-gdgt.vmdk -O raw chrome-os.img&lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;Then just specify the image file in 'disk' line of domain config file, like:&lt;br /&gt;disk = [ 'file:/root/chrome-os.img,hda,w' ]&lt;br /&gt;&lt;br /&gt;Here's screenshot of chrome OS:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_uMM6sJPJ1ug/Swjpo47YpZI/AAAAAAAAAS8/S-JxVsS4lDE/s1600/chrome.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 249px;" src="http://2.bp.blogspot.com/_uMM6sJPJ1ug/Swjpo47YpZI/AAAAAAAAAS8/S-JxVsS4lDE/s320/chrome.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5406828241343784338" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here's chrome OS login screen, I have a Fedora 12 hvm domain and a Ubuntu 9.04 32bit domainU also running on this machine. The domain0 itself is Fedora 12 64bit with pvops kernel 2.6.31.6.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_uMM6sJPJ1ug/Swjs_g0KJTI/AAAAAAAAATs/nGZLKwtnhQc/s1600/chromeos2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 256px;" src="http://3.bp.blogspot.com/_uMM6sJPJ1ug/Swjs_g0KJTI/AAAAAAAAATs/nGZLKwtnhQc/s320/chromeos2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5406831928542897458" /&gt;&lt;/a&gt;&lt;br /&gt;I had to use standard VGA driver(stdvga=1), the default Cirrus Logic driver give me a screen like this after I login:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_uMM6sJPJ1ug/Swjr1bPFplI/AAAAAAAAATM/NA9C_iorHG8/s1600/chromiumosxenhvm.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 256px;" src="http://1.bp.blogspot.com/_uMM6sJPJ1ug/Swjr1bPFplI/AAAAAAAAATM/NA9C_iorHG8/s320/chromiumosxenhvm.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5406830655734916690" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-9096603344666264459?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/9096603344666264459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=9096603344666264459' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/9096603344666264459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/9096603344666264459'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2009/11/chrome-os-on-xen-hvm.html' title='Chrome OS on Xen HVM'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_uMM6sJPJ1ug/Swjpo47YpZI/AAAAAAAAAS8/S-JxVsS4lDE/s72-c/chrome.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-8299595734938190961</id><published>2009-10-27T01:24:00.004-05:00</published><updated>2009-11-06T02:27:24.356-06:00</updated><title type='text'>POC: online barcode qrcode scan with webcam</title><content type='html'>This is proof of concept(POC).  The idea is to scan rebates, coupons, tickets etc. in the forms of barcode and qr-code using your web-cam.  &lt;br /&gt;&lt;br /&gt;Such an idea is really nothing new.  With cellphone, you can now scan the barcode when you pick up an item in store, and get price information on whether it is cheaper at nearby stores or online.  Also barcodes on cellphone can now be used for mobile ticketing.&lt;br /&gt;&lt;br /&gt;But I have not heard a lot about scanning rebates/coupons/tickets with webcam online.  So I created this POC project.&lt;br /&gt;Screenshot:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://wensheng.com/static/camscan.jpg"&gt;&lt;img style="margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 593; height: 512px;" src="http://wensheng.com/static/camscan.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It somewhat works.  QR-code works consistently but most of times the program can not read UPC and code 128.  I am sure with some added backend photo processing, I can improve the result, but I doubt it will help a lot.  Two of my 3 webcams have a focal length that make it impossible to snap a clear code image, unless of course the image is real large like 400x400 or 500x500px.  So I guesstimate most webcams are not suited code scanning?&lt;br /&gt;&lt;br /&gt;Here's &lt;a href="http://wensheng.com/camscan.php"&gt;actual page&lt;/a&gt; in a iframe:&lt;br /&gt;&lt;iframe src="http://wensheng.com/camscan.php" frameborder='0' height='500' scrolling='no' width='720'&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;The frontend is build with Flex SDK.  The webcam code come straight from &lt;a href="http://tinkerlog.com/2007/11/03/webcam-snapshots-with-flex3/"&gt;here&lt;/a&gt;.&lt;br /&gt;The backend is using &lt;a href="http://code.google.com/p/zxing/"&gt;Zxing&lt;/a&gt;.&lt;br /&gt;The QRcode test sample is generated from &lt;a href="http://wensheng.com/gqrcode.html"&gt;here&lt;/a&gt; with google chart api.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-8299595734938190961?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/8299595734938190961/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=8299595734938190961' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/8299595734938190961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/8299595734938190961'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2009/10/poc-online-barcode-qrcode-scan-with.html' title='POC: online barcode qrcode scan with webcam'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-5088761777048438853</id><published>2009-09-02T23:52:00.012-05:00</published><updated>2010-01-18T13:53:52.636-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lyrics'/><category scheme='http://www.blogger.com/atom/ns#' term='jw media player'/><title type='text'>JW media player with lyrics scroller</title><content type='html'>&lt;a href="http://blog.wensheng.com/2009/09/javascript-mp3-player-with-scrolling.html"&gt;Yesterday&lt;/a&gt;, I made a lyrics scroller.   The thing works, but it's missing quite a few things, like, progress bar, seek, time display, volume control, videos.&lt;br /&gt;&lt;br /&gt;So today I made a new one, this time using jw media player.  &lt;a href="http://www.longtailvideo.com/players/jw-flv-player/"&gt;JW media player&lt;/a&gt; is a full featured web media player.  It has almost everything.  Now it has a lyrics scroller;)&lt;br /&gt;&lt;br /&gt;Below is a demo, it's a iframe of &lt;a href="http://wensheng.com/code/jw_lyrics/"&gt;this page&lt;/a&gt;.&lt;br /&gt;&lt;iframe src="http://wensheng.com/code/jw_lyrics/" scrolling="no" frameborder="0" height="1250" width="500"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;Usage:&lt;br /&gt;Include 4 javascript files in the html header:&lt;br /&gt;jquery.js, jquery.scrollTo-1.4.2-min.js, swfobject.js, jwplrc.js&lt;br /&gt;&lt;br /&gt;Then put these javascript code in html:&lt;br /&gt;&lt;blockquote&gt;  var flashvars = {&lt;br /&gt;          file:"somesong.mp3",&lt;br /&gt;          lrc:"somelrc.lrc"&lt;br /&gt;};&lt;br /&gt;create_jwplrc("player_divid","320","80",flashvars,{},"some_uniq_id");&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The "file" flashvar can be used to specify a media file such as mp3 or a playlist xml file.&lt;br /&gt;If it's a single media file, you need to specify "lrc" flashvar to tell the player where lrc file is.  (update on 1/18/10)&lt;strike&gt;It can be in your web directory or anywhere on the web.&lt;br /&gt;if it's a playlist, no "lrc" flashvar is needed.  You imply that lrc and media are at&lt;br /&gt;same location/directory, and lrc and media have the same filename.&lt;/strike&gt; If it's a playlist, you need to specify lrc file in "&amp;lt;info&amp;gt; &amp;lt;/info&amp;gt;" inside playlist xml file.  The media files can be anywhere on the web, but lrc files has to be on your own site.&lt;br /&gt;&lt;br /&gt;"create_jwplrc" is just a wrapper function that wraps "swfobject.embedSWF". The first argument for create_jwplrc is the id of a "&amp;lt;div&amp;gt;" that will be the player, 2nd/3rd are width and height, 4th is flashvars, 5th is parameters, it can be empty {}.  The 6th argument is a unique name for the player.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://wensheng.com/code/jwlyrics.tgz"&gt;File download wensheng.com/code/jwlyrics.tgz&lt;/a&gt; (updated 1/18/10)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-5088761777048438853?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/5088761777048438853/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=5088761777048438853' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/5088761777048438853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/5088761777048438853'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2009/09/jw-media-player-with-lyrics-scroller.html' title='JW media player with lyrics scroller'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-9050390876910871616</id><published>2009-09-02T03:00:00.008-05:00</published><updated>2009-09-02T03:55:37.958-05:00</updated><title type='text'>A javascript mp3 player with scrolling lyrics (lrc) display</title><content type='html'>When listening to music on PC, I use a Chinese mp3 player called &lt;a href="http://ttplayer.qianqian.com/"&gt;TTPlayer&lt;/a&gt;.  The main feature of TTPlayer is it display lyrics that synced with the music.&lt;br /&gt;Searching for a web equivalent, the closest thing i found is &lt;a href="http://dt.in.th/2008-05-18.javascript-karaoke-lyric-scroller.html"&gt;this&lt;/a&gt;.  But it has issues, for me anyway, i.e. play only one song, no play/pause control, can't scroll back, can't replay, use an unfamiliar animation framework.  So I look at the code and come up with my own.  The player is based on &lt;a href="http://www.schillmania.com/projects/soundmanager2/"&gt;soundmanager2 &lt;/a&gt;demo code.  It use &lt;a href="http://jquery.com/"&gt;jquery &lt;/a&gt;and &lt;a href="http://plugins.jquery.com/project/ScrollTo"&gt;jquery scrollto plugin&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://wensheng.com/code/sm_lyrics/blogger.html" frameborder='0' height='400' scrolling='no' width='500'&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The demo is at: &lt;a href="http://wensheng.com/code/sm_lyrics/"&gt;http://wensheng.com/code/sm_lyrics/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The code can be downloaded &lt;a href="http://wensheng.com/code/sm_lyrics/sm_lyrics.tgz"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-9050390876910871616?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/9050390876910871616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=9050390876910871616' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/9050390876910871616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/9050390876910871616'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2009/09/javascript-mp3-player-with-scrolling.html' title='A javascript mp3 player with scrolling lyrics (lrc) display'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-3482258557399351698</id><published>2009-07-31T00:12:00.009-05:00</published><updated>2009-07-31T01:29:09.862-05:00</updated><title type='text'>Happy Girls</title><content type='html'>I will be watching Tonight's &lt;a href="http://en.wikipedia.org/wiki/Super_Girl_%28contest%29"&gt;Super Girls&lt;/a&gt; (or Happy Girls, as it's called now).  I don't know why I watch it.  I never watched American Idols or any other pop contest shows. And I absolutely hate the most populor one of previous super-girls winner - &lt;a href="http://en.wikipedia.org/wiki/Li_Yuchun"&gt;Li Yuchun&lt;/a&gt;.&lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;But since I watched this year's happy-girls one night with wife, I got hooked.  Maybe it's just the pretty girls I'd like to watch.  I told a co-worker the other day I like Happy-girls, she said I'd have become dirty middle-aged man (龌龊中年男人). Is that the reason? Ouch..&lt;br /&gt;&lt;br /&gt;I am rooting for Liu Xijun 刘惜君. &lt;a href="http://3.bp.blogspot.com/_uMM6sJPJ1ug/SnKDZMhqrFI/AAAAAAAAAR8/uHmd0jDGgWM/s1600-h/liu.jpg"&gt;(big pic)&lt;/a&gt;&lt;br /&gt;&lt;img src="http://3.bp.blogspot.com/_uMM6sJPJ1ug/SnKDZMhqrFI/AAAAAAAAAR8/uHmd0jDGgWM/s200/liu.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;I also like Tan Lina 谈莉娜, she's very pretty. &lt;a href="http://1.bp.blogspot.com/_uMM6sJPJ1ug/SnKEGx2NmQI/AAAAAAAAASE/iWPivPuFRgw/s1600-h/eo090702966.jpg"&gt;(pic)&lt;/a&gt;&lt;br /&gt;I like Li Xiaoyun 李宵云 too （&lt;a href="http://www.youtube.com/watch?v=HyGPk8N3k5A"&gt;video&lt;/a&gt;), but she's not good-looking.  Huang ying's good too, but her voice style gets old after a while.  I really don't care for other girls.&lt;br /&gt;&lt;br /&gt;Here's a video of Liu from youtube singing "伤痕".   In my opinion, it's better than Lin yilian's original.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/4VHpsbwPpqA&amp;amp;hl=en&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/4VHpsbwPpqA&amp;amp;hl=en&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;a class="pdufwbnxsualdtkxwebo" href="http://www.youtube.com/v/4VHpsbwPpqA&amp;amp;hl=en&amp;amp;fs=1&amp;amp;"&gt;&lt;/a&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-3482258557399351698?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/3482258557399351698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=3482258557399351698' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/3482258557399351698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/3482258557399351698'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2009/07/happy-girls.html' title='Happy Girls'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_uMM6sJPJ1ug/SnKDZMhqrFI/AAAAAAAAAR8/uHmd0jDGgWM/s72-c/liu.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-4119228052658578359</id><published>2009-07-30T23:38:00.000-05:00</published><updated>2009-07-31T00:09:13.898-05:00</updated><title type='text'>set up geo dns (geodns) on Fedora using geoipdns pt 2</title><content type='html'>Here I describe the steps of set up &lt;a href="http://code.google.com/p/geoipdns/"&gt;Geoipdns&lt;/a&gt; (a &lt;a href="http://cr.yp.to/djbdns/tinydns.html"&gt;Tinydns&lt;/a&gt; fork at does geo dns).  First following &lt;a href="http://blog.wensheng.com/2009/07/set-up-tinydns-on-fedora.html"&gt;these steps here&lt;/a&gt; to set up Tinydns.  Even though Geoipdns is a fork, it doesn't provide the configuration programs such as tinydns-conf that's in Tinydns.  So it's much easier to set up Geoipdns after we already have Tinydns set up.&lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;You can read Geoipdns document on &lt;a href="http://pub.mud.ro/wiki/Geoipdns"&gt;http://pub.mud.ro/wiki/Geoipdns&lt;/a&gt;.&lt;br /&gt;Here are quick steps:&lt;br /&gt;   $yum install inotify-tools-devel&lt;br /&gt;#geoipdns use libinotifytools.&lt;br /&gt;&lt;br /&gt;   $mkdir vdns&lt;br /&gt;   $cd vdns/&lt;br /&gt;   $wget http://pub.mud.ro/~cia/files/vdns-src.tgz&lt;br /&gt;   $tar xfz vdns-src.tgz&lt;br /&gt;   $vi conf-cc&lt;br /&gt;#Add " -include /usr/include/errno.h" to the first line of conf-cc&lt;br /&gt;&lt;br /&gt;   $LOCAL_CFLAGS="-DUSE_LOCMAPS -DUSE_SFHASH -DUSE_TOUCH_RELOADS -DDEBUG_MODE -DHAVE_MMAP_READAHEAD"&lt;br /&gt;   $make&lt;br /&gt;   $mkdir /usr/local/apps&lt;br /&gt;   $./install&lt;br /&gt;   $cp -rp /usr/local/apps/vdns/bin/* /usr/local/bin/&lt;br /&gt;The last step is to allow us access vdnsd vdnsdb without add to PATH.&lt;br /&gt;&lt;br /&gt;Now geoipdns is installed.  Next we need to configure it so it does geo dns.&lt;br /&gt;  $cd /etc/tinydns&lt;br /&gt;  $cp run run.tinydns #backup run&lt;br /&gt;  $vi run&lt;br /&gt;#inside run, we change /usr/local/bin/tinydns to/usr/local/bin/vdnsd&lt;br /&gt;&lt;br /&gt;  $cd root&lt;br /&gt;  $vi Makefile&lt;br /&gt;#inside Makefile we change tinydns-data to vdnsdb&lt;br /&gt;&lt;br /&gt;  $make&lt;br /&gt;  $svc -t /service/tinydns&lt;br /&gt;&lt;br /&gt;Now vdnsd should be running, use "ps -ef" to see that vdnsd is running tinydns is not, but you still should see "supervise tinydns".&lt;br /&gt;Do some dig to make sure everything still works just like Tinydns is running.&lt;br /&gt;&lt;br /&gt;Now you need to query the server from at least 2 different locations, otherwise you don't know if geodns works or not.&lt;br /&gt;If you set up dns on local network, such as 192.168.1.0, you can put IP's of local machines in "data" and test geodns from these local machine.&lt;br /&gt;If you have a world facing DNS server and you want to test geodns, you can put the IP's of your home, work, colocated server, or VPS in data, then test dns from those locations.&lt;br /&gt;&lt;br /&gt;However if you want to test it fast at where you are, you are also in luck, because there're several online dig sites you can use.  I will use 2 such sites as examples:&lt;br /&gt;&lt;a href="http://dig.menandmice.com/knowledgehub/tools/dig"&gt;  http://dig.menandmice.com/knowledgehub/tools/dig&lt;/a&gt; ip is 207.57.2.84&lt;br /&gt;&lt;a href="http://www.subnetonline.com/pages/network-tools/online-dig.php"&gt;  http://www.subnetonline.com/pages/network-tools/online-dig.php&lt;/a&gt; ip is 85.17.250.238&lt;br /&gt;Note these Ip's are as of this writing. If they have changed at the time of your testing, you need to change them too in your data file.&lt;br /&gt;&lt;br /&gt;Now the data.  Suppose  your DNS server name is ns1.myserver.com (replace it with your real dns server name), add these to your /etc/tinydns/root/data file:&lt;blockquote&gt;%onlinedig1:207.57.2.84:32&lt;br /&gt;%onlinedig2:85.17.250.238:32&lt;br /&gt;.example.com::ns1.myserver.com:259200&lt;br /&gt;+www.example.com:1.1.1.1:3600::onlinedig1&lt;br /&gt;+www.example.com:2.2.2.2:3600::onlinedig2&lt;br /&gt;+www.example.com:3.3.3.3:3600::nomatch&lt;/blockquote&gt;Do a "make" to update the data hash.&lt;br /&gt;&lt;br /&gt;Now you can start testing. First do a "dig @ns1.myserver.com www.example.com" locally.  It should say 3.3.3.3.    Then go to http://dig.menandmice.com/knowledgehub/tools/dig , enter name server "ns1.myserver.com", enter domain name "www.example.com", click "perform query", it should say 1.1.1.1.  Now do the same on http://www.subnetonline.com/pages/network-tools/online-dig.php, it should say 2.2.2.2.&lt;br /&gt;If they display correct fake information, your geo dns works.&lt;br /&gt;&lt;br /&gt;Next you need to add real IP location data and setup geo dns for your real domains.&lt;br /&gt;I will talk about this in another post.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-4119228052658578359?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/4119228052658578359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=4119228052658578359' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/4119228052658578359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/4119228052658578359'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2009/07/set-up-geo-dns-or-geodns-on-fedora.html' title='set up geo dns (geodns) on Fedora using geoipdns pt 2'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-4137117110505734820</id><published>2009-07-29T23:50:00.001-05:00</published><updated>2009-07-30T17:52:36.344-05:00</updated><title type='text'>Why geo dns - setting up geodns on fedora part 1</title><content type='html'>First of all, what is geodns? Let's look at an example.  The following show the outputs of dig and ping on www.google.com from 3 different geographical locations.&lt;br /&gt;First from Dallas:&lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;&lt;blockquote&gt;270 06:13 PM wang@ns1)dig www.google.com +short&lt;br /&gt;www.l.google.com.&lt;br /&gt;74.125.47.99&lt;br /&gt;74.125.47.103&lt;br /&gt;(truncated)&lt;br /&gt;271 06:13 PM wang@ns1)ping -c 2 www.google.com&lt;br /&gt;PING www.l.google.com (74.125.47.99) 56(84) bytes of data.&lt;br /&gt;64 bytes from yw-in-f99.google.com (74.125.47.99): icmp_seq=1 ttl=54 time=21.2 ms&lt;br /&gt;64 bytes from yw-in-f99.google.com (74.125.47.99): icmp_seq=2 ttl=54 time=21.0 ms&lt;/blockquote&gt; Next from Xi'an, China: &lt;blockquote&gt;[wang@www ~]$ dig www.google.com +short&lt;br /&gt;www.l.google.com.&lt;br /&gt;64.233.189.104&lt;br /&gt;64.233.189.147&lt;br /&gt;64.233.189.99&lt;br /&gt;[wang@www ~]$ ping -c 2 www.google.com&lt;br /&gt;PING www.l.google.com (64.233.189.147) 56(84) bytes of data.&lt;br /&gt;64 bytes from hk-in-f147.google.com (64.233.189.147): icmp_seq=1 ttl=242 time=45.7 ms&lt;br /&gt;64 bytes from hk-in-f147.google.com (64.233.189.147): icmp_seq=2 ttl=242 time=45.8 ms&lt;/blockquote&gt; Finally from Zhejiang China:&lt;blockquote&gt;137 03:06 PM wang@cn)dig www.google.com +short&lt;br /&gt;www.l.google.com.&lt;br /&gt;66.249.89.99&lt;br /&gt;66.249.89.104&lt;br /&gt;66.249.89.147&lt;br /&gt;138 03:06 PM wang@cn)ping -c 2 www.google.com&lt;br /&gt;PING www.l.google.com (66.249.89.99) 56(84) bytes of data.&lt;br /&gt;64 bytes from jp-in-f99.google.com (66.249.89.99): icmp_seq=1 ttl=243 time=47.4 ms&lt;br /&gt;64 bytes from jp-in-f99.google.com (66.249.89.99): icmp_seq=2 ttl=243 time=47.4 ms&lt;/blockquote&gt;  You can see the IP's for www.google.com from these locations are different.  The reason for this is that Google want to send www.google.com visitors to their nearest web servers. Why? you might ask.  Because of network latency.  Here's output from pinging US google server from China:&lt;blockquote&gt;[wang@www ~]$ ping 74.125.47.99 -c 2&lt;br /&gt;PING 74.125.47.99 (74.125.47.99) 56(84) bytes of data.&lt;br /&gt;64 bytes from 74.125.47.99: icmp_seq=1 ttl=44 time=258 ms&lt;br /&gt;64 bytes from 74.125.47.99: icmp_seq=2 ttl=44 time=261 ms&lt;/blockquote&gt; So the ping time is &gt;10 times as long as ping time from within US.  If Google doesn't have servers in China (or hk, jp, or whatever closer to China), the experience of Chinese www.google.com visitors will be really bad (long response time, slow page load).&lt;br /&gt;&lt;br /&gt;The 3 popular DNS software (bind, powerdns, tinydns) all have geo capability, either with patch, backend, or in tinydns case, a fork called geoipdns.  I have been using &lt;a href="http://cr.yp.to/djbdns/tinydns.html"&gt;Tinydns &lt;/a&gt;for several years and very satisfied with its ease of use and performance.  So I stick with Tinydns for my geodns.&lt;br /&gt;The geodns fork of Tinydns is called &lt;a href="http://code.google.com/p/geoipdns/"&gt;geoipdns&lt;/a&gt;, it's written by &lt;a href="http://pub.mud.ro/~cia/id/"&gt;Adrian Ilarion Ciobanu&lt;/a&gt;.&lt;br /&gt;I will talk about how to set up Geoipdns in the next post.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-4137117110505734820?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/4137117110505734820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=4137117110505734820' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/4137117110505734820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/4137117110505734820'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2009/07/why-geo-dns-setting-up-geodns-on-fedora.html' title='Why geo dns - setting up geodns on fedora part 1'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-3319561135312815671</id><published>2009-07-29T20:23:00.000-05:00</published><updated>2009-07-30T17:39:15.336-05:00</updated><title type='text'>Set up Tinydns on Fedora</title><content type='html'>Installing Tinydns (djbdns) on Fedora consists of 4 steps:&lt;br /&gt;1, Install daemontools&lt;br /&gt;2, Install ucspi-tcp&lt;br /&gt;3, Install djbdns&lt;br /&gt;4, configure tinydns&lt;br /&gt;&lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Step 1: Daemontools&lt;/span&gt;&lt;br /&gt;First of all, make sure we have all the packages that's needed:&lt;blockquote&gt;yum install gcc gcc-c++ make flex bison # etc. &lt;/blockquote&gt;This will install all the compilers, kernel-headers, tools and stuff.&lt;br /&gt;Then &lt;blockquote&gt;mkdir daemontools&lt;br /&gt;cd daemontools&lt;br /&gt;wget http://cr.yp.to/daemontools/daemontools-0.76.tar.gz&lt;br /&gt;tar xvfz daemontools-0.76.tar.gz&lt;br /&gt;cd admin/daemontools-0.76/&lt;br /&gt;vi compile/conf-cc #add " -include /usr/include/errno.h" at the end of 1st line&lt;br /&gt;./package/install&lt;br /&gt;cd /command&lt;br /&gt;\rm * #get rid of links, we will use actual excutables here&lt;br /&gt;cp -rp /root/daemontools/admin/daemontools/command/* . &lt;br /&gt;vi /etc/inittab #get rid of that svscanboot line because it's not used from fc9 &lt;br /&gt;vi /etc/event.d/svscan #create this new file &lt;/blockquote&gt;&lt;br /&gt;The content of this file /etc/event.d/svscan is: &lt;blockquote&gt;start on runlevel [2345]&lt;br /&gt;stop on runlevel [016]&lt;br /&gt;respawn&lt;br /&gt;exec /command/svscanboot&lt;/blockquote&gt; Now daemontools setup is complete. Do a "ps -ef" to see if svscan is running.  If not, manually start it, or reboot.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Step 2: ucspi-tcp&lt;/span&gt;&lt;br /&gt;This is simple:&lt;blockquote&gt;mkdir ucspi-tcp&lt;br /&gt;cd ucspi-tcp/&lt;br /&gt;wget http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz&lt;br /&gt;tar xvfz ucspi-tcp-0.88.tar.gz&lt;br /&gt;cd ucspi-tcp-0.88&lt;br /&gt;vi conf-cc # put " -include /usr/include/errno.h" at the end of 1st line&lt;br /&gt;make&lt;br /&gt;./install&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Step 3: djbdns&lt;/span&gt;&lt;br /&gt;This is quick too:&lt;br /&gt;&lt;blockquote&gt;mkdir djbdns&lt;br /&gt;cd djbdns/&lt;br /&gt;wget http://cr.yp.to/djbdns/djbdns-1.05.tar.gz&lt;br /&gt;tar xvfz djbdns-1.05.tar.gz&lt;br /&gt;cd djbdns-1.05&lt;br /&gt;vi conf-cc # add " -include /usr/include/errno.h" to the 1st line&lt;br /&gt;make&lt;br /&gt;./install&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Step 4: configuration&lt;/span&gt;&lt;br /&gt;I will only tinydns here, setting up dnscache is very similiar to setting up tinydns.&lt;br /&gt;&lt;blockquote&gt;useradd –s /bin/false tinydns&lt;br /&gt;useradd –s /bin/false dnslog&lt;br /&gt;tinydns-conf tinydns dnslog /etc/tinydns your_external_ip &lt;br /&gt;ln -s /etc/tinydns /service/&lt;br /&gt;svstat /service/tinydns&lt;/blockquote&gt;&lt;br /&gt;That's it, do "svstat /service/tinydns" again, it should show the seconds it's up keep increasing. If not, like for example it stuck at 0 or 1 second, then your setup is not correct. &lt;br /&gt;To debug the problem, do some of these:&lt;br /&gt;Look at /etc/tinydns/log/main/current to see if there's error.&lt;br /&gt;Make sure there's a supervise directory in /etc/tinydns/&lt;br /&gt;Make sure there's No directory under /etc/tinydns/env&lt;br /&gt;remove /service/tinydns link and re-link&lt;br /&gt;remove /etc/tinydns directory and re-create them using tinydns-conf&lt;br /&gt;stop and start the service using "svc" ("svc -d" then "svc_u" or "svc -t" etc.)&lt;br /&gt;&lt;br /&gt;Next, just add records to "/etc/tinydns/root/data", and then "make", tinydns should now happily serve any requests from anywhere. If not, use "dig" to debug the problem.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-3319561135312815671?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/3319561135312815671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=3319561135312815671' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/3319561135312815671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/3319561135312815671'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2009/07/set-up-tinydns-on-fedora.html' title='Set up Tinydns on Fedora'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-7212797813216220370</id><published>2009-06-12T11:42:00.004-05:00</published><updated>2009-06-12T11:59:09.691-05:00</updated><title type='text'>Creating a Fedora 11 image</title><content type='html'>Fedora 11 is out.  I made a fedora 11 image as my domU.  The steps for making a Fedora 11 image is little different than those for Fedora 10 that I have described &lt;a href="http://blog.wensheng.com/2008/11/how-to-make-fedora-10-image-from-old.html"&gt;here&lt;/a&gt;.  But there are some caveats, all related to RPM.&lt;br /&gt;&lt;br /&gt;First you have must rpm version &gt; 4.6, otherwise you have have this MD5 errors (fedora 11 doesn't use md5 checksum anymore).&lt;br /&gt;&lt;br /&gt;Second, the new rpm in fedora 11 use LUA, but liblua.so is not installed by yum groupinstall. So inside fedora 11, we have this chicken and egg problem.  To install liblua.so from liblua.rpm (and anything else from rpm) we need rpm; but to run rpm, we need liblua.so.  To solve this, just copy liblua.so from fedora 10 to fedora 11's /usr/lib when fedora 11's image is mounted in fedora 10.&lt;br /&gt;&lt;br /&gt;Other than these, everything's fine with making Fedora 11 image.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-7212797813216220370?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/7212797813216220370/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=7212797813216220370' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/7212797813216220370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/7212797813216220370'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2009/06/creating-fedora-11-image.html' title='Creating a Fedora 11 image'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-2942098526953689304</id><published>2009-05-29T15:12:00.003-05:00</published><updated>2009-05-29T15:24:59.425-05:00</updated><title type='text'>Vim takes 9 G memory</title><content type='html'>Today I used Vim to edit a big file, about 1.5Gig in size.  At the end of editing, Vim occupied 9.1G memory. Fortunately the machine has 64G.  I was using visual mode to do column delete.  I can't use cut and paste (Unix command line, not windows cut and paste) because I didn't delete whole columns. The whole editing session took more than 1 hour with most time spent waiting for commands to complete.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_uMM6sJPJ1ug/SiBEWrGi2aI/AAAAAAAAAQU/yzmM7zgADSQ/s1600-h/9p1gig.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 241px;" src="http://3.bp.blogspot.com/_uMM6sJPJ1ug/SiBEWrGi2aI/AAAAAAAAAQU/yzmM7zgADSQ/s400/9p1gig.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5341344314379393442" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-2942098526953689304?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/2942098526953689304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=2942098526953689304' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/2942098526953689304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/2942098526953689304'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2009/05/vim-takes-9-g-memory.html' title='Vim takes 9 G memory'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_uMM6sJPJ1ug/SiBEWrGi2aI/AAAAAAAAAQU/yzmM7zgADSQ/s72-c/9p1gig.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-43664852369402458</id><published>2009-05-16T13:41:00.004-05:00</published><updated>2009-05-16T14:05:51.881-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chinese'/><title type='text'>Chinese language test</title><content type='html'>My colleague passed me a Chinese language test. It's an Excel spreadsheet. There are 100 2-choice character questions.  I was kinda surprised I only scored 79. After all I'm Chinese and I thought my Chinese was good.  But anyway it's a good test.  So I made a web version:&lt;br /&gt;&lt;br /&gt;   &lt;a href="http://wensheng.com/code/cntest/"&gt;http://wensheng.com/code/cntest/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I shuffle the questions so it doesn't come out the same every time. You can also score yourself anytime. (In Excel you have to answer all 100 to get your score.)  The test works in Firefox, Opera, Chrome, and Internet Explorer 8.  It doesn't work in IE7 and IE6 because they don't' allow setting the NAME attribute of radio button dynamically.  There are ways around it but I don't want to waste my time fixing it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-43664852369402458?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/43664852369402458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=43664852369402458' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/43664852369402458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/43664852369402458'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2009/05/chinese-language-test.html' title='Chinese language test'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-9215662603793896401</id><published>2009-04-28T12:35:00.004-05:00</published><updated>2009-05-15T15:28:44.179-05:00</updated><title type='text'>msvc2005 release crash debug OK</title><content type='html'>I had a strange problem with Visual C++ 2005 today.  I needed to add some feature to a program I developed several years ago.  I used VC2005. &lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;During debugging, everything's fine.  But when I built a release and tested it, it crashed.  So I set a breakpoint before the location where I thought it crashed, and run the debug, this is what I got:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_uMM6sJPJ1ug/SfdBLtRdyfI/AAAAAAAAAQM/GMnt6LPfLjU/s1600-h/vs2005.PNG" target="_blank"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://1.bp.blogspot.com/_uMM6sJPJ1ug/SfdBLtRdyfI/AAAAAAAAAQM/GMnt6LPfLjU/s320/vs2005.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5329800353403488754" /&gt;&lt;/a&gt;&lt;br /&gt;How is that even possible? "0&lt;0" is true?! Apparently the memory is messed up.  I don't have time to get to the bottom of this so I just released the debug version.&lt;br /&gt;&lt;br /&gt;(update 5/15/09: In case I forget.  If I set Property-&gt;Configuration-&gt;C/C++-&gt;Code Generation-&gt;Basic Runtime Checks to "Stack Frames (/RTCs)", the program will works fine.  From MS (&lt;a href="http://msdn.microsoft.com/en-us/library/aa289171.aspx"&gt;http://msdn.microsoft.com/en-us/library/aa289171.aspx&lt;/a&gt;): /RTCs - Stack Frame Run-Time Error Checking&lt;br /&gt;This option does several things that help to protect the stack from corruption.&lt;br /&gt;    * Initialize all local variables to non-zero values each time the function is called. This prevents inadvertent use of values on the stack from previous calls.&lt;br /&gt;    * Verify the stack pointer to check for corruption, such as that caused by defining a function as __stdcall in one place and __cdecl in another.&lt;br /&gt;    * Detect overruns and underruns of local variables. This differs from /GS because it is available only in debug builds, and it detects corruption on either end of a buffer and for all buffers.&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-9215662603793896401?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/9215662603793896401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=9215662603793896401' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/9215662603793896401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/9215662603793896401'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2009/04/msvc2005-release-crash-debug-ok.html' title='msvc2005 release crash debug OK'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_uMM6sJPJ1ug/SfdBLtRdyfI/AAAAAAAAAQM/GMnt6LPfLjU/s72-c/vs2005.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-5710712023202999625</id><published>2009-01-20T00:46:00.012-06:00</published><updated>2009-01-20T08:52:12.106-06:00</updated><title type='text'>The adventure of (re)installing linux on Tyan s5150 with rocketraid 2220 and Hitachi Deskstar T7K250</title><content type='html'>More than 3 years ago, I built a backup server for others to use.  It's set up with a &lt;a href="http://www.tyan.com/archive/products/html/tomcati7221.html"&gt;Tyan S5150 motherboard&lt;/a&gt; with Pentium 630 (3.0Ghz), Highpoint &lt;a href="http://www.highpoint-tech.com/USA/rr2220.htm"&gt;RocketRaid 2220 (rr2220)&lt;/a&gt;, 7 SATA drives in a 3U rackmount Antec case.  I don't remember how much it costed me, but it's sure more than $2000 (hard disks alone was $1000).  &lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;Recently the server was freed up.  Even though the hard disks are real cheap now (the cheapest 1T drive is $94 now at newegg, Seagate 7200.11 1.5T drive is selling for $129) I hate to see those hard-drives idle, so I brought it home and intended to build a file server.&lt;br /&gt;5 of the 7 SATA drives are 250GB Hitachi Deskstar T7k250.  These drives are from the same batch, all produced in July 2005.  The problem with these drives is that they can not be used by any other computers. Either bios doesn't read these disks or the it read as 0MB and can not use them.  I also have 3 USB SATA hardware enclosures, none of those disks work with any of the enclosures.  These are the only SATA drives I have that have this problem (I have a lot of drives).  What's strage is that the same 250G T7K250 drives that produced a month later (August 2005) have no such problem.&lt;br /&gt;So I have to use rr2200 (which is a pci-x card) for these drives, which means I have to use Tyan S5150 board because it has a PCI-X slot.  As I try to install the board, I found I have to use a EPS12V power-supply.  But all I have is ATX.  So i pulled EPS12V PS from the Antec case (I can't use the case, it's like a helicopter when it's turned on).  Basically the whole server got re-used except the metal shell.&lt;br /&gt;&lt;br /&gt;The server used to have Fedora Core 4 on it.  I remembered it took a lot of time for me to install and configure it.  But unfortunately I didn't document what I did.  Huge mistake!! Now the problem only begins.&lt;br /&gt;&lt;br /&gt;First of all, With the raid card rr2220 inserted, and a raid array configured.  The server can't even boot to the point it trying to load OS (any OS on any media, hard disk or CD or USB).  &lt;br /&gt;It only boot to an OS after I deleted the raid array, leaving the 5 disks unconfigured.  Still, I can not boot Centos, Ubuntu installation CD.  I can only boot with Fedora 10 CD, and only after adding "edd=off" to boot line.&lt;br /&gt;It take a long time to get to welcome screen, at times it appeared stalled.  But tty4 shows it's some disk error, and still trying.  &lt;br /&gt;During the configuring the installation, this show up.  &lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_uMM6sJPJ1ug/SXWAXdQx62I/AAAAAAAAAOU/s-eXQ3D3Rd8/s1600-h/CIMG0006.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://2.bp.blogspot.com/_uMM6sJPJ1ug/SXWAXdQx62I/AAAAAAAAAOU/s-eXQ3D3Rd8/s320/CIMG0006.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5293278077524241250" /&gt;&lt;/a&gt;You bet it's a BUG! The installation aborted.  &lt;br /&gt;This bug is caused by conflicting drivers sata_mv and tg3.  You may wonder why a sata driver (sata_mv) conflict with a ethernet card driver (tg3), beats me.  &lt;br /&gt;&lt;br /&gt;Only after I pulled out the rr2220 can I successfully install fedora 10. So I did the installation.  Boot the new OS, blacklisted sata_mv, compiled and installed so-called "open-source" driver from Highpoint. Did a modprobe hptmv6, it shows the driver loaded succesfuly and it saw 5 drives.&lt;br /&gt;But I can not use them.  Because somehow they can not be used a individual disks, They can only be used as raid arrays.  So I went ahead and configured RAID arrays.  But lo and behold, I can NOT boot again.  I tried a GRUB CD, it doesn't boot either.  I do have spare floppy drive, but I remember I tried that 3 years ago it didn't work so I didn't bother.  &lt;br /&gt;&lt;br /&gt;So I did some research (i.e. google) and it seems the problem is that rr2220 was trying to be first and only boot device no matter what you told motherboard bios.  The problem can only be corrected by change in rr2220 bios. The change requires disabling INT13 and/or EBDA reallocation.&lt;br /&gt;But the Linux bios update utility from Highpoint have no such options, only with their windows version can you make this change.  What could I do?&lt;br /&gt;&lt;br /&gt;Running out of options, I installed windows xp (after un-insert rr2220 of course), download flash utility and new bios,  re-insert rr2220, reboot, run the utility, check "disable INT13" and "disable Allocating EBDA  " and "disable stop or error", then flashed the bios.&lt;br /&gt;Yes, I wasted an hour just to install Windows and run Highpoint bios flashing utility.&lt;br /&gt;&lt;br /&gt;Now it's Fedora 10 installation all over again.  Pulled out raid card, install fedora 10,  boot to fedora 10, blacklist "sata_mv", download and built and install "open-source" rr2220 driver, install driver.  Shutdown,  re-insert Raid card, boot, create raid arrays, continue boot, fdisk, mkfs, mount, install and configure Samba.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_uMM6sJPJ1ug/SXWKW-CYgXI/AAAAAAAAAOc/JLCfAdQ-Uw0/s1600-h/CIMG0008.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://3.bp.blogspot.com/_uMM6sJPJ1ug/SXWKW-CYgXI/AAAAAAAAAOc/JLCfAdQ-Uw0/s320/CIMG0008.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5293289064258634098" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_uMM6sJPJ1ug/SXWLGSgcAgI/AAAAAAAAAOk/ogyGQdXBSfQ/s1600-h/CIMG0009.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://1.bp.blogspot.com/_uMM6sJPJ1ug/SXWLGSgcAgI/AAAAAAAAAOk/ogyGQdXBSfQ/s320/CIMG0009.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5293289877207253506" /&gt;&lt;/a&gt;&lt;br /&gt;Finally my file server is set up.  It has 1.2 Tera Byte of storage.  Not much, but I got to use the 5 disks that otherwise can't be used.  Besides, it has room to expand.  RocketRaid 2220 is an 8 port SATA2 card.  Tyan motherboard itself has 4 SATA ports.  So in theory, at today's 1.5T per drive, I can have 1.5*12 = 18 Tera Byte of storage (at 5M/song, it's 3 million MP3 songs, or at 6G/dvd it's 3000 DVD movies). &lt;br /&gt;When the price on 1.5T drive drops to sub-$50 range, I will get some of those (assuming per GB SSD price is still much higher then).  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-5710712023202999625?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/5710712023202999625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=5710712023202999625' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/5710712023202999625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/5710712023202999625'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2009/01/adventure-of-reinstalling-linux-on-tyan.html' title='The adventure of (re)installing linux on Tyan s5150 with rocketraid 2220 and Hitachi Deskstar T7K250'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_uMM6sJPJ1ug/SXWAXdQx62I/AAAAAAAAAOU/s-eXQ3D3Rd8/s72-c/CIMG0006.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-7718026935296157275</id><published>2008-12-24T01:58:00.003-06:00</published><updated>2008-12-24T02:24:22.614-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gfw'/><title type='text'>on GFW of China</title><content type='html'>GFW=great fire wall.&lt;br /&gt;On my vacation to China this last summer I tried to access this blog from different locations in China: Xi'an, Beijing, Dalian, Shanghai. Never once did I succeed.  &lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;I can read Wikipedia, but I heard from other people it's hit &amp; miss.  I had no problem with porn sites though.  &lt;br /&gt;I always thought this censoring by Chinese government is really stupid. Today I read a excellent column on NY Times by World-is-flat author Tom Friedman, towards the end of &lt;a href="http://www.nytimes.com/2008/12/24/opinion/24friedman.html?_r=1"&gt;the article&lt;/a&gt;, it struck a chord with me:&lt;br /&gt;&lt;blockquote&gt;America still has the right stuff to thrive. We still have the most creative, diverse, innovative culture and open society — in a world where the ability to imagine and generate new ideas with speed and to implement them through global collaboration is the most important competitive advantage. China may have great airports, but last week it went back to censoring The New York Times and other Western news sites. Censorship restricts your people’s imaginations. That’s really, really dumb. And that’s why for all our missteps, the 21st century is still up for grabs.&lt;/blockquote&gt;&lt;br /&gt;For the benefit of the China and Chinese people's future, Mr. Hu, Tear down this great fire-wall. (&lt;a href="http://uk.youtube.com/watch?v=WjWDrTXMgF8"&gt;tear down this wall&lt;/a&gt;). 胡哥, 这墙拆了得了. &lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-7718026935296157275?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/7718026935296157275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=7718026935296157275' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/7718026935296157275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/7718026935296157275'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2008/12/on-gfw-of-china.html' title='on GFW of China'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-7553604750775735344</id><published>2008-12-21T12:52:00.005-06:00</published><updated>2008-12-21T13:01:47.430-06:00</updated><title type='text'>Emacs utf8 and Chinese on Windows</title><content type='html'>Download &lt;a href="http://ourcomments.org/cgi-bin/emacsw32-dl-latest.pl"&gt;EmacsW32 latest binary&lt;/a&gt; (emacs 23 + emacsw32).  Then add following to your .emacs&lt;br /&gt;&lt;blockquote&gt;(setq locale-coding-system 'utf-8)&lt;br /&gt;(set-terminal-coding-system 'utf-8)&lt;br /&gt;(set-keyboard-coding-system 'utf-8)&lt;br /&gt;(set-selection-coding-system 'utf-8)&lt;br /&gt;(prefer-coding-system 'utf-8)&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;All your problems of viewing/editing Chinese on Windows Emacs will go away.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-7553604750775735344?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/7553604750775735344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=7553604750775735344' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/7553604750775735344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/7553604750775735344'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2008/12/emacs-utf8-and-chinese-on-windows.html' title='Emacs utf8 and Chinese on Windows'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-2370233542069072446</id><published>2008-12-19T01:49:00.005-06:00</published><updated>2008-12-19T02:23:34.371-06:00</updated><title type='text'>Adding Emacs to right click context menu</title><content type='html'>To add Emacs (or any program) to right click context menu for any type of files, open regedit, add a key under HKCR/*/shell, name it whatever you want, I name it "run emacs".  &lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;Then under it, create a new key called "command", change it data to your path to emacs, plus a "%1" at the end.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_uMM6sJPJ1ug/SUtUrlJ5djI/AAAAAAAAANs/p68qeDADajw/s1600-h/add+emacs+context+menu.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 154px;" src="http://1.bp.blogspot.com/_uMM6sJPJ1ug/SUtUrlJ5djI/AAAAAAAAANs/p68qeDADajw/s320/add+emacs+context+menu.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5281408095706773042" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you want to add Emacs to just a specific type of file, for example, ".org" file for &lt;a href="http://orgmode.org/"&gt;Orgmode&lt;/a&gt;, it's a little more work.&lt;br /&gt;Create a new key ".org" under HKCR, give it data value "Orgmode.File".  Then create a new key "Orgmode.File" under HKCR. Under it, create key "Shell", under which create key "Emacs", under which create key "command", change its data to emacs path plus "%1".&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_uMM6sJPJ1ug/SUtWYvIlQRI/AAAAAAAAAN0/GFXAaNtQBx0/s1600-h/add+emacs+to+org+context+menu.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 260px;" src="http://1.bp.blogspot.com/_uMM6sJPJ1ug/SUtWYvIlQRI/AAAAAAAAAN0/GFXAaNtQBx0/s320/add+emacs+to+org+context+menu.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5281409970991350034" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you want to add Emacs to directory context menu, create the same keys under HKCR/Folder.&lt;br /&gt;&lt;br /&gt;Of course, all these apply to any programs, not just emacs.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-2370233542069072446?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/2370233542069072446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=2370233542069072446' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/2370233542069072446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/2370233542069072446'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2008/12/adding-emacs-to-right-click-context.html' title='Adding Emacs to right click context menu'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_uMM6sJPJ1ug/SUtUrlJ5djI/AAAAAAAAANs/p68qeDADajw/s72-c/add+emacs+context+menu.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-5476527654957843616</id><published>2008-11-26T12:53:00.009-06:00</published><updated>2008-12-04T16:59:27.009-06:00</updated><title type='text'>how to make fedora 10 image from old version</title><content type='html'>&lt;a href="https://fedoraproject.org/"&gt;Fedora 10&lt;/a&gt; just came out.  If you have an old redhat OS (fedora or CentOS) and you want a new fedora 10 image, to be used as a &lt;a href="http://xen.org/"&gt;Xen&lt;/a&gt; domainU or a customized &lt;a href="http://aws.amazon.com/ec2/"&gt;Amazon EC2 AMI&lt;/a&gt; or whatever, here's how to do it:&lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;Step 1: Create a 2Gig sparse file or lvm and mount it to /mnt.&lt;br /&gt;examples:&lt;br /&gt;for sparse file: &lt;br /&gt;    # dd if=/dev/zero of=f10.img bs=1024k count=1 seek=2000&lt;br /&gt;    # mkfs.ext3 f10.img&lt;br /&gt;    # mount -o loop f10.img /mnt&lt;br /&gt;for lvm: &lt;br /&gt;    # lvcreate -L2G -n f10 vg0 (assume you have a volume group called vg0)&lt;br /&gt;    # mkfs.xfs /dev/vg0/f10&lt;br /&gt;    # mount /dev/vg0/f10 /mnt&lt;br /&gt;&lt;br /&gt;Step 2: edit /etc/yum.repo.d/fedora.repo&lt;br /&gt;    go to /etc/yum.repo.d, create a new directory, then move everything to the new directory. (you will move them back up to /etc/yum.repo.d after creating fedora 10).  Create a new file call fedora.repo with content:&lt;br /&gt;-----------------&lt;br /&gt;&lt;blockquote&gt;[fedora]&lt;br /&gt;name=Fedora 10 - i386&lt;br /&gt;baseurl=http://download.fedora.redhat.com/pub/fedora/linux/releases/10/Everything/i386/os/&lt;br /&gt;mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-10&amp;arch=i386&lt;br /&gt;enabled=1&lt;br /&gt;gpgcheck=0&lt;/blockquote&gt;&lt;br /&gt;-----------------&lt;br /&gt;&lt;br /&gt;Step 3: do a "yum groupinstall"&lt;br /&gt;   #yum clean all&lt;br /&gt;   #yum makecache&lt;br /&gt;   # yum --installroot=/mnt -y groupinstall Base&lt;br /&gt;   Go have a cup of tea, or read some blogs, or downmod some reddits.&lt;br /&gt;   After the installation is complete, to make it actually useable, you need to create these devices:&lt;br /&gt;       # MAKEDEV -d /mnt/dev -x console&lt;br /&gt;       # MAKEDEV -d /mnt/dev -x null&lt;br /&gt;       # MAKEDEV -d /mnt/dev -x zero&lt;br /&gt;   And create a root passwd:&lt;br /&gt;       # chroot /mnt&lt;br /&gt;       # pvconv&lt;br /&gt;       # passwd&lt;br /&gt;       # exit&lt;br /&gt;   Create some files:&lt;br /&gt;       # vi /mnt/etc/fstab&lt;br /&gt;       # vi /mnt/etc/sysconfig/network&lt;br /&gt;       # vi /mnt/etc/sysconfig/network-scripts/ifcfg-eth0&lt;br /&gt;       # vi /mnt/etc/resolv.conf&lt;br /&gt;The contents of these files depends on your settings, use the files on your current OS as references.&lt;br /&gt;&lt;br /&gt;That's it, you're done. Unmount the image.  Now you should be able to boot it.  After you boot it(e.g. as a Xen domU), do some configurations.  These are what I did:&lt;br /&gt;    # chkconfig NetworkManager off&lt;br /&gt;    # chkconfig network on&lt;br /&gt;    # service NetworkManager stop&lt;br /&gt;    # service network start #use network instead of NetworkManager&lt;br /&gt;    # chkconfig atd off&lt;br /&gt;    # chkconfig bluetooth off&lt;br /&gt;    # chkconfig cups off&lt;br /&gt;    # chkconfig haldaemon off&lt;br /&gt;    # chkconfig ip6tables off&lt;br /&gt;    # chkconfig mdmonitor off&lt;br /&gt;    # chkconfig netfs off&lt;br /&gt;    # chkconfig netfs off&lt;br /&gt;    # chkconfig nfslock off&lt;br /&gt;    # chkconfig pcscd off&lt;br /&gt;    # chkconfig portreserve off&lt;br /&gt;    # chkconfig rpcbind off&lt;br /&gt;    # chkconfig rpcidmapd off&lt;br /&gt;    # chkconfig rpcgssd off  #all these services are useless for me&lt;br /&gt;    # yum install xfsprogs   #my filesystem is xfs&lt;br /&gt;    # vi /etc/rc.d/rc.sysinit #comment out a bunch of lines to get rid of false err/warning device-mapper messages during boot-up&lt;br /&gt;&lt;br /&gt;Don't forget to delete (in your current OS) fedora.repo in /etc/yum.repo.d and move everthing back in there.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-5476527654957843616?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/5476527654957843616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=5476527654957843616' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/5476527654957843616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/5476527654957843616'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2008/11/how-to-make-fedora-10-image-from-old.html' title='how to make fedora 10 image from old version'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-13757205199992162</id><published>2008-11-07T23:57:00.014-06:00</published><updated>2008-11-08T17:02:04.548-06:00</updated><title type='text'>Super Easy Python powered Christmas light controller for $40</title><content type='html'>There're lots of ways to control Christmas lights.  The easiest (but expensive) is just getting a lightorama.  I'm not spending $400 on a controller.  So I decided to build my own.&lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;&lt;a href="http://computerchristmas.com/christmas/link-how_to"&gt;Computer Christmas&lt;/a&gt; has many articles showing you how to do this.  There's a how-to for a &lt;a href="http://computerchristmas.com/christmas/link-how_to/HowToId-4/How_To_Build_A_Parallel_Port_Controller_Box"&gt;320 channel controller&lt;/a&gt;.  All I need is 8 channel on/off (no dimming), so a simple parallel port relay box is perfect for me. &lt;a href="http://computerchristmas.com/index.php?link=how_to&amp;amp;HowToId=2&amp;amp;LowLimit=0"&gt;This how-to&lt;/a&gt; tells you how to building one.  But actually you don't need to build a relay box yourself, there are parallel port relay kits sold online for cheap. You just buy the kit and connect to electric box.&lt;br /&gt;&lt;br /&gt;So Here's how to build a Python powered Xmas light controllers for $40(more or less).&lt;br /&gt;&lt;br /&gt;1, get a parallel port relay kit for about $32, for example: &lt;a href="http://www.electronics123.com/s.nl/it.A/id.446/.f?sc=8&amp;amp;category=35"&gt;here&lt;/a&gt; or &lt;a href="http://www.electronickits.com/kit/complete/elec/ck1601.htm"&gt;here&lt;/a&gt;. You can get it &lt;a href="http://www.electronics123.com/s.nl?sc=8&amp;amp;category=&amp;amp;search=kit%20165"&gt;assembled&lt;/a&gt; or in &lt;a href="http://www.electronics123.com/s.nl/it.A/id.1713/.f"&gt;module form&lt;/a&gt; for a few more bucks.  I didn't want to spend much time assembling so I got a module.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_uMM6sJPJ1ug/SRU8xmZOW4I/AAAAAAAAAM8/kiAwv-73LQU/s1600-h/002.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 214px;" src="http://4.bp.blogspot.com/_uMM6sJPJ1ug/SRU8xmZOW4I/AAAAAAAAAM8/kiAwv-73LQU/s320/002.JPG" alt="" id="BLOGGER_PHOTO_ID_5266182162097265538" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;2, get electric box and outlets from Homedepot or Loews for total $8.  Again I'm lazy so I just got a power strip from Walmart for $4, but it only has 7 outlets, I couldn't find one with 8.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_uMM6sJPJ1ug/SRU9U6ELMiI/AAAAAAAAANE/TOSmKdqK_2c/s1600-h/001.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 214px;" src="http://2.bp.blogspot.com/_uMM6sJPJ1ug/SRU9U6ELMiI/AAAAAAAAANE/TOSmKdqK_2c/s320/001.JPG" alt="" id="BLOGGER_PHOTO_ID_5266182768673108514" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;3, Wire the kit to your electric box.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_uMM6sJPJ1ug/SRU9rxQN8_I/AAAAAAAAANM/zom64ld7Uco/s1600-h/003.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 214px;" src="http://4.bp.blogspot.com/_uMM6sJPJ1ug/SRU9rxQN8_I/AAAAAAAAANM/zom64ld7Uco/s320/003.JPG" alt="" id="BLOGGER_PHOTO_ID_5266183161444692978" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;4, Connect to computer and fire up Python (see my previous post).&lt;br /&gt;Video of testing session.&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/jFkykPdENuU&amp;hl=en&amp;fs=1&amp;ap=%2526fmt%3D18"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;param name="wmode" value="window"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/jFkykPdENuU&amp;hl=en&amp;fs=1&amp;ap=%2526fmt%3D18" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true"  wmode="window" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;/div&gt;Here's &lt;a href="http://wensheng.com/code/lightcon.tgz"&gt;source code&lt;/a&gt; for the GUI program (in wxpython), most of code were generated by wxglade, I just created the event handlers for the mouse clicks.  The speed control (slider) is not implemented yet.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-13757205199992162?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/13757205199992162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=13757205199992162' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/13757205199992162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/13757205199992162'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2008/11/super-easy-python-powered-christmas.html' title='Super Easy Python powered Christmas light controller for $40'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_uMM6sJPJ1ug/SRU8xmZOW4I/AAAAAAAAAM8/kiAwv-73LQU/s72-c/002.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-8820811638071270770</id><published>2008-10-18T01:44:00.003-05:00</published><updated>2008-10-18T01:57:42.470-05:00</updated><title type='text'>python parallel port on Windows</title><content type='html'>Tried different ways of controlling parallel port with Python on Windows.  The easiest way is with &lt;a href="http://logix4u.net/Legacy_Ports/Parallel_Port/Inpout32.dll_for_Windows_98/2000/NT/XP.html"&gt;Inpout32.dll&lt;/a&gt;.&lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;Just download &lt;a href="http://logix4u.net/inpout32_source_and_bins.zip"&gt;the dll&lt;/a&gt;, put it in system32 folder. Then from python:&lt;br /&gt;&lt;blockquote&gt;from ctypes import windll&lt;br /&gt;p = windll.inpout32&lt;br /&gt;p.Inp32(0x378) #default 255(all high) on my pc &lt;br /&gt;p.Out32(0x378, 0) #put all low on port 2-9&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The address 0x378 might be different on your machine, open System-&gt;Hardware-&gt;Device Manager-&gt;Ports-&gt;ECP Printer Port-&gt;Properties-&gt;Resources, use the first number as your address. &lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-8820811638071270770?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/8820811638071270770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=8820811638071270770' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/8820811638071270770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/8820811638071270770'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2008/10/python-parallel-port-on-windows.html' title='python parallel port on Windows'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-5440294574622341481</id><published>2008-07-18T19:02:00.006-05:00</published><updated>2008-07-20T15:26:50.736-05:00</updated><title type='text'>Create QRcode with google chart API</title><content type='html'>Google recently add QRCode to its &lt;a href="http://code.google.com/apis/chart/"&gt;Chart API&lt;/a&gt;.  This make QRCode generation a breeze.  All you need to do is sending a GET request to google.&lt;br /&gt;QR Code is the most popular 2d barcode.  I put a page up that make it easy to generate QR Code with Google Chart API:&lt;br /&gt;&lt;br /&gt;    &lt;a href="http://wensheng.com/gqrcode.html"&gt;http://wensheng.com/gqrcode.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To create a URL, you need to put 'http://' at the beginning.  Otherwise code reader will see it as just text.   Likewise to create a telephone number, you need to put 'tel:' at the beginning, otherwise it's just code and you can't dial it from your phone.&lt;br /&gt;&lt;br /&gt;There're a lot of code readers.  I have &lt;a href="http://reader.kaywa.com/en"&gt;Kaywa Reader&lt;/a&gt; on my cellphone,  it works really well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-5440294574622341481?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/5440294574622341481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=5440294574622341481' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/5440294574622341481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/5440294574622341481'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2008/07/create-qrcode-with-google-chart-api.html' title='Create QRcode with google chart API'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-5093074084407956398</id><published>2008-06-30T23:33:00.004-05:00</published><updated>2008-07-01T10:55:34.941-05:00</updated><title type='text'>Can't believe my brain is only 20</title><content type='html'>So I took this &lt;a href="http://flashfabrica.com/f_learning/brain/brain.html"&gt;japanese flash test for brain age&lt;/a&gt;, it show my brain age (脳年齢) was 20. I don't know if it helped that I was drinking a beer at the time of testing.&lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_uMM6sJPJ1ug/SGm0zIBO5DI/AAAAAAAAAIw/Ru9LNE3Le0w/s1600-h/brain_age_test.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_uMM6sJPJ1ug/SGm0zIBO5DI/AAAAAAAAAIw/Ru9LNE3Le0w/s320/brain_age_test.PNG" alt="" id="BLOGGER_PHOTO_ID_5217900433704412210" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Add: Hmm, Chimps do much better.&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/nTgeLEWr614&amp;hl=en"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/nTgeLEWr614&amp;hl=en" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-5093074084407956398?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/5093074084407956398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=5093074084407956398' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/5093074084407956398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/5093074084407956398'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2008/06/cant-believe-my-brain-is-only-20.html' title='Can&apos;t believe my brain is only 20'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_uMM6sJPJ1ug/SGm0zIBO5DI/AAAAAAAAAIw/Ru9LNE3Le0w/s72-c/brain_age_test.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35201715.post-4966308073175250771</id><published>2008-06-30T12:06:00.008-05:00</published><updated>2008-06-30T12:47:21.562-05:00</updated><title type='text'>Grid/Cloud/Utility computing is expensive!</title><content type='html'>Utility computing is hot now.  Two major players are &lt;a href="http://aws.amazon.com/ec2"&gt;Amazon EC2&lt;/a&gt; and &lt;a href="http://code.google.com/appengine/"&gt;Google AppEngine&lt;/a&gt;.  There are many minor players too.  It's also evident that some ISP's are jumping onto the bandwagon.&lt;br /&gt;I did some quick research on several vendors and sumarizd by findings here:&lt;br /&gt;&lt;div class="fullpost"&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_uMM6sJPJ1ug/SGkWq8J3igI/AAAAAAAAAIo/bk03yZ47N88/s1600-h/cloud+providers.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_uMM6sJPJ1ug/SGkWq8J3igI/AAAAAAAAAIo/bk03yZ47N88/s320/cloud+providers.PNG" alt="" id="BLOGGER_PHOTO_ID_5217726570243262978" target="_blank" border="0" /&gt;&lt;/a&gt;click to enlarge&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;For me, Google AppEngine makes most sense.  You pay nothing for up-to 5 million page-views per month.  The only problem, albeit a major one, is that it's only python.  It's not a problem for me though since I know python.&lt;br /&gt;&lt;br /&gt;Other providers are way too expensive.  Look at engineyard.com, $400 per month get you a meager 760Mb ram, only 250GB transfer. Someone must be out of his mind to purchase it.&lt;br /&gt;&lt;br /&gt;For those who don't go with AppEngine, I would say it's best to just get a VPS.  You can do whatever you want with VPS just like a dedicated server.  And it's cheap, you can easily find a 512M ram VPS with plenty of diskspace and bandwidth for less than $50, that's all you pay.  (Just make sure your VPS is Xen based, not Virtuozzo/OpenVZ based, as they allow ram bursting, which means you will NOT get your ram when you really need it, as other users on the same host machine as you stole it.)&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35201715-4966308073175250771?l=blog.wensheng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.wensheng.com/feeds/4966308073175250771/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=35201715&amp;postID=4966308073175250771' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/4966308073175250771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35201715/posts/default/4966308073175250771'/><link rel='alternate' type='text/html' href='http://blog.wensheng.com/2008/06/gridcloudutility-computing-is-expensive.html' title='Grid/Cloud/Utility computing is expensive!'/><author><name>Wensheng Wang</name><uri>http://www.blogger.com/profile/06378277709501525260</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='13759523476777519438'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_uMM6sJPJ1ug/SGkWq8J3igI/AAAAAAAAAIo/bk03yZ47N88/s72-c/cloud+providers.PNG' height='72' width='72'/><thr:total>0</thr:total></entry></feed>