<?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>Query7 &#187; Tutorials</title>
	<atom:link href="http://query7.com/category/tutorials/feed" rel="self" type="application/rss+xml" />
	<link>http://query7.com</link>
	<description>PHP, Javascript, Python and Web Development</description>
	<lastBuildDate>Sat, 25 Jun 2011 21:29:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Kohana 3.1 Wiki Tutorial Routes</title>
		<link>http://query7.com/kohana-3-1-wiki-tutorial-routes</link>
		<comments>http://query7.com/kohana-3-1-wiki-tutorial-routes#comments</comments>
		<pubDate>Mon, 16 May 2011 07:39:43 +0000</pubDate>
		<dc:creator>logan</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[kohana]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://query7.com/?p=1655</guid>
		<description><![CDATA[<p>In the original <a href="http://query7.com/kohana-3-1-wiki-tutorial">Kohana wiki application</a> the URLs in the views were hardcoded. If we wanted to change the domain name or restructure a route we would need to go through the application and change every single URL.</p>
<p>Thankfully the Kohana <em>Route</em> class comes with a method <em>url()</em> which allows us to generate URLs to routes we have specified in the application. In the first <a href="http://query7.com/kohana-3-1-wiki-tutorial">tutorial</a> we defined the following routes in <strong>application/bootstrap.php</strong>:</p>
<pre>Route::set('wiki-edit', 'wiki/&#60;page&#62;/edit')
	-&#62;defaults(array(
		'controller'=> 'wiki',
		'action'	=> 'edit_page',
	));

Route::set('wiki-save', 'wiki/&#60;page&#62;/save')
	-&#62;defaults(array(
		'controller'=> 'wiki',
		'action'	=> 'save_page',
	));

Route::set('wiki-page', 'wiki/&#60;page&#62;')
	-&#62;defaults(array(
		'controller'=> 'wiki',
		'action'	=> 'view_page',
	));

Route::set('default', 'wiki')
	-&#62;defaults(array(
		'controller' => 'wiki',
		'action'     => 'view_page',
		'id'		 => 'index',
	));
</pre>
<p>Before we can generate routes we need to set some configuration options in <strong>application/bootstrap.php</strong> (line ~82). We need to specify the <em>base_url</em> and <em>index_file</em> attributes in the array passed to <em>Kohana::init()</em>. The application on my local install is located at 127.0.0.1/query7kwiki/index.php, so my <em>Kohana::init()</em> statement would read:</p>
<pre>Kohana::init(array(
	'base_url'   =&#62; '/query7kwiki/',
	'index_file' =&#62; 'index.php'
));</pre>
<p>In <strong>application/views/edit.php</strong> the form <em>action</em> attribute was hardcoded to the value <em>/query7kwiki/index.php/wiki/</em>. That can be replaced by:</p>
<pre>&#60;?php echo Route::url('wiki-save', array('page' =&#62; $page)); ?&#62;</pre>
<p>In <strong>application/views/single.php</strong> there is a&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>In the original <a href="http://query7.com/kohana-3-1-wiki-tutorial">Kohana wiki application</a> the URLs in the views were hardcoded. If we wanted to change the domain name or restructure a route we would need to go through the application and change every single URL.</p>
<p>Thankfully the Kohana <em>Route</em> class comes with a method <em>url()</em> which allows us to generate URLs to routes we have specified in the application. In the first <a href="http://query7.com/kohana-3-1-wiki-tutorial">tutorial</a> we defined the following routes in <strong>application/bootstrap.php</strong>:</p>
<pre>Route::set('wiki-edit', 'wiki/&lt;page&gt;/edit')
	-&gt;defaults(array(
		'controller'=> 'wiki',
		'action'	=> 'edit_page',
	));

Route::set('wiki-save', 'wiki/&lt;page&gt;/save')
	-&gt;defaults(array(
		'controller'=> 'wiki',
		'action'	=> 'save_page',
	));

Route::set('wiki-page', 'wiki/&lt;page&gt;')
	-&gt;defaults(array(
		'controller'=> 'wiki',
		'action'	=> 'view_page',
	));

Route::set('default', 'wiki')
	-&gt;defaults(array(
		'controller' => 'wiki',
		'action'     => 'view_page',
		'id'		 => 'index',
	));
</pre>
<p>Before we can generate routes we need to set some configuration options in <strong>application/bootstrap.php</strong> (line ~82). We need to specify the <em>base_url</em> and <em>index_file</em> attributes in the array passed to <em>Kohana::init()</em>. The application on my local install is located at 127.0.0.1/query7kwiki/index.php, so my <em>Kohana::init()</em> statement would read:</p>
<pre>Kohana::init(array(
	'base_url'   =&gt; '/query7kwiki/',
	'index_file' =&gt; 'index.php'
));</pre>
<p>In <strong>application/views/edit.php</strong> the form <em>action</em> attribute was hardcoded to the value <em>/query7kwiki/index.php/wiki/</em>. That can be replaced by:</p>
<pre>&lt;?php echo Route::url('wiki-save', array('page' =&gt; $page)); ?&gt;</pre>
<p>In <strong>application/views/single.php</strong> there is a link to the edit that specific page. We can replace the <em>href</em> of the anchor tag with:</p>
<pre>&lt;?php echo Route::url('wiki-edit', array('page' =&gt; $page)); ?&gt;</pre>
<p>In the view <strong>application/views/create.php</strong> change the <em>href</em> of the create page link to:</p>
<pre>&lt;?php echo Route::url('wiki-edit', array('page' =&gt; $page)); ?&gt;</pre>
<p>The wiki application is now portable and can safely be moved to a different server without functionality breaking.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/kohana-3-1-wiki-tutorial-routes/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Kohana 3.1 Wiki Tutorial</title>
		<link>http://query7.com/kohana-3-1-wiki-tutorial</link>
		<comments>http://query7.com/kohana-3-1-wiki-tutorial#comments</comments>
		<pubDate>Mon, 09 May 2011 06:09:52 +0000</pubDate>
		<dc:creator>logan</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[kohana]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://query7.com/?p=1632</guid>
		<description><![CDATA[<p>In this tutorial you will learn how to create a simple wiki using the PHP framework Kohana version 3.1. Several years ago Siddharta Govindaraj created a <a href="http://showmedo.com/videotutorials/video?name=1100000&#038;fromSeriesID=110">screencast</a> demonstrating how to create a wiki using Django, this is essentially the Kohana version of that. It covers using Kohana&#8217;s Routing, ORM and MVC systems. Full source code of the application is available on <a href="https://github.com/lastkarrde/query7kwiki">github</a>.</p>
<p>The wiki application has 3 different pages: </p>
<ul>
<li>/wiki/somepage/save &#8211; handles the saving of the page</li>
<li>/wiki/somepage/edit &#8211; displays a form that allows the user to edit the page</li>
<li>/wiki/somepage &#8211; displays the page</li>
</ul>
<h3>Configuration</h3>
<p>We will be using the ORM module to query the database for our wiki pages so we must load it in the <strong>application/bootstrap.php</strong> file (Line ~99).</p>
<pre>Kohana::modules(array(

	'database'   => MODPATH.'database',   // Database access
	'orm'        => MODPATH.'orm',        // Object Relationship Mapping

	));</pre>
<p>We also need to specify our database configuration settings. This is done in <strong>application/config/database.php</strong>.</p>
<pre>&#60;?php

return array
  (
  	'default' => array
  	(
  		'type'       => 'mysql',
  		'connection' => array(
  			'hostname'   => '127.0.0.1',
  			'username'   => 'root',
  			'password'   => 'root',
  			'persistent' => FALSE,
  			'database'   => 'query7kwiki',
  		),
  		'table_prefix' => '',
  		'charset'      => 'utf8',
  		'caching'      => FALSE,
  		'profiling'    => TRUE,
  	),
  );</pre><p>&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>In this tutorial you will learn how to create a simple wiki using the PHP framework Kohana version 3.1. Several years ago Siddharta Govindaraj created a <a href="http://showmedo.com/videotutorials/video?name=1100000&#038;fromSeriesID=110">screencast</a> demonstrating how to create a wiki using Django, this is essentially the Kohana version of that. It covers using Kohana&#8217;s Routing, ORM and MVC systems. Full source code of the application is available on <a href="https://github.com/lastkarrde/query7kwiki">github</a>.</p>
<p>The wiki application has 3 different pages: </p>
<ul>
<li>/wiki/somepage/save &#8211; handles the saving of the page</li>
<li>/wiki/somepage/edit &#8211; displays a form that allows the user to edit the page</li>
<li>/wiki/somepage &#8211; displays the page</li>
</ul>
<h3>Configuration</h3>
<p>We will be using the ORM module to query the database for our wiki pages so we must load it in the <strong>application/bootstrap.php</strong> file (Line ~99).</p>
<pre>Kohana::modules(array(

	'database'   => MODPATH.'database',   // Database access
	'orm'        => MODPATH.'orm',        // Object Relationship Mapping

	));</pre>
<p>We also need to specify our database configuration settings. This is done in <strong>application/config/database.php</strong>.</p>
<pre>&lt;?php

return array
  (
  	'default' => array
  	(
  		'type'       => 'mysql',
  		'connection' => array(
  			'hostname'   => '127.0.0.1',
  			'username'   => 'root',
  			'password'   => 'root',
  			'persistent' => FALSE,
  			'database'   => 'query7kwiki',
  		),
  		'table_prefix' => '',
  		'charset'      => 'utf8',
  		'caching'      => FALSE,
  		'profiling'    => TRUE,
  	),
  );

  ?&gt;</pre>
<h3>Model</h3>
<p>Compared to most ORMs (Django, Doctrine, Propel), Kohana&#8217;s ORM is relatively light. You don&#8217;t need to specify the fields of your table as the Kohana ORM doesn&#8217;t attempt to generate the tables for you. It simply maps attribute names of the model object to field names in the database table. Be sure to check the <a href="http://kohanaframework.org/3.1/guide/">Kohana Documentation</a> for a detailed explanation of the ORM.</p>
<p><strong>application/classes/model/page.php</strong></p>
<pre>class Model_Page extends ORM
{

	protected $_table_name = 'page';

	public function rules()
	{
		return array(

			'title' => array(
						array('not_empty')
							)

		);
	}

}</pre>
<p>Execute the following SQL:</p>
<pre>CREATE TABLE `page` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`title` VARCHAR( 255 ) NOT NULL ,
`content` TEXT NOT NULL
) ENGINE = MYISAM ;</pre>
<h3>Routing</h3>
<p>I define all routes at the bottom of <strong>application/bootstrap.php</strong>, however if you are working on a large application it may beneficial in the long run to define them in a separate file and then include them into the bootstrap file.</p>
<p><em>Route::set()</em> accepts 2 parameters. The first is the name of the route and the second is the URI pattern it should match. Because <em>Route::set()</em> returns an instance of <em>Kohana_Route</em>, we can chain the <em>defaults</em> method onto it. There we specify the controller and action that should be executed if the route is matched. </p>
<p>The <em>&lt;page&gt;</em> section of the URI pattern is captured from the URI and automatically passed to the controller method as an argument.</p>
<pre>Route::set('wiki-edit', 'wiki/&lt;page&gt;/edit')
	-&gt;defaults(array(
		'controller'=> 'wiki',
		'action'	=> 'edit_page',
	));

Route::set('wiki-save', 'wiki/&lt;page&gt;/save')
	-&gt;defaults(array(
		'controller'=> 'wiki',
		'action'	=> 'save_page',
	));

Route::set('wiki-page', 'wiki/&lt;page&gt;')
	-&gt;defaults(array(
		'controller'=> 'wiki',
		'action'	=> 'view_page',
	));

Route::set('default', 'wiki')
	-&gt;defaults(array(
		'controller' => 'wiki',
		'action'     => 'view_page',
		'id'		 => 'index',
	));
</pre>
<h3>Views</h3>
<p><strong><a href="http://query7.com/kohana-3-1-wiki-tutorial-routes">Read this tutorial on generating domain-independent, non hardcoded URLs</a></strong></p>
<p><strong>application/views/single.php</strong></p>
<pre>&lt;html&gt;
	&lt;head&gt;
		&lt;title&gt;&lt;?php echo $page; ?&gt;&lt;/title&gt;
	&lt;/head&gt;

	&lt;body&gt;

		&lt;h1&gt;&lt;?php echo $page; ?&gt;&lt;/h1&gt;
		&lt;p&gt;
			&lt;?php echo $content; ?&gt;
		&lt;/p&gt;
		&lt;hr&gt;
		&lt;p&gt;
			&lt;a href=&quot;/query7kwiki/index.php/wiki/&lt;?php echo $page; ?&gt;/edit&quot;&gt;Edit&lt;/a&gt;
		&lt;/p&gt;
	&lt;/body&gt;
&lt;/html&gt;</pre>
<p><strong>application/views/create.php</strong></p>
<pre>&lt;html&gt;
	&lt;head&gt;
		&lt;title&gt;&lt;?php echo $page; ?&gt; - Create&lt;/title&gt;
	&lt;/head&gt;

	&lt;body&gt;

		&lt;h1&gt;&lt;?php echo $page; ?&gt;&lt;/h1&gt;
		&lt;p&gt;This page does not exist. &lt;a href=&quot;/query7kwiki/index.php/wiki/&lt;?php echo $page; ?&gt;/edit/&quot;&gt;Create?&lt;/a&gt;&lt;/p&gt;

	&lt;/body&gt;
&lt;/html&gt;</pre>
<p><strong>application/views/edit.php</strong></p>
<pre>&lt;html&gt;
	&lt;head&gt;
		&lt;title&gt;&lt;?php echo $page; ?&gt; - Edit&lt;/title&gt;
	&lt;/head&gt;

	&lt;body&gt;

		&lt;h1&gt;&lt;?php echo $page; ?&gt; - Edit&lt;/h1&gt;
		&lt;p&gt;
			&lt;form method=&quot;POST&quot; action=&quot;/query7kwiki/index.php/wiki/&lt;?php echo $page; ?&gt;/save/&quot;&quot;&gt;

				&lt;textarea rows=&quot;10&quot; cols=&quot;60&quot; name=&quot;content&quot;&gt;&lt;?php echo $content; ?&gt;&lt;/textarea&gt;
				&lt;br /&gt;
				&lt;input type=&quot;submit&quot; value=&quot;Edit Page&quot; name=&quot;submit&quot;&gt;
			&lt;/form&gt;
		&lt;/p&gt;
	&lt;/body&gt;
&lt;/html&gt;</pre>
<h3>Controller</h3>
<p>The wiki only has one controller, <em>Controller_Wiki</em>, located in <strong>application/classes/controller/wiki.php</strong>. All of the methods accept one parameter, the name of the page which is automatically passed by the URL Router.</p>
<p>The <em>action_view_page()</em> method will display the wiki page if it exists or a &#8216;create&#8217; page if it does not exist. <em>$single-&gt;loaded()</em> will return true if the ORM returned a result, so if the page exists we load the &#8216;single&#8217; view and attach the appropriate variables to the view, if it does not exist then we load the &#8216;create&#8217; view.</p>
<pre>public function action_view_page($page)
{

	$single = ORM::factory('page')
			-&gt;where('title', '=', $page)
			-&gt;find();

	if($single->loaded())
	{
		$v = View::factory('single');
		$v-&gt;page = $page;
		$v-&gt;content = $single-&gt;content;
				}
	else
	{
		$v = View::factory('create');
		$v-&gt;page = $page;
	}

	$this-&gt;response-&gt;body($v);

}</pre>
<p><em>action_edit_page()</em> returns the &#8216;edit&#8217; page with the correct <em>content</em> field.</p>
<pre>public function action_edit_page($page)
{
	$single = ORM::factory('page')
			-&gt;where('title', '=', $page)
			-&gt;find();

	if($single-&gt;loaded())
	{
		$content = $single-&gt;content;
	}
	else
	{
		$content = '';
	}

	$v = View::factory('edit');
	$v-&gt;page = $page;
	$v-&gt;content = $content;

	$this-&gt;response-&gt;body($v);
}</pre>
<p><em>action_save_page()</em> handles saving the page after the user submits the edit form. It first checks to see if the page exists. If it does exist then we update the <em>content</em> attribute of the model with whatever was posted in the form. If it doesn&#8217;t exist then we make a new page by instantiating a new model, assigning the <em>title</em> and <em>content</em> attributes and saving it.</p>
<pre>public function action_save_page($page)
{
	$single = ORM::factory('page')
			-&gt;where('title', '=', $page)
			-&gt;find();

	$content = $this-&gt;request-&gt;post('content');

	if($single-&gt;loaded())
	{
		$single-&gt;content = $content;
		$single-&gt;save();
	}
	else
	{
		$new_single = new Model_Page();
		$new_single-&gt;title = $page;
		$new_single-&gt;content = $content;
		$new_single-&gt;save();
	}

	$this-&gt;request-&gt;redirect('http://127.0.0.1/query7kwiki/index.php/wiki/' . $page);

}</pre>
<p>Full source code of the application is available on <a href="https://github.com/lastkarrde/query7kwiki">Github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/kohana-3-1-wiki-tutorial/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tutorial Django Dojo DataGrid</title>
		<link>http://query7.com/tutorial-django-dojo-datagrid</link>
		<comments>http://query7.com/tutorial-django-dojo-datagrid#comments</comments>
		<pubDate>Mon, 18 Apr 2011 10:03:57 +0000</pubDate>
		<dc:creator>logan</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://query7.com/?p=1476</guid>
		<description><![CDATA[<p>Dojo is an open source Javascript toolkit. It provides an easy way to access and modify the DOM as well as a rich user interface widget library. One of the most powerful widgets in the Dojo toolkit is <a href="http://dojotoolkit.org/reference-guide/dojox/grid/DataGrid.html">DataGrid</a>. It provides an easy way to represent what is essentially a cross between a spreadsheet and a table. In a recent Django project I needed to output the contents of a model into the DataGrid. Thanks to <a href="http://code.google.com/p/django-dojoserializer/">django-dojoserializer</a> this is very easy.</p>
<h3>Setup</h3>
<p>We need the Python package <a href="http://code.google.com/p/django-dojoserializer/">django-dojoserializer</a>. This can be installed by downloading the source and running
<pre>python setup.py install</pre>
</p><p> or with setuptools using
<pre>easy_install django-dojoserializer</pre>
</p><p> or with pip using
<pre>pip install django-dojoserializer</pre>
</p><p> Then add <em>django-dojoserializer</em> to the <em>INSTALLED_APPS</em> tuple in <strong>settings.py</strong>.</p>
<p>Dojo will need to be linked correctly in the Django template. We need to require the <em>dojox.grid.DataGrid</em> and <em>dojo.data.ItemFileReadStore</em> classes.</p>
<pre>&#60;script src="/static/libs/dojo/dojo.js" djConfig="parseOnLoad: true"&#62;%lt;/script&#62;
&#60;script type="text/javascript"&#62;
dojo.require('dojox.grid.DataGrid');
dojo.require('dojo.data.ItemFileReadStore');
&#60;/script&#62;
</pre>
<h3>Django Model</h3>
<pre>PROXY_TYPE_CHOICES = (

	('SOCKS4', 'SOCKS4'),
	('SOCKS5', 'SOCKS5'),
	('HTTP', 'HTTP'),

)

class Proxy(models.Model):
	ip = models.CharField(max_length=50)
	type = models.CharField(max_length=6, choices=PROXY_TYPE_CHOICES)
	alive = models.BooleanField(default=False)
	added = models.DateTimeField(auto_now=False, auto_now_add=True)
	last_checked = models.DateTimeField(auto_now=True, auto_now_add=False)

	def __unicode__(self):
		return self.ip</pre>
<h3>Django View</h3>
<p>The view needs&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>Dojo is an open source Javascript toolkit. It provides an easy way to access and modify the DOM as well as a rich user interface widget library. One of the most powerful widgets in the Dojo toolkit is <a href="http://dojotoolkit.org/reference-guide/dojox/grid/DataGrid.html">DataGrid</a>. It provides an easy way to represent what is essentially a cross between a spreadsheet and a table. In a recent Django project I needed to output the contents of a model into the DataGrid. Thanks to <a href="http://code.google.com/p/django-dojoserializer/">django-dojoserializer</a> this is very easy.</p>
<h3>Setup</h3>
<p>We need the Python package <a href="http://code.google.com/p/django-dojoserializer/">django-dojoserializer</a>. This can be installed by downloading the source and running
<pre>python setup.py install</pre>
<p> or with setuptools using
<pre>easy_install django-dojoserializer</pre>
<p> or with pip using
<pre>pip install django-dojoserializer</pre>
<p> Then add <em>django-dojoserializer</em> to the <em>INSTALLED_APPS</em> tuple in <strong>settings.py</strong>.</p>
<p>Dojo will need to be linked correctly in the Django template. We need to require the <em>dojox.grid.DataGrid</em> and <em>dojo.data.ItemFileReadStore</em> classes.</p>
<pre>&lt;script src="/static/libs/dojo/dojo.js" djConfig="parseOnLoad: true"&gt;%lt;/script&gt;
&lt;script type="text/javascript"&gt;
dojo.require('dojox.grid.DataGrid');
dojo.require('dojo.data.ItemFileReadStore');
&lt;/script&gt;
</pre>
<h3>Django Model</h3>
<pre>PROXY_TYPE_CHOICES = (

	('SOCKS4', 'SOCKS4'),
	('SOCKS5', 'SOCKS5'),
	('HTTP', 'HTTP'),

)

class Proxy(models.Model):
	ip = models.CharField(max_length=50)
	type = models.CharField(max_length=6, choices=PROXY_TYPE_CHOICES)
	alive = models.BooleanField(default=False)
	added = models.DateTimeField(auto_now=False, auto_now_add=True)
	last_checked = models.DateTimeField(auto_now=True, auto_now_add=False)

	def __unicode__(self):
		return self.ip</pre>
<h3>Django View</h3>
<p>The view needs to display data from our model as JSON which is correctly formatted for the Dojo DataTable. Simply encoding the Django queryset as a JSON object would not work. Thankfully <me>django-dojoserializer</em> provides the <em>dojoserializer.serialize()</em> method which correctly formats our the queryset in a format the DataTable can read. The route <em>/render/proxies</em> maps to the following view:</p>
<pre>
from django.http import HttpResponse
from proxies.models import Proxy
from dojoserializer import serialize

def render_json(request):

	proxies = Proxy.objects.filter(alive=True)

	json_data = serialize(proxies)

	return HttpResponse(json_data, mimetype="application/json")
</pre>
<p>This gives the following output:</p>
<p><a href="http://query7.com/wp-content/uploads/json.png"><img src="http://query7.com/wp-content/uploads/json.png" alt="" title="json" width="540" height="274" class="aligncenter size-full wp-image-1482" /></a></p>
<h3>Defining the DataTable</h3>
<p>We define the Dojo DataTable in two parts. The first is a Javascript representation of the structure of the DataTable, the second part is a <em>&lt;div&gt;</em> for where the DataTable will sit in markup. Note that each <em>field</em> attribute is the exact name of the corresponding field from the Django model. If the names do match the data will not display in the table.</p>
<pre>var layoutProxies = [
            [{
                field: "ip",
                name: "IP",
                width: 'auto'
            },
            {
                field: "type",
                name: "Type",
                width: 'auto'
            },
            {
                field: "last_checked",
                name: "Last Checked",
                width: 10
            },
            {
                field: "alive",
                name: "Alive",
                width: 'auto'
            }

            ]];</pre>
<p>Note the structure attribute of the <em>div</em> is set to the value of our structure. We will define <em>proxyStore</em>, the value of the <em>store</em> attribute below.</p>
<pre>
&lt;div id="proxyGrid" dojoType="dojox.grid.DataGrid" store="proxyStore" structure="layoutProxies" query="{}" rowsPerPage="40"&gt;&lt;/div&gt;</pre>
<h3>Connecting the DataTable to The Proxy Data</h3>
<p>Finally we need to specify the <em>proxyStore</em> variable for the table to pull its data from. <em>proxyStore</em> is an instance of <em>dojo.data.ItemFileReadStore()</em>. We pass the URL of our JSON file and set <em>urlPreventCache</em> to true.</p>
<pre>proxyStore = new dojo.data.ItemFileReadStore({url: '/render/proxies', urlPreventCache: true});</pre>
<p>Which gives the final product:</p>
<p><img src="http://query7.com/wp-content/uploads/ss.png" alt="" title="ss" width="540" height="300" class="aligncenter size-full wp-image-1480" /></p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/tutorial-django-dojo-datagrid/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Celery with Django</title>
		<link>http://query7.com/tutorial-celery-with-django</link>
		<comments>http://query7.com/tutorial-celery-with-django#comments</comments>
		<pubDate>Mon, 04 Apr 2011 07:38:53 +0000</pubDate>
		<dc:creator>logan</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://query7.com/?p=1400</guid>
		<description><![CDATA[<h3>Introduction</h3>
<p>In a recent Django project I needed to issue some HTTP requests to a website, save the results and then display the information to the user. I could have issued those HTTP requests in a Django view, however the requests could take up to 10 seconds to return, and I didn&#8217;t want the page hanging that long for the user. I ended up using Celery, an asynchronous task queue written in Python, to execute the requests. </p>
<h3>Installation</h3>
<p><strong>Celery</strong><br />
Celery is in <a href="http://pypi.python.org/pypi/celery#downloads">pypi</a> so installation is simple.</p>
<pre>easy_install celery</pre>
<pre>pip install celery</pre>
<p>Or download the source code, extract it and </p>
<pre>python setup.py install</pre>
<p><strong>Django + Celery</strong><br />
In a high traffic production environment Celery should be paired with the RabbitMQ backend. However for my low traffic application I went with the <em>django-kombu</em> backend. <em>django-kombu</em> uses the Django database as a message store and requires very little configuration compared to other backends. We also need the <em>djcelery</em> package.</p>
<pre>easy_install django-kombu</pre>
<pre>easy_install django-celery</pre>
<h3>Configuration</h3>
<p>Before we can start using Celery we need configure our Django project. In <strong>settings.py</strong> make sure you add <em>djkombu</em> and <em>djcelery</em> to the <em>INSTALLED_APPS</em> tuple. Also make sure your database is configured and working.</p>
<p>Also add&#8230;</p>]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>In a recent Django project I needed to issue some HTTP requests to a website, save the results and then display the information to the user. I could have issued those HTTP requests in a Django view, however the requests could take up to 10 seconds to return, and I didn&#8217;t want the page hanging that long for the user. I ended up using Celery, an asynchronous task queue written in Python, to execute the requests. </p>
<h3>Installation</h3>
<p><strong>Celery</strong><br />
Celery is in <a href="http://pypi.python.org/pypi/celery#downloads">pypi</a> so installation is simple.</p>
<pre>easy_install celery</pre>
<pre>pip install celery</pre>
<p>Or download the source code, extract it and </p>
<pre>python setup.py install</pre>
<p><strong>Django + Celery</strong><br />
In a high traffic production environment Celery should be paired with the RabbitMQ backend. However for my low traffic application I went with the <em>django-kombu</em> backend. <em>django-kombu</em> uses the Django database as a message store and requires very little configuration compared to other backends. We also need the <em>djcelery</em> package.</p>
<pre>easy_install django-kombu</pre>
<pre>easy_install django-celery</pre>
<h3>Configuration</h3>
<p>Before we can start using Celery we need configure our Django project. In <strong>settings.py</strong> make sure you add <em>djkombu</em> and <em>djcelery</em> to the <em>INSTALLED_APPS</em> tuple. Also make sure your database is configured and working.</p>
<p>Also add the following lines to <strong>settings.py</strong>.</p>
<pre>import djcelery
djcelery.setup_loader()</pre>
<pre>BROKER_BACKEND = "djkombu.transport.DatabaseTransport"
#celery
BROKER_HOST = "localhost"
BROKER_PORT = 5672
BROKER_USER = "guest"
BROKER_PASSWORD = "guest"
BROKER_VHOST = "/"</pre>
<h3>Defining Tasks</h3>
<p>All Celery tasks should be defined in <em>PROJECT/APPNAME/tasks.py</em>. You can define your tasks as methods with a Celery decorator, or as classes which inherit from a base Celery <em>Task</em> class. I prefer the class definitions. Each task must define a <em>run</em> method (which is called when the task is executed). Finally, each task must be registered with Celery so that they can be found. Below is a modified version of one of my Tasks. </p>
<pre>import pycurl
from celery.task import Task
from celery.registry import tasks
from website.models import Website

class CheckWebsiteTask(Task):

	def run(self, ip, **kwargs):

		p, created = Website.objects.get_or_create(ip=ip)

		try:
			c = pycurl.Curl()
			c.setopt(pycurl.URL, ip)
			c.setopt(pycurl.TIMEOUT, 10)

			c.perform()

			p.alive = True

		except Exception, e:
			print e
			p.alive = False

		p.save()

tasks.register(CheckWebsiteTask)</pre>
<h3>Calling Tasks</h3>
<p>Typically you will want to call your tasks somewhere in your view code. Just import your task and call it&#8217;s <em>delay</em> method, passing in the arguments that you specified in the <em>run</em> method of your task. The task will then be added to the queue within 5 or 10 seconds and the queue will then start to clear itself.</p>
<pre>from django.http import HttpResponseRedirect

from website.tasks import CheckWebsiteTask
from website.models import Website

def check(request,id):

	website = Website.objects.get(id=id)

	CheckWebsiteTask.delay(website.ip)

	return HttpResponseRedirect('/')</pre>
<h3>Starting Celery</h3>
<pre>python manage.py celeryd -l info --settings=settings</pre>
<p><img src="http://query7.com/wp-content/uploads/hi.gif" alt="" title="hi" width="540" height="277" class="aligncenter size-full wp-image-1413" /></p>
<h3>Celery In The Real World</h3>
<p>If you want to learn more about Celery then I recommend you read up on the various articles and tutorials on the <a href="http://www.celeryproject.org">Celery website</a>. There is a <a href="https://github.com/ask/celery/wiki">list</a> of Django apps that use Celery in one way or another, you may be able to use some of these in your own applications. Finally you can browse the source code of <a href="https://github.com/ask/celery">celery</a.> and <a href="https://github.com/ask/django-celery">django-celery</a> on github to learn how they work under the hood.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/tutorial-celery-with-django/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NodeJS cURL Tutorial</title>
		<link>http://query7.com/nodejs-curl-tutorial</link>
		<comments>http://query7.com/nodejs-curl-tutorial#comments</comments>
		<pubDate>Mon, 28 Mar 2011 01:34:25 +0000</pubDate>
		<dc:creator>logan</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[nodejs]]></category>

		<guid isPermaLink="false">http://query7.com/?p=1369</guid>
		<description><![CDATA[<p>NodeJS is a powerful evented Javascript platform running on top of Google&#8217;s V8 javascript engine. Over the last year the popularity of NodeJS has increased greatly, as shown by the number of discussions on programming forums such as Hacker News, Reddit and Stackoverflow. Despite this NodeJS is still young and it falls short to Python and Ruby when it comes to the number and range of libraries and modules available.</p>
<h3>The Problem</h3>
<p>I wanted to convert one of my web scraping applications I made in PHP to NodeJS. The application interacts with SOCKS4 and SOCKS5 proxies using PHP&#8217;s cURL bindings. Unfortunately there are no cURL bindings (or SOCKS protocol wrappers) written for NodeJS. NodeJS does come with an HTTP client module that can issue web requests, however it doesn&#8217;t support SOCKS proxies.</p>
<h3>The Solution</h3>
<p>Although there are no specific NodeJS bindings for cURL, we can still issue cURL requests via the command line interface. NodeJS comes with the <em>child_process</em> module which easily allows us to start processes and read their output. Doing so is fairly straight forward. We just need to import the <a href="http://nodejs.org/docs/v0.4.3/api/child_processes.html#child_process.exec">exec</a> method from the <a href="http://nodejs.org/docs/v0.4.3/api/child_processes.html">child_process</a> module and call it. The first parameter is the command&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>NodeJS is a powerful evented Javascript platform running on top of Google&#8217;s V8 javascript engine. Over the last year the popularity of NodeJS has increased greatly, as shown by the number of discussions on programming forums such as Hacker News, Reddit and Stackoverflow. Despite this NodeJS is still young and it falls short to Python and Ruby when it comes to the number and range of libraries and modules available.</p>
<h3>The Problem</h3>
<p>I wanted to convert one of my web scraping applications I made in PHP to NodeJS. The application interacts with SOCKS4 and SOCKS5 proxies using PHP&#8217;s cURL bindings. Unfortunately there are no cURL bindings (or SOCKS protocol wrappers) written for NodeJS. NodeJS does come with an HTTP client module that can issue web requests, however it doesn&#8217;t support SOCKS proxies.</p>
<h3>The Solution</h3>
<p>Although there are no specific NodeJS bindings for cURL, we can still issue cURL requests via the command line interface. NodeJS comes with the <em>child_process</em> module which easily allows us to start processes and read their output. Doing so is fairly straight forward. We just need to import the <a href="http://nodejs.org/docs/v0.4.3/api/child_processes.html#child_process.exec">exec</a> method from the <a href="http://nodejs.org/docs/v0.4.3/api/child_processes.html">child_process</a> module and call it. The first parameter is the command we want to execute and the second is a callback function that accepts <em>error</em>, <em>stdout</em>, <em>stderr</em>.</p>
<h3>The Code</h3>
<pre>var util = require('util');
var exec = require('child_process').exec;

var command = 'curl -sL -w "%{http_code} %{time_total}\\n" "http://query7.com" -o /dev/null'

child = exec(command, function(error, stdout, stderr){

	console.log('stdout: ' + stdout);
	console.log('stderr: ' + stderr);

	if(error !== null)
	{
		console.log('exec error: ' + error);
	}

});</pre>
<p>This returns the HTTP code and time it took for the request to be issued:</p>
<pre>stdout: 200 0.710</pre>
<h3>Conclusion</h3>
<p>Although NodeJS is still young and bindings haven&#8217;t been made for alot of C libraries, the code above shows how you can still interact with the functionality they provide. That being said, the number of NodeJS modules is growing weekly. Be sure to keep an eye on the <a href="https://github.com/joyent/node/wiki/modules">module wiki</a> and <a href="http://search.npmjs.org/">npm registry</a> for a list of modules.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/nodejs-curl-tutorial/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Titanium Mobile Android Development: Soundboard App</title>
		<link>http://query7.com/titanium-mobile-android-development-soundboard-app</link>
		<comments>http://query7.com/titanium-mobile-android-development-soundboard-app#comments</comments>
		<pubDate>Mon, 07 Mar 2011 07:43:25 +0000</pubDate>
		<dc:creator>logan</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Titanium Mobile]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://query7.com/?p=1248</guid>
		<description><![CDATA[<p>In this series of tutorials we use Appcelerator’s Titanium Mobile platform to create Android applications. This tutorial walks you through developing and packaging a soundboard application. Full source and packaged application is available on <a href="https://github.com/lastkarrde/query7Soundboard">github</a>.</p>
<ul>
<li><a href="http://query7.com/titanium-mobile-android-development-installation">Installation &#038; setup of Titanium Mobile</a></li>
<li><a href="http://query7.com/titanium-mobile-android-development-first-application">How to make your first Android application with Titanium Mobile</a></li>
<li>]]></description>
			<content:encoded><![CDATA[<p>In this series of tutorials we use Appcelerator’s Titanium Mobile platform to create Android applications. This tutorial walks you through developing and packaging a soundboard application. Full source and packaged application is available on <a href="https://github.com/lastkarrde/query7Soundboard">github</a>.</p>
<ul>
<li><a href="http://query7.com/titanium-mobile-android-development-installation">Installation &#038; setup of Titanium Mobile</a></li>
<li><a href="http://query7.com/titanium-mobile-android-development-first-application">How to make your first Android application with Titanium Mobile</a></li>
<li><a href=http://query7.com/titanium-mobile-android-development-soundboard-app">How to make a Soundboard application with Titanium Mobile</a></li>
<li><a href="http://query7.com/titanium-mobile-android-development-device-information">How to make a Device Information application with Titanium Mobile</a></li>
</ul>
<h3>The Application</h3>
<p>A soundboard application lists and plays quotes from movies, games or people. Our soundboard will play quotes from the Zealot, Immortal and Stalker units from Starcraft2.</p>
<p><center><img src="http://query7.com/wp-content/uploads/ss1.jpg" alt="" title="ss1" width="332" height="491" class="aligncenter size-full wp-image-1249" /></center></p>
<p><center><em>Clicking a unit name takes the user to a page where all of the unit&#8217;s quotes are shown.</em></center></p>
<p><center><img src="http://query7.com/wp-content/uploads/ss21.jpg" alt="" title="ss2" width="330" height="459" class="aligncenter size-full wp-image-1252" /></center></p>
<p><center><em>Clicking a quote on the unit page plays the .mp3 file of the quote.</em></center></p>
<h3>Directory Structure</h3>
<p><center><img src="http://query7.com/wp-content/uploads/dir.jpg" alt="" title="dir" width="276" height="686" class="aligncenter size-full wp-image-1254" /></center></p>
<h3>The User Interface</h3>
<p>The user interface is made up of several instances of the Titanium view elements <em>Window</em> and <em>TableView</em>. The home screen lists the names of different units that can play sounds. When the unit name is clicked we create a new instance of <em>Window</em> which is then populated with the appropriate view (If the user clicked on <em>Immortal</em> then the new window would load <em>v/immortal.js</em>).</p>
<p>UI code of <strong>app.js</strong></p>
<pre>var data = [

	{title: 'Immortal', view: 'v/immortal.js'},
	{title: 'Stalker', view: 'v/stalker.js'},
	{title: 'Zealot', view: 'v/zealot.js'},

];

var window = Titanium.UI.createWindow({

	title: 'Query7 SC2 Soundboard',
	backgroundColor:'#000',
	exitOnClose: true,

});

var tableView = Titanium.UI.createTableView({
	data: data,
	headerTitle: 'Query7 SC2 SoundBoard',
	});

window.add(tableView);
win.open();</pre>
<h3>Click Events</h3>
<p>When the name of a unit is clicked, we want to open a new Titanium <em>Window</em> View and populate it with a <em>TableView</em> that shows the quotes from the appropriate unit. In the code below we listen for click events on the main <em>TableView</em>. If a row is clicked, then we open a new <em>Window</em> and pass the <em>url</em> parameter. This will set the contents of the new <em>Window</em> to whatever is in the source of the passed argument. In this case we specified in the array <em>data</em> an attribute called <em>view</em> which holds the path to the javascript file for each individual unit.</p>
<p>Event code of <strong>app.js</strong></p>
<pre>tableView.addEventListener('click', function(e)
{

	var win = Titanium.UI.createWindow({
		url: e.rowData.view,
		title: e.rowData.title,
		navBarHidden: true,
		exitOnClose: false,
	});

	win.open();

});</pre>
<h3>Individual Unit Pages</h3>
<p>Each unit will have it&#8217;s own view script located in the <em>v</em> (for view) directory. Each script contains a definition of the <em>TableView</em> that shows the quotes the units can say.<br />
UI code of <strong>v/immortal.js</strong></p>
<pre>var win = Titanium.UI.currentWindow;

var data = [

	{title: 'For the ancients', file: 'sound_immortal_atk_1.mp3'},
	{title: 'The cycle is unchanging', file: 'sound_immortal_death_1.mp3'},
	{title: 'The enemy closes', file: 'sound_immortal_help_1.mp3'},
	{title: 'I return to serve', file: 'sound_immortal_ready_1.mp3'},
	{title: 'The battle is ours', file: 'sound_immortal_victory_2.mp3'},
	{title: 'Our cannons shall sing', file: 'sound_immortal_yesg1.mp3'},

];

var tableView = Titanium.UI.createTableView({

	data: data,
	headerTitle: 'Immortal',

});

win.add(tableView);</pre>
<h3>Playing Music</h3>
<p>Whenever an item on an Individual Unit Page is clicked we want to play the appropriate sound file. We store the location of the mp3 file in the <em>data</em> array.</p>
<pre>tableView.addEventListener('click', function (e){

	var sound = Titanium.Media.createSound();

	sound.url = '../mp3/' + e.rowData.file;

	sound.play();

});</pre>
<h3 id="packaging">Packaging</h3>
<p>Now all we need to do is package our application into a <em>.apk</em> file so that it can be distributed among Android devices. We need to generate a key to sign our Android app. Run the command below in the MSDOS prompt. You will be asked some additional information such as your name or country. None of it is really important unless you intend to put this app on the Android Market. Remember the <em>KEYALIASNAME</em> and password you set as Titanium requires you enter them.</p>
<pre>keytool -genkey -v -keystore <em>KEYSTORENAME</em> -alias <em>KEYALIASNAME</em> -keyalg RSA -validity 11000</pre>
<p><img src="http://query7.com/wp-content/uploads/out.jpg" alt="" title="out" width="540" height="483" class="aligncenter size-full wp-image-1261" /></p>
<p>After clicking package Titanium will compile your app into <em>.apk</em> format. From there you can put it on your phone&#8217;s SD card and install it. If you intend to publish an app you create onto the Android Market then be sure to give <a href="http://developer.appcelerator.com/doc/mobile/android_market">this</a> and <a href="http://developer.appcelerator.com/doc/mobile/android_market">this</a> a good read.</p>
<p>If you have any comments, questions or requests for tutorials, please ask below.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/titanium-mobile-android-development-soundboard-app/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Titanium Mobile Android Development: First Application</title>
		<link>http://query7.com/titanium-mobile-android-development-first-application</link>
		<comments>http://query7.com/titanium-mobile-android-development-first-application#comments</comments>
		<pubDate>Mon, 28 Feb 2011 08:35:39 +0000</pubDate>
		<dc:creator>logan</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Titanium Mobile]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://query7.com/?p=1159</guid>
		<description><![CDATA[<p>In this series of tutorials we use Appcelerator’s Titanium Mobile platform to create Android applications. This tutorial walks you through developing and packaging your first Titanium application. Full source and packaged application is available on <a href="https://github.com/lastkarrde/query7rss">github</a>.</p>
<ul>
<li><a href="http://query7.com/titanium-mobile-android-development-installation">Installation &#038; setup of Titanium Mobile</a></li>
<li><a href="http://query7.com/titanium-mobile-android-development-first-application">How to make your first Android application with Titanium Mobile</a></li>
<li>]]></description>
			<content:encoded><![CDATA[<p>In this series of tutorials we use Appcelerator’s Titanium Mobile platform to create Android applications. This tutorial walks you through developing and packaging your first Titanium application. Full source and packaged application is available on <a href="https://github.com/lastkarrde/query7rss">github</a>.</p>
<ul>
<li><a href="http://query7.com/titanium-mobile-android-development-installation">Installation &#038; setup of Titanium Mobile</a></li>
<li><a href="http://query7.com/titanium-mobile-android-development-first-application">How to make your first Android application with Titanium Mobile</a></li>
<li><a href=http://query7.com/titanium-mobile-android-development-soundboard-app">How to make a Soundboard application with Titanium Mobile</a></li>
<li><a href="http://query7.com/titanium-mobile-android-development-device-information">How to make a Device Information application with Titanium Mobile</a></li>
</ul>
<h3>The Application</h3>
<p>The application itself is fairly basic but incorporates many techniques that you may need to use in your own apps. It fetches the latest 10 items off the Query7.com RSS feed and displays them in a <em>TableView</em>. If you click on one of the items Android will open the link in a web browser (<em>Internet</em>, Opera Mini, Firefox etc, whatever your default Android browser is). </p>
<p><center><img src="http://query7.com/wp-content/uploads/query7rss.jpg" alt="" title="query7rss" width="338" height="496" class="aligncenter size-full wp-image-1160" /></center></p>
<h3>The User Interface</h3>
<p>The user interface has two Titanium view elements &#8211; a <em>Window</em> and a <em>TableView</em>. After creating both views we need to call the <em>add</em> method on the instance of <em>Window</em> to ensure the <em>TableView</em> shows on the page. Doing so is fairly straight forward:</p>
<pre>Titanium.UI.setBackgroundColor('#000');

var win = Titanium.UI.createWindow({
    title:'Query7 RSS Feed',
    backgroundColor:'#000'
});

var data = [];

var tableview = Titanium.UI.createTableView({
	data:data,
	headerTitle: 'Query7 RSS',
	backgroundColor:'#000'
});

win.add(tableview);
win.open();</pre>
<h3>HTTP Requests</h3>
<p>The next step is to retrieve the RSS feed from the Query7 blog. Titanium has a very nice <a href="http://developer.appcelerator.com/apidoc/mobile/latest/Titanium.Network.HTTPClient-object.html">HTTPClient</a> object that allows us to perform requests similar to the way we would using Ajax/JS in the web browser. We specify an <em>onload</em> method that handles the response of the request and an <em>open</em> method in which we specify the type of request (GET/POST/PUT/DELETE) and the URL we are requesting. Finally we initiate the request by calling the <em>send</em> method. </p>
<pre>var xhr = Titanium.Network.createHTTPClient();

xhr.onload = function()
{

	try
	{
		// manipulate response data here

	}
	catch(E)
	{
		alert(E);
	}

};

xhr.open('GET', 'http://feeds.feedburner.com/query7blog.rss');
xhr.send();</pre>
<h3>Parsing XML using Titanium</h3>
<p>Even though we are coding in Javascript, we are not in a web browser environment, so the usual <em>document</em> and <em>window</em> objects do not exist. This means frameworks which make XML manipulation easy, such as jQuery and Mootools, will not work. Luckily Titanium offers us the <a href="http://developer.appcelerator.com/apidoc/mobile/latest/Titanium.XML.DOMDocument-object.html">DOMDocument</a> object, which acts and has a similar API to the web browser <em>document</em> object.</p>
<p>In the code below we can get the output of the HTTP request and automatically turn it into a <em>DOMDocument</em> object by accessing it as <em>this.responseXML.documentElement</em>. If you just wanted to get the output as plain text, you would access it by <em>this.responseText</em>. Now that the <em>DOMDocument</em> instance is set up, we do a simple XPath query to get the title and iterate over the items to get the data about the individual posts.</p>
<pre>
// manipulate response data here

var doc = this.responseXML.documentElement;
var items = doc.getElementsByTagName('item');
var doctitle = doc.evaluate("//channel/title/text()").item(0).nodeValue;

var urls = new Array();

for(var c=0; c&gt;items.length;c++)
{

	urls[c] = items.item(c).getElementsByTagName('link').item(0).text;

	postName = items.item(c).getElementsByTagName('title').item(0).text;
	postUrl = items.item(c).getElementsByTagName('link').item(0).text;

}</pre>
<h3>Populating the <em>TableView</em></h3>
<p>Now that we have the data from the RSS feed we can populate the <em>TableView</em>. To do this we create several <a href="http://developer.appcelerator.com/apidoc/mobile/latest/Titanium.UI.TableViewRow-object.html">Titanium.UI.TableViewRow</a> objects and then append them to our <em>TableView</em>.</p>
<pre>
row = Titanium.UI.createTableViewRow({
			title: postName,
			backgroundColor:'#000',
			color: '#FF0'
		});

tableview.appendRow(row);
</pre>
<h3>Click events, Intents</h3>
<p>Now that we have data in the <em>TableView</em> we want to add functionality so that when an item in the <em>TableView</em> is clicked, the Android web browser will open to that specific post. Our code needs to listen for a click event on a <em>TableViewRow</em> and then launch a <a href="http://developer.appcelerator.com/apidoc/mobile/latest/Titanium.Android.Intent-object.html">Titanium.Android.Intent</a>.</p>
<pre>row.addEventListener('click', function (e){

	var intent = Titanium.Android.createIntent({

			action: Titanium.Android.ACTION_VIEW,
			data: urls[e.index],

		});

	intent.addCategory(Titanium.Android.CATEGORY_BROWSABLE);
	Ti.Android.currentActivity.startActivity(intent);

});</pre>
<h3>Packaging</h3>
<p>Now all we need to do is package our application into a <em>.apk</em> file so that it can be distributed among Android devices. We need to generate a key to sign our Android app. Run the command below in the MSDOS prompt. You will be asked some additional information such as your name or country. None of it is really important unless you intend to put this app on the Android Market. Remember the <em>KEYALIASNAME</em> and password you set as Titanium requires you enter them.</p>
<pre>keytool -genkey -v -keystore <em>KEYSTORENAME</em> -alias <em>KEYALIASNAME</em> -keyalg RSA -validity 11000</pre>
<p><img src="http://query7.com/wp-content/uploads/dist.jpg" alt="" title="dist" width="540" height="495" class="aligncenter size-full wp-image-1170" /></p>
<p>After clicking package Titanium will compile your app into <em>.apk</em> format. From there you can put it on your phone&#8217;s SD card and install it. If you intend to publish an app you create onto the Android Market then be sure to give <a href="http://developer.appcelerator.com/doc/mobile/android_market">this</a> and <a href="http://developer.appcelerator.com/doc/mobile/android_market">this</a> a good read.</p>
<p>And thats it, your first Android application is now complete. Next week we will look at creating a Soundboard application using Titanium Mobile. As always if you have any comments, questions or requests for tutorials, please ask below.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/titanium-mobile-android-development-first-application/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Using Proxies with cURL in PHP</title>
		<link>http://query7.com/using-proxies-with-curl-in-php</link>
		<comments>http://query7.com/using-proxies-with-curl-in-php#comments</comments>
		<pubDate>Sun, 13 Feb 2011 21:30:21 +0000</pubDate>
		<dc:creator>logan</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://query7.com/?p=982</guid>
		<description><![CDATA[<p>If you are new to using PHP and cURL please refer to the <a href="http://query7.com/php-curl">PHP cURL tutorial</a>. It covers why you should using cURL (as opposed to file_get_contents) and goes over how to make cURL requests with a custom class.</p>
<p>This tutorial will cover how to use different types of proxies &#8211; SOCKS4, SOCKS5 and HTTP with cURL. </p>
<h3>Basic cURL Request</h3>
<p>We&#8217;ll start by creating a simple cURL script that requests the web page <a href="http://checkip.dyndns.org">checkip.dyndns.org</a> and displays the result on the screen. The website just displays our current IP address, this is useful when working with proxies. Below is our very basic cURL request. </p>
<pre>$url = 'http://checkip.dyndns.org/';

$c = curl_init($url);

curl_setopt($c, CURLOPT_RETURNTRANSFER, true);

$result = curl_exec($c);

echo '&#60;pre&#62;';
var_dump($result);
echo '&#60;/pre&#62;';

curl_close($c);</pre>
<p>As we can expect, the output will be your IP address.</p>
<pre>202.183.56.21</pre>
<h3>Using Proxies with cURL</h3>
<p>To use proxies with cURL we need to set 2 additional cURL options: <em>CURLOPT_PROXYTYPE</em> and <em>CURLOPT_PROXY</em>. <em>CURLOPT_PROXYTYPE</em> should be set to either <em>CURLPROXY_SOCKS5</em> or <em>CURLPROXY_SOCKS4</em>, depending on the type of proxy you are using. <em>CURLOPT_PROXY</em> should be set to the IP address and port of the proxy you are using.</p>
<p>If you are using an HTTP proxy then you&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>If you are new to using PHP and cURL please refer to the <a href="http://query7.com/php-curl">PHP cURL tutorial</a>. It covers why you should using cURL (as opposed to file_get_contents) and goes over how to make cURL requests with a custom class.</p>
<p>This tutorial will cover how to use different types of proxies &#8211; SOCKS4, SOCKS5 and HTTP with cURL. </p>
<h3>Basic cURL Request</h3>
<p>We&#8217;ll start by creating a simple cURL script that requests the web page <a href="http://checkip.dyndns.org">checkip.dyndns.org</a> and displays the result on the screen. The website just displays our current IP address, this is useful when working with proxies. Below is our very basic cURL request. </p>
<pre>$url = 'http://checkip.dyndns.org/';

$c = curl_init($url);

curl_setopt($c, CURLOPT_RETURNTRANSFER, true);

$result = curl_exec($c);

echo '&lt;pre&gt;';
var_dump($result);
echo '&lt;/pre&gt;';

curl_close($c);</pre>
<p>As we can expect, the output will be your IP address.</p>
<pre>202.183.56.21</pre>
<h3>Using Proxies with cURL</h3>
<p>To use proxies with cURL we need to set 2 additional cURL options: <em>CURLOPT_PROXYTYPE</em> and <em>CURLOPT_PROXY</em>. <em>CURLOPT_PROXYTYPE</em> should be set to either <em>CURLPROXY_SOCKS5</em> or <em>CURLPROXY_SOCKS4</em>, depending on the type of proxy you are using. <em>CURLOPT_PROXY</em> should be set to the IP address and port of the proxy you are using.</p>
<p>If you are using an HTTP proxy then you only need to set <em>CURLOPT_PROXY</em> to your proxy. <em>CURLOPT_PROXYTYPE</em> automatically defaults to <em>CURLPROXY_HTTP</em>.</p>
<p>As you can expect, the following script displays the IP address of the proxy.</p>
<pre>$url = 'http://checkip.dyndns.org/';

$c = curl_init($url);

curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
curl_setopt($c, CURLOPT_PROXY, '68.119.83.81:27977');

$result = curl_exec($c);

echo '&lt;pre&gt;';
var_dump($result);
echo '&lt;/pre&gt;';

curl_close($c);</pre>
<p>Note: You&#8217;ll need to use your own proxy. The one supplied is made up.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/using-proxies-with-curl-in-php/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Interacting with Skype from Python using Skype4Py</title>
		<link>http://query7.com/interacting-with-skype-from-python-using-skype4py</link>
		<comments>http://query7.com/interacting-with-skype-from-python-using-skype4py#comments</comments>
		<pubDate>Mon, 03 Jan 2011 09:10:23 +0000</pubDate>
		<dc:creator>logan</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://query7.com/?p=875</guid>
		<description><![CDATA[<p><a href="http://pypi.python.org/pypi/Skype4Py/0.9.28.7">Skype4Py</a> is a Python module that allows developers to programatically interact with the Skype client running on their computer. In this tutorial we will look at and use the <em>Skype4Py</em> module to create simple but useful scripts.</p>
<h3>Installation</h3>
<p><em>Skype4Py</em> is a normal Python module and is listed in the Python package index (Pypi). To install it with <a href="http://pypi.python.org/pypi/setuptools">setuptools</a> enter the following in a command prompt.</p>
<pre>easy_install Skype4Py</pre>
<p>To install it with <a href="http://pypi.python.org/pypi/pip">pip</a> enter the following in a command prompt.</p>
<pre>pip install Skype4Py</pre>
<h3>Getting Started</h3>
<p><em>Skype4Py</em> interacts with the Skype client running on your desktop, it doesn&#8217;t talk directly to the Skype servers. For any of the scripts we cover in this tutorial to work the Skype application must be running and you need to be logged in. You can either start Skype yourself or use the following snippet to start it using <em>Skype4Py</em>.</p>
<pre>s = Skype4Py.Skype()

if not s.Client.IsRunning:
	s.Client.Start()</pre>
<p>Before we can interact with the Skype client from Skype2Py, we need to connect Skype4Py to the instance of Skype running on your desktop. This is done using the <em>Attach</em> method.</p>
<pre>import Skype4Py

s = Skype4Py.Skype()
s.Attach()</pre>
<p>After executing this you need to check the Skype client on&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://pypi.python.org/pypi/Skype4Py/0.9.28.7">Skype4Py</a> is a Python module that allows developers to programatically interact with the Skype client running on their computer. In this tutorial we will look at and use the <em>Skype4Py</em> module to create simple but useful scripts.</p>
<h3>Installation</h3>
<p><em>Skype4Py</em> is a normal Python module and is listed in the Python package index (Pypi). To install it with <a href="http://pypi.python.org/pypi/setuptools">setuptools</a> enter the following in a command prompt.</p>
<pre>easy_install Skype4Py</pre>
<p>To install it with <a href="http://pypi.python.org/pypi/pip">pip</a> enter the following in a command prompt.</p>
<pre>pip install Skype4Py</pre>
<h3>Getting Started</h3>
<p><em>Skype4Py</em> interacts with the Skype client running on your desktop, it doesn&#8217;t talk directly to the Skype servers. For any of the scripts we cover in this tutorial to work the Skype application must be running and you need to be logged in. You can either start Skype yourself or use the following snippet to start it using <em>Skype4Py</em>.</p>
<pre>s = Skype4Py.Skype()

if not s.Client.IsRunning:
	s.Client.Start()</pre>
<p>Before we can interact with the Skype client from Skype2Py, we need to connect Skype4Py to the instance of Skype running on your desktop. This is done using the <em>Attach</em> method.</p>
<pre>import Skype4Py

s = Skype4Py.Skype()
s.Attach()</pre>
<p>After executing this you need to check the Skype client on your desktop. A notification similar to the one below will appear. This ensures that no virus or 3rd party program can use your Skype account without your knowledge. Click &#8216;Allow access&#8217;.<br />
<a href="http://query7.com/wp-content/uploads/skypeaccess.png"><img src="http://query7.com/wp-content/uploads/skypeaccess.png" alt="" title="skypeaccess" width="540" height="79" class="aligncenter size-full wp-image-876" /></a></p>
<h3>User Information</h3>
<p><em>Skype4Py</em> provides a <a href="http://skype4py.sourceforge.net/doc/html/Skype4Py.user.User-class.html">User class</a> which represents a user&#8217;s Skype account. We can access information such as the user&#8217;s full name, their Skype status and when they were last logged into Skype. To get the person who is currently logged into the Skype client&#8217;s information we need to use the <em>CurrentUser</em> class.</p>
<pre>import Skype4Py
s = Skype4Py.Skype()
s.Attach()

print 'Full Name: %s' % s.CurrentUser.FullName
print 'Skype Status: %s' % s.CurrentUser.OnlineStatus
print 'Country: %s' % s.CurrentUser.Country</pre>
<p>To access information about the current Skype user&#8217;s friends, we need to use the <em>Friends</em> class. The snippet below iterates over all of the current Skype user&#8217;s friends and prints some information about them.</p>
<pre>import Skype4Py
s = Skype4Py.Skype()
s.Attach()

for f in s.Friends:
	print 'Full Name: %s' % f.FullName
	print 'Skype Status: %s' % f.OnlineStatus
	print 'Country: %s' % f.Country</pre>
<h3>Sending SMS Messages</h3>
<p><em>Skype4Py</em> can also be used to send SMS messages. Only Skype users who have credit in their Skype account can send SMS. Be sure to check local SMS rates on the <a href="http://www.skype.com/intl/en/prices/sms-rates/">Skype website</a> before using and <strong>never</strong> put this code in a loop without double checking it first. Make sure you include your country&#8217;s international prefix at the beginning of the number <em>variable</em>. After using this code my phone received the SMS 20 seconds later (NZ carrier).</p>
<pre>import Skype4Py
s = Skype4Py.Skype()
s.Attach()

message = 'Hello SMS from Query7'
number = '+641234567890' 

m = s.CreateSms(Skype4Py.smsMessageTypeOutgoing, number)
m.Body = message

m.Send()</pre>
<h3>What Else Can Skype4Py Do?</h3>
<ul>
<li><a href="http://skype4py.sourceforge.net/doc/html/Skype4Py.voicemail.Voicemail-class.html">Download and play voice mail messages</a></li>
<li><a href="http://skype4py.sourceforge.net/doc/html/Skype4Py.filetransfer.FileTransfer-class.html">Transfer files between Skype clients</a></li>
<li><a href="http://skype4py.sourceforge.net/doc/html/">Interact with Skype chat messages</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/interacting-with-skype-from-python-using-skype4py/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing a module for Kohana3</title>
		<link>http://query7.com/writing-a-module-for-kohana3</link>
		<comments>http://query7.com/writing-a-module-for-kohana3#comments</comments>
		<pubDate>Mon, 20 Dec 2010 20:43:54 +0000</pubDate>
		<dc:creator>logan</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[kohana]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[twig]]></category>

		<guid isPermaLink="false">http://query7.com/?p=775</guid>
		<description><![CDATA[<p>In this tutorial we will cover how to build a module from scratch in Kohana 3. If you aren&#8217;t familiar with the Kohana framework then I recommend you read the <a href="http://query7.com/an-introduction-to-kohana3-php-framework">beginners introduction to Kohana</a>.</p>
<h3>The Plan</h3>
<p>We will be building a module that replaces Kohana&#8217;s own view layer (<em>Kohana_View</em>). It will use the PHP template library <a href="http://twig-project.org">Twig</a>. We want our own view layer to be API compatible with Kohana&#8217;s view layer. This will ensure that other modules work out of the box and that the only code the developer will need to alter in their application are the templates (so that they are Twig compatible). No code in any controller will need to be modified.</p>
<p> Because Kohana follows HMVC (see beginners introduction to Kohana) we will be calling our class <i>View</i>. This means that all calls in the application to the class of <i>View</i> will be to the <i>View</i> class in our module, not Kohana&#8217;s own <i>View</i> class. </p>
<h3>Directory Structure</h3>
<p><a href="http://query7.com/wp-content/uploads/dir.png"><img src="http://query7.com/wp-content/uploads/dir.png" alt="" title="dir" width="148" height="201" class="aligncenter size-full wp-image-783" /></a></p>
<h3>Enabling The Module</h3>
<p>The name of any Kohana module is the same name as the directory inside the <i>modules</i> directory. So in this case it is <i>twig</i>. To activate any module, we must add it&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>In this tutorial we will cover how to build a module from scratch in Kohana 3. If you aren&#8217;t familiar with the Kohana framework then I recommend you read the <a href="http://query7.com/an-introduction-to-kohana3-php-framework">beginners introduction to Kohana</a>.</p>
<h3>The Plan</h3>
<p>We will be building a module that replaces Kohana&#8217;s own view layer (<em>Kohana_View</em>). It will use the PHP template library <a href="http://twig-project.org">Twig</a>. We want our own view layer to be API compatible with Kohana&#8217;s view layer. This will ensure that other modules work out of the box and that the only code the developer will need to alter in their application are the templates (so that they are Twig compatible). No code in any controller will need to be modified.</p>
<p> Because Kohana follows HMVC (see beginners introduction to Kohana) we will be calling our class <i>View</i>. This means that all calls in the application to the class of <i>View</i> will be to the <i>View</i> class in our module, not Kohana&#8217;s own <i>View</i> class. </p>
<h3>Directory Structure</h3>
<p><a href="http://query7.com/wp-content/uploads/dir.png"><img src="http://query7.com/wp-content/uploads/dir.png" alt="" title="dir" width="148" height="201" class="aligncenter size-full wp-image-783" /></a></p>
<h3>Enabling The Module</h3>
<p>The name of any Kohana module is the same name as the directory inside the <i>modules</i> directory. So in this case it is <i>twig</i>. To activate any module, we must add it to the array passed to <i>Kohana::modules</i> in <i>application/bootstrap.php</i>.</p>
<p><b>application/bootstrap.php &#8211; line 88</b></p>
<pre>Kohana::modules(array(
	'twig' => MODPATH.'twig',
	// 'auth'       => MODPATH.'auth',       // Basic authentication
	// 'cache'      => MODPATH.'cache',      // Caching with multiple backends
	// 'codebench'  => MODPATH.'codebench',  // Benchmarking tool
	// 'database'   => MODPATH.'database',   // Database access
	// 'image'      => MODPATH.'image',      // Image manipulation
	// 'orm'        => MODPATH.'orm',        // Object Relationship Mapping
	// 'oauth'      => MODPATH.'oauth',      // OAuth authentication
	// 'pagination' => MODPATH.'pagination', // Paging of results
	// 'unittest'   => MODPATH.'unittest',   // Unit testing
	// 'userguide'  => MODPATH.'userguide',  // User guide and API documentation
	));
</pre>
<h3>Twig</h3>
<p>We will be using Fabien Potencier&#8217;s Twig project as a replacement templating engine for Kohana. The Twig files themselves will be stored in <i>modules/twig/Twig/</i>. If you are familiar with git you could create a git submodule of Twig so you can update Twig independently from our <i>twig</i> Kohana module. However for the sake of this tutorial it is easier just to download the tarball and extract it.</p>
<p>Rather than including all Twig files explicitly (using <i>include</i> or <i>require</i> statements) we will use Twig&#8217;s own autoloader. We could call it either in <i>application/bootstrap.php</i> or <i>modules/twig/init.php</i>. Since the autoloader is specific to the <em>twig</em> module (and not to the application) it is better to put it in <i>modules/twig/init.php</i>. Every <i>init.php</i> file in every enabled module is called automatically every request by Kohana.</p>
<p><b>modules/twig/init.php</b></p>
<pre>require 'Twig/Autoloader.php';

Twig_Autoloader::register();
</pre>
<h3>Configuration</h3>
<p>Each developer that uses our <i>twig</i> module will have a different template directory and will want to pass different options to the Twig library when it&#8217;s instantiated (such as whether Twig runs in debug mode). Rather than hard coding these options into our module (which would force every developer using it to alter module code) we can use Kohana&#8217;s configuration system. </p>
<p>Because the configuration for our module is application specific, create <i>application/config/twig.php</i></p>
<p><b>application/config/twig.php</b></p>
<pre>// http://www.twig-project.org/book/03-Twig-for-Developers

return array(

	//Edit these per app.
	'template_dir' => 'C:/wamp/www/kohanaresources/application/views/',
	'cache_dir' => 'C:/wamp/www/kohanaresources/application/cache/',

	//Set to false in production application
	'auto_reload' => true,
	'debug' => true,

	//Misc settings. Don't touch unless you know what your doing.
	'trim_blocks' => false,
	'charset' => 'utf8',
	'base_template_class' => 'Twig_Template',
	'strict_variables' => false,

);
</pre>
<p>To access these array parameters that the developer sets, its a simple matter of:</p>
<pre>Kohana::config('twig.template_dir');</pre>
<h3>The View Class</h3>
<p><i>modules/twig/classes/view.php</i> is going to contain our class, <i>View</i>. It will handle the rendering of the template using Twig. As discussed above, we want our <i>View</i> class to have the same API as <i>Kohana_View</i>, so we will copy <i>system/classes/kohana/view.php</i> and make a small alteration to it. Most of the methods in <i>Kohana_View</i> provide different ways to set variables to the instance of <i>Kohana_View</i>. For example all three of these essentially do the same thing:</p>
<pre>$v = new View('some/template');

$v->website = 'Query7';
$v->set('website', 'Query7');
$v->bind('website', 'Query7');</pre>
<p>All loading and parsing of the template file is done in View::capture(). This is the only method from the original <i>Kohana_View</i> class that we will need to alter. Here is our new method in full:</p>
<p><b>modules/twig/classes/view.php &#8211; View::capture</b></p>
<pre>protected static function capture($kohana_view_filename, array $kohana_view_data)
{
	if (isset(View::$_global_data))
	{
		$data = array_merge($kohana_view_data, View::$_global_data);
	}
	else
	{
		$data = $kohana_view_data;
	}

	$loader = new Twig_Loader_Filesystem(Kohana::config('twig.template_dir'));

	$twig = new Twig_Environment($loader, array(

		'cache' => Kohana::config('twig.cache_dir'),
		'debug' => Kohana::config('twig.debug'),

		'auto_reload' => Kohana::config('twig.auto_reload'),
		'trim_blocks' => Kohana::config('twig.trim_blocks'),
		'charset' => Kohana::config('twig.charset'),
		'base_template_class' => Kohana::config('twig.base_template_class'),
		'strict_variables' => Kohan::config('twig.strict_variables')
	));

	$template = $twig->loadTemplate($kohana_view_filename);

	return $template->render($data);
}</pre>
<p>Our function first combines all data to be passed to the template in a single array, <i>$data</i>. It then instantiates <i>Twig_Loader_Filesystem</i> and passes the location of the template directory to it. <i>Twig_Enviroment</i> is then instantiated and the different configuration options are passed there. Finally the template is loaded and rendered.</p>
<h3>Example of <i>twig</i> in use</h3>
<p><b>some method in a controller</b></p>
<pre>$v = new View('colors.html');

$v->colors = array('red','blue','yellow','purple');

$this->request->response = $v->render();</pre>
<p><b>colors.html</b></p>
<pre>
{% for c in colors %}
    {{ c }},
{% endfor %}
</pre>
<p><b>output</b></p>
<pre>
red,blue,yellow,purple,
</pre>
<h3>Finishing Up</h3>
<p>After you have finished any Kohana module you should write the necessary documentation and tests. Kohana has it&#8217;s own <a href="https://github.com/kohana/unittest">module</a> that integrates PHPUnit with the Kohana framework. The majority of Kohana modules are open source on Github, with repositories named kohana-<i>*modulename*</i>. Finally you will want to promote your module. Announcing it on the Kohana <a href="http://forum.kohanaframework.org/">forum</a> and on Twitter are good ways to get it some attention.</p>
<p>If you have any questions or feedback please leave them in the comments below.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/writing-a-module-for-kohana3/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

