<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wikidot="http://www.wikidot.com/rss-namespace">

	<channel>
		<title>Piotr Gabryjeluk blog</title>
		<link>http://piotrgabryjeluk.wikidot.com</link>
		<description>Blog, photos and developer notes of Piotr Gabryjeluk, one of Wikidot.com developers.</description>
				<copyright></copyright>
		<lastBuildDate>Thu, 21 May 2026 02:00:05 +0000</lastBuildDate>
		
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:july-news</guid>
				<title>July News</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:july-news</link>
				<description>

&lt;p&gt;Some of you may be more used to me posting more often, than in last time.&lt;br /&gt;
Some of you may wonder why I stopped blogging.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1779328804&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Tue, 28 Jul 2009 15:41:03 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Some of you may be more used to me posting more often, than in last time.<br /> Some of you may wonder why I stopped blogging.</p> <div class="content-separator" style="display: none:"></div> <h2><span>Brussels</span></h2> <p>Last month was full of adventures. It started 1st of July with me going to Brussels meat our friend to talk about wikipedia-like site about art. We're going to help this man build the most complete site about art using Wikidot software!</p> <p>BTW, this was my first flight in lifetime. Quite a strange feeling, but generally fine.</p> <h2><span>Forms</span></h2> <p>I was working on some nice technical and UI improvements to Wikidot, that is crucial for the art site (but really really nice for Wikidot as well, like forms for editing, entering and viewing structured data to wiki pages).</p> <h2><span>Search issues</span></h2> <p>That week was also spent on some massive Wikidot.com search engine tweaks. A stupid one-line bug, which was <strong>not</strong> exporting proper LC_ALL environmental variable in indexing script, caused many sites that used Asian or East-European languages to be not indexed (most notably the great <a href="http://istorijska-biblioteka.wikidot.com/">ИСТОРИЈСКА БИБЛИОТЕКА</a>). At first we though that we can re-index the broken sites, but our re-indexing mechanism was way too slow (would last for weeks for all broken sites).</p> <p>Pieter then challenged me. He said he can index whole Wikidot in 6 hours. I thought it's not even possible, but then I started to work on that and I managed to index the whole Wikidot in less than 2 hours without indexing tags at first. Then with tags, it took 2 hours and 10 minutes or so. That was damn fast!</p> <p>Inspired by this and an accident of disk full error on /var partition of our webserver (but this is why we keep user-uploaded files and other important things on separate disks), I also rewrote the incremental indexer, to work in similar way to the whole-Wikidot-re-indexer.</p> <h2><span><tt>search-api reindex</tt></span></h2> <p>If you care about some technical details:</p> <ul> <li>all search operations are issued with use of search-api, a separate program that can: <ul> <li>re-index whole Wikidot</li> <li>queue indexing page/thread</li> <li>queue deleting page/thread</li> <li>queue re-indexing site</li> <li>flush queue</li> </ul> </li> <li>search-api is written in Python</li> <li>search-api uses PyLucene - a native Java Lucene library binded to CPython objects with PyJCC. Compiled with GNU Java Compiler to native code (like C programs), this binding has improved performance over using Lucene with Sun's Java.</li> <li>before rewriting it to only-Python, search-api was written in BASH and was a wrapper to: <ul> <li><tt>java -jar searchApiHelper.jar search &quot;phrase-to-search&quot;</tt></li> <li><tt>php search-api-helper.php flush</tt></li> </ul> </li> <li>search-api also takes care of file locking to assure that <ul> <li>only one process tries to modify the index</li> <li>items are added to queue one-after-another</li> <li>when doing some big index modification (read: full re-index) queue is not flushed (so that after the re-index all changes are applied to new index)</li> <li>when flushing queue takes more time, and cron tries to run more flushing processes, they simply end (so only one process flushes the queue at a time)</li> </ul> </li> </ul> <h2><span>Union of Rock Festival</span></h2> <p>Just after week spent in Brussels in nice hotel I went to Węgorzewo, Mazury (Poland biggest lakes distinct) to have fun on rock music festival. Unfortunately, the music level was not very impressive, so I mainly enjoyed the atmosphere on the camping area.</p> <p>The weather was not great. It was wet everywhere, the ground was covered in 20 centimeters of mud and it was hard to walk around without getting dirty. But during the first day of being there, I learned to do that.</p> <h2><span>Improved workflow at Wikidot</span></h2> <p>Some of you noticed, that recently we started to work more efficiently, but this is not quite true. In fact we work as efficiently as before, but we are better organized, and have better priorities on tasks. Also we keep track of what we do, so we can then tell what we've done. So for us, this is a little more work of &quot;documenting&quot; our work (so maybe we work even less efficiently than before?), but for the outside world, we make more noise (in a positive meaning) around that. So basically, people know what we do, what we are going to do, when they can expect changes and most importantly, they understand why some feature request is being postponed. This is (and was) because we have more important things to do, but before they couldn't tell it.</p> <p><span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/squark" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=160264&amp;amp;size=small&amp;amp;timestamp=1779328804" alt="Squark" style="background-image:url(http://www.wikidot.com/userkarma.php?u=160264)" /></a><a href="http://www.wikidot.com/user:info/squark" >Squark</a></span> turned into a professional project manager, that manages our time. <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/pieterh" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=99&amp;amp;size=small&amp;amp;timestamp=1779328804" alt="pieterh" style="background-image:url(http://www.wikidot.com/userkarma.php?u=99)" /></a><a href="http://www.wikidot.com/user:info/pieterh" >pieterh</a></span> decided to <a href="http://blog.wikidot.com/">talk</a> to the Community and listen to their complaints (he reads or at least skims every post on Community forums). He tells Łukasz what needs to be done, Łukasz knows when we will have time to do this. This way communication inside Wikidot improved. Also we (<span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/michal-frackowiak" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=1&amp;amp;size=small&amp;amp;timestamp=1779328804" alt="michal-frackowiak" style="background-image:url(http://www.wikidot.com/userkarma.php?u=1)" /></a><a href="http://www.wikidot.com/user:info/michal-frackowiak" >michal-frackowiak</a></span> and me) no longer look on Community forums (some of you may regret), but this allows us to concentrate on our work.</p> <h2><span>The work continues</span></h2> <p>As I mentioned before, we want to introduce a great feature to Wikidot, which is <em>forms</em>. But the implementation now concentrates on the <a href="http://www.wikidot.org/">open source version of Wikidot software</a> (once it's ready, working and tested we'll copy the feature to the Wikidot.com service).</p> <h2><span><tt>aptitude install wikidot</tt></span></h2> <p>As forms is a huge change, I started to prepare a good ground for it and closed most important bugs in Wikidot open source and I'm about to start making Ubuntu packages for it to allow even-simpler installation on Debian-based systems. Now the installation involves only <a href="http://www.wikidot.org/installation-guide">6 child-easy steps</a> and in fact can be done by copying&amp;pasting a few commands.</p> <h2><span>Yesterday's party</span></h2> <p>Yesterday I went to met some old-school-times friends in the heart of the city. It was meant to be a meeting for &quot;a beer or two&quot; but evolved into beer and dancing till morning. That was first time I get a morning bus (not even the first) to my home just after partying.</p> <p>It was such a great fun and great folks I met.</p> <h2><span>Summary</span></h2> <p>I hope with this long blog post (but divided into friendly sections ;) ) I recompensed long period of not-posting anything here.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1779328804" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:announcing-pymalist</guid>
				<title>Announcing pymalist</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:announcing-pymalist</link>
				<description>

&lt;p&gt;I would like to announce &lt;a href=&quot;http://piotrgabryjeluk.wikidot.com/pymalist&quot;&gt;pymalist&lt;/a&gt; project. It is a stupid and simple highly-modular Pythonic mail list server, that uses basic concepts to do the job well.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1779328804&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Sat, 23 May 2009 12:24:04 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>I would like to announce <a href="http://piotrgabryjeluk.wikidot.com/pymalist">pymalist</a> project. It is a stupid and simple highly-modular Pythonic mail list server, that uses basic concepts to do the job well.</p> <div class="content-separator" style="display: none:"></div> <p>Read more on <a href="http://piotrgabryjeluk.wikidot.com/pymalist">pymalist</a> page, browse the source on <a href="http://github.com/gabrys/pymalist">GitHub project page</a>.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1779328805" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:working-on-mobile-webbrowser</guid>
				<title>Working On Mobile Webbrowser</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:working-on-mobile-webbrowser</link>
				<description>

&lt;p&gt;As I noted &lt;a href=&quot;http://piotrgabryjeluk.wikidot.com/dev:easter-time&quot;&gt;before&lt;/a&gt;, I&#039;m running Gentoo in chroot of my iPAQ H3870. As next step of fun with this PDA, I&#039;m willing to create a mobile webbrowser for this (and other) Linux-powered mobile devices. Inspired by iPhone&#039;s Safari I want the browser to have the following features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fast&lt;/li&gt;
&lt;li&gt;easy to use&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1779328805&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 15 Apr 2009 18:42:03 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>As I noted <a href="http://piotrgabryjeluk.wikidot.com/dev:easter-time">before</a>, I'm running Gentoo in chroot of my iPAQ H3870. As next step of fun with this PDA, I'm willing to create a mobile webbrowser for this (and other) Linux-powered mobile devices. Inspired by iPhone's Safari I want the browser to have the following features:</p> <ul> <li>fast</li> <li>easy to use</li> </ul> <div class="content-separator" style="display: none:"></div> <p>I want to use Qt and Webkit for this purpose. I will use PyQt for prototyping. As the interface will be minimal this should not add big overhead. For final version probably I'll compile C++ code statically (inserting the latest Qt library into the result program).</p> <p>What features the browser should have and how I will implement them?</p> <ul> <li>fast &#8212; using Webkit engine &#8212; well integrated with Qt 4.4+</li> <li>fast &#8212; using fast JavaScript engine &#8212; one of newest Qt/Webkit's features using JIT</li> <li>easy to use &#8212; full page zooming &#8212; using Qt/Webkit zoomFactor property</li> <li>easy to use &#8212; kinetic scrolling &#8212; feature popular in iPhone GUI (already implemented by some Qt hackers)</li> <li>fast &#8212; some hacky-features should be implemented like weight(-and-number-of-connections)-reducing proxy (like in Opera browser) and some AdBlock-like features (probably non-configurable)</li> </ul> <p>I'm planning VERY minimal interface. No long-history, no bookmark management. Only a button to &quot;save&quot; a page to the browser's dashboard. Also I think about some cool internal things to really make the browser usable and to make it as good as the iPhone's browser.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1779328805" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:wikidot-api</guid>
				<title>Wikidot API</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:wikidot-api</link>
				<description>

&lt;p&gt;A few days ago I started working on Wikidot &lt;a href=&quot;http://en.wikipedia.org/wiki/API&quot;  &gt;API&lt;/a&gt;. The API will be a standardized way to access the Wikidot.com service in a programmable way (i.e. not using a browser) to retrieve, create and update information stored on Wikidot, including site browsing, page editing and commenting.&lt;/p&gt;
&lt;p&gt;In simple words this will allow people to write applications that connect to Wikidot.com and perform some actions for the user that runs the application.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1779328805&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 22 Jan 2009 18:57:07 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>A few days ago I started working on Wikidot <a href="http://en.wikipedia.org/wiki/API" >API</a>. The API will be a standardized way to access the Wikidot.com service in a programmable way (i.e. not using a browser) to retrieve, create and update information stored on Wikidot, including site browsing, page editing and commenting.</p> <p>In simple words this will allow people to write applications that connect to Wikidot.com and perform some actions for the user that runs the application.</p> <div class="content-separator" style="display: none:"></div> <p>Technically, the Wikidot.com API is an <a href="http://en.wikipedia.org/wiki/XML-RPC" >XML-RPC</a> service exporting methods from a few especially designed classes.</p> <p>To connect to an XML-RPC service, you must know its endpoint, which is a regular URL (http:// or https://) address. We decided to use <a href="http://en.wikipedia.org/wiki/HTTPS" >HTTPS</a> to secure the channel from the very start.</p> <p>The operations we are going to support are:</p> <h2><span>Browse</span></h2> <ul> <li>site.categories</li> <li>site.pages</li> <li>page.get</li> </ul> <p>Above ones are already implemented. Using the API calls you get retrieve almost all data you stored on the Wikidot.com sites!</p> <h2><span>Modify</span></h2> <ul> <li>page.save</li> </ul> <p>This will be the basic method to update the content on your site. We plan several other methods, but this is the one that is the most important.</p> <h2><span>Comments</span></h2> <ul> <li>page.comments</li> <li>page.comment</li> </ul> <p>They will be used to get and post comments on a given page. Using <tt>reply_to</tt> parameter, there is a possibility to reply to a particular comment.</p> <h2><span>Forum</span></h2> <ul> <li>forum.groups</li> <li>forum.categories</li> <li>forum.threads</li> <li>forum.post</li> </ul> <p>This bunch of methods are going to give you full access to the forums you have started on Wikidot.</p> <h1><span>How to use the API</span></h1> <p>We haven't yet enabled the API access to the main Wikidot.com server, but testing the API with Python XML-RPC library is as easy as this:</p> <div class="code"> <div class="hl-main"> <pre><span class="hl-code">&gt;&gt;&gt; </span><span class="hl-reserved">from</span><span class="hl-code"> </span><span class="hl-identifier">xmlrpclib</span><span class="hl-code"> </span><span class="hl-reserved">import</span><span class="hl-code"> </span><span class="hl-identifier">ServerProxy</span><span class="hl-code"> &gt;&gt;&gt; </span><span class="hl-identifier">s</span><span class="hl-code"> = </span><span class="hl-identifier">ServerProxy</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">SOME-URL</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code"> &gt;&gt;&gt; </span><span class="hl-identifier">s</span><span class="hl-code">.</span><span class="hl-identifier">system</span><span class="hl-code">.</span><span class="hl-identifier">listMethods</span><span class="hl-brackets">()</span><span class="hl-code"> </span><span class="hl-brackets">[</span><span class="hl-quotes">'</span><span class="hl-string">system.listMethods</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">system.methodHelp</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">system.methodSignature</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">system.multicall</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">site.pages</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">site.categories</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">page.get</span><span class="hl-quotes">'</span><span class="hl-brackets">]</span><span class="hl-code"> &gt;&gt;&gt; </span><span class="hl-reserved">print</span><span class="hl-code"> </span><span class="hl-identifier">s</span><span class="hl-code">.</span><span class="hl-identifier">system</span><span class="hl-code">.</span><span class="hl-identifier">methodHelp</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">site.pages</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-identifier">Get</span><span class="hl-code"> </span><span class="hl-identifier">pages</span><span class="hl-code"> </span><span class="hl-reserved">from</span><span class="hl-code"> </span><span class="hl-identifier">a</span><span class="hl-code"> </span><span class="hl-identifier">site</span><span class="hl-code"> </span><span class="hl-identifier">Argument</span><span class="hl-code"> </span><span class="hl-identifier">array</span><span class="hl-code"> </span><span class="hl-identifier">keys</span><span class="hl-code">: </span><span class="hl-identifier">site</span><span class="hl-code">: </span><span class="hl-identifier">site</span><span class="hl-code"> </span><span class="hl-identifier">to</span><span class="hl-code"> </span><span class="hl-identifier">get</span><span class="hl-code"> </span><span class="hl-identifier">pages</span><span class="hl-code"> </span><span class="hl-reserved">from</span><span class="hl-code"> </span><span class="hl-identifier">category</span><span class="hl-code">: </span><span class="hl-identifier">category</span><span class="hl-code"> </span><span class="hl-identifier">to</span><span class="hl-code"> </span><span class="hl-identifier">get</span><span class="hl-code"> </span><span class="hl-identifier">pages</span><span class="hl-code"> </span><span class="hl-identifier">from</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-identifier">optional</span><span class="hl-brackets">)</span><span class="hl-code"> &gt;&gt;&gt; </span><span class="hl-identifier">s</span><span class="hl-code">.</span><span class="hl-identifier">site</span><span class="hl-code">.</span><span class="hl-identifier">categories</span><span class="hl-brackets">(</span><span class="hl-code">{</span><span class="hl-quotes">'</span><span class="hl-string">site</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">gamemaker</span><span class="hl-quotes">'</span><span class="hl-code">}</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">[</span><span class="hl-quotes">'</span><span class="hl-string">project</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">rpg</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">_default</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">action</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">admin</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">badge</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">beginner</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">contests</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">error</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">event</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">example</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">forum</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">gamemaker</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">gml</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">gmlcode</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">gmupload</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">help</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">ide</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">include</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">mamber</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">member</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">nav</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">portal</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">resource</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">search</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">system</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">talk</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">template</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">tutorial</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">video-tutorial</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">wiki</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">challenge</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">howto</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">recent-changes</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">scratch-pad</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">helpdesk</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">helprequest</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">default</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">testimonial</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">testimonials</span><span class="hl-quotes">'</span><span class="hl-brackets">]</span><span class="hl-code"> &gt;&gt;&gt; </span><span class="hl-brackets">[</span><span class="hl-identifier">p</span><span class="hl-brackets">[</span><span class="hl-quotes">'</span><span class="hl-string">name</span><span class="hl-quotes">'</span><span class="hl-brackets">]</span><span class="hl-code"> </span><span class="hl-reserved">for</span><span class="hl-code"> </span><span class="hl-identifier">p</span><span class="hl-code"> </span><span class="hl-reserved">in</span><span class="hl-code"> </span><span class="hl-identifier">s</span><span class="hl-code">.</span><span class="hl-identifier">site</span><span class="hl-code">.</span><span class="hl-identifier">pages</span><span class="hl-brackets">(</span><span class="hl-code">{</span><span class="hl-quotes">'</span><span class="hl-string">site</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">gamemaker</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">category</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">badge</span><span class="hl-quotes">'</span><span class="hl-code">}</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-brackets">[</span><span class="hl-quotes">'</span><span class="hl-string">cool</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">flux</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">c-team</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">gml</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">member</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">madman</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">not-a-noob</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">f-madman</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">start</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">break-it</span><span class="hl-quotes">'</span><span class="hl-brackets">]</span><span class="hl-code"> &gt;&gt;&gt; </span><span class="hl-reserved">print</span><span class="hl-code"> </span><span class="hl-identifier">s</span><span class="hl-code">.</span><span class="hl-identifier">page</span><span class="hl-code">.</span><span class="hl-identifier">get</span><span class="hl-brackets">(</span><span class="hl-code">{</span><span class="hl-quotes">'</span><span class="hl-string">site</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">gamemaker</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">page</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">badge:cool</span><span class="hl-quotes">'</span><span class="hl-code">}</span><span class="hl-brackets">)[</span><span class="hl-quotes">'</span><span class="hl-string">source</span><span class="hl-quotes">'</span><span class="hl-brackets">]</span><span class="hl-code"> </span><span class="hl-brackets">[[</span><span class="hl-identifier">table</span><span class="hl-code"> </span><span class="hl-identifier">style</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">width:98%;margin-right:auto;margin-left:auto;margin-bottom:1%;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]][[</span><span class="hl-identifier">row</span><span class="hl-brackets">]][[</span><span class="hl-identifier">cell</span><span class="hl-code"> </span><span class="hl-identifier">style</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">width:360px;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]]</span><span class="hl-code"> </span><span class="hl-brackets">[[</span><span class="hl-identifier">div</span><span class="hl-code"> </span><span class="hl-reserved">class</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">error-block</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]]</span><span class="hl-code"> </span><span class="hl-identifier">Included</span><span class="hl-code"> </span><span class="hl-identifier">page</span><span class="hl-code"> </span><span class="hl-quotes">&quot;</span><span class="hl-string">include:cool-badge</span><span class="hl-quotes">&quot;</span><span class="hl-code"> </span><span class="hl-identifier">does</span><span class="hl-code"> </span><span class="hl-reserved">not</span><span class="hl-code"> </span><span class="hl-identifier">exist</span><span class="hl-code"> </span><span class="hl-brackets">([</span><span class="hl-code">/</span><span class="hl-identifier">include</span><span class="hl-code">:</span><span class="hl-identifier">cool</span><span class="hl-code">-</span><span class="hl-identifier">badge</span><span class="hl-code">/</span><span class="hl-identifier">edit</span><span class="hl-code">/</span><span class="hl-identifier">true</span><span class="hl-code"> </span><span class="hl-identifier">create</span><span class="hl-code"> </span><span class="hl-identifier">it</span><span class="hl-code"> </span><span class="hl-identifier">now</span><span class="hl-brackets">])</span><span class="hl-code"> </span><span class="hl-brackets">[[</span><span class="hl-code">/</span><span class="hl-identifier">div</span><span class="hl-brackets">]]</span><span class="hl-code"> </span><span class="hl-identifier">The</span><span class="hl-code"> </span><span class="hl-identifier">Cool</span><span class="hl-code"> </span><span class="hl-identifier">Badge</span><span class="hl-code"> </span><span class="hl-reserved">is</span><span class="hl-code"> </span><span class="hl-identifier">given</span><span class="hl-code"> </span><span class="hl-identifier">to</span><span class="hl-code"> </span><span class="hl-identifier">people</span><span class="hl-code"> </span><span class="hl-identifier">who</span><span class="hl-code"> </span><span class="hl-identifier">make</span><span class="hl-code"> </span><span class="hl-identifier">something</span><span class="hl-code"> </span><span class="hl-identifier">really</span><span class="hl-code"> </span><span class="hl-identifier">cool</span><span class="hl-code">. </span><span class="hl-brackets">[[</span><span class="hl-code">/</span><span class="hl-identifier">cell</span><span class="hl-brackets">]]</span><span class="hl-code"> </span><span class="hl-brackets">[[</span><span class="hl-identifier">cell</span><span class="hl-code"> </span><span class="hl-identifier">style</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">vertical-align:top;border:1px solid #ddd;padding:1%;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]]</span><span class="hl-code"> +++ </span><span class="hl-identifier">Display</span><span class="hl-code"> </span><span class="hl-identifier">Code</span><span class="hl-code"> </span><span class="hl-brackets">[[</span><span class="hl-identifier">table</span><span class="hl-code"> </span><span class="hl-reserved">class</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">code</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]][[</span><span class="hl-identifier">row</span><span class="hl-brackets">]][[</span><span class="hl-identifier">cell</span><span class="hl-brackets">]]</span><span class="hl-code"> @@</span><span class="hl-brackets">[[</span><span class="hl-identifier">include</span><span class="hl-code"> </span><span class="hl-identifier">include</span><span class="hl-code">:</span><span class="hl-identifier">cool</span><span class="hl-code">-</span><span class="hl-identifier">badge</span><span class="hl-code"> </span><span class="hl-identifier">member</span><span class="hl-code">=</span><span class="hl-identifier">member</span><span class="hl-code"> </span><span class="hl-identifier">name</span><span class="hl-brackets">]]</span><span class="hl-code">@@ </span><span class="hl-brackets">[[</span><span class="hl-code">/</span><span class="hl-identifier">cell</span><span class="hl-brackets">]][[</span><span class="hl-code">/</span><span class="hl-identifier">row</span><span class="hl-brackets">]][[</span><span class="hl-code">/</span><span class="hl-identifier">table</span><span class="hl-brackets">]]</span><span class="hl-code"> +++ </span><span class="hl-identifier">Tag</span><span class="hl-code"> {{</span><span class="hl-identifier">cool</span><span class="hl-code">-</span><span class="hl-identifier">badge</span><span class="hl-code">}} </span><span class="hl-brackets">[[</span><span class="hl-code">/</span><span class="hl-identifier">cell</span><span class="hl-brackets">]][[</span><span class="hl-code">/</span><span class="hl-identifier">row</span><span class="hl-brackets">]][[</span><span class="hl-code">/</span><span class="hl-identifier">table</span><span class="hl-brackets">]]</span><span class="hl-code"> </span><span class="hl-brackets">[[</span><span class="hl-identifier">table</span><span class="hl-code"> </span><span class="hl-identifier">style</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">border:1px solid #ddd;padding:1%;margin-right:auto;margin-left:auto;margin-bottom:1%;width:98%;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]][[</span><span class="hl-identifier">row</span><span class="hl-brackets">]][[</span><span class="hl-identifier">cell</span><span class="hl-brackets">]]</span><span class="hl-code"> ++ </span><span class="hl-identifier">Earn</span><span class="hl-code"> </span><span class="hl-identifier">It</span><span class="hl-code"> * </span><span class="hl-identifier">Program</span><span class="hl-code"> </span><span class="hl-identifier">something</span><span class="hl-code"> </span><span class="hl-identifier">really</span><span class="hl-code"> </span><span class="hl-identifier">cool</span><span class="hl-code"> </span><span class="hl-identifier">using</span><span class="hl-code"> </span><span class="hl-identifier">gml</span><span class="hl-code"> * </span><span class="hl-identifier">Make</span><span class="hl-code"> </span><span class="hl-identifier">a</span><span class="hl-code"> </span><span class="hl-identifier">really</span><span class="hl-code"> </span><span class="hl-identifier">cool</span><span class="hl-code"> </span><span class="hl-identifier">game</span><span class="hl-code"> +++ </span><span class="hl-identifier">Tips</span><span class="hl-code"> * </span><span class="hl-identifier">Make</span><span class="hl-code"> </span><span class="hl-identifier">sure</span><span class="hl-code"> </span><span class="hl-identifier">you</span><span class="hl-code"> </span><span class="hl-identifier">post</span><span class="hl-code"> </span><span class="hl-identifier">your</span><span class="hl-code"> </span><span class="hl-identifier">examples</span><span class="hl-code"> </span><span class="hl-reserved">and</span><span class="hl-code"> </span><span class="hl-identifier">games</span><span class="hl-code"> </span><span class="hl-identifier">on</span><span class="hl-code"> </span><span class="hl-identifier">the</span><span class="hl-code"> </span><span class="hl-brackets">[[[</span><span class="hl-identifier">forum</span><span class="hl-code">:</span><span class="hl-identifier">start</span><span class="hl-code">|</span><span class="hl-identifier">forum</span><span class="hl-brackets">]]]</span><span class="hl-code">. </span><span class="hl-identifier">Otherwise</span><span class="hl-code"> </span><span class="hl-identifier">no</span><span class="hl-code"> </span><span class="hl-identifier">one</span><span class="hl-code"> </span><span class="hl-identifier">can</span><span class="hl-code"> </span><span class="hl-identifier">see</span><span class="hl-code"> </span><span class="hl-identifier">it</span><span class="hl-code"> </span><span class="hl-reserved">and</span><span class="hl-code"> </span><span class="hl-identifier">nominate</span><span class="hl-code"> </span><span class="hl-identifier">you</span><span class="hl-code"> </span><span class="hl-reserved">for</span><span class="hl-code"> </span><span class="hl-identifier">the</span><span class="hl-code"> </span><span class="hl-identifier">cool</span><span class="hl-code"> </span><span class="hl-identifier">badge</span><span class="hl-code">. </span><span class="hl-brackets">[[</span><span class="hl-code">/</span><span class="hl-identifier">cell</span><span class="hl-brackets">]][[</span><span class="hl-code">/</span><span class="hl-identifier">row</span><span class="hl-brackets">]][[</span><span class="hl-code">/</span><span class="hl-identifier">table</span><span class="hl-brackets">]]</span><span class="hl-code"> </span><span class="hl-brackets">[[</span><span class="hl-identifier">table</span><span class="hl-code"> </span><span class="hl-identifier">style</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">border:1px solid #ddd;padding:1%;margin-right:auto;margin-left:auto; width:98%;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]][[</span><span class="hl-identifier">row</span><span class="hl-brackets">]][[</span><span class="hl-identifier">cell</span><span class="hl-brackets">]]</span><span class="hl-code"> ++ </span><span class="hl-identifier">Members</span><span class="hl-code"> </span><span class="hl-identifier">Who</span><span class="hl-code"> </span><span class="hl-identifier">Have</span><span class="hl-code"> </span><span class="hl-identifier">Earned</span><span class="hl-code"> </span><span class="hl-identifier">the</span><span class="hl-code"> </span><span class="hl-identifier">Cool</span><span class="hl-code"> </span><span class="hl-identifier">Badge</span><span class="hl-code"> </span><span class="hl-brackets">[[</span><span class="hl-identifier">module</span><span class="hl-code"> </span><span class="hl-identifier">ListPages</span><span class="hl-code"> </span><span class="hl-identifier">category</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">member</span><span class="hl-quotes">&quot;</span><span class="hl-code"> </span><span class="hl-identifier">order</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">titleAsc</span><span class="hl-quotes">&quot;</span><span class="hl-code"> </span><span class="hl-identifier">tag</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">cool-badge</span><span class="hl-quotes">&quot;</span><span class="hl-code"> </span><span class="hl-identifier">perPage</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">100</span><span class="hl-quotes">&quot;</span><span class="hl-code"> </span><span class="hl-identifier">separate</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">false</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]]</span><span class="hl-code"> * %%</span><span class="hl-identifier">linked_title</span><span class="hl-code">%% </span><span class="hl-brackets">[[</span><span class="hl-code">/</span><span class="hl-identifier">module</span><span class="hl-brackets">]]</span><span class="hl-code"> </span><span class="hl-brackets">[[</span><span class="hl-code">/</span><span class="hl-identifier">cell</span><span class="hl-brackets">]][[</span><span class="hl-code">/</span><span class="hl-identifier">row</span><span class="hl-brackets">]][[</span><span class="hl-code">/</span><span class="hl-identifier">table</span><span class="hl-brackets">]]</span><span class="hl-code"> &gt;&gt;&gt;</span></pre></div> </div> <p>A few words of explanation:</p> <ul> <li>first we import ServerProxy class from XML-RPC library,</li> <li>then we construct the ServerProxy object s supplying the endpoint URL (SOME-URL in this case, as we don't have yet decided what the URL is going to be)</li> <li>we can see a list of methods by calling <tt>system.listMethods</tt> on the ServerProxy object</li> <li>we get a help message for a method by calling <tt>system.methodHelp</tt></li> <li>then we get categories of site gamemaker (yeah, it's a part of the wikicomplete.info)</li> <li>then we call <tt>site.pages</tt> method (specifying site and category parameters), but instead of displaying the whole list of structures that describe pages, we only display their names</li> <li>calling <tt>page.get</tt> returns an array with the information about a page, including: <ul> <li>wiki source, array key: source</li> <li>generated HTML, array key: html</li> <li>array with various meta-data, array key: meta</li> </ul> </li> <li>we call <tt>page.get</tt> passing as the argument array that specifies site and page name, get the page object, but displays only what's stored under the <tt>source</tt> array key</li> </ul> <p>As you see playing with this is really easy as is browsing the available methods and using them.</p> <h1><span>Why XML-RPC</span></h1> <p>We've chosen this protocol because it is an easy way to develop both server and client in almost any programming language. Also it gives some flexibility in passed arguments and return values.</p> <p>We use <tt>struct</tt> XML-RPC type as the argument and return value type, which is mapped to associative array or dictionary in client (and server) libraries. Each API method gets a bunch of required and optional parameters, that are basically values stored in the struct passed to API methods.</p> <p>For example <tt>site.pages</tt> gets a struct with the following keys:</p> <ul> <li>site (site name to get pages from) &#8212; required</li> <li>category (category to get pages from) &#8212; optional</li> </ul> <p>This means, you have to create an associative array (when using PHP) or a dictionary (using Python) and pass it as the method argument:</p> <div class="code"> <div class="hl-main"> <pre><span class="hl-code"># PHP $pages = $server-&gt;site-&gt;pages(array(&quot;site&quot; =&gt; &quot;my-site&quot;, &quot;category&quot; =&gt; &quot;my-category&quot;));</span></pre></div> </div> <div class="code"> <div class="hl-main"> <pre><span class="hl-comment"># Python</span><span class="hl-code"> </span><span class="hl-identifier">pages</span><span class="hl-code"> = </span><span class="hl-identifier">server</span><span class="hl-code">.</span><span class="hl-identifier">site</span><span class="hl-code">.</span><span class="hl-identifier">pages</span><span class="hl-brackets">(</span><span class="hl-code">{</span><span class="hl-quotes">&quot;</span><span class="hl-string">site</span><span class="hl-quotes">&quot;</span><span class="hl-code">: </span><span class="hl-quotes">&quot;</span><span class="hl-string">my-site</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">category</span><span class="hl-quotes">&quot;</span><span class="hl-code">: </span><span class="hl-quotes">&quot;</span><span class="hl-string">my-category</span><span class="hl-quotes">&quot;</span><span class="hl-code">}</span><span class="hl-brackets">)</span></pre></div> </div> <p>Using other programming languages, you'll end with something similar. You can almost always create the array/dictionary in-place, so having this convention is not a big deal.</p> <h1><span>Applications</span></h1> <p>I'm working on a filesystem based access to Wikidot site (using <a href="http://en.wikipedia.org/wiki/FUSE" >FUSE</a> and Python).</p> <p>We plan having a Wikidot application for iPhone.</p> <p>A save-it-directly-on-wikidot plugin would be a nice thing for various text editors (and probably other applications).</p> <p>And probably there are billions of other ways to use this API we're not even aware of. If you have any, feel free to leave a comment.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1779328805" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:bridging-python-and-php</guid>
				<title>Bridging Python And PHP</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:bridging-python-and-php</link>
				<description>

&lt;p&gt;Imagine you have a PHP-based application (like Wikidot). Now, you want to extend it using Python. Through all ways to do it, I&#039;ll show you how to achieve this using XML-RPC protocol.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1779328805&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Sun, 11 Jan 2009 10:48:16 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Imagine you have a PHP-based application (like Wikidot). Now, you want to extend it using Python. Through all ways to do it, I'll show you how to achieve this using XML-RPC protocol.</p> <div class="content-separator" style="display: none:"></div> <h1><span>Background</span></h1> <p><a href="http://www.xmlrpc.com/">XML-RPC</a> is a client-server protocol for remote procedure call.</p> <p>On server this works like getting a bunch of functions from your application and exporting it with HTTP.</p> <p>On client this works like connecting to a XML-RPC server, finding out what function it delivers and constructing a so called server proxy &#8212; an object having a method for every function exported by an XML-RPC server.</p> <p>Calling the methods of the server proxy connects to the server using HTTP, passes arguments and transport the result back to the client. So basically this works AS you have a remote located object locally available.</p> <p>The data encoding between client and server is defined in XML-RPC specification and is a language based on XML (but you actually never touch it, the XML is converted to objects by libraries).</p> <h1><span>Overview</span></h1> <p>We want to run an XML-RPC server exposing a class in PHP and an XML-RPC client in Python to communicate with the XML-RPC server.</p> <p>Traditionally we would need to have an HTTP server for the PHP XML-RPC server, because HTTP is used as the XML-RPC transport. But digging a bit into the specification, you'll discover, that none HTTP-specific parts of the protocol are used. It's just used as a line to transport the XML data.</p> <p>So you may wonder if it's possible to use XML-RPC with transport other than HTTP. In short, yes. But you may need to hack around the XML-RPC libraries (because they usually suppose you'll want to use HTTP).</p> <h1><span>PHP XML-RPC server</span></h1> <p>First, you need some class, that you want to expose with PHP XML-RPC:</p> <div class="code"> <div class="hl-main"> <pre><span class="hl-inlinetags">&lt;?php</span><span class="hl-code"> </span><span class="hl-reserved">class</span><span class="hl-code"> </span><span class="hl-identifier">MyClass</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code"> </span><span class="hl-comment">/** *</span><span class="hl-inlinedoc"> @param </span><span class="hl-comment">string $input *</span><span class="hl-inlinedoc"> @return </span><span class="hl-comment">string */</span><span class="hl-code"> </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-reserved">function</span><span class="hl-code"> </span><span class="hl-identifier">repeat</span><span class="hl-brackets">(</span><span class="hl-var">$input</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code"> </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-var">$input</span><span class="hl-code">; </span><span class="hl-brackets">}</span><span class="hl-code"> </span><span class="hl-brackets">}</span></pre></div> </div> <p>Notice I've set the parameter and return type in phpdoc.</p> <p>Now let's expose this class with <a href="http://framework.zend.com/manual/en/zend.xmlrpc.server.html#zend.xmlrpc.server.introduction">Zend Framework XML-RPC implementation</a>.</p> <p>You need to download Zend Framework first, let's say to /path/to/zf directory.</p> <div class="code"> <div class="hl-main"> <pre><span class="hl-inlinetags">&lt;?php</span><span class="hl-code"> </span><span class="hl-reserved">class</span><span class="hl-code"> </span><span class="hl-identifier">MyClass</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code"> </span><span class="hl-comment">/** *</span><span class="hl-inlinedoc"> @param </span><span class="hl-comment">string $input *</span><span class="hl-inlinedoc"> @return </span><span class="hl-comment">string */</span><span class="hl-code"> </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-reserved">function</span><span class="hl-code"> </span><span class="hl-identifier">repeat</span><span class="hl-brackets">(</span><span class="hl-var">$input</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code"> </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-var">$input</span><span class="hl-code">; </span><span class="hl-brackets">}</span><span class="hl-code"> </span><span class="hl-brackets">}</span><span class="hl-code"> </span><span class="hl-identifier">set_include_path</span><span class="hl-brackets">(</span><span class="hl-identifier">get_include_path</span><span class="hl-brackets">()</span><span class="hl-code"> . </span><span class="hl-reserved">PATH_SEPARATOR</span><span class="hl-code"> . </span><span class="hl-quotes">'</span><span class="hl-string">zf/library</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">; </span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-quotes">&quot;</span><span class="hl-string">Zend/XmlRpc/Server.php</span><span class="hl-quotes">&quot;</span><span class="hl-code">; </span><span class="hl-var">$server</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Zend_XmlRpc_Server</span><span class="hl-brackets">()</span><span class="hl-code">; </span><span class="hl-var">$server</span><span class="hl-code">-&gt;</span><span class="hl-identifier">setClass</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">MyClass</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">myclass</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">; </span><span class="hl-reserved">echo</span><span class="hl-code"> </span><span class="hl-var">$server</span><span class="hl-code">-&gt;</span><span class="hl-identifier">handle</span><span class="hl-brackets">()</span><span class="hl-code">;</span></pre></div> </div> <p>Set_include_path line adds the /path/to/zf/library directory to PHP path, so you can import the Zend_XmlRpc_Server class (located in /path/to/zf/library/Zend/XmlRpc/Server.php file).</p> <p>Then there is an instance of Zend_XmlRpc_Server created, then there is MyClass attached as the class for <strong>myclass</strong> XMLRPC namespace. This means the repeat method is to be called via the XML-RPC as <strong>myclass.repeat</strong>.</p> <p>If you place the file on your server and have it under some URL, for example:</p> <p><a href="http://your-server.com/myclass.php">http://your-server.com/myclass.php</a></p> <p>This URL is fully valid XML-RPC server endpoint for XML-RPC clients.</p> <h1><span>Python client</span></h1> <p>Having the XML-RPC server running we can connect to it from any XML-RPC enabled library in any programming language around.</p> <p>In Python, to call the remote procedure <strong>myclass.repeat</strong> on the XML-RPC endpoint <a href="http://your-server.com/myclass.php">http://your-server.com/myclass.php</a>, you would do the following:</p> <div class="code"> <div class="hl-main"> <pre><span class="hl-reserved">from</span><span class="hl-code"> </span><span class="hl-identifier">xmlrpclib</span><span class="hl-code"> </span><span class="hl-reserved">import</span><span class="hl-code"> </span><span class="hl-identifier">ServerProxy</span><span class="hl-code"> </span><span class="hl-identifier">server</span><span class="hl-code"> = </span><span class="hl-identifier">ServerProxy</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">http://your-server.com/myclass.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-reserved">print</span><span class="hl-code"> </span><span class="hl-identifier">server</span><span class="hl-code">.</span><span class="hl-identifier">myclass</span><span class="hl-code">.</span><span class="hl-identifier">repeat</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">Hello RPC service</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span></pre></div> </div> <p>Running this code:</p> <div class="code"> <pre><code># python xmlrpc-test.py</code></pre></div> <p>gives you:</p> <div class="code"> <pre><code>Hello RPC service</code></pre></div> <p>Under the hood:</p> <ul> <li>Python script makes a connection to <a href="http://your-server.com/myclass.php">http://your-server.com/myclass.php</a> <ul> <li>your webserver runs the myclass.php script <ul> <li>the $server-&gt;handle() line processes the data received <ul> <li>chooses a class and a method to run (this would be MyClass and repeat)</li> <li>passes the arguments (a string 'Hello RPC service') to the method</li> <li>gets the return value</li> </ul> </li> <li>passes it back to the client wrapped in XML-RPC protocol</li> </ul> </li> </ul> </li> <li>Python gets XML reply and converts it back to simple string ('Hello RPC service')</li> <li>and prints it on the console</li> </ul> <h1><span>Omitting the HTTP protocol</span></h1> <p>Probably you have both Python and PHP scripts to be run on the same machine, so the HTTP part is quite useless and an additional point of failure.</p> <p>As I already stated, the HTTP is only a transport and you can replace it (with some cost) with some other transport.</p> <p>I came into an idea to use stdout/stdin as the transport, so Python would execute a PHP script (command line interface) and pass the XML-RPC request to the script's stdin. PHP would then have to get the XML-RPC request from stdin instead of from HTTP request.</p> <p>This means two modifications in server and client code.</p> <p>First the server:</p> <div class="code"> <div class="hl-main"> <pre><span class="hl-inlinetags">&lt;?php</span><span class="hl-code"> </span><span class="hl-reserved">class</span><span class="hl-code"> </span><span class="hl-identifier">MyClass</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code"> </span><span class="hl-comment">/** *</span><span class="hl-inlinedoc"> @param </span><span class="hl-comment">string $input *</span><span class="hl-inlinedoc"> @return </span><span class="hl-comment">string */</span><span class="hl-code"> </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-reserved">function</span><span class="hl-code"> </span><span class="hl-identifier">repeat</span><span class="hl-brackets">(</span><span class="hl-var">$input</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code"> </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-var">$input</span><span class="hl-code">; </span><span class="hl-brackets">}</span><span class="hl-code"> </span><span class="hl-brackets">}</span><span class="hl-code"> </span><span class="hl-identifier">set_include_path</span><span class="hl-brackets">(</span><span class="hl-identifier">get_include_path</span><span class="hl-brackets">()</span><span class="hl-code"> . </span><span class="hl-reserved">PATH_SEPARATOR</span><span class="hl-code"> . </span><span class="hl-quotes">'</span><span class="hl-string">zf/library</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">; </span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-quotes">&quot;</span><span class="hl-string">Zend/XmlRpc/Server.php</span><span class="hl-quotes">&quot;</span><span class="hl-code">; </span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-quotes">&quot;</span><span class="hl-string">Zend/XmlRpc/Request/Stdin.php</span><span class="hl-quotes">&quot;</span><span class="hl-code">; </span><span class="hl-var">$server</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Zend_XmlRpc_Server</span><span class="hl-brackets">()</span><span class="hl-code">; </span><span class="hl-var">$server</span><span class="hl-code">-&gt;</span><span class="hl-identifier">setClass</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">MyClass</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">myclass</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">; </span><span class="hl-reserved">echo</span><span class="hl-code"> </span><span class="hl-var">$server</span><span class="hl-code">-&gt;</span><span class="hl-identifier">handle</span><span class="hl-brackets">(</span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Zend_XmlRpc_Request_Stdin</span><span class="hl-brackets">())</span><span class="hl-code">;</span></pre></div> </div> <p>The change is passing an instance of Zend_XmlRpc_Request_Stdin to $server-&gt;handle(). This is all needed. Guys from Zend Framework already predicted such a use.</p> <p>Then, the client part.</p> <p>Xmlrpclib allows passing a custom transport in case you want to implement some proxies or other thing. We'll make a transport, that instead of making a HTTP connection, runs a PHP script, passes the request to its stdin and gets the response from stdout:</p> <div class="code"> <div class="hl-main"> <pre><span class="hl-reserved">from</span><span class="hl-code"> </span><span class="hl-identifier">xmlrpclib</span><span class="hl-code"> </span><span class="hl-reserved">import</span><span class="hl-code"> </span><span class="hl-identifier">Transport</span><span class="hl-code">, </span><span class="hl-identifier">Server</span><span class="hl-code"> </span><span class="hl-reserved">from</span><span class="hl-code"> </span><span class="hl-identifier">subprocess</span><span class="hl-code"> </span><span class="hl-reserved">import</span><span class="hl-code"> </span><span class="hl-identifier">Popen</span><span class="hl-code">, </span><span class="hl-identifier">PIPE</span><span class="hl-code"> </span><span class="hl-reserved">class</span><span class="hl-code"> </span><span class="hl-identifier">LocalFileTransport</span><span class="hl-brackets">(</span><span class="hl-identifier">Transport</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-reserved">class</span><span class="hl-code"> </span><span class="hl-identifier">Connection</span><span class="hl-code">: </span><span class="hl-reserved">def</span><span class="hl-code"> </span><span class="hl-identifier">setCmd</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">cmd</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">cmd</span><span class="hl-code"> = </span><span class="hl-identifier">Popen</span><span class="hl-brackets">([</span><span class="hl-quotes">'</span><span class="hl-string">php</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">cmd</span><span class="hl-brackets">]</span><span class="hl-code">, </span><span class="hl-identifier">stdin</span><span class="hl-code">=</span><span class="hl-identifier">PIPE</span><span class="hl-code">, </span><span class="hl-identifier">stdout</span><span class="hl-code">=</span><span class="hl-identifier">PIPE</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-reserved">def</span><span class="hl-code"> </span><span class="hl-identifier">send</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">content</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">cmd</span><span class="hl-code">.</span><span class="hl-identifier">stdin</span><span class="hl-code">.</span><span class="hl-identifier">write</span><span class="hl-brackets">(</span><span class="hl-identifier">content</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">cmd</span><span class="hl-code">.</span><span class="hl-identifier">stdin</span><span class="hl-code">.</span><span class="hl-identifier">close</span><span class="hl-brackets">()</span><span class="hl-code"> </span><span class="hl-reserved">def</span><span class="hl-code"> </span><span class="hl-identifier">getreply</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">200</span><span class="hl-code">, </span><span class="hl-quotes">''</span><span class="hl-code">, </span><span class="hl-brackets">[]</span><span class="hl-code"> </span><span class="hl-reserved">def</span><span class="hl-code"> </span><span class="hl-identifier">getfile</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">cmd</span><span class="hl-code">.</span><span class="hl-identifier">stdout</span><span class="hl-code"> </span><span class="hl-reserved">def</span><span class="hl-code"> </span><span class="hl-identifier">make_connection</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">host</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">Connection</span><span class="hl-brackets">()</span><span class="hl-code"> </span><span class="hl-reserved">def</span><span class="hl-code"> </span><span class="hl-identifier">send_request</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">connection</span><span class="hl-code">, </span><span class="hl-identifier">handler</span><span class="hl-code">, </span><span class="hl-identifier">request_body</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-identifier">connection</span><span class="hl-code">.</span><span class="hl-identifier">setCmd</span><span class="hl-brackets">(</span><span class="hl-identifier">handler</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-reserved">def</span><span class="hl-code"> </span><span class="hl-identifier">send_content</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">connection</span><span class="hl-code">, </span><span class="hl-identifier">request_body</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-identifier">connection</span><span class="hl-code">.</span><span class="hl-identifier">send</span><span class="hl-brackets">(</span><span class="hl-identifier">request_body</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-reserved">def</span><span class="hl-code"> </span><span class="hl-identifier">send_host</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">connection</span><span class="hl-code">, </span><span class="hl-identifier">host</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-reserved">pass</span><span class="hl-code"> </span><span class="hl-reserved">def</span><span class="hl-code"> </span><span class="hl-identifier">send_user_agent</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">connection</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-reserved">pass</span><span class="hl-code"> </span><span class="hl-identifier">server</span><span class="hl-code"> = </span><span class="hl-identifier">Server</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">http://host.com/path/to/the/php/script/myclass.php</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">transport</span><span class="hl-code"> = </span><span class="hl-identifier">LocalFileTransport</span><span class="hl-brackets">())</span><span class="hl-code"> </span><span class="hl-reserved">print</span><span class="hl-code"> </span><span class="hl-identifier">server</span><span class="hl-code">.</span><span class="hl-identifier">myclass</span><span class="hl-code">.</span><span class="hl-identifier">repeat</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">Hello XML-RPC with no HTTP service</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span></pre></div> </div> <p>Notes:</p> <ul> <li>host.com in the URL is completely ignored, use whatever value you want</li> <li>/path/to/the/php/script/myclass.php in URL is passed as the PHP script to run</li> </ul> <h1><span>What to do next?</span></h1> <p>Having this simple skeleton, you can now extend the MyClass, actually give it more proper name first! You can also attach more classes to the XML-RPC server using different namespaces:</p> <div class="code"> <div class="hl-main"> <pre><span class="hl-code">$server-&gt;setClass('SomeClass', 'some); $server-&gt;setClass('MyClass', 'my'); $server-&gt;setClass('YourClass', 'your');</span></pre></div> </div> <p>Only public methods are exposed to the XML-RPC clients, so you can hide some logic inside of private or protected methods and only expose what you need from given classes.</p> <p>This solution is a quick way to actually use some of your well-working PHP code in your fancy-new and elegant Python application. This can help if you want to make a filesystem with Python-FUSE, but want to data be taken from PHP application.</p> <h1><span>Did it help you?</span></h1> <p>I hope this helps someone. Feel free to comment.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1779328805" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:po-gazie-0-2</guid>
				<title>Po GaZie 0.2</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:po-gazie-0-2</link>
				<description>

&lt;p&gt;&lt;a href=&quot;http://piotrgabryjeluk.wikidot.com/gaza-0-2&quot;&gt;GaZa 0.2&lt;/a&gt; zakończona. Spotkanie poświęcone było frameworkowi &lt;a href=&quot;http://djangoproject.com/&quot;&gt;Django&lt;/a&gt;, który umożliwia pisanie własnych serwisów internetowych przy użyciu języka skryptowego Python i szablonów Django. Zawiera również warstwę obiektowego dostępu do bazy danych.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1779328805&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 17 Dec 2008 18:01:38 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p><a href="http://piotrgabryjeluk.wikidot.com/gaza-0-2">GaZa 0.2</a> zakończona. Spotkanie poświęcone było frameworkowi <a href="http://djangoproject.com/">Django</a>, który umożliwia pisanie własnych serwisów internetowych przy użyciu języka skryptowego Python i szablonów Django. Zawiera również warstwę obiektowego dostępu do bazy danych.</p> <div class="content-separator" style="display: none:"></div> <p>Spotkanie trwało półtorej godziny (16.45 do 18.15). Zdążyłem przez ten czas pokazać jak zainstalować bibilotekę Django, stworzyć pierwszy projekt i pierwszą aplikację, uruchomić deweloperski serwer WWW dołączony do Django.</p> <p>Skorzystaliśmy również w prosty sposób z systemu szablonów i pokazaliśmy wyższość Django nad Ruby on Rails pokazywanym na [<a href="http://piotrgabryjeluk.wikidot.com/gaza-0-1">poprzedniej gazie</a>.</p> <p>Przyszło sporo uczestników. Np. Kamil nie robił problemów i ładnie wyglądał.</p> <p>Następna Gaza prawdopodnie po świętach w <a href="http://piotrgabryjeluk.wikidot.com/nowy-termin-gazy">poniedziałek o 16.45</a>.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1779328805" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:learning-django</guid>
				<title>Learning Django</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:learning-django</link>
				<description>

&lt;p&gt;Today I started (again) to learn &lt;a href=&quot;http://djangoproject.com/&quot;&gt;Django&lt;/a&gt; &amp;#8212; framework for writing web applications in Python (rocks!).&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1779328805&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 11 Dec 2008 20:47:09 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Today I started (again) to learn <a href="http://djangoproject.com/">Django</a> &#8212; framework for writing web applications in Python (rocks!).</p> <div class="content-separator" style="display: none:"></div> <p>Anyone could tell looking at my browser:</p> <p style="text-align: center;"><a href="http://piotrgabryjeluk.wdfiles.com/local--files/blog:learning-django/learning-django.png"><img src="http://piotrgabryjeluk.wdfiles.com/local--resized-images/blog:learning-django/learning-django.png/small.jpg" alt="learning-django.png" class="image" /></a></p> <p style="text-align: center;">click to enlarge</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1779328805" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:hacking-pympd-and-last-fm</guid>
				<title>Hacking pympd and Last.fm</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:hacking-pympd-and-last-fm</link>
				<description>

&lt;p&gt;Hello again,&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1779328805&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Fri, 26 Sep 2008 22:36:01 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Hello again,</p> <p>My girlfriend was very unhappy with me not having my played songs submitted to <a href="http://last.fm/user/Gabrys">Last.fm</a> social music revolution portal.</p> <p>That was because used to use <a href="http://musicpd.org/">Music Player Daemon</a> and its various clients. Most of the clients don't implement the AudioScrobbler protocol, but as a matter of fact this is not needed, because there can be a separate MPD client meant just to submit the info to last.fm, running in parallel to one actually playing music.</p> <p>I used to use <a href="http://scmpc.berlios.de/">scmpc</a> for this reason, but since I bought my new laptop and migrated to Ubuntu I quit it &#8212; because the application was not in their repo.</p> <p>Today I decided to find some short python-based implementation of audioscrobbler and enrich one of MPD clients with the Last.fm integration. I found <a href="http://pympd.sourceforge.net/">pympd</a> really good &#8212; nice looking, having plugin architecture, clean and simple. So I decided it to be my new favorite MPD client. Then I quick-hacked some random plugin and created a new one including almost 100% source from <a href="http://sourceforge.net/projects/scrobbler">python-scrobbler project</a>. The plugin:</p> <ul> <li>sends &quot;now playing&quot; info to Last.fm on each track-change and loading of plugin</li> <li>sends &quot;song played&quot; info to Last.fm on track-change and plugin unload event if song was listened at least to the half of its total length and is longer than 30 seconds.</li> </ul> <p>Now the Last.fm user and password are hardcoded, but I hope to create a quick-and-dirty configuration window for it.</p> <p>I had some problems with time convertion. The python-scrobbler sources suggest using datetime.utcnow() method while actually using datetime.now() is giving the right results.</p> <p>You can check my <a href="http://www.lastfm.pl/user/Gabrys">Last.fm</a> records:</p> <ul> <li>July &#8212; submitted by scmpc from Gentoo &#8212; the old computer</li> <li>first records in October &#8212; submitted with <strong>MY PLUGIN</strong></li> <li>two hours gap &#8212; before fixing UTC issue, the songs were submitted as played two hours earlier (timezone difference)</li> </ul> <p>So it seems working!</p> <p>It's a pretty cool <a href="http://piotrgabryjeluk.wikidot.com/dev:working-on-tagfs">Python day</a> today.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1779328805" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:working-on-tagfs</guid>
				<title>Working On TagFs</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:working-on-tagfs</link>
				<description>

&lt;p&gt;Today I spent another hour or two on working on tagfs (described in &lt;a href=&quot;http://piotrgabryjeluk.wikidot.com/dev:tagfs-idea&quot;&gt;TagFs Idea&lt;/a&gt;). It&#039;s now pretty much usable. You can now:&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1779328805&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Fri, 26 Sep 2008 19:23:52 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Today I spent another hour or two on working on tagfs (described in <a href="http://piotrgabryjeluk.wikidot.com/dev:tagfs-idea">TagFs Idea</a>). It's now pretty much usable. You can now:</p> <ul> <li>browse files with the tag-directory mapping <ul> <li>directory <tt>tag1/tag2/tag3</tt> is the same as <tt>tag2/tag3/tag1</tt> or <tt>tag3/tag1/tag2</tt></li> </ul> </li> <li>read/write files <ul> <li>file <tt>tag1/tag2/tag3/file</tt> is the same as <tt>tag2/tag3/tag1/file</tt> AND <strong>even <tt>tag2/tag1,tag3,file</tt></strong></li> <li>tags are not only allowed as directory names, but also as comma-separated file prefix</li> </ul> </li> <li>create new files <ul> <li><tt>echo Some Content &gt; tag1/tag2/some_file</tt></li> <li><tt>echo Some Other Content &gt; tag1/tag2,some_file</tt></li> </ul> </li> <li>files have all their &quot;real&quot; properties (owner, group, modification time &#8212; this is stored on the back-end filesystem)</li> </ul> <p>Things to do yet:</p> <ul> <li>forbid creating a file with tags rendering some directory with name of existing file <ul> <li>example: you have <tt>tag1/great</tt> file</li> <li>then you create a <tt>tag1/tag2,great,people.txt</tt> file</li> <li>this way, you would have a <tt>great</tt> directory showing in the <tt>tag1</tt> directory, because there is a file having both tag1 and great</li> <li>you also have <tt>great</tt> file there, so you end up with a file and a directory (tag) of the same name</li> </ul> </li> <li>scan and list files by their properties <ul> <li>file type &#8212; PDF, JPEG, HTML, &#8230;</li> <li>EXIF tags for JPEG &#8212; date taken, camera info</li> <li>ID3 tags for MP3 &#8212; artist, title, album</li> </ul> </li> <li>improve directory listing <ul> <li>include SOME files in sub-directories if the sub-directories consist of small number of files</li> <li>as a result we get a easily-browsable repository of files</li> </ul> </li> <li>do some marketing <ul> <li>I would like to serve files from such a file system with FTP or Apache to let people feel the system</li> </ul> </li> </ul> <p>I think this experiment is really worth working on this.</p> <p>In case you want to test the FS, drop me a note or comment.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1779328805" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:tagfs-idea</guid>
				<title>tag filesystem idea</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:tagfs-idea</link>
				<description>

&lt;p&gt;I just thought of my ideal file system, where nothing hides and is &lt;strong&gt;easy&lt;/strong&gt; to find (without going through the whole system &amp;#8212; either manually, or automatically &amp;#8212; &lt;tt&gt;find&lt;/tt&gt; or even the indexed way &amp;#8212; &lt;tt&gt;mlocate&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1779328805&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Sun, 31 Aug 2008 08:14:59 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>I just thought of my ideal file system, where nothing hides and is <strong>easy</strong> to find (without going through the whole system &#8212; either manually, or automatically &#8212; <tt>find</tt> or even the indexed way &#8212; <tt>mlocate</tt>).</p> <p>The main idea is tags.<br /> When I save a file I want to give it some tags.<br /> Moreover, I want to be able to find a file based on its properties, like</p> <ul> <li>file properties &#8212; author, date created, type (PDF/TXT/XML)</li> <li>EXIF data &#8212; camera name, camera settings</li> <li>audio tags &#8212; artist, title, year, album, genre</li> </ul> <p>How could it look like?</p> <div class="code"> <pre><code># ls /home/quake wikidot/ python/ work/ tmp/ img/ music/ # ls /home/quake/wikidot work/ tmp/ img/ howto.pdf # ls /home/quake/wikidot/work new-idea.txt # ls /home/quake/work/wikidot new-idea.txt</code></pre></div> <p>So it looks, like it doesn't matter if you navigate to work and then to wikidot or the reverse.</p> <p>Moreover, I want to browse all my music files (having music tag) by author information:</p> <div class="code"> <pre><code># ls /home/quake/music/+artist/ Britney Spears/ Shakira/</code></pre></div> <p>PDF files inside of wikidot:</p> <div class="code"> <pre><code># ls /home/quake/wikidot/+type/pdf/ howto.pdf</code></pre></div> <p>This idea will be implemented with:</p> <ul> <li>Filesystem in User SpacE &#8212; FUSE</li> <li>Python</li> <li>SQLite</li> <li>Ubuntu laptop :)</li> </ul> <p>Wish me luck</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1779328805" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:python-database-the-work-continues</guid>
				<title>Python Database: The Work Continues</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:python-database-the-work-continues</link>
				<description>

&lt;p&gt;Today more work was done by me on the object oriented database implemented in Python.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1779328805&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 28 Aug 2008 21:36:18 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Today more work was done by me on the object oriented database implemented in Python.</p> <p>I dealt with some problems I came across like proper object encapsulation. Now, my database allows any object to be stored in it, even of classes that are internally used by my database.</p> <p>I implemented &quot;.&quot; and &quot;WHERE&quot; operators, which seemed the worst, because they needed working environmental stack.</p> <p>Now comes, what's the most individual &#8212; optimizing things with query cache. Actually it's not a query cache, but rather a evaluateNode cache, but this works very similar (the only difference is that the evaluateNode cache is more deep in operation and can be used inside of queries. This means it can accelerate the processing even for one query!</p> <p>More work will come for sure on this, because the cache seems to be really tricky with such a flexible database model we've assumed.</p> <p>Keep tuned for more news</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1779328805" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:object-database-in-python-day-2</guid>
				<title>Object Database In Python - Day 2</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:object-database-in-python-day-2</link>
				<description>

&lt;p&gt;Hello again,&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1779328805&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Sat, 16 Aug 2008 16:12:09 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Hello again,</p> <p>as pointed in <a href="http://piotrgabryjeluk.wikidot.com/dev:starting-work-on-object-database-in-python#comments">the previous day comment</a>, there is another IDE for developing in Python, which is BoaConstructor. As a matter of fact, I haven't taken that into consideration, because it was told it is a IDE for GUI development. As I was not about creating a GUI, this was completely skipped.</p> <p>My impressions of the IDEs:</p> <ul> <li>pida, geany, drpython &#8212; interesting, but not worth a try for me</li> <li>eric &#8212; good overall, but raises many dialog boxes with information of exceptions. These are fatal and are about the GUI, so you have to click OK and continue working</li> </ul> <p>I tried the Eric first, because it was written as a really good program. I like it, but it is not polished and would never be bought (if commercial) by anyone:</p> <ul> <li>the support for SVN is really tricky</li> <li>the GUI is really not intuitive &#8212; no &quot;delete a file&quot; or &quot;new file (here)&quot; in the navigator context menu</li> <li>the code completion is there, but not really so clever</li> </ul> <p>for example, having the following code:</p> <div class="code"> <div class="hl-main"> <pre><span class="hl-reserved">class</span><span class="hl-code"> </span><span class="hl-identifier">aClass</span><span class="hl-code">: </span><span class="hl-reserved">def</span><span class="hl-code"> </span><span class="hl-identifier">method</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">param</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-reserved">assert</span><span class="hl-code"> </span><span class="hl-builtin">isinstance</span><span class="hl-brackets">(</span><span class="hl-identifier">param</span><span class="hl-code">, </span><span class="hl-identifier">list</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-identifier">param</span><span class="hl-code">.</span></pre></div> </div> <p>the IDE should know, that the param is a list and complete the list methods! I believe the PyDev plugin for Eclipse already did it when I last used it.</p> <p>After trying all the listed IDEs I got back to Eric as one of two best Python IDEs tried by me (the second is PyDev).</p> <p>Happy Pythoning<br /> Your Piotr</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1779328805" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:starting-work-on-object-database-in-python</guid>
				<title>Starting Work On Object Database In Python</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:starting-work-on-object-database-in-python</link>
				<description>

&lt;p&gt;Good morning everyone,&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1779328805&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Fri, 15 Aug 2008 10:08:35 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Good morning everyone,</p> <p>today I start working on object database to be implemented in Python. This is my individual project for my classes.</p> <p>During the study-year I was taught how to parse sophisticated grammar with PLY (Python Lex and Yacc library). I've then learned how to then process the parsed queries, to get the results.</p> <p>The database query language is similar to the SQL language. The difference is, we don't have definitions of tables and fields. Any object (row in table) can have fields other that other objects with the same name (of the same table).</p> <p>This seems quite hard, but it has its pros.</p> <p>Moreover we've analyzed the following query using the simple parsing and processing:</p> <div class="code"> <div class="hl-main"> <pre><span class="hl-reserved">SELECT</span><span class="hl-code"> </span><span class="hl-identifier">employee</span><span class="hl-code">.</span><span class="hl-identifier">salary</span><span class="hl-code"> </span><span class="hl-reserved">WHERE</span><span class="hl-code"> </span><span class="hl-identifier">employee</span><span class="hl-code">.</span><span class="hl-identifier">salary</span><span class="hl-code"> &gt; </span><span class="hl-var">AVG</span><span class="hl-brackets">(</span><span class="hl-identifier">employee</span><span class="hl-code">.</span><span class="hl-identifier">salary</span><span class="hl-brackets">)</span><span class="hl-code">;</span></pre></div> </div> <p>now, having as much as 10000 employees, using the standard processing, this would mean calculating the average (AVG) from ALL salaries for EACH of the 10000 employees.</p> <p>So the teacher proposed to use tree decoration, to mark the branches of the query syntax tree, that can be run once (i.e. their value does not depend on the rest of the query).</p> <p>I proposed to do it other way: to don't analyze the tree to much, but instead implement a sort of caching. Each time we try to get the AVG(employee.salary) we check whether this was already calculated, if not (only the first time we get the AVG), we calculate this and populates the cache with the value.</p> <p>This has the following pros:</p> <ul> <li>we can use the cache in successive queries</li> <li>we don't have to decorate query trees &#8212; it's not Christmas here</li> </ul> <p>Today work I start with selecting a Python IDE to work with. During the classes I used PyDev &#8212; the Python plugin for Eclipse IDE, but I believe there any many new choices out there now &#8212; after a few months:</p> <ul> <li>eric</li> <li>pida</li> <li>geany</li> <li>drpython</li> </ul> <p>(all from Ubuntu default repository)</p> <p>More IDEs I found with Google:</p> <ul> <li>TruStudio: <a href="http://sourceforge.net/projects/trustudio/">http://sourceforge.net/projects/trustudio/</a></li> <li>only windows(?): pyscripter &#8212; <a href="http://code.google.com/p/pyscripter/downloads/list">http://code.google.com/p/pyscripter/downloads/list</a></li> <li>commercial: Wing, Komodo, BlackAdder</li> </ul> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1779328805" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
				</channel>
</rss>