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

<channel>
	<title>Mats Lindh &#187; Programming</title>
	<atom:link href="http://e-mats.org/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://e-mats.org</link>
	<description>Where desperate is just another word for a regular day.</description>
	<lastBuildDate>Wed, 01 Feb 2012 14:42:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>A Gentle Introduction to Gearman and its Concepts</title>
		<link>http://e-mats.org/2011/08/a-gentle-introduction-to-gearman-and-its-concepts/</link>
		<comments>http://e-mats.org/2011/08/a-gentle-introduction-to-gearman-and-its-concepts/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 21:21:54 +0000</pubDate>
		<dc:creator>Mats</dc:creator>
				<category><![CDATA[Gearman]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[gearmand]]></category>
		<category><![CDATA[introduction]]></category>
		<category><![CDATA[message queues]]></category>
		<category><![CDATA[mq]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[workers]]></category>

		<guid isPermaLink="false">http://e-mats.org/?p=935</guid>
		<description><![CDATA[Gearman (an anagram for &#8220;Manager&#8221;) is a system for farming out work units to several different servers (or several processes on one server), allowing the calling code to do something completely different while the task is performed. Gearman is not intended for inter-process communication, but is a way to tell other processes that there are [...]]]></description>
			<content:encoded><![CDATA[<p>Gearman (an anagram for &#8220;Manager&#8221;) is a system for farming out work units to several different servers (or several processes on one server), allowing the calling code to do something completely different while the task is performed. Gearman is not intended for inter-process communication, but is a way to tell other processes that there are work available, and letting these processes (called workers) grab a piece of work for themselves.</p>
<p>One of the common themes that show up at the gearman IRC channel on freenode is an attempt to understand what <a href="http://gearman.org/">gearman</a> is and how everything fits together. I&#8217;ll try to explain the different concepts and what the different responsibilities of a working gearman infrastructure are. There&#8217;s also a &#8220;<a href="http://gearman.org/index.php?id=getting_started">Getting Started</a>&#8221; guide on the Gearman web site with a bit of example code and installation instructions, so you might want to keep that open in another tab. So here we go: a simple gearman tutorial explaining the concepts and not just throwing example code your way.</p>
<p>There are three core components of a gearman installation. These are a client (someone requesting a task to be performed), a worker (someone performing a task) and the server (which coordinates tasks between clients and workers). All these three components need to be running for you to be able to something useful with gearman. It&#8217;s worth noting that I&#8217;ll use name &#8220;task&#8221; for a single item to be performed, you&#8217;ll also see this named &#8216;function&#8217; (which is the name of the actual function the task asks to be performed &#8211; a server offers several &#8220;functions&#8221; that a client can call). Some APIs might also refer to a &#8220;task&#8221; as a collection of functions to be called. I&#8217;ll use the first definition; a task is a call to a function on the server, together with the data for the task and a task identifier. Several subsequent tasks will call the same function.</p>
<p>I&#8217;ll go a bit more in detail about each of these components, but it&#8217;s important that you understand how everything is interconnected first. An exchange of messages between the different parts can be illustrated as follows:</p>
<pre>
client -> server: ask server to perform a task
server acknowledges request and assigns an identificator to the request
server -> all workers: tell workers registered for the task that there is work to be performed
worker -> server: I'll perform the task you just told us about
server -> worker: ok, go ahead, here's the information about the task.
worker -> server: here's the result of the task performed
server -> client: here's the result of the task you asked me to get someone to do for you
</pre>
<p>The idea behind the server telling all the workers that there are work available is to let the worker that responds fastest to actually get the task, as it&#8217;s assumed that this is the worker with the least load on the server it&#8217;s running on (as it responds quickly, the server is not busy doing other things). As I wrote above, the worker is the piece of code actually doing the work &#8211; the worker performs the task that a client has submitted to the gearman server.</p>
<p>You&#8217;ll find that most of Gearman is designed according to the same principle &#8211; keep stuff simple. The server only needs to keep track of which workers perform which functions, and then let the workers grab a task when it becomes available.</p>
<h3>The Gearman Client</h3>
<p>In Gearman the client is the piece of code that connects to the server and asks for a task to be performed. This can be a dynamic web page (running in python, ruby, PHP, perl or another language with a suitable Gearman library), a completely application that connects to Gearman, a worker (to submit a new task or to divide the current task into several smaller tasks to be performed by other workers) or a combination of the above. The important part is that this is simply a client &#8211; it has a task that needs to be handled, and it&#8217;ll ask the Gearman server to find someone who can perform the task.</p>
<p>The client can be run in synchronous (blocking) or asynchronous (non-blocking) mode. The first will make the client wait until the task has been performed by a worker (and if no worker is available, it&#8217;ll wait indefinitely or until reaching a timeout in the client), while the latter will simply fire-and-forget the task to the Gearman server (the server will confirm that the task has been received) and then go on its merry way afterwards. The Gearman server will provide a task identification value which the asynchronous client can use to query the current state of the task it asked to be performed (as long as the actual worker provide such updates).</p>
<p>A small example of how a client might work (using PHP):</p>
<div class="geshi no php">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$client</span> <span class="sy0">=</span> <span class="kw2">new</span> GearmanClient<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$client</span><span class="sy0">-&gt;</span><span class="me1">addServer</span><span class="br0">&#40;</span><span class="st0">&#39;localhost&#39;</span><span class="sy0">,</span> <span class="nu0">4730</span><span class="br0">&#41;</span><span class="sy0">;</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$arguments</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#39;url&#39;</span> <span class="sy0">=&gt;</span> <span class="st0">&#39;http://www.example.com/&#39;</span><span class="sy0">,</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$client</span><span class="sy0">-&gt;</span><span class="me1">addTaskBackground</span><span class="br0">&#40;</span><span class="st0">&#39;fetchURL&#39;</span><span class="sy0">,</span> json_encode<span class="br0">&#40;</span><span class="re1">$arguments</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$client</span><span class="sy0">-&gt;</span><span class="me1">runTasks</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
<p>This will submit a request to a Gearman server running on the same machine as the script, asking for the function &#8220;fetchURL&#8221; to be run, and including an array of arguments to the function (you could simply include just the URL, but I find that this way is easier to extend in the future &#8211; and using JSON for data exchange makes the worker code more programming language independent). This code uses addTaskBackground to submit the task to be performed in an asynchronous manner. We&#8217;re not interested in the result of this task in this particular piece of code &#8211; the worker will either provide the result through other means (storing it in a database, in memcache, call an API function telling us that it&#8217;s finished) or perhaps we&#8217;re not interested in the result at all, just that we&#8217;ve attempted to perform the task. If you&#8217;re using the synchronous interface, the data returned from the worker will be returned to your code as the return value from the client.</p>
<p>As you can see, the client code is very, very simple. There is no actual work being performed here, we&#8217;re just telling the server that we&#8217;d like some work to be performed for us.</p>
<h3>The Gearman Worker</h3>
<p>The Gearman worker is where all the actual work (.. who&#8217;d guess) is performed. This is the application that receives a notice that it has to wake up and do a bit of hard work, and which actually goes out and does just that. What kind of work it does depends on what you&#8217;re using Gearman for, but a couple of use cases could be to resize an image into smaller sizes (such as thumbnails), to convert an uploaded video into another format for a specific device, sending notification emails, updating an internal search engine such a Solr and quite a few other tasks. As long as the task is not important for the application to continue running (no need for waiting for an E-mail to be delivered if you&#8217;re going to show a &#8220;Your information has been saved&#8221; message), then Gearman (and other alternative message queues) is a valid solution.</p>
<p>You&#8217;ll run each worker as its own process. A worker can perform several different functions (although you should (usually) stay away from multi-threading to perform them at the same time). This means starting several copies of the same worker if you want to allow for more than one worker performing a task at the same time (i.e., if you want to send 30 e-mails in parallel), you&#8217;ll start each worker as separate processes (30 workers in that case). There are several daemons and frameworks that can help you manage the number of processes available depending on server and task load, such as <a href="http://supervisord.org/">supervisord</a> and <a href="https://github.com/brianlmoon/GearmanManager">GearmanManager</a> (a PHP daemon). Another possible solution is to use <a href="http://www.gnu.org/s/screen/">screen</a> to start several workers, which also will allow you to attach to the output of any worker at any time.</p>
<p>How the worker performs its work is up to the worker itself. In most cases you&#8217;ll have to write a bit of code to expose your code as a Gearman function (so that clients can submit tasks to perform that function), but this code will usually just instantiate the worker framework from the Gearman library you&#8217;re using, letting you register what functions you&#8217;ll be able to perform and attaching callbacks telling the library what part of your own code should be called when a request to perform a task arrives.</p>
<p>A simple example modified from the Gearman Getting Started guide:</p>
<div class="geshi no php">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$worker</span> <span class="sy0">=</span> <span class="kw2">new</span> GearmanWorker<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$worker</span><span class="sy0">-&gt;</span><span class="me1">addServer</span><span class="br0">&#40;</span><span class="st0">&quot;localhost&quot;</span><span class="sy0">,</span> <span class="nu0">4730</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$worker</span><span class="sy0">-&gt;</span><span class="me1">addFunction</span><span class="br0">&#40;</span><span class="st0">&quot;fetchURL&quot;</span><span class="sy0">,</span> <span class="st0">&quot;fetch_url&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">while</span> <span class="br0">&#40;</span><span class="re1">$worker</span><span class="sy0">-&gt;</span><span class="me1">work</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> fetch_url<span class="br0">&#40;</span><span class="re1">$job</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$arguments</span> <span class="sy0">=</span> json_decode<span class="br0">&#40;</span><span class="re1">$job</span><span class="sy0">-&gt;</span><span class="me1">workload</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="kw3">empty</span><span class="br0">&#40;</span><span class="re1">$arguments</span><span class="br0">&#91;</span><span class="st0">&#39;url&#39;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">print</span><span class="br0">&#40;</span><span class="st0">&quot;Fetching &quot;</span> <span class="sy0">.</span> <span class="re1">$arguments</span><span class="br0">&#91;</span><span class="st0">&#39;url&#39;</span><span class="br0">&#93;</span> <span class="sy0">.</span> <span class="st0">&quot;<span class="es0">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw3">file_get_contents</span><span class="br0">&#40;</span><span class="re1">$arguments</span><span class="br0">&#91;</span><span class="st0">&#39;url&#39;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>The <strong>$worker->work()</strong> method call will wait until a work arrives, then execute the callback as defined in the addFunction call. addFunction instructs the worker to tell the gearman server that this worker is able to perform any tasks calling the &#8220;fetchURL&#8221; function. The callback provided to the library (&#8220;call this PHP function (&#8216;fetch_url&#8217;) when tasks want to call &#8216;fetchURL&#8217;&#8221;) will then receive the job object containing information about the job (task) to be performed. The workload() method returns the workload &#8211; the information we included in addition to which function to call in the client example. The server receives the workload from the client and then sends it to the worker together with the task information.</p>
<p>Since our client calls the server using the asynchronous interface it&#8217;ll not wait for the worker to return the web page contents, but by using ->do() or one of the other foreground methods in the PHP Gearman library.</p>
<h3>The Gearman Server</h3>
<p>The Gearman Server used is usually the C version of the server. There&#8217;s also a PERL version, but these days the C server is the one being actively developed. There&#8217;s not much to say about the server, you usually just start it and let it run by itself, doing what it was supposed to do all along.</p>
<p>I&#8217;ve got one simple suggestion if you&#8217;re just playing around with Gearman for the first time: start the server with the -vvv option. This will make gearmand a lot noisier, and will allow you to see clients registering themselves with the server, pinging the server and getting a bit more information about what&#8217;s happening inside the server process.</p>
<p>You&#8217;ll also want to provide an IP address that the gearman server should bind to &#8211; by default it binds to all interfaces, and since gearmand does not have any authentication built in by default, you don&#8217;t want to expose your server to the whole world.</p>
<p>Here&#8217;s an example of how we start gearmand at one of our servers:</p>
<div class="geshi no bash">
<ol>
<li class="li1">
<div class="de1">screen -d -m -S gearmand <span class="sy0">/</span>usr<span class="sy0">/</span><span class="kw3">local</span><span class="sy0">/</span>sbin<span class="sy0">/</span>gearmand -L <span class="nu0">127.0</span><span class="nu0">.0</span><span class="nu0">.1</span> -p <span class="nu0">4730</span> -vvv</div>
</li>
</ol>
</div>
<p>You can drop the part related to screen if you just want to play with gearmand:</p>
<div class="geshi no bash">
<ol>
<li class="li1">
<div class="de1"><span class="sy0">/</span>usr<span class="sy0">/</span><span class="kw3">local</span><span class="sy0">/</span>sbin<span class="sy0">/</span>gearmand -L <span class="nu0">127.0</span><span class="nu0">.0</span><span class="nu0">.1</span> -p <span class="nu0">4730</span> -vvv</div>
</li>
</ol>
</div>
<p>If you have gearmand in your path and not in the same location as us, drop /usr/local/sbin :-) This will bind gearmand to your localhost and use the default port (earlier the default port was something other than 4730, so we provide it just in case).</p>
<h3>Making it all come together</h3>
<p>The easiest way to play around with gearman is to simply open three terminal windows: one for gearmand with logging turned on, one for your worker and its output and the last window for a client sending a task request to gearmand (you can use the &#8216;gearman&#8217; binary for this, just be sure to include any data in an appropriate format). As you submit a task for a function that the worker has registered, you should see it pick it up and then start processing the task as soon as possible. After a while (depending on how you&#8217;ve implemented your worker and what function it performs) the result should appear in your client.</p>
<p>Our production setups usually use a web application (PHP or python/django) as the client in the above scenario. The functions are usually long running tasks, such as <a hef="http://www.gone.fm/">analysing GPS paths</a>, <a href="http://www.gamer.no/">encoding videos and downloading files</a> or internal web site analytics (where we just want to get things logged and not wait for the actual logging to complete). The web application submits a request to gearmand as soon as a file has been received, with a payload of the path to the file to be processed. The workers perform their function and then store the information back into the database or to disk, then usually call a web service to tell the web application that the work has been performed and any internal state can be updated to include (and show) the result of the task.</p>
<p>Message queues (such as Gearman) has become one of the core technologies behind many modern web applications (and non-web applications for that matter), so there&#8217;s really no reason to avoid at least playing around a bit with it and adding another possible tool to your future options.</p>
]]></content:encoded>
			<wfw:commentRss>http://e-mats.org/2011/08/a-gentle-introduction-to-gearman-and-its-concepts/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Creating / Generating a URL Friendly Snippet in Django</title>
		<link>http://e-mats.org/2011/03/creating-generating-a-url-friendly-snippet-in-django/</link>
		<comments>http://e-mats.org/2011/03/creating-generating-a-url-friendly-snippet-in-django/#comments</comments>
		<pubDate>Sat, 19 Mar 2011 12:15:11 +0000</pubDate>
		<dc:creator>Mats</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://e-mats.org/?p=866</guid>
		<description><![CDATA[When generating URLs that say something about the content it contains, you usually have the need to create url-friendly strings (such as &#8220;creating-generating-a-url-friendly-snippet-in-django&#8221; for this post). Earlier today I had the need build something like that in Django, but came up empty handed for a while &#8211; simply because I didn&#8217;t realize that they&#8217;re called [...]]]></description>
			<content:encoded><![CDATA[<p>When generating URLs that say something about the content it contains, you usually have the need to create url-friendly strings (such as &#8220;creating-generating-a-url-friendly-snippet-in-django&#8221; for this post). Earlier today I had the need build something like that in Django, but came up empty handed for a while &#8211; simply because I didn&#8217;t realize that they&#8217;re called slugs in the Django documentation (which in turn inherited it from the print paper world). That helped quite a bit, and here&#8217;s the things you need to know:</p>
<p>If you want your model to perform validation and automagically add a database index for the slug, put in a <a href="http://docs.djangoproject.com/en/1.2/ref/models/fields/#slugfield">SlugField</a> in your model. You could use a regular CharField, but this will not provide any validation of the field in the admin interface (and you&#8217;d have to add db_index yourself). This will however not populate the field with a value, but <a href="http://stackoverflow.com/questions/837828/how-to-use-a-slug-in-django">this stack overflow question</a> has a few pointers on how you could implement that. I&#8217;ll cite the interesting parts here:</p>
<div class="geshi no python">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">from</span> django.<span class="me1">template</span>.<span class="me1">defaultfilters</span> <span class="kw1">import</span> slugify</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">class</span> <span class="kw3">test</span><span class="br0">&#40;</span>models.<span class="me1">Model</span><span class="br0">&#41;</span>:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; q = models.<span class="me1">CharField</span><span class="br0">&#40;</span>max_length=<span class="nu0">30</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; s = models.<span class="me1">SlugField</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">def</span> save<span class="br0">&#40;</span><span class="kw2">self</span>, <span class="sy0">*</span>args, <span class="sy0">**</span>kwargs<span class="br0">&#41;</span>:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw2">self</span>.<span class="kw2">id</span>:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">s</span> = slugify<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">q</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">super</span><span class="br0">&#40;</span><span class="kw3">test</span>, <span class="kw2">self</span><span class="br0">&#41;</span>.<span class="me1">save</span><span class="br0">&#40;</span><span class="sy0">*</span>args, <span class="sy0">**</span>kwargs<span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>This will populate the slug field the first time the entry is saved, and will not update the slug value if the object itself is updated.</p>
<p>You can however also handle this yourself in the <code>get_absolute_url</code> of your object, if you don&#8217;t need to perform any lookups on the value (although you could still save it to avoid regenerating it later). This will also give you the current slug for the entry (again, if you only use it as a part of the URL and do not validate it in any way):</p>
<div class="geshi no python">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">from</span> django.<span class="me1">template</span>.<span class="me1">defaultfilters</span> <span class="kw1">import</span> slugify</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">def</span> <span class="kw3">test</span><span class="br0">&#40;</span>models.<span class="me1">Model</span><span class="br0">&#41;</span>:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; q = models.<span class="me1">CharField</span><span class="br0">&#40;</span>max_length=<span class="nu0">30</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @models.<span class="me1">permalink</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">def</span> get_absolute_url<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span><span class="st0">&#39;reviewerer.views.sites_detail&#39;</span>, <span class="br0">&#91;</span><span class="kw2">str</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="kw2">id</span><span class="br0">&#41;</span>, slugify<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">q</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>Hopefully that will help you solve your issue .. or at least search for the correct term next time :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://e-mats.org/2011/03/creating-generating-a-url-friendly-snippet-in-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parse a DSN string in Python</title>
		<link>http://e-mats.org/2011/01/parse-a-dsn-string-in-python/</link>
		<comments>http://e-mats.org/2011/01/parse-a-dsn-string-in-python/#comments</comments>
		<pubDate>Mon, 31 Jan 2011 11:46:12 +0000</pubDate>
		<dc:creator>Mats</dc:creator>
				<category><![CDATA[Hacks]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[dsn]]></category>
		<category><![CDATA[pdo]]></category>

		<guid isPermaLink="false">http://e-mats.org/?p=852</guid>
		<description><![CDATA[A simple hack to get the different parts of a DSN string (which are used in PDO in PHP): def parse_dsn&#40;dsn&#41;: &#160; &#160; m = re.search&#40;&#34;([a-zA-Z0-9]+):(.*)&#34;, dsn&#41; &#160; &#160; values = &#123;&#125; &#160; &#160; &#160; &#160; if &#40;m and m.group&#40;1&#41; and m.group&#40;2&#41;&#41;: &#160; &#160; &#160; &#160; values&#91;&#39;driver&#39;&#93; = m.group&#40;1&#41; &#160; &#160; &#160; &#160; m_options = [...]]]></description>
			<content:encoded><![CDATA[<p>A simple hack to get the different parts of a DSN string (which are used in PDO in PHP):</p>
<div class="geshi no python">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">def</span> parse_dsn<span class="br0">&#40;</span>dsn<span class="br0">&#41;</span>:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; m = <span class="kw3">re</span>.<span class="me1">search</span><span class="br0">&#40;</span><span class="st0">&quot;([a-zA-Z0-9]+):(.*)&quot;</span>, dsn<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; values = <span class="br0">&#123;</span><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>m <span class="kw1">and</span> m.<span class="me1">group</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span> <span class="kw1">and</span> m.<span class="me1">group</span><span class="br0">&#40;</span><span class="nu0">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span>:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; values<span class="br0">&#91;</span><span class="st0">&#39;driver&#39;</span><span class="br0">&#93;</span> = m.<span class="me1">group</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; m_options = <span class="kw3">re</span>.<span class="me1">findall</span><span class="br0">&#40;</span><span class="st0">&quot;([a-zA-Z0-9]+)=([a-zA-Z0-9]+)&quot;</span>, m.<span class="me1">group</span><span class="br0">&#40;</span><span class="nu0">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> pair <span class="kw1">in</span> m_options:</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; values<span class="br0">&#91;</span>pair<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#93;</span> = pair<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> values</div>
</li>
</ol>
</div>
<p>The returned dictionary contains one entry for each of the entries in the DSN.</p>
<p>Update: helge also submitted a simplified version of the above:</p>
<div class="geshi no python">
<ol>
<li class="li1">
<div class="de1">driver, rest = dsn.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&#39;:&#39;</span>, <span class="nu0">1</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">values = <span class="kw2">dict</span><span class="br0">&#40;</span><span class="kw3">re</span>.<span class="me1">findall</span><span class="br0">&#40;</span><span class="st0">&#39;(<span class="es0">\w</span>+)=(<span class="es0">\w</span>+)&#39;</span>, rest<span class="br0">&#41;</span>, driver=driver<span class="br0">&#41;</span></div>
</li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://e-mats.org/2011/01/parse-a-dsn-string-in-python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Introducing Mismi &#8211; Amazon Price Comparison for Norwegian Customers</title>
		<link>http://e-mats.org/2011/01/introducing-mismi-amazon-price-comparison-for-norwegian-customers/</link>
		<comments>http://e-mats.org/2011/01/introducing-mismi-amazon-price-comparison-for-norwegian-customers/#comments</comments>
		<pubDate>Mon, 10 Jan 2011 21:40:19 +0000</pubDate>
		<dc:creator>Mats</dc:creator>
				<category><![CDATA[Hacks]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[amazon.co.uk]]></category>
		<category><![CDATA[amazon.com]]></category>
		<category><![CDATA[billigste alternativ]]></category>
		<category><![CDATA[ehandel]]></category>
		<category><![CDATA[mismi]]></category>
		<category><![CDATA[zf]]></category>

		<guid isPermaLink="false">http://e-mats.org/?p=831</guid>
		<description><![CDATA[My main project in December was Mismi &#8211; a service that compares the total price of items from Amazon.com and from Amazon.co.uk for Norwegians. The solution is built on top of the Zend_Service_Amazon class (with a few extensions of my own). The reasoning behind making the service is that there are several factors that are [...]]]></description>
			<content:encoded><![CDATA[<p>My main project in December was <a href="http://mismi.e-mats.org" title="Finn ut hva som er billigst - Amazon.com eller Amazon.co.uk">Mismi</a> &#8211; a service that compares the total price of items from Amazon.com and from Amazon.co.uk for Norwegians. The solution is built on top of the Zend_Service_Amazon class (with a few extensions of my own).</p>
<p>The reasoning behind making the service is that there are several factors that are in play when deciding whether to order a product from the US or from the UK: the exchange rate for GBP and USD, the shipping cost, the delivery situation for the item and whether the item is sold in the store at all. </p>
<p>The user enters a list of the URLs to the products they&#8217;re considering purchasing from an Amazon-store, press submit and get a list back of which items are in stock, where the item is the cheapest and what the total sum of an order placed at the store would be. In addition I added a alpha stage feature just before Christmas which will also tell you the &#8220;optimum&#8221; set of items for the orders &#8211; &#8220;order item 1,4,7,9 from .com, item 2,3,5,6,8 from .co.uk&#8221;. This took quite a bit of hacking &#8211; you also have to consider the initial price of shipping, shipping for each item and other fun things.</p>
<p>Feel free to play with it over at <a href="http://mismi.e-mats.org/" title="Billig og bra på Amazon.com og Amazon.co.uk">mismi.e-mats.org</a>. It&#8217;s in Norwegian, but it should be easy to understand anyhow with the description above.</p>
]]></content:encoded>
			<wfw:commentRss>http://e-mats.org/2011/01/introducing-mismi-amazon-price-comparison-for-norwegian-customers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mod_jk and Internal Server Error (HTTP 500)</title>
		<link>http://e-mats.org/2011/01/mod_jk-and-internal-server-error-http-500/</link>
		<comments>http://e-mats.org/2011/01/mod_jk-and-internal-server-error-http-500/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 12:26:11 +0000</pubDate>
		<dc:creator>Mats</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Solr]]></category>
		<category><![CDATA[jk]]></category>
		<category><![CDATA[loadbalancing]]></category>
		<category><![CDATA[mod_jk]]></category>

		<guid isPermaLink="false">http://e-mats.org/?p=823</guid>
		<description><![CDATA[We&#8217;ve extended our previously single Solr-node to a few nodes in a cluster. This allows us to run queries against one node while updating or configuring another, distributing the load across several servers (although we&#8217;re not there yet load wise) and being able to handle any out of memory or other critical errors. While Solr [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve extended our previously single Solr-node to a few nodes in a cluster. This allows us to run queries against one node while updating or configuring another, distributing the load across several servers (although we&#8217;re not there yet load wise) and being able to handle any out of memory or other critical errors.</p>
<p>While Solr supports querying several cores or distributing the queries internally, we decided to move the load balancing and handling of failed nodes higher up in the hierarchy. We&#8217;re now doing simple load balancing and handling of failed nodes by using <strong>mod_jk</strong> in our existing Apache-based environment. mod_jk also handles failed servers without any administrator interaction. We were already using mod_jk for our main web frontend, and since we use Tomcat as our application container for Solr, things should be a breeze!</p>
<p>Well, no. After copying our existing mod_jk setup, configuring our new workers and restarting Apache, all I got was the well known 500 INTERNAL SERVER ERROR. Here&#8217;s the worker configuration file:</p>
<pre>
worker.list=loadbalancer,status

worker.solr1.port=8009
worker.solr1.host=10.0.0.4
worker.solr1.type=ajp13
worker.solr1.lbfactor=1
worker.solr1.cachesize=10

worker.solr2.port=8009
worker.solr2.host=10.0.0.5
worker.solr2.type=ajp13
worker.solr2.lbfactor=4
worker.solr2.cachesize=10

worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=solr1,solr2
worker.loadbalancer.sticky_session=0

worker.status.type=status
</pre>
<p>This provides us with two solr servers and one status worker (the status worker is responsible for providing a simple web interface for enabling/disabling/seeing the status of the other workers), configured with a 1:4 load balancing (the second server has quite a bit more memory available for Solr).</p>
<p>I provided the configuration of the workers through the <strong>JkWorkersFile</strong> configuration setting (in a VirtualHost block&#8230; don&#8217;t do that):</p>
<pre>
JkWorkersFile conf/workers.properties
</pre>
<p>I&#8217;d also enable debug logging to attempt to find the problem (still in a VirtualHost block):</p>
<pre>
JkLogFile logs/mod_jk.log
JkLogLevel debug
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
</pre>
<p>Other mod_jk settings (in the VirtualHost block) were:</p>
<pre>
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
JkRequestLogFormat "%w %V %T"
JkShmFile logs/jk.shm
JkMount /* loadbalancer

&lt;Location /jkstatus&gt;
	JkMount status
	Order deny,allow
        Deny from all
        Allow from 127.0.0.1
&lt;/Location&gt;
</pre>
<p>Still no solution. Peeking at the log files mod_jk provided, I were able to deduce the following:</p>
<pre>
[debug] map_uri_to_worker::jk_uri_worker_map.c (525): Attempting to map context URI '/jkstatus'
[debug] map_uri_to_worker::jk_uri_worker_map.c (550): Found an exact match status -> /jkstatus
[debug] jk_handler::mod_jk.c (1920): Into handler jakarta-servlet worker=status r->proxyreq=0
[debug] wc_get_worker_for_name::jk_worker.c (111): did not find a worker status
[info]  jk_handler::mod_jk.c (2071): Could not find a worker for worker name=status
</pre>
<p>This indicates that mod_jk was unable to find a worker matching the name I provided in the JkMount statement above; <em>status</em>. Weird. I added some garbage characters to the &#8220;JkWorkersFile&#8221; setting, and Apache complained that it were unable to find the workers file. Changed it back, reloaded, and still nothing. It was apparently unable to find the worker. The map did however work, as it tried to launch a worker.</p>
<p>Looking back at the start up sequence of mod_jk, the following were found in the log:</p>
<pre>
[debug] build_worker_map::jk_worker.c (236): creating worker ajp13
[debug] wc_create_worker::jk_worker.c (141): about to create instance ajp13 of ajp13
[debug] wc_create_worker::jk_worker.c (154): about to validate and init ajp13
[debug] ajp_validate::jk_ajp_common.c (1922): worker ajp13 contact is 'localhost:8009'
[debug] ajp_init::jk_ajp_common.c (2047): setting endpoint options:
[debug] ajp_init::jk_ajp_common.c (2050): keepalive:        0
[debug] ajp_init::jk_ajp_common.c (2054): timeout:          -1
[debug] ajp_init::jk_ajp_common.c (2058): buffer size:      0
ajp_init::jk_ajp_common.c (2062): pool timeout:     0
[debug] ajp_init::jk_ajp_common.c (2066): connect timeout:  0
[debug] ajp_init::jk_ajp_common.c (2070): reply timeout:    0
[debug] ajp_init::jk_ajp_common.c (2074): prepost timeout:  0
[debug] ajp_init::jk_ajp_common.c (2078): recovery options: 0
[debug] ajp_init::jk_ajp_common.c (2082): retries:          2
[debug] ajp_init::jk_ajp_common.c (2086): max packet size:  8192
[debug] ajp_create_endpoint_cache::jk_ajp_common.c (1959): setting connection pool size to 1 with min 0
</pre>
<p>It took a bit of time, but I realized that this tells me that mod_jk created _a default_ worker named ajp13. Apparently it was not reading my worker file at all, but it still complained if I changed the file name. You&#8217;d think that the setting which loads the configuration file would work when it complains when it doesn&#8217;t. But .. well. After an hour of attempting to find out why the workers didn&#8217;t load, revising the workers file to a minimal example, trying with just a single status worker, I concluded that my workers file was correct, and obviously mod_jk found it when it attempted to load it.</p>
<p>Then I suddenly discovered the small notice in <a href="http://tomcat.apache.org/connectors-doc/reference/printer/apache.html">the mod_jk configuration manual</a>:</p>
<p><strong>JkWorkersFile: This directive is only allowed once. It must be put into the <em>global part</em> of the configuration.</strong></p>
<p>JkWorkersFile <strong>can not</strong> be defined in a &lt;VirtualHost&gt; section. It will NOT complain if you do it, it&#8217;ll just never define any workers. It <em>will</em> complain if the file doesn&#8217;t exist, even if it never tries to actually load it. </p>
<p>Confusing.</p>
<p><strong>Moving the JkWorkersFile statement out from the &lt;VirtualHost&gt; block and to the LoadModule statement instead solved the issue. This is also the case for <em>JkWorkerProperty</em></strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://e-mats.org/2011/01/mod_jk-and-internal-server-error-http-500/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Patch for Max Iterations for a foreach Block in Smarty</title>
		<link>http://e-mats.org/2010/08/patch-for-max-iterations-for-a-foreach-block-in-smarty/</link>
		<comments>http://e-mats.org/2010/08/patch-for-max-iterations-for-a-foreach-block-in-smarty/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 17:35:27 +0000</pubDate>
		<dc:creator>Mats</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://e-mats.org/?p=807</guid>
		<description><![CDATA[After running into a need for a max iteration count on a foreach block tonight and seeing that several others have had the need during the years, I&#8217;ve created a simple patch to add max= as an attribute to the foreach block. I tried to search the archives for a reason why this hadn&#8217;t already [...]]]></description>
			<content:encoded><![CDATA[<p>After running into a need for a max iteration count on a foreach block tonight and seeing that several others have had the need during the years, I&#8217;ve created a simple patch to add max= as an attribute to the foreach block. I tried to search the archives for a reason why this hadn&#8217;t already been included, so feel free to ignore this patch if there are proper reasons why this isn&#8217;t available as an argument. There are cases where a simple break in the loop is more efficient than making a copy with array_slice if you need the same data several places but in different slice sizes.</p>
<p>The patch also contains three tests to test the max attribute.</p>
<p>The patch is available here: <a href="http://e-mats.org/resources/smarty.foreach.max.patch">smarty.foreach.max.patch</a>. The patch is against the current SVN trunk of 2010-08-08.</p>
<p>Example:</p>
<p>{foreach item=x from=[0,1,2,3,4,5,6,7,8,9] max=5}{$x}{/foreach}</p>
<p>Output:</p>
<p>01234</p>
]]></content:encoded>
			<wfw:commentRss>http://e-mats.org/2010/08/patch-for-max-iterations-for-a-foreach-block-in-smarty/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unbreak My Hea.. Firefox Ctrl Click Please!</title>
		<link>http://e-mats.org/2010/03/unbreak-my-hea-firefox-ctrl-click-please/</link>
		<comments>http://e-mats.org/2010/03/unbreak-my-hea-firefox-ctrl-click-please/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 21:57:34 +0000</pubDate>
		<dc:creator>Mats</dc:creator>
				<category><![CDATA[Hacks]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[ctrl click]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[stoppropagation]]></category>

		<guid isPermaLink="false">http://e-mats.org/?p=765</guid>
		<description><![CDATA[When we launched Gamer.no over a year ago, we had to come up with a wallpaper advertising solution in a rush (everything were a rush back then as we built and launched a site from scratch (after disagreements between the previous owner and Gamer) in just under four days (or 96 hours)). While this solution [...]]]></description>
			<content:encoded><![CDATA[<p>When we launched Gamer.no over a year ago, we had to come up with a wallpaper advertising solution in a rush (everything were a rush back then as we built and launched a site from scratch (after disagreements between the previous owner and Gamer) in just under four days (or 96 hours)). While this solution has worked .. good enough .. it has always had a few irky bugs that I&#8217;ve never really had the right inspiration to uncover the cause of. Usually I&#8217;ve spent an hour and decided that the time wasn&#8217;t worth it at the moment and then moved onto something else, but today! Today is a glorious day! </p>
<p>The bug has been fixed!</p>
<p>The wallpaper element is placed around the main content div, which sadly also makes the wallpaper element receive any click elements that the main content div receives. This leads to the wallpaper getting clicked and the wallpaper ad window opening regardless of where people click &#8211; which will get very, very annoying very quick. So to battle this issue the original solution was to call <code>.stopPropagation()</code> on the evt object in a click handler for the main content div. This solved the issue and everyone rejoiced! However, all was not perfect in paradise.</p>
<p>Some time later we discovered that the .stopPropagation() fix borked ctrl-click a link in Firefox. Other browsers handled it just fine, but Firefox were obviously not happy. Not happy at all. Mad and going on a killing spree it shot down the proposed fixes from both myself and other people who had a brief look at the code. It wasn&#8217;t a big issue as we only run the wallpaper code for small intervals of time and people didn&#8217;t complain (maybe we were some of the few who had the issue).</p>
<p>Today I decided to have a look at the issue again, and finally I realized that we had been way to focused on our call to <code>.stopPropagation()</code>. Everyone had been planning how we could get .stopPropagation to do what we wanted it to do &#8211; after all &#8211; the issue was that stopPropagation didn&#8217;t behave when we ctrl-clicked in Firefox. But wait.</p>
<p>If you instead think of the original problem; the window.open gets triggered when people click the inner element instead of the outer, there may be alternative solutions to using stopPropagation. And yes, THAT was quite a simple fix. Instead of trying to stop the event from bubling up through the cloud.. let&#8217;s just set a status variable that tells the code handling the wallpaper click that THIS CLICK IS NOT FOR YOU BAD HANDLER GO AWAY LET OTHER GROWNUPS HANDLE THIS. So that I did.</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1">$<span class="br0">&#40;</span>document<span class="br0">&#41;</span>.<span class="me1">ready</span><span class="br0">&#40;</span><span class="kw2">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; innerClick = <span class="kw2">false</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&#39;#wallpaper&#39;</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>innerClick<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; innerClick = <span class="kw2">false</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">true</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; window.<span class="kw3">open</span><span class="br0">&#40;</span><span class="st0">&quot;..&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&#39;#content&#39;</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span>evt<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; innerClick = <span class="kw2">true</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>As soon as I actually spent some time on what we were trying to solve instead of what seemed like the cause of the issue .. everything went better than expected.</p>
]]></content:encoded>
			<wfw:commentRss>http://e-mats.org/2010/03/unbreak-my-hea-firefox-ctrl-click-please/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Fixing Issue With PHPs SoapClient Overwriting Duplicate Attribute and Tag Names</title>
		<link>http://e-mats.org/2010/02/fixing-issue-with-phps-soapclient-overwriting-duplicate-attribute-and-tag-names/</link>
		<comments>http://e-mats.org/2010/02/fixing-issue-with-phps-soapclient-overwriting-duplicate-attribute-and-tag-names/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 13:48:59 +0000</pubDate>
		<dc:creator>Mats</dc:creator>
				<category><![CDATA[Hacks]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[preg_replace]]></category>
		<category><![CDATA[soap]]></category>
		<category><![CDATA[soapclient]]></category>
		<category><![CDATA[subclassing]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://e-mats.org/?p=750</guid>
		<description><![CDATA[The setting: An SOAP request contains an Id attribute &#8211; and an element with the exact name in the response (directly beneath the element containing the attribute &#8211; an immediate child): &#60;res z:Id=&#34;i123&#34;&#62; &#160; &#60;Id&#62;foobar&#60;/Id&#62; &#60;/res&#62; The problem is that the generated result object from the SoapClient (at least of PHP 5.2.12) contains the attribute [...]]]></description>
			<content:encoded><![CDATA[<p>The setting:</p>
<p>An SOAP request contains an Id attribute &#8211; and an element with the exact name in the response (directly beneath the element containing the attribute &#8211; an immediate child):</p>
<div class="geshi no xml">
<ol>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;res</span> <span class="re0">z:Id</span>=<span class="st0">&quot;i123&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;Id<span class="re2">&gt;</span></span></span>foobar<span class="sc3"><span class="re1">&lt;/Id<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;/res<span class="re2">&gt;</span></span></span></div>
</li>
</ol>
</div>
<p>The problem is that the generated result object from the SoapClient (at least of PHP 5.2.12) contains the attribute value, and not the element value. In our case we could ignore the z:Id attribute, as it was simply an Id to identify the element in the response (this might be something that ASP.NET or some other .NET component does).</p>
<p>Our solution is to subclass the internal SoapClient and handle the <em>__doRequest</em> method, stripping out the part of the request that gives the wrong value for the Id field:</p>
<div class="geshi no php">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">class</span> Provider_SoapClient <span class="kw2">extends</span> SoapClient</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> __doRequest<span class="br0">&#40;</span><span class="re1">$request</span><span class="sy0">,</span> <span class="re1">$location</span><span class="sy0">,</span> <span class="re1">$action</span><span class="sy0">,</span> <span class="re1">$version</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$result</span> <span class="sy0">=</span> parent<span class="sy0">::</span>__doRequest<span class="br0">&#40;</span><span class="re1">$request</span><span class="sy0">,</span> <span class="re1">$location</span><span class="sy0">,</span> <span class="re1">$action</span><span class="sy0">,</span> <span class="re1">$version</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$result</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st0">&#39;/ z:Id=&quot;i[0-9]+&quot;/&#39;</span><span class="sy0">,</span> <span class="st0">&#39;&#39;</span><span class="sy0">,</span> <span class="re1">$result</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re1">$result</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>This removes the attribute from all the values (there is no danger that the string will be present in any other of the elements. If there is &#8211; be sure to adjust the regular expression). And voilá, it works!</p>
]]></content:encoded>
			<wfw:commentRss>http://e-mats.org/2010/02/fixing-issue-with-phps-soapclient-overwriting-duplicate-attribute-and-tag-names/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Avoid Escaping Spaces in the Query String in a Solr Query</title>
		<link>http://e-mats.org/2010/01/avoid-escaping-spaces-in-the-query-string-in-a-solr-query/</link>
		<comments>http://e-mats.org/2010/01/avoid-escaping-spaces-in-the-query-string-in-a-solr-query/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 22:24:14 +0000</pubDate>
		<dc:creator>Mats</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Solr]]></category>
		<category><![CDATA[escaping]]></category>
		<category><![CDATA[query string]]></category>
		<category><![CDATA[spaces]]></category>

		<guid isPermaLink="false">http://e-mats.org/?p=744</guid>
		<description><![CDATA[Following up on the previous post about escaping values in a Solr query string, it&#8217;s important to note that you should not escape spaces in the query itself. The reason for this is that if you escape spaces in the query &#8220;foo bar&#8221;, the search will be performed on the term &#8220;foo bar&#8221; itself, and [...]]]></description>
			<content:encoded><![CDATA[<p>Following up on <a href="http://e-mats.org/2010/01/escaping-characters-in-a-solr-query-solr-url/">the previous post about escaping values in a Solr query string</a>, it&#8217;s important to note that you should not escape spaces in the query itself. The reason for this is that if you escape spaces in the query &#8220;foo bar&#8221;, the search will be performed on the term &#8220;foo bar&#8221; itself, and not with &#8220;foo&#8221; as one term and &#8220;bar&#8221; as the other. This will only return documents that has the string &#8220;foo bar&#8221; in sequence.</p>
<p>The solution is to either remove the space from the escape list in the previous function &#8211; and use another function for escaping values where you actually should escape the spaces &#8211; or break up the string into &#8220;escapable&#8221; parts.</p>
<p>The code included beneath performs the last task; it splits the string into different parts delimited by space and then escapes each part of the query by itself.</p>
<div class="geshi no php">
<ol>
<li class="li1">
<div class="de1"><span class="re1">$queryParts</span> <span class="sy0">=</span> <span class="kw3">explode</span><span class="br0">&#40;</span><span class="st0">&#39; &#39;</span><span class="sy0">,</span> <span class="re1">$this</span><span class="sy0">-&gt;</span><span class="me1">getQuery</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$queryEscaped</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re1">$queryParts</span> <span class="kw1">as</span> <span class="re1">$queryPart</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$queryEscaped</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">=</span> self<span class="sy0">::</span><span class="me2">escapeSolrValue</span><span class="br0">&#40;</span><span class="re1">$queryPart</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re1">$queryEscaped</span> <span class="sy0">=</span> <span class="kw3">join</span><span class="br0">&#40;</span><span class="st0">&#39; &#39;</span><span class="sy0">,</span> <span class="re1">$queryEscaped</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://e-mats.org/2010/01/avoid-escaping-spaces-in-the-query-string-in-a-solr-query/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Simple Smarty Modifier to Generate a Chart Through Google Chart API</title>
		<link>http://e-mats.org/2010/01/a-simple-smarty-modifier-to-generate-a-chart-through-google-chart-api/</link>
		<comments>http://e-mats.org/2010/01/a-simple-smarty-modifier-to-generate-a-chart-through-google-chart-api/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 22:48:55 +0000</pubDate>
		<dc:creator>Mats</dc:creator>
				<category><![CDATA[Hacks]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[charts]]></category>
		<category><![CDATA[google chart]]></category>
		<category><![CDATA[google chart api]]></category>
		<category><![CDATA[smarty]]></category>

		<guid isPermaLink="false">http://e-mats.org/?p=739</guid>
		<description><![CDATA[After the longest title of my blog so far follows one of the shortest posts. The function has two required parameters &#8211; the first one is provided automagically for you by smarty (it&#8217;s the value of the variable you&#8217;re applying the modifier to). This should be an array of objects containing the value you want [...]]]></description>
			<content:encoded><![CDATA[<p>After the longest title of my blog so far follows one of the shortest posts.</p>
<p>The function has two required parameters &#8211; the first one is provided automagically for you by smarty (it&#8217;s the value of the variable you&#8217;re applying the modifier to). This should be an array of objects containing the value you want to graph. The only required argument you have to provide to the modifier is the method to use for fetching the values for graphing. </p>
<p>Usage:<br />
{$objects|googlechart:&#8221;getValue&#8221;}</p>
<p>This will dynamically load your plugin from the file modifier.googlechart.php in your Smarty plugins directory, or you can register the plugin manually by calling register_modifier on the template object after you&#8217;ve created it.</p>
<div class="geshi no php">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">function</span> smarty_modifier_googlechart<span class="br0">&#40;</span><span class="re1">$points</span><span class="sy0">,</span> <span class="re1">$method</span><span class="sy0">,</span> <span class="re1">$size</span> <span class="sy0">=</span> <span class="st0">&quot;600&#215;200&quot;</span><span class="sy0">,</span> <span class="re1">$low</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="re1">$high</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$pointStr</span> <span class="sy0">=</span> <span class="st0">&#39;&#39;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$maxValue</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$minValue</span> <span class="sy0">=</span> INT_MAX<span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re1">$points</span> <span class="kw1">as</span> <span class="re1">$point</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re1">$point</span><span class="sy0">-&gt;</span><span class="re1">$method</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">&gt;</span> <span class="re1">$maxValue</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$maxValue</span> <span class="sy0">=</span> <span class="re1">$point</span><span class="sy0">-&gt;</span><span class="re1">$method</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re1">$point</span><span class="sy0">-&gt;</span><span class="re1">$method</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">&lt;</span> <span class="re1">$minValue</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$minValue</span> <span class="sy0">=</span> <span class="re1">$point</span><span class="sy0">-&gt;</span><span class="re1">$method</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="kw3">empty</span><span class="br0">&#40;</span><span class="re1">$high</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$maxValue</span> <span class="sy0">=</span> <span class="re1">$high</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$scale</span> <span class="sy0">=</span> <span class="nu0">100</span> <span class="sy0">/</span> <span class="re1">$maxValue</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">foreach</span><span class="br0">&#40;</span><span class="re1">$points</span> <span class="kw1">as</span> <span class="re1">$point</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$pointStr</span> <span class="sy0">.=</span> <span class="br0">&#40;</span>int<span class="br0">&#41;</span> <span class="br0">&#40;</span><span class="re1">$point</span><span class="sy0">-&gt;</span><span class="re1">$method</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">*</span> <span class="re1">$scale</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st0">&#39;,&#39;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$pointStr</span> <span class="sy0">=</span> <span class="kw3">substr</span><span class="br0">&#40;</span><span class="re1">$pointStr</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="nu0">-1</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// labels (5)</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$labels</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$steps</span> <span class="sy0">=</span> <span class="nu0">4</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$interval</span> <span class="sy0">=</span> <span class="re1">$maxValue</span> <span class="sy0">/</span> <span class="re1">$steps</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">for</span><span class="br0">&#40;</span><span class="re1">$i</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> <span class="re1">$i</span> <span class="sy0">&lt;</span> <span class="re1">$steps</span><span class="sy0">;</span> <span class="re1">$i</span><span class="sy0">++</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">$labels</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="br0">&#40;</span>int<span class="br0">&#41;</span> <span class="br0">&#40;</span><span class="re1">$i</span> <span class="sy0">*</span> <span class="re1">$interval</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$labels</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="br0">&#40;</span>int<span class="br0">&#41;</span> <span class="re1">$maxValue</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">&#39;http://chart.apis.google.com/chart?cht=lc&amp;amp;chd=t:&#39;</span> <span class="sy0">.</span> <span class="re1">$pointStr</span> <span class="sy0">.</span> <span class="st0">&#39;&amp;amp;chs=&#39;</span> <span class="sy0">.</span> <span class="re1">$size</span> <span class="sy0">.</span> <span class="st0">&#39;&amp;amp;chxt=y&amp;amp;chxl=0:|&#39;</span> <span class="sy0">.</span> <span class="kw3">join</span><span class="br0">&#40;</span><span class="st0">&#39;|&#39;</span><span class="sy0">,</span> <span class="re1">$labels</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>The function does not support the short version of the Google Chart API Just Yet &#8482; as it is an simple proof of concept hack made a few months ago.</p>
]]></content:encoded>
			<wfw:commentRss>http://e-mats.org/2010/01/a-simple-smarty-modifier-to-generate-a-chart-through-google-chart-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

