<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2854746392031016967</id><updated>2025-11-12T10:26:05.405-06:00</updated><category term="Programming"/><category term="Linux"/><category term="Ubuntu"/><category term="Python"/><category term="Script"/><category term="Notes"/><category term="Perl"/><category term="Gateway T1616"/><category term="QQ"/><category term="rtl8187b"/><category term="wireless"/><category term="Regular Expression"/><category term="Web"/><category term="hardware"/><category term="Apple"/><category term="Blogging"/><category term="CSS"/><category term="Glade"/><category term="Installation"/><category term="Instant Message"/><category term="Linux Mint"/><category term="Mac"/><category term="PyGTK"/><category term="internet"/><category term="C"/><category term="Django"/><category term="GAE"/><category term="GRUB"/><category term="Git"/><category term="Google"/><category term="HTML"/><category term="Javascript"/><category term="Mandriva"/><category term="iPod"/><category term=".Net/Mono"/><category term="AJAX"/><category term="AWN"/><category term="Algorithms"/><category term="Baidu"/><category term="CHM"/><category term="Compiz Fusion"/><category term="Desktop"/><category term="Dropbox"/><category term="Facebook"/><category term="GFW"/><category term="GUI"/><category term="Games"/><category term="Gentoo"/><category term="Hardy Heron"/><category term="IT Observation"/><category term="LaTeX"/><category term="Language"/><category term="Laptop"/><category term="OOP"/><category term="Ruby"/><category term="Search Engine"/><category term="Shell"/><category term="Sphinx"/><category term="Vim"/><category term="Virtual Machine"/><category term="iPhone"/><category term="iTunes"/><category term="jQuery"/><category term="ndiswrapper"/><category term="reStructuredText"/><category term="tools"/><category term="wine"/><category term="wxPython"/><title type='text'>$ls /home/DaNmarner/blog</title><subtitle type='html'>#!/usr/bin/env geekism</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>64</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-5197109404800132104</id><published>2010-06-03T23:43:00.001-05:00</published><updated>2010-06-03T23:44:50.433-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Django"/><category scheme="http://www.blogger.com/atom/ns#" term="Git"/><title type='text'>Why hasn&#39;t Django moved to Git or Hg yet?</title><content type='html'>This is a question that has been bothering me a lot recently. But it bothers someone else even more and for longer time.&lt;br /&gt;
&lt;br /&gt;
Oh yes, this &quot;someone else&quot; are the core developers of Django. I believe I&#39;ve seen their response to this question for multiple times and I think it makes a lot of sense. Everytime I feel bothered again, I&#39;d read this response and peace will come back. So here is one of those responses from RKM on the developer group:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;Moving to git will change *exactly nothing* in Django&#39;s development process. There will *always* be an &quot;official&quot; repository. Commit access to that core repository will be limited. It doesn&#39;t matter whether that repository is git, svn, or hg - there will always be a single, canonical, exclusive repository for trunk. &lt;br /&gt;
&lt;br /&gt;
If you want to use Git to help you manage your own source code or your contributions to Django, you&#39;re welcome to do so. There are well maintained git mirrors that you can use as a starting point. There are many people in the Django community using this mirror to manage their &lt;br /&gt;
own development work. Allow me to assure you that if you have a git branch that is worth pulling, someone in the Django core will be able to pull that branch and merge it into SVN trunk without *any* difficulty. Multi-db, for instance, was almost entirely developed by &lt;br /&gt;
Alex Gaynor on his github branch. &lt;br /&gt;
&lt;br /&gt;
And this is completely independent of the bike shed argument of which DVCS we will adopt. This isn&#39;t even remotely a settled argument. By making an official move to git, we would alienate a large community that, for better or worse, can&#39;t move their production platforms to git. It also alienates the hg and bzr communities, which is a not insignificant consideration (for the record, there are also well maintained hg and bzr mirrors). &lt;/blockquote&gt;</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/5197109404800132104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/5197109404800132104' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/5197109404800132104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/5197109404800132104'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2010/06/why-hasnt-django-moved-to-git-or-hg-yet.html' title='Why hasn&#39;t Django moved to Git or Hg yet?'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-8101938679864513197</id><published>2010-04-21T01:04:00.002-05:00</published><updated>2010-04-21T14:08:46.744-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Django"/><category scheme="http://www.blogger.com/atom/ns#" term="Dropbox"/><category scheme="http://www.blogger.com/atom/ns#" term="iPhone"/><category scheme="http://www.blogger.com/atom/ns#" term="iPod"/><category scheme="http://www.blogger.com/atom/ns#" term="LaTeX"/><category scheme="http://www.blogger.com/atom/ns#" term="Mac"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><category scheme="http://www.blogger.com/atom/ns#" term="reStructuredText"/><category scheme="http://www.blogger.com/atom/ns#" term="Sphinx"/><title type='text'>How to read PDF of Django Documentation on iPod</title><content type='html'>This is how I got a pdf of the latest Django Documentation onto my iPod. Of course this would work on your iPhone (iPad?) too. Everything shown here is don in Ubuntu. But the steps shouldn&#39;t be much different on other OS, be it Windows or Mac OS X, as long as you have root.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Step 1: get the source.&lt;/b&gt;&lt;br /&gt;
Good news, Django is Open Source! OK, that&#39;s kinda silly. But it&#39;s the fundamental reason all this is possible. Anyway, more useful info is that Django uses svn as its version control system and the Doc is part of the source in the repository. So let&#39;s check the source out:&lt;br /&gt;
&lt;blockquote&gt;svn co http://code.djangoproject.com/svn/django/trunk/&lt;/blockquote&gt;Caution: this is a fairly big repo so the check-out takes quite a bit of time!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Step 2: Compile the documentation&lt;/b&gt;&lt;br /&gt;
Here&#39;s the key to the next piece: Django uses a Python documentation generator called &lt;a href=&quot;http://sphinx.pocoo.org/&quot;&gt;Sphinx&lt;/a&gt; to produce the Doc. Sphinx compiles reStructuredText into multiple formats, including HTML, CHM and &lt;i&gt;LaTeX&lt;/i&gt;. And the source of the documentation is maintained in reStructuredText format. Our final goal here is to get a pdf, obviously we would generate that from LaTex. So, we need the sphinx-build script to compile the source into LaTeX. For Ubuntu users, the sphinx package in the official repo is called python-sphinx, install it:&lt;br /&gt;
&lt;blockquote&gt;sudo apt-get install python-sphinx&lt;/blockquote&gt;This will automatically install several related packages. When it&#39;s done, the compile should be smooth:&lt;br /&gt;
&lt;blockquote&gt;sphinx-build .../path/to/Doc/source/ .../path/to/the/latex/files&lt;/blockquote&gt;&lt;br /&gt;
&lt;b&gt;Step 3: Get the PDF&lt;/b&gt;&lt;br /&gt;
Now it&#39;s time to turn the LaTeX source code from last step into a PDF file. I&#39;m a daily LaTeX user on Ubuntu, so for others there might be some additional latex-related packages to install from the official repo. But when I tried running pdflatex command, it complains that two style package were missing. I had to find them online: &lt;a href=&quot;http://www.ee.iitb.ac.in/~trivedi/LatexHelp/StyleFiles/wrapfig.sty&quot;&gt;wrapfig.sty&lt;/a&gt;, &lt;a href=&quot;http://mirror.ctan.org/macros/latex/contrib/titlesec/titlesec.sty&quot;&gt;titlesec.sty&lt;/a&gt;. According to &lt;a href=&quot;https://help.ubuntu.com/community/LaTeX&quot;&gt;Ubuntu Community Documentation&lt;/a&gt;, I did the following:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;mkdir ~/texmf/tex/latex/titlesec&lt;br /&gt;
mv titlesec.sty ~/texmf/tex/latex/titlesec/&lt;br /&gt;
mkdir ~/texmf/tex/latex/wrapfig&lt;br /&gt;
mv wrapfig.sty ~/texmf/tex/latex/wrapfig/&lt;br /&gt;
texhash ~/texmf/&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Basically, this creates folders for each package under the home path and informs tex of the added packages.&lt;br /&gt;
&lt;br /&gt;
And now it should compile:&lt;br /&gt;
&lt;blockquote&gt;cd .../path/to/latex/files&lt;br /&gt;
pdflatex django.tex django.toc&lt;/blockquote&gt;&lt;br /&gt;
When its done, you should find django.pdf lying in the folder, epic.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Step 4: Put the PDF into the iPod/iPhone(/iPad?)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
There are tons of PDF reading apps in App Store. The one I&#39;ve been using is a free app called Good Reader. It lets you read text, pics and PDF. The reason I&#39;m using it is that it supports some really handy ways to transfer the files on to the mobile devices, including &lt;a href=&quot;https://www.dropbox.com/referrals/NTIzNjc2MzI5&quot;&gt;Dropbox&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
If you haven&#39;t used Dropbox to sync files between your different devices I highly recommend that you follow this &lt;a href=&quot;https://www.dropbox.com/referrals/NTIzNjc2MzI5&quot;&gt;link&lt;/a&gt; to create a account and start using it immediately. For a starter, it&#39;s waaaay more convenient than emailing files as attachments. Anyway, once you get Dropbox folder syncing on your box, drop in djang.pdf there.&lt;br /&gt;
&lt;br /&gt;
Open Good Read on your iPod/iPhone, go to Web Downloads -&gt; Connect to Server -&gt; Create New Connection to -&gt; Dropbox. Fill in your username and password, hit &quot;add&quot;. Go back to Connect to Server, click the the newly added account to navigate to the Dropbox folder, find django.pdf and download it.&lt;br /&gt;
&lt;br /&gt;
And we are done, enjoy your mobile, beautiful copy of Django Documentation!</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/8101938679864513197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/8101938679864513197' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/8101938679864513197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/8101938679864513197'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2010/04/how-to-read-pdf-of-django-documentation.html' title='How to read PDF of Django Documentation on iPod'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-859869092798024708</id><published>2010-03-27T23:56:00.001-05:00</published><updated>2010-03-28T00:00:22.774-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AJAX"/><category scheme="http://www.blogger.com/atom/ns#" term="Javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="jQuery"/><title type='text'>A little hack on AJAX timing</title><content type='html'>Say you need to initialize a web/app page with data dynamically loaded from some server by a Javascript module written with jQuery. Often, the problem encountered would be the pacing. That is, the events in the script don&#39;t necessarily take place in the same order as your code indicated. Here&#39;s an example that illustrates the evilness:&lt;br /&gt;
&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;javascript&quot;&gt;data = someModule.AjaxFetch(); // loading...
alert(data.item1); // Oh no, executed before AjaxFetch() has returned, undefined!
&lt;/pre&gt;&lt;br /&gt;
The typical solution is passing a callback function to the AjaxFetch() method. I don&#39;t know about you, but leaving that callback-function argument always makes me feel itchy(I&#39;m a big Python fan, so doubt not about my awareness of the benefit of having the flexibility. After all, what&#39;s the point of modularization if I have to call a method from module A in module B?). It could be worse, what if the Ajax module doesn&#39;t provide the callback slot you needed?&lt;br /&gt;
&lt;br /&gt;
The other possible solution is using some kind of delay function, pausing the script for some time and hope that the communication would be finished by then. Obviously this is too lousy for a reasonable programmer.&lt;br /&gt;
&lt;br /&gt;
Here&#39;s what I came up today.&lt;br /&gt;
&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;javascript&quot;&gt;data = someModule.AjaxFetch();
$(document).ajaxComplete(function(){
    $(document).unbind($.ajaxComplete);
    alert(data.item1);
    // some more useful and complex code here.
});
&lt;/pre&gt;&lt;br /&gt;
The trick is to take advantage of $.ajaxComplete() provided by jQuery and unbind this event immediately after it happens for the first time.&lt;br /&gt;
&lt;br /&gt;
The reason to unbind doesn&#39;t seem obvious at the first look. Here it is: $.ajaxComplete() listens to all kinds of Ajax communication conducted by jQuery. If the code in its call back involves more Ajax events, the call back will be called again, which is usually not an expected behavior!&lt;br /&gt;
&lt;br /&gt;
Happy AJAXing!</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/859869092798024708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/859869092798024708' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/859869092798024708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/859869092798024708'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2010/03/little-hack-on-ajax-timing.html' title='A little hack on AJAX timing'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-1948216072174741053</id><published>2010-01-02T02:52:00.002-06:00</published><updated>2010-01-02T02:55:33.107-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="GAE"/><category scheme="http://www.blogger.com/atom/ns#" term="Google"/><category scheme="http://www.blogger.com/atom/ns#" term="Language"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Python Wrapper of Google Language API with GAE Support</title><content type='html'>Code is hosted &lt;a href=&quot;http://github.com/DaNmarner/google-language-api-python&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Licensed under MIT license.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; from glanguage import Translator&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; t = Translator()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; t.translate(&#39;Hello, World&#39;, lang_from=&#39;en&#39;, lang_to=&#39;fr&#39;)&lt;br /&gt;
&#39;Bonjour tout le monde&#39;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; what = t.detect(&#39;你好&#39;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; what.lang&lt;br /&gt;
&#39;Chinese_simplified&#39;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; what.lang_code&lt;br /&gt;
&#39;zh-CN&#39;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print what&lt;br /&gt;
&amp;lt;language: (chinese_simplified)=&quot;&quot; zh-cn=&quot;&quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the value of lang_from in the translate() method is omitted, &lt;br /&gt;
the language of the original text will be detected automatically.&lt;br /&gt;
The value of lang_to is default to &#39;en&#39;.&lt;br /&gt;
&lt;br /&gt;
Support for Google App Engine is added. The usage stays the same&lt;br /&gt;
on GAE. I also did some simplification to the original code &lt;br /&gt;
found online.&lt;br /&gt;
&lt;br /&gt;
A lot credit goes to Peteris Krumins (peter@catonmat.net), who&lt;br /&gt;
wrote the code originally.</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/1948216072174741053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/1948216072174741053' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/1948216072174741053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/1948216072174741053'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2010/01/python-wrapper-of-google-language-api.html' title='Python Wrapper of Google Language API with GAE Support'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-725858020117904639</id><published>2009-11-28T01:20:00.003-06:00</published><updated>2009-11-28T01:21:23.540-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Git"/><title type='text'>Introducing Glossary Kit</title><content type='html'>I wrote some script to help a translation project I took part in recently. I think its generic enough to benefit other translation project, hence decide to give them a name and advertise them here :)&lt;br /&gt;
&lt;br /&gt;
You can find &lt;a href=&quot;http://github.com/DaNmarner/glossary-kit&quot;&gt;a repo&lt;/a&gt; for the scripts on Github, as well as &lt;a href=&quot;http://cloud.github.com/downloads/DaNmarner/glossary-kit/glossarykit.tar.gz&quot;&gt;the package&lt;/a&gt; for direct download.&lt;br /&gt;
&lt;br /&gt;
And I&#39;m just going to post the README file in HTML here,  which is generated by markdown.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Glossary Kit&lt;/h2&gt;&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;p&gt;&lt;strong&gt;What is glossary-kit?&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;This is a set of scripts that helps a translation project&lt;br /&gt;
check its cooperative work against a glossary, typically&lt;br /&gt;
a bilingual word list that unifies a translation for certain&lt;br /&gt;
terminologies throughout the projects.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;strong&gt;How does it work?&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Given the glossary in the original text (or text), glossary-kit&lt;br /&gt;
will gather all the appearances of the listed words in the&lt;br /&gt;
glossary and each corresponding translation into single&lt;br /&gt;
files, where the translators can examine the result, modify&lt;br /&gt;
the content if necessary. After the translation for the word(s)&lt;br /&gt;
is in satisfying status, glossary-kit can apply all the changes&lt;br /&gt;
made in the generated files to where they ought to be in the&lt;br /&gt;
translation.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;strong&gt;How to use it?&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;glossay-kit takes 2 assumptions for the translation project:&lt;/p&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;p&gt;It is stored in text file. Including text source files such&lt;br /&gt;
as markdown or TeX.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The original files and the translated files are stored under&lt;br /&gt;
two seperate directories that has the same substructure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The translation keeps the original line positions of the text.&lt;br /&gt;
For one, every translated file has to have the same number&lt;br /&gt;
of lines as the original text.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;p&gt;&lt;em&gt;Usage&lt;/em&gt;&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;To check a certain &lt;em&gt;keyword&lt;/em&gt;:&lt;/p&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;p&gt;gkfind.py &lt;em&gt;keyword&lt;/em&gt; rootToText rootToTranslation [outputFile]&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;To check a list of words:&lt;/p&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;p&gt;gkfind.py -l listname rootToText rootToTranslation &lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;The list should be a text file consist of a list of keywords, each&lt;br /&gt;
occupying its own line.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;gkfind.py will generate files named keyword.checklist, which contains&lt;br /&gt;
the lines where &lt;em&gt;keyword&lt;/em&gt; appears, both the text and the translation,&lt;br /&gt;
as well as meta info such as the location of the files and the line&lt;br /&gt;
number of appearance. Edit the tranlsation in this/these file(s) to&lt;br /&gt;
satifying status. And run&lt;/p&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;p&gt;gkapply.py keyword.checklist [keyword2.checklist] ...&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;The changes made are now applied to the translation files.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;strong&gt;Why not Bash?&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;I&#39;m aware that a lot of wheel-inventing seemed to be happening&lt;br /&gt;
here. With a shell language like Bash and some typical commands&lt;br /&gt;
on *nix systems like grep, diff and patch, this toolkit might&lt;br /&gt;
be redundent. Nevertheless, I wrote this to take advantage of&lt;br /&gt;
the portability of Python. Specifically, it might benefit the&lt;br /&gt;
translators using MS Windows system more than anybody else.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;strong&gt;Copyright&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;These scripts are released under Apache License 2.0, see COPYING for more details.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/725858020117904639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/725858020117904639' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/725858020117904639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/725858020117904639'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2009/11/introducing-glossary-kit.html' title='Introducing Glossary Kit'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-6892076313280072367</id><published>2009-02-02T23:14:00.001-06:00</published><updated>2009-02-02T23:25:42.199-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Gentoo"/><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu"/><title type='text'>Installing Gentoo with Ubuntu</title><content type='html'>Ubuntu has been the only OS on my Gateway t-1616 laptop for over a year now, and I&#39;m pretty happy with it except for its occasional slowness. I&#39;ve done some research and made up my mind to install Gentoo as a secondary os and maybe replace Ubuntu with it someday in the future. I read through the intallation &lt;a href=&quot;http://www.gentoo.org/doc/en/handbook/index.xml&quot;&gt;instruction&lt;/a&gt; on the official website and found out that the install CD does no more than providing a pre-existing linux to set up the environment for the new system. Then you chroot into the new environment and let emerge take care of the rest of work (not true, really).

Instead of downloading the install cd, I just fired up a terminal under gnome, Ubuntu and did the job anyway. It was way more enjoyable than doing it on a live cd. I made the new partition with the GUI of gparted, and downloaded stage3 and portage with Firefox 3. And of course I surfed the net while emerging stuff into the new system.

That&#39;s kind of fun, isn&#39;t it?</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/6892076313280072367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/6892076313280072367' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/6892076313280072367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/6892076313280072367'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2009/02/installing-gentoo-with-ubuntu.html' title='Installing Gentoo with Ubuntu'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-7501389122785848582</id><published>2009-01-08T02:45:00.010-06:00</published><updated>2009-10-31T18:54:45.731-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>How to get the reference of a global class by name in Python</title><content type='html'>1 Useing Globals().&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;python&quot;&gt;Globals()[&#39;classname&#39;]&lt;/pre&gt;&lt;br /&gt;
2 Using eval.&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;python&quot;&gt;eval(&#39;classname&#39;)&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
3 Using new-style classes,make up a base class that has a classmethod, something like this:&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;python&quot;&gt;class Parent(object):
    @classmethod
    def getSubClass(cls,name):
        for c in cls.__subclasses__:
            if c.__name__ == name:
            return c
&lt;/pre&gt;&lt;br /&gt;
Everything classes inherits this one, which will enable it possible to dynamically get the references of the sub-classes.&lt;br /&gt;
&lt;br /&gt;
4 Using getattr(), if the module that the the class lives in is known.&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;python&quot;&gt;getattr(module,classname)&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/7501389122785848582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/7501389122785848582' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/7501389122785848582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/7501389122785848582'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2009/01/how-to-get-reference-of-global-class-by.html' title='How to get the reference of a global class by name in Python'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-5613350610972025011</id><published>2008-12-22T21:15:00.003-06:00</published><updated>2008-12-22T21:29:51.145-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>Appending new items in JSON arrays with javascript</title><content type='html'>I decided to blog about this because it was a question that I struggled to solve and I couldn&#39;t find any material that gives the answer via google.

To add a item to the end of a array in a JSON object, we need to take advantage of the &lt;span style=&quot;font-style:italic;&quot;&gt;length&lt;/span&gt; attribute of it. It is clearer to demonstrate this with code, like this piece of javascript:

&lt;blockquote&gt;&lt;pre&gt;
json_data = {
    &quot;some_array&quot;:[],
};

json_data.some_array[json_data.some_array.length] = new_item;
&lt;/pre&gt;&lt;/blockquote&gt;</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/5613350610972025011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/5613350610972025011' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/5613350610972025011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/5613350610972025011'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/12/appending-new-items-in-json-arrays-with.html' title='Appending new items in JSON arrays with javascript'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-2705531755845494330</id><published>2008-12-17T05:20:00.002-06:00</published><updated>2008-12-17T05:29:35.162-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="GAE"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><category scheme="http://www.blogger.com/atom/ns#" term="Web"/><title type='text'>Google App Engine&#39;s real indexing limit</title><content type='html'>5000, that the number you are looking for. I tried to fill up a db.ListProperty(int) as much as I could. The SDK stopped working and started complaining about me having too much to be indexed at this point, 5000. 

So if you have more than 5000 entities to index in a ListProperty, get around.
I came up with a solution where you use a db.ListProperty(db.Key) to hold the keys of the actual ListProperty(s) you use to store stuff. And then make some special interface for it so that it loop through its parts automatically. Implementing such kind of interface, including a reading method, a saving method and a deleting method took up about 70 lines of code, empty lines included. And then I have no limits on GAE&#39;s indexing any more!</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/2705531755845494330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/2705531755845494330' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/2705531755845494330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/2705531755845494330'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/12/google-app-engines-real-indexing-limit.html' title='Google App Engine&#39;s real indexing limit'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-8051223128270729942</id><published>2008-09-26T00:39:00.002-05:00</published><updated>2008-09-26T00:41:52.834-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Gateway T1616"/><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu"/><title type='text'>Gateway T-1616 Users: Get Ready for Ubuntu Intrepid</title><content type='html'>No more Linux Mint-for-the-wireless.
Install Intrepid in no time and you will get a fully functioning Gateway T-1616!
I doubt if this is the last time writing about Gateway T-1616 and Ubuntu Linux.</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/8051223128270729942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/8051223128270729942' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/8051223128270729942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/8051223128270729942'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/09/gateway-t-1616-users-get-ready-for.html' title='Gateway T-1616 Users: Get Ready for Ubuntu Intrepid'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-5678768859966959301</id><published>2008-09-23T01:08:00.004-05:00</published><updated>2008-09-23T01:21:56.369-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Gateway T1616"/><category scheme="http://www.blogger.com/atom/ns#" term="rtl8187b"/><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu"/><category scheme="http://www.blogger.com/atom/ns#" term="wireless"/><title type='text'>WPA Working Smoothly on Ubuntu Intrepid ( 8.10 )</title><content type='html'>It is a nightmare to wait for the new release of Ubuntu 8.10 for me. Plus I accidentally crashed my old Ubuntu 8.10 by mistyping a rm command.

So there&#39;s no reason why shouldn&#39;t I install alpha 6 version of Intrepid several days earlier than the plan.

What thrilled my is that I found the wireless card of my Gateway T-1616, which is an rtl8187b, is working perfectly for a WPA wireless network. The weird inexplainable behaver before, such as connects to a WPA wireless signal and then works on a strength of 0%, are all gone!

What&#39;s better, I can really use the new-human theme for a while!</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/5678768859966959301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/5678768859966959301' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/5678768859966959301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/5678768859966959301'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/09/wpa-working-smoothly-on-ubuntu-intrepid.html' title='WPA Working Smoothly on Ubuntu Intrepid ( 8.10 )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-9133244048081565500</id><published>2008-09-05T23:17:00.007-05:00</published><updated>2008-09-08T12:24:12.887-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Gateway T1616"/><category scheme="http://www.blogger.com/atom/ns#" term="rtl8187b"/><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu"/><title type='text'>Full Functioning Gateway T-1616 ( rtl8187b ) with Ubuntu 8.04 and Later</title><content type='html'>As questions about rtl8187b wireless card (of Gateway T-1616) + Ubuntu 8.04 accumulating &lt;a href=&quot;http://danmarner.blogspot.com/2008/01/rtl8187b-linux-native-driver-works-on.html&quot;&gt;here&lt;/a&gt;, I figured that it is time to make a reply.

My answer is: I don&#39;t know how to make it work. Despite the fact that Ubuntu 8.04 is the only OS on my Gateway T-1616 and almost everything is working healthily, wireless included.

To get that: Install a Linux Mint, you will find yourself being able to install a working windows driver for rtl8187b with ndiswrapper. Then change your /etc/apt/sources.list into the same as a normal Ubuntu hardy one, update &amp; upgrade everything. The wireless then will still work, so will be other stuff.

And if you don&#39;t like the look &amp; feel of Mint, go ahead and read &lt;a href=&quot;http://dl.fullcirclemagazine.org/issue16_en.pdf&quot;&gt;Full Circle Issue 16&lt;/a&gt;: GNOME-Look Guide. It does an excellent job telling us how to change the look of everything on ubuntu.

The only blemish of this approach is that the mic of Gateway T-1616 wouldn&#39;t work.</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/9133244048081565500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/9133244048081565500' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/9133244048081565500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/9133244048081565500'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/09/full-functioning-gateway-t-1616-with.html' title='Full Functioning Gateway T-1616 ( rtl8187b ) with Ubuntu 8.04 and Later'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-7045008174840090288</id><published>2008-08-05T00:47:00.005-05:00</published><updated>2008-08-05T01:06:33.765-05:00</updated><title type='text'>An alternative for urllib.urlopen in Google App Engine</title><content type='html'>It took me a little searching to find out that there is a alternative for the disabled urllib.urlopen function (due to its usage of socket) in Google App Engine. It lies in google.appengine.api. The following illustrates the way to use it with the equal code using urllib.urlopen commented.

&lt;blockquote&gt;# import urllib
from google.appengine.api import urlfetch

# result = urllib.urlopen(&#39;http://DaNmarner.blogspot.com&#39;)
result = urlfetch.fetch(&#39;http://DaNmarner.blogspot.com&#39;)

# do_something_with(result.read())
do_something_with(result.content)&lt;/blockquote&gt;</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/7045008174840090288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/7045008174840090288' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/7045008174840090288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/7045008174840090288'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/08/alternative-for-urlliburlopen-in-google.html' title='An alternative for urllib.urlopen in Google App Engine'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-8451127993703095257</id><published>2008-07-24T16:02:00.002-05:00</published><updated>2008-07-24T16:28:01.764-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Facebook"/><title type='text'>Go internationalize your Facebook application now</title><content type='html'>If you are a Facebook app developer, having more and more users to install your application is (hopefully) one of the main goal. If this applies to you, then here, take this tip.

Facebook is going international. And, as always, it does not forget its fellow developers! Yes, actually it is going international for (almost) free, and it is now taking all of you to internationalize for (absolutely) free!

The idea to achieve this is sort of slick, it is done via a official application called &lt;span style=&quot;font-style:italic;&quot;&gt;Translations&lt;/span&gt;. It has been there for quite a while already. As a normal user, you can install this application and pick a language to translate Facebook into a certain non-English language. So far some excellent work has been done. The Official part of Facebook (including the basic interface and official apps) speaks more than 15 languages today.  But that&#39;s of course not the end of the story: &lt;span style=&quot;font-weight:bold;&quot;&gt;Translations is now open to all third-party Facebook applications!&lt;/span&gt;

I can&#39;t think of any reason not to do this: go install &lt;span style=&quot;font-style:italic;&quot;&gt;Translations &lt;/span&gt;and click Admin Panel. There you choose the language whose users you want (tick them all!). And your app will get internationalize in a couple of days!

It is that easy.</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/8451127993703095257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/8451127993703095257' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/8451127993703095257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/8451127993703095257'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/07/go-internationalize-your-facebook.html' title='Go internationalize your Facebook application now'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-4794593293751142726</id><published>2008-07-06T02:23:00.003-05:00</published><updated>2008-07-06T02:28:21.724-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Launching the default web brower with Python</title><content type='html'>I found this in standard modules. So I put it here for a record:

To open a certain web page(google.com, for example) with the system default web browse programmatically, do the following:

&lt;blockquote&gt;import webbrowser
webbrowser.open(&#39;http://google.com&#39;)&lt;/blockquote&gt;

Python didn&#39;t let me down this time.....again!</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/4794593293751142726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/4794593293751142726' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/4794593293751142726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/4794593293751142726'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/07/launching-default-web-brower-with.html' title='Launching the default web brower with Python'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-1085680924279492151</id><published>2008-07-03T22:11:00.004-05:00</published><updated>2008-07-03T23:21:24.933-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="GUI"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><category scheme="http://www.blogger.com/atom/ns#" term="wxPython"/><title type='text'>Using py2exe and wxPython on Windows XP</title><content type='html'>In my opinion, wxPython is practically the most acceptable platform-crossing GUI toolkit. However neither it nor python are shipped with MS Windows. Since we can&#39;t expect our users to have python and wxPython installed, py2exe is no doubt a decent deal to make our python applications standalone. I had some trouble on the first trying it out on Windows XP, so I decided to write the solution here in case someone else encounters the same problem.

Let me start at the very beginning.

First of all you need to make sure everything needed is installed, for that matter, at least &lt;a href=&quot;http://www.python.org/download/&quot;&gt;python&lt;/a&gt;, &lt;a href=&quot;http://wxpython.org/download.php&quot;&gt;wxPython&lt;/a&gt; and &lt;a href=&quot;http://sourceforge.net/project/showfiles.php?group_id=15583&quot;&gt;py2exe&lt;/a&gt; must be there in our case.

The versions of my installed packages are as following:

Python: 2.5.2
py2exe: 0.6.6 for win32 python2.5
wxPython: unicode-2.8.7.1 for python 2.5

Just to be safe, you need to install python before the rest of the two packages.

Now, I assume you have already tested &amp; debugged your application into a satisfying status. All you need now is to make it standalone. Another assumption here is you know the path where python is installed.(I will use python25\ and emit the previous part in this essay)

To achieve that, you need to write a setup.py script, which takes advantage of the method &lt;span style=&quot;font-weight:bold;&quot;&gt;setup &lt;/span&gt;in standard module &lt;span style=&quot;font-weight:bold;&quot;&gt;distutils.core&lt;/span&gt;. You can find &lt;a href=&quot;http://www.py2exe.org/&quot;&gt;instructions on py2exe&#39;s website&lt;/a&gt; for this step. Another good resource to learn it is the samples that come with py2exe, they are under the path
Python25\Lib\site-packages\py2exe\samples

You may want to refer to the python library reference to learn about &lt;a href=&quot;http://docs.python.org/dist/module-distutils.core.html&quot;&gt;distutils.core&lt;/a&gt;, but, before you get confused (which I did), I need to point out that py2exe added some &lt;a href=&quot;http://www.py2exe.org/index.cgi/ListOfOptions&quot;&gt;additional options to the setup mothed&lt;/a&gt;, which will probably be all you&#39;ll be using.

OK, a simplistic, but generally always working example of the setup.py would be:

&lt;blockquote&gt;from distutils.core import setup
import py2exe

setup([&#39;MainScript.py&#39;]) # Replace MainScript.py with your script&lt;/blockquote&gt;

Save the setup.py script in your app dictionary.

Next thing is to make sure that you can run python in a command terminal. Which requires the path of python to be added in the Environment Variable &lt;span style=&quot;font-weight:bold;&quot;&gt;PATH&lt;/span&gt;:

1 From the desktop, right-click My Computer and click properties.
2 In the System Properties window, click on the Advanced tab.
3 In the Advanced section, click the Environment Variables button. 
4 Finally, in the Environment Variables window, highlight the path variable in the Systems Variable section and click edit. Add a semicolon to the end if there isn&#39;t one, and then your python path.

Open a command prompt(by running cmd), go to your app path, run the setup.py with the argument py2exe:
&lt;blockquote&gt;python setup.py py2exe&lt;/blockquote&gt;

A lot of information shows up and then you will find two new dictionary in your app path, here you just need &lt;span style=&quot;font-style:italic;&quot;&gt;dist&lt;/span&gt;. If you wonder what&#39;s in there, check out &lt;a href=&quot;http://www.py2exe.org/index.cgi/FAQ&quot;&gt;the Official FAQ&lt;/a&gt;.

But you won&#39;t find your exe working, because msvcp71.dll is missing, and changing the name of MSVRP71.DLL won&#39;t work. I think this is probably a bug of py2exe. So you need to copy &#39;Python\Lib\site-packages\wx-2.8-msw-unicode\msvcp71.dll&#39; manually here.

That&#39;s how I made my wxPython application work so far.

Farther information is surely welcomed :).</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/1085680924279492151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/1085680924279492151' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/1085680924279492151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/1085680924279492151'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/07/using-py2exe-and-wxpython-on-windows-xp.html' title='Using py2exe and wxPython on Windows XP'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-6716806890549481812</id><published>2008-06-18T17:05:00.010-05:00</published><updated>2008-12-10T07:05:57.868-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Instant Message"/><category scheme="http://www.blogger.com/atom/ns#" term="internet"/><category scheme="http://www.blogger.com/atom/ns#" term="IT Observation"/><category scheme="http://www.blogger.com/atom/ns#" term="QQ"/><title type='text'>How did QQ make $523 million in a year?</title><content type='html'>QQ, the giant Chinese social network, as many of you may have heard, made a profit of $523 million last year. While Facebook encountered a lose of $50 million. How did this happen? What is the magic of this IM tool? Of course Tencent has its marketing tricks, &lt;a href=&quot;http://www.culture-buzz.com/blog/QQ-Chinese-ICQ-outdoes-Facebook-1601.html&quot;&gt;this essay&lt;/a&gt; may give you a big picture as a part of the answer.&lt;br /&gt;&lt;br /&gt;As an eight-year QQ user, here I will focus on the second question. To meet the interest of what on earth the IM tool is like, let&#39;s take a close look of the money generator.&lt;br /&gt;&lt;br /&gt;The basic services of QQ&#39;s, including text messaging, video/audio chatting, file transporting, as well as many extended services like email, online music, games, blog and so on, are all free. Despite the fact that the program consumes a lot of system resources of a computer, users are able to enjoy all this in a easy-going, nice-looking, integrated interface. However, if you zoom in to take a careful look of the UI, it&#39;s easy to notice that it is way more complicated than other IM tools, such as MSN, Yahoo! Messenger, let alone Gtalk. And there, as you may expect, is the clue for the money source.&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://2.bp.blogspot.com/_YZGwrGlcsOk/SFmh8boZFMI/AAAAAAAABxg/Ng-C_6ePI3w/s1600-h/qqUI.jpg&quot;&gt;&lt;img style=&quot;float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;&quot; src=&quot;http://2.bp.blogspot.com/_YZGwrGlcsOk/SFmh8boZFMI/AAAAAAAABxg/Ng-C_6ePI3w/s400/qqUI.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5213376103239455938&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To illustrate, here is the main window of QQ and the panel that appears when you move the mouse over to a buddy. I&#39;ve marked 1-6 on some elements in the picture to make my following writing easier. &lt;br /&gt;1  this part is a series of buttons, which indicates the services this user has activated. Some of which are free while most are not. The extension of every single service could be non-free. Such as more advanced facial expressions in text chatting, larger space in email, fancier decoration in Q-zone, the blog service, etc. &lt;br /&gt;&lt;br /&gt;2 A image which differs from the normal icon in users&#39; profile. A place where you can DIY the looking of the clothes, hairstyle, gesture, attachment of your figure, WITH MONEY. Virtual goods is a main source of the income. Beyond the figure you see, virtual goods could be found every where in all the services. A &quot;flower&quot; that needs to be taken care of in your blog, a virtual pet that need to be fed (buy the food!), or an assistant item in a online game.&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://3.bp.blogspot.com/_YZGwrGlcsOk/SFmsfoRJE5I/AAAAAAAABxo/zHsFObw6O9s/s1600-h/Screenshot-2.jpg&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;&quot; src=&quot;http://3.bp.blogspot.com/_YZGwrGlcsOk/SFmsfoRJE5I/AAAAAAAABxo/zHsFObw6O9s/s400/Screenshot-2.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5213387703043298194&quot; /&gt;&lt;center&gt;&quot;Online clothes shopping&quot;&lt;/center&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;3 These icons tell the user&#39;s &quot;level&quot;, a statistic that indicates the length of the time that the user has logged in. When a user reaches certain level, he/she will be able to have some special privilege for free. A good example would be the power to customize the profile icon with your self uploaded picture. &lt;br /&gt;&lt;br /&gt;4 The tabs on the main windows directs the user to other products provided by Tencent. You can find links to its online B2B websites, uploading service, blog service, stock website, &quot;bank&quot; and its reader.&lt;br /&gt;&lt;br /&gt;5 VIP icon. Well this tells you this user is very important because he spent a certain amount of money to keep this icon. Of course he also get some privilege that&#39;s not shared by everybody. Such as changing the profile icon before reaching the required &quot;level&quot;, or &lt;span style=&quot;font-weight:bold;&quot;&gt;being able to turn off the ads that show up on the start of the program&lt;/span&gt;. The latter may sounds strange but it is a nuisance that every QQ user has to deal with. This icon, though strangely enough, is not the only special membership a user can buy. There&#39;s a &quot;diamond&quot; for every certain product which gives you more flexible, more fancier, and probably more enjoyable (at least for me) services. All payments are available in various ways including paying by credit cards, virtual coupon or even the user&#39;s tele/mobilephone account.&lt;br /&gt;&lt;br /&gt;Above is a corner look of the Tencent empire. Surrounding its core product, QQ, are the dominating social networking company&#39;s fast-growing market in almost all aspects in China. &lt;br /&gt;&lt;br /&gt;As you can tell from my description, QQ is not one of the best IM options to pick for a netizen in China, yet it is the most possible first internet experience for him/her, since E-mailing, web-browsing, and blogging are much less popular among the majority of Chinese netizens. What&#39;s more, even if I don&#39;t like it, it is still impossible for me to drop it, because historically and presently, all my friends, family and co-workers are using it ,for the same reason as mine.&lt;br /&gt;&lt;br /&gt;So, how did to make $523 million in a year? Trap 300 million active users and ask for money. You can do the same thing.</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/6716806890549481812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/6716806890549481812' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/6716806890549481812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/6716806890549481812'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/06/how-did-qq-make-523-million-in-year.html' title='How did QQ make $523 million in a year?'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_YZGwrGlcsOk/SFmh8boZFMI/AAAAAAAABxg/Ng-C_6ePI3w/s72-c/qqUI.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-7842761174326460602</id><published>2008-06-18T14:16:00.002-05:00</published><updated>2008-06-18T14:40:07.428-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu"/><title type='text'>Learn Python On Ubuntu Linux FOR FREE</title><content type='html'>Dig the repository and you will be able to find some Python caddies. Like this package:

&lt;blockquote&gt;diveintopython&lt;/blockquote&gt;

A Python tutorial written by Mark Pilgrim. There&#39;s even a Chinese version in the repository:

&lt;blockquote&gt;diveintopython-zh&lt;/blockquote&gt;

If you are interested in GUI development, check this out:

&lt;blockquote&gt;python-gtk2-tutorial&lt;/blockquote&gt;

Another tutorial on NumPy:

&lt;blockquote&gt;python-numeric-tutorial&lt;/blockquote&gt;

What else? Keep digging!:)</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/7842761174326460602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/7842761174326460602' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/7842761174326460602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/7842761174326460602'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/06/learn-python-on-ubuntu-linux-for-free.html' title='Learn Python On Ubuntu Linux FOR FREE'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-7456711375266533716</id><published>2008-06-12T11:31:00.006-05:00</published><updated>2008-06-13T23:53:25.533-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu"/><category scheme="http://www.blogger.com/atom/ns#" term="Virtual Machine"/><title type='text'>Installing Virtualbox 1.6.2 on Ubuntu 8.04 ( Hardy )</title><content type='html'>Apparently Virtualbox has made a good improvement after being taken by Sun. However it is still not mature enough to work out of the box when it is installed on Ubuntu 8.04 in the first place. A little hacking is still required.

First of all, download the full version from the &lt;a href=&quot;http://virtualbox.org/wiki/Downloads&quot;&gt;website of Virtualbox&lt;/a&gt; (instead of install the open source version directly from the repository). Install it in a way you like. And hope it works. If it doesn&#39;t, carry on reading this.

You need to add your current user to a group named vboxusers, again, in your favorite way. If you don&#39;t have one, try this one.
Check if the group exists:
&lt;blockquote&gt;sudo grep vboxusers /etc/group&lt;/blockquote&gt;
If nothing shows up, add it:
&lt;blockquote&gt;sudo addgroup vboxusers&lt;/blockquote&gt;
Now add the user to the group:
&lt;blockquote&gt;usermod -a -G vboxusers $USER&lt;/blockquote&gt;

Now you should at least be able to open Virtualbox properly and install an operating system on it. Let&#39;s take Windows XP for an example here, make sure you installed Guest Additions (Devices-Install Guest Additions).

The next step is to authorize the user to use USB.

Edit /etc/init.d/mountdevsubfs.sh with your best editor, make sure the following lines are &lt;span style=&quot;font-weight:bold;&quot;&gt;uncommented&lt;/span&gt; 
&lt;blockquote&gt;mkdir -p /dev/bus/usb/.usbfs
domount usbfs “” /dev/bus/usb/.usbfs -obusmode=0700,devmode=0600,listmode=0644
ln -s .usbfs/devices /dev/bus/usb/devices
mount –rbind /dev/bus/usb /proc/bus/usb &lt;/blockquote&gt;

Create a new group and add the current user to it:
&lt;blockquote&gt;sudo addgroup usbfs
sudo usermod -a -G usbfs $USER&lt;/blockquote&gt;

Then edit /etc/udev/rules.d/40-permissions.rules
Find
&lt;blockquote&gt;LABEL=”usb_serial_start”
ATTRS{idVendor}==”0403″, ATTRS{idProduct}==”6001″, \
, MODE=”0660″, GROUP=”dialout”
LABEL=”usb_serial_end”&lt;/blockquote&gt;
Add GROUP=&quot;usbfs&quot; to it, like this:
&lt;blockquote&gt;LABEL=”usb_serial_start”
ATTRS{idVendor}==”0403″, ATTRS{idProduct}==”6001″, \
GROUP=&quot;usbfs&quot;, MODE=”0660″, GROUP=”dialout”
LABEL=”usb_serial_end”&lt;/blockquote&gt;

Save the file. 
Find out the group id:
&lt;blockquote&gt;grep usbfs /etc/group&lt;/blockquote&gt;
Remember the number within it, for example on this machine, I get the result
&lt;blockquote&gt;vboxusers:x:1003:name&lt;/blockquote&gt;
Thus &lt;blockquote&gt;1003&lt;/blockquote&gt; is the id.

Open /etc/fstab, add the following line to the end:
&lt;blockquote&gt;none /proc/bus/usb usbfs devgid=1003,devmode=664 0 0&lt;/blockquote&gt;

Reboot the host system.

And then you should be able to enjoy the VM with available USB support.</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/7456711375266533716/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/7456711375266533716' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/7456711375266533716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/7456711375266533716'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/06/installing-virtualbox-162-on-ubuntu-804.html' title='Installing Virtualbox 1.6.2 on Ubuntu 8.04 ( Hardy )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-4332869861475808802</id><published>2008-06-02T03:08:00.005-05:00</published><updated>2008-06-12T01:46:05.774-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><category scheme="http://www.blogger.com/atom/ns#" term="Vim"/><title type='text'>Dynamic Indentation Width In Vim</title><content type='html'>How to auto-indent differently when coding in different programming languages ?

I started hacking this problem when I found myself prefer to indent 4 spaces in Python yet 8 for C.

As a Vim user, I do this:

Of course I put this in my vimrc:&lt;blockquote&gt;filetype plugin indent on
&lt;/blockquote&gt;Then I copy
&lt;blockquote&gt;$VIMRUNTIME/indent/python.vim&lt;/blockquote&gt;which is the original indentation setting file for python, to
&lt;blockquote&gt;~/.vim/indent/&lt;/blockquote&gt;Finally, customize it by adding the following lines in to the new copy:&lt;blockquote&gt;setlocal shiftwidth=4
setlocal ts=4
&lt;/blockquote&gt;
The default indentation width in vim is 8 spaces, and when vim detects a Python source file, it automatically changes that to 4 spaces. Problem solved!

A hint about $VIMRUNTIME: you can use this variable IN vim, or find the path it stands for by typing&lt;blockquote&gt;:!ls $VIMRUNTIME
&lt;/blockquote&gt;then hit TAB.


I&#39;m curious if someone else has solved the same problem. What&#39;s your solution in vim? How about other editors? IDE?</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/4332869861475808802/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/4332869861475808802' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/4332869861475808802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/4332869861475808802'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/06/dynamic-indentation-width-in-vim.html' title='Dynamic Indentation Width In Vim'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-388745478333336340</id><published>2008-05-31T00:23:00.003-05:00</published><updated>2008-06-12T03:56:08.001-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Glade"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="PyGTK"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>PyGTK and Glade on Windows</title><content type='html'>It&#39;s been told that the PyGTK &amp;amp; Glade is a cross-platform developing combo. And there&#39;s a good reason to believe that most folks started it from Linux as I did. Well, now it is time to deliver the combo&#39;s platform-crossing feature: let&#39;s march on to MS Windows.

I tested this on Windows XP and so far everything seemed fine.

To set up the developing environment, several packages are needed. I list their names as well as downloading links below.

&lt;ul&gt;&lt;li style=&quot;color: rgb(51, 51, 255);&quot;&gt;&lt;a href=&quot;http://downloads.sourceforge.net/gladewin32/gtk-dev-2.12.9-win32-2.exe&quot;&gt;Gtk+ 2.12.9 Development Environment Revision 2&lt;/a&gt;&lt;/li&gt;&lt;li style=&quot;color: rgb(51, 51, 255);&quot;&gt;&lt;a href=&quot;http://downloads.sourceforge.net/gladewin32/glade-2.12.1-rc1.zip?modtime=1139438298&amp;amp;big_mirror=0&quot;&gt;glade-2.12.1-rc1.zip&lt;/a&gt;&lt;/li&gt;&lt;li style=&quot;color: rgb(51, 51, 255);&quot;&gt;&lt;a href=&quot;http://www.python.org/ftp/python/2.5.2/python-2.5.2.msi&quot;&gt;Python 2.5.2 Windows installer&lt;/a&gt;&lt;/li&gt;&lt;li style=&quot;color: rgb(51, 51, 255);&quot;&gt;&lt;a href=&quot;http://ftp.gnome.org/pub/GNOME/binaries/win32/pycairo/1.4/&quot;&gt;PyCairo&lt;/a&gt;&lt;/li&gt;&lt;li style=&quot;color: rgb(51, 51, 255);&quot;&gt;&lt;a href=&quot;http://ftp.gnome.org/pub/GNOME/binaries/win32/pygobject/2.14/&quot;&gt;PyGObject&lt;/a&gt;&lt;/li&gt;&lt;li style=&quot;color: rgb(51, 51, 255);&quot;&gt;&lt;a href=&quot;http://ftp.gnome.org/pub/GNOME/binaries/win32/pygtk/2.12/&quot;&gt;PyGTK&lt;/a&gt;&lt;/li&gt;&lt;li style=&quot;color: rgb(51, 51, 255);&quot;&gt;&lt;a href=&quot;http://sourceforge.net/project/showfiles.php?group_id=15583&quot; onclick=&quot;window.location=&#39;/project/downloading.php?group_id=15583&amp;amp;use_mirror=voxel&amp;amp;filename=py2exe-0.6.6.win32-py2.5.exe&amp;amp;&#39;+Math.floor(Math.random()*100000000); return false;&quot;&gt;py2exe-0.6.6.win32-py2.5.exe&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;    
Assuming you haven&#39;t installed any of them before, I would suggest that you download them all (don&#39;t install yet). Even if you have, the version might not be guaranteed to work with other components.

I also need to mention py2exe here. It is not essential for the application development. What it does is &quot;compiling&quot; your script into a executable and collecting other related files required by the script together, so that it will be able to run independently on those windows systems where the packages don&#39;t exist. Since you can&#39;t expect your users to have installed every packages, it indeed roles significantly in this game.

The order of the installation does matter here.

First you need to install &lt;a href=&quot;http://downloads.sourceforge.net/gladewin32/gtk-dev-2.12.9-win32-2.exe&quot;&gt;Gtk+ 2.12.9 Development Environment&lt;/a&gt;, this includes GTK+ development environment, libglade and Glade3. However the launcher it creates on your desktop has a little problem: it points to glade-2. You can fix that manually by modify its properties.

Since many tutorials about PyGTK &amp;amp; Glade only apply on glade2, you may want to install &lt;a href=&quot;http://downloads.sourceforge.net/gladewin32/glade-2.12.1-rc1.zip?modtime=1139438298&amp;amp;big_mirror=0&quot;&gt;glade-2&lt;/a&gt;. You can decompress the package and copy the files into corresponding path (e.g GTK/bin and GTK/share) if you like.

Next, install &lt;a href=&quot;http://www.python.org/ftp/python/2.5.2/python-2.5.2.msi&quot;&gt;Python 2.5&lt;/a&gt;. And then the rest. This is where the order matters. Because the rest of the packages wouldn&#39;t be able to detect the right location to go if python was absent.

Now the installation is done. You can open IDLE and try import pygtk, gtk and py2exe to see if everything works. You also should also be able to edit you GUI with Glade now.

Some more words on py2exe. You can find a brief tutorial on its usage &lt;a style=&quot;color: rgb(102, 102, 102);&quot; href=&quot;http://www.py2exe.org/index.cgi/Tutorial&quot;&gt;[here]&lt;/a&gt;. And how to combine it with PyGTK &lt;a style=&quot;color: rgb(102, 102, 102);&quot; href=&quot;http://www.py2exe.org/index.cgi/Py2exeAndPyGTK&quot;&gt;[here]&lt;/a&gt;. The second link tells you to copy some stuff from GTK to your executable path, that makes the size of you application way more bigger that it was. Try to remove some of the unrelated files in these folders, like Docs, as long as your executable behaves properly.</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/388745478333336340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/388745478333336340' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/388745478333336340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/388745478333336340'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/05/pygtk-and-glade-on-windows.html' title='PyGTK and Glade on Windows'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-4203278558398253753</id><published>2008-05-29T01:20:00.014-05:00</published><updated>2008-12-10T07:05:58.298-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Glade"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="PyGTK"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Creating a message box dialog with PyGTK and Glade</title><content type='html'>Being a newbie to Python, GTK and Glade, I found it rather enjoyable developing stuff fast and easily with this language/library/tool combination. All you need to do to get a GUI up and running is to &quot;draw&quot; it with Glade and connect it with pygtk.&lt;br /&gt;&lt;br /&gt;What makes it not so perfect is that there&#39;s hardly any systematical material online to tell folks how these great things works together. I could only find some separate pieces of information here and there about this, &lt;a style=&quot;color: rgb(51, 51, 255);&quot; href=&quot;http://danmarner.blogspot.com/2008/05/resources-to-learn-pygtk-python-and.html&quot;&gt;as I wrote before&lt;/a&gt;. Fortunately these pieces information are all great. So I highly recommended those absolute beginners to read &lt;a style=&quot;color: rgb(51, 51, 255);&quot; href=&quot;http://www.learningpython.com/2006/05/07/creating-a-gui-using-pygtk-and-glade/&quot;&gt;this essay&lt;/a&gt;, to say the least, to get things started.&lt;br /&gt;&lt;br /&gt;Here I&#39;m going to show the way to create a message box, which is probably the most (simple?) commonly used dialog in a GUI. It has a OK button and displays a message you passed. Like this:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://2.bp.blogspot.com/_YZGwrGlcsOk/SD5MWRLUPTI/AAAAAAAABxI/55rfrZ5JJ70/s1600-h/Screenshot-dialog1.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;http://2.bp.blogspot.com/_YZGwrGlcsOk/SD5MWRLUPTI/AAAAAAAABxI/55rfrZ5JJ70/s320/Screenshot-dialog1.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5205682164738571570&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;When you use it, simply create a instance and pass the message (and the title of the dialog if necessary) to it:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;div style=&quot;background-color: rgb(204, 204, 204); color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(255, 255, 0);&quot;&gt;1 &lt;/span&gt;&lt;span style=&quot;color: rgb(255, 64, 255);&quot;&gt;from&lt;/span&gt; msgBox &lt;span style=&quot;color: rgb(255, 64, 255);&quot;&gt;import&lt;/span&gt; messageBox&lt;br /&gt;&lt;span style=&quot;color: rgb(255, 255, 0);&quot;&gt;2 &lt;/span&gt;messageBox(&#39;&lt;span style=&quot;color: rgb(255, 96, 96);&quot;&gt;Guess what? I am a message box!&lt;/span&gt;&#39;)&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;How does that look?&lt;br /&gt;&lt;br /&gt;First of all, let&#39;s draw the message box out. This is really easy:&lt;br /&gt;&lt;br /&gt;Open Glade2, find &quot;dialog&quot; in the palette and click it. Choose &quot;Standard Button Layout&quot;, &quot;OK&quot;. After the dialog shows up, click &quot;label&quot; on the pallette and then click on the blank area in the previous dialog window.&lt;br /&gt;&lt;br /&gt;Next, we are going to set up the signals. Thanks to glade, this part becomes so simple in our case that all we need is click the OK button (or, notice that you can always go to View-&gt;Show Widget Tree to focus on the widget you are looking for). In the Properties window, choose &quot;Signals&quot; tab, click on the &quot;...&quot; button after &quot;Signal&quot; entry. Find &quot;clicked&quot; and click &quot;OK&quot;. Now don&#39;t forget to click &quot;Add&quot; afterwards.&lt;br /&gt;&lt;br /&gt;Notice that here we are using mostly default names: dialog1,okbutton1,label1,etc. And you can always choose your own.&lt;br /&gt;&lt;br /&gt;Now save the project and quit, I name it &quot;msgBox&quot;. And you should get a new folder named the same as the project and two files with the name plus suffix .glade and .gladep. If you try to open them with a editor, you will find them just XML files that represent the widget trees and the properties of each widget we created.&lt;br /&gt;&lt;br /&gt;Now type in the following script in a editor and save the file as msgBox.py (line number not included, of course), I&#39;ll explain it line by line.&lt;br /&gt;&lt;blockquote&gt;msgBox.py&lt;br /&gt;&lt;div style=&quot;background-color: rgb(204, 204, 204); color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;&amp;nbsp;1 &lt;/font&gt;&lt;font color=&quot;#ffff00&quot;&gt;try&lt;/font&gt;:&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;&amp;nbsp;2 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ff40ff&quot;&gt;import&lt;/font&gt;&amp;nbsp;pygtk&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;&amp;nbsp;3 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pygtk.require(&#39;&lt;font color=&quot;#ff6060&quot;&gt;2.0&lt;/font&gt;&#39;)&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;&amp;nbsp;4 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ff40ff&quot;&gt;import&lt;/font&gt;&amp;nbsp;gtk&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;&amp;nbsp;5 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ff40ff&quot;&gt;import&lt;/font&gt;&amp;nbsp;gtk.glade&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;&amp;nbsp;6 &lt;/font&gt;&lt;font color=&quot;#ffff00&quot;&gt;except&lt;/font&gt;:&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;&amp;nbsp;7 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff00&quot;&gt;print&lt;/font&gt;&amp;nbsp;&#39;&lt;font color=&quot;#ff6060&quot;&gt;Install pygtk,libgtk2.0 and libglade2.0&lt;/font&gt;&#39;&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;&amp;nbsp;8 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ff40ff&quot;&gt;import&lt;/font&gt;&amp;nbsp;os&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;&amp;nbsp;9 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;os.exit(1)&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;10 &lt;/font&gt;&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;11 &lt;/font&gt;&lt;font color=&quot;#ffff00&quot;&gt;class&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#00ffff&quot;&gt;messageBox&lt;/font&gt;:&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;12 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff00&quot;&gt;def&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#00ffff&quot;&gt;__init__&lt;/font&gt;(self, lbl_msg = &#39;&lt;font color=&quot;#ff6060&quot;&gt;Message here&lt;/font&gt;&#39;,&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;13 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dlg_title = &#39;&#39;):&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;14 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.wTree = gtk.glade.XML(&#39;&lt;font color=&quot;#ff6060&quot;&gt;msgbox.glade&lt;/font&gt;&#39;)&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;15 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.dlg = self.wTree.get_widget(&#39;&lt;font color=&quot;#ff6060&quot;&gt;dialog1&lt;/font&gt;&#39;)&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;16 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.lbl = self.wTree.get_widget(&#39;&lt;font color=&quot;#ff6060&quot;&gt;label1&lt;/font&gt;&#39;)&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;17 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.dlg.set_title(dlg_title) &lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;18 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.lbl.set_text(lbl_msg)&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;19 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;handlers = { &#39;&lt;font color=&quot;#ff6060&quot;&gt;on_okbutton1_clicked&lt;/font&gt;&#39;:self.done }&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;20 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.wTree.signal_autoconnect( handlers )&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;21 &lt;/font&gt;&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;22 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff00&quot;&gt;def&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#00ffff&quot;&gt;done&lt;/font&gt;(self,w):&lt;br /&gt;&lt;font color=&quot;#ffff00&quot;&gt;23 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.dlg.destroy()&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;Line1-9 imports the modules we need. If you&#39;ve checked the recommended essays in the beginning, you shouldn&#39;t have problems with these lines.&lt;br /&gt;&lt;br /&gt;The rest of the code defines a class that calls up our message box dialog.&lt;br /&gt;&lt;br /&gt;Line 12-13: We pass two arguments to the __init__ method: the message you are going to display and the title of the the dialog window.&lt;br /&gt;&lt;br /&gt;Line 14: this is the highlight of the whole point. The method gtk.glade.XML takes the XML file we created with glade, parses it and creats gtk.glade.XML object( which has the widgets tree and some methods ) accordingly.&lt;br /&gt;&lt;br /&gt;Line 15-16 uses the gtk.glade.XML method get_widget to fetch the references of the widgets, whose names are passed as arguments.&lt;br /&gt;&lt;br /&gt;Line 17, as you may guess, sets the title of the dialog window to the name we assigned.&lt;br /&gt;&lt;br /&gt;Line 18 sets the message.&lt;br /&gt;&lt;br /&gt;Line 19-20: remember the signal we set for the OK button? here we bind the signal and its handler in a dictionary and pass it to the method gtk.glade.XML.signal_autoconnect. That means when the GUI releases the signal &quot;on_okbutton1_clicked&quot; (which happens when the OK button is clicked, obviously), the program will call the corresponding method( self.done ).&lt;br /&gt;&lt;br /&gt;Line 22-23: defines the method done, which is our handler of the signal &quot;on_onkbutton_clicked&quot;. It does one thing: call the destroy method, which will terminates the dialog.&lt;br /&gt;&lt;br /&gt;A little summary here: we created the GUI object according to the XML files, set up the message we intended to play and make the &quot;OK&quot; button destroys the dialog.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now you get msgBox.glade, msgBox.gladep and msgBox.py. Whenever you need a message box in your application, just copy them to your package and take advantage of it as introduced in the beginning. The following is a package of all the files described before as well as a simple example of using the class:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://code-of-danmarner.googlecode.com/files/msgBox.zip&quot;&gt;http://code-of-danmarner.googlecode.com/files/msgBox.zip&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/4203278558398253753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/4203278558398253753' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/4203278558398253753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/4203278558398253753'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/05/creating-message-box-with-pygtk-and.html' title='Creating a message box dialog with PyGTK and Glade'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_YZGwrGlcsOk/SD5MWRLUPTI/AAAAAAAABxI/55rfrZ5JJ70/s72-c/Screenshot-dialog1.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-8763517164441005146</id><published>2008-05-26T17:58:00.004-05:00</published><updated>2008-05-31T02:13:31.024-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Glade"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="PyGTK"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Resources to learn PyGTK ( Python ) and Glade</title><content type='html'>I&#39;ve developed a good interest in the combination of Python and Glade. And it did give me some exciting moments creating GUIs so easily and quickly.  I am going to write about it as soon as I feel comfortable playing around this (&lt;span style=&quot;font-style: italic;&quot;&gt;update: &lt;a href=&quot;http://danmarner.blogspot.com/search/label/Glade&quot;&gt;here they are&lt;/a&gt;!&lt;/span&gt;). Before that, here&#39;s a bunch of useful links that I found while digging into it.

&lt;span style=&quot;font-weight: bold;&quot;&gt;Great Documentation/Tutorials/Essays on PyGTK&#39;s official website:&lt;/span&gt;
&lt;a style=&quot;color: rgb(51, 51, 255);&quot; href=&quot;http://www.pygtk.org/&quot;&gt;http://www.pygtk.org/&lt;/a&gt;

&lt;span style=&quot;font-weight: bold;&quot;&gt;Documentation on Glade&#39;s website:&lt;/span&gt;
&lt;a style=&quot;color: rgb(51, 51, 255);&quot; href=&quot;http://glade.gnome.org/documentation.html&quot;&gt;http://glade.gnome.org/documentation.html&lt;/a&gt;

&lt;span style=&quot;font-weight: bold;&quot;&gt;Awesome essays on some awesome blogs:&lt;/span&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;
&lt;a style=&quot;color: rgb(51, 51, 255);&quot; href=&quot;http://www.learningpython.com/2006/05/07/creating-a-gui-using-pygtk-and-glade/&quot; rel=&quot;bookmark&quot; title=&quot;Permanent Link: Creating a GUI using PyGTK and Glade&quot;&gt;Creating a GUI using PyGTK and Glade&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;
&lt;a style=&quot;color: rgb(51, 51, 255);&quot; href=&quot;http://www.learningpython.com/2006/05/30/building-an-application-with-pygtk-and-glade/&quot; rel=&quot;bookmark&quot; title=&quot;Permanent Link: Building an Application with PyGTK and Glade&quot;&gt;Building an Application with PyGTK and Glade&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;
&lt;a style=&quot;color: rgb(51, 51, 255);&quot; href=&quot;http://www.linuxjournal.com/article/6586&quot;&gt;A Beginner&#39;s Guide to Using pyGTK and Glade&lt;/a&gt;&lt;/span&gt;

&lt;span style=&quot;font-weight: bold;&quot;&gt;A walkthough on how to get glade work on Win32:&lt;/span&gt;
&lt;a style=&quot;color: rgb(51, 51, 255);&quot; href=&quot;http://faq.pygtk.org/index.py?req=show&amp;amp;file=faq21.002.htp&quot;&gt;http://faq.pygtk.org/index.py?req=show&amp;amp;file=faq21.002.htp&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/8763517164441005146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/8763517164441005146' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/8763517164441005146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/8763517164441005146'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/05/resources-to-learn-pygtk-python-and.html' title='Resources to learn PyGTK ( Python ) and Glade'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-1221010698475700971</id><published>2008-05-19T04:07:00.000-05:00</published><updated>2008-12-10T07:05:58.457-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="OOP"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>A Python illustration of how abstract superclass works</title><content type='html'>I made this after reading &lt;span style=&quot;font-style: italic;&quot;&gt;Learning Python 3rd Edtion&lt;/span&gt;, Part VI, Page 490.&lt;br /&gt;&lt;br /&gt;The picture shows what happens when a instance&#39;s method, which is declared in a superclass and implemented later in a subclass, is called.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://2.bp.blogspot.com/_YZGwrGlcsOk/SDFB0cDdywI/AAAAAAAABxA/3qcjSgbyxOU/s1600-h/superclass_py_ill.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;http://2.bp.blogspot.com/_YZGwrGlcsOk/SDFB0cDdywI/AAAAAAAABxA/3qcjSgbyxOU/s320/superclass_py_ill.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5202011413729364738&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/1221010698475700971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/1221010698475700971' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/1221010698475700971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/1221010698475700971'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/05/python-illustration-of-how-abstract.html' title='A Python illustration of how abstract superclass works'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_YZGwrGlcsOk/SDFB0cDdywI/AAAAAAAABxA/3qcjSgbyxOU/s72-c/superclass_py_ill.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2854746392031016967.post-1327232815032992637</id><published>2008-05-14T01:19:00.008-05:00</published><updated>2008-06-12T12:38:47.500-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Games"/><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="wine"/><title type='text'>Starcraft Brood War on Ubuntu Hardy Heron ( 8.04 )</title><content type='html'>Since the message that Starcraft II is coming out gets around a lot these days, I start to recall all the good time when I was in crazy about Starcraft.

And I did a little more than recalling about it.

I installed it on Ubuntu Linux.

Now I can click on the Starcraft icon and play the newest version of the game anytime I like on my laptop, UNDER LINUX!

My laptop is a Gateway T1616 ( &lt;a href=&quot;http://support.gateway.com/s/Mobile/2007/Triton/1014772R/1014772Rsp2.shtml&quot;&gt;Specifications&lt;/a&gt; ). The OS is Ubuntu 8.04 (Hardy Heron).

Here&#39;s something you need to do in order to get this:

&lt;span style=&quot;font-size:130%;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;First of all, get your Starcraft disk &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-weight: bold; font-style: italic;font-size:130%;&quot; &gt;image&lt;/span&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;s&lt;/span&gt; prepared.&lt;/span&gt;&lt;/span&gt;
If you have the CD,put it in your first cdrom and type these in a terminal:
&lt;blockquote&gt;sudo umount /dev/cdrom0
dd if=/dev/cdrom0 of=/your_path/Starcraft_Original.iso
&lt;/blockquote&gt;If you also have the BroodWar CD, go ahead and do the same thing, using a different name for the image file, for instance,Starcraft_Broodwar.iso

Or, you can get the iso images in &lt;a href=&quot;http://www.thepiratebay.org/&quot;&gt;other ways&lt;/a&gt;.

You may also need the update patch, which can be found &lt;a href=&quot;http://us.blizzard.com/support/article.xml?articleId=21149&amp;amp;rhtml=true&quot;&gt;here&lt;/a&gt;.

Here&#39;s what you should get after all, to say the least:
&lt;blockquote&gt;BW-1152.exe
Starcraft_Original.iso
Starcraft_Broodwar.iso
&lt;/blockquote&gt;
&lt;span style=&quot;font-weight: bold;font-size:130%;&quot; &gt;Install wine.&lt;/span&gt;
This is easy for Ubuntu users:&lt;blockquote&gt;sudo aptitude update
sudo aptitude upgrade
sudo aptitude install wine
&lt;/blockquote&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Install Starcraft.&lt;/span&gt;&lt;/span&gt;
You need to find a place to mount the iso files, I did this:
&lt;blockquote&gt;sudo mkdir /mnt/starcraft
&lt;/blockquote&gt;Mount the original image:
&lt;blockquote&gt;sudo mount -o loop /your_path/Starcraft_Original.iso /mnt/starcraft
&lt;/blockquote&gt;Install the original version:
&lt;blockquote&gt;wine /mnt/starcraft/install.exe
&lt;/blockquote&gt;Of course you need a CD-Key here. I suggest that you install it with the default settings.

Then, mount the Broodwar image, and install it:
&lt;blockquote&gt;sudo mount -o loop /your_path/Starcraft_Broodwar.iso /mnt/starcraft
wine /mnt/starcraft/install.exe
&lt;/blockquote&gt;Update the game to the newest version:
&lt;blockquote&gt;wine /your_path/BW-1152.exe
&lt;/blockquote&gt;The installation of the game is easy enough to be skipped, I think.

You should be able to find the game under &lt;span style=&quot;font-style: italic;&quot;&gt;Start-Wine-Programs-Starcraft&lt;/span&gt; now. However, it requires the CD.

&lt;span style=&quot;font-weight: bold;font-size:130%;&quot; &gt;Start playing the game.&lt;/span&gt;

Add the path you mount your image files as a device in wine:
&lt;blockquote&gt;cd ~/.wine/dosdevices/
ln -s /mnt/starcraft d:
&lt;/blockquote&gt;Here, I hadn&#39;t added any wine devices so I used &#39;d:&#39;.

Mount the image file (if it is not mounted yet):&lt;blockquote&gt;sudo mount -o loop /your_path/Starcraft_Broodwar.iso /mnt/starcraft
&lt;/blockquote&gt;And then enjoy the game!


Well, this is almost the end of the story. At last here&#39;s something for those who don&#39;t want to do the mounting work every time they want to play.

Edit &lt;span style=&quot;font-style: italic;&quot;&gt;/etc/fstab&lt;/span&gt; , so that the image will be mounted automatically when the OS starts. Add this in a new line:
&lt;blockquote&gt;/your_path/Starcraft_Broodwar.iso /mnt/starcraft iso9660 loop 0 0&lt;/blockquote&gt;</content><link rel='replies' type='application/atom+xml' href='http://danmarner.blogspot.com/feeds/1327232815032992637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2854746392031016967/1327232815032992637' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/1327232815032992637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2854746392031016967/posts/default/1327232815032992637'/><link rel='alternate' type='text/html' href='http://danmarner.blogspot.com/2008/05/starcraft-brood-war-on-ubuntu-hardy.html' title='Starcraft Brood War on Ubuntu Hardy Heron ( 8.04 )'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry></feed>