<?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>Beardy Geek</title>
	<atom:link href="http://www.beardygeek.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.beardygeek.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Thu, 04 Mar 2010 11:34:10 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Google Calls for Link Spam Reports</title>
		<link>http://www.beardygeek.com/2010/03/google-calls-for-link-spam-reports/</link>
		<comments>http://www.beardygeek.com/2010/03/google-calls-for-link-spam-reports/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 10:34:45 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=73</guid>
		<description><![CDATA[In Matt Cutts latest blog post, he calls for users to report any sites they deem 'spammy'.]]></description>
			<content:encoded><![CDATA[<p><img class="size-medium wp-image-75 alignnone" style="border: 0pt none; margin-left: 5px; margin-right: 10px;" title="Spam" src="http://www.beardygeek.com/wp-content/uploads/2010/03/spam1-300x171.jpg" alt="Spam" width="300" height="171" /></p>
<p><a href="http://www.flickr.com/photos/63056612@N00/155554663/" target="_blank" style="font-size: smaller" onclick="pageTracker._trackPageview('/outgoing/www.flickr.com/photos/63056612_N00/155554663/?referer=');">[<em>image attribution</em>]</a></p>
<p>In <a href="http://www.mattcutts.com/blog/calling-for-link-spam-reports/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.mattcutts.com/blog/calling-for-link-spam-reports/?referer=');">Matt Cutts latest blog post</a>, he calls for users to report any sites they deem &#8217;spammy&#8217;.  On the <a href="https://www.google.com/webmasters/tools/spamreport" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.google.com/webmasters/tools/spamreport?referer=');">report form</a>, this includes anything that is considered:</p>
<ul>
<li>Hidden text or links</li>
<li>Misleading or repeated words</li>
<li><label for="description">Page does not match Google&#8217;s description</label></li>
<li><label for="cloaked">Cloaked page</label></li>
<li><label for="redirects">Deceptive redirects</label></li>
<li><label for="doorway">Doorway pages</label></li>
<li><label for="duplicate">Duplicate site or pages</label></li>
</ul>
<p>Matt says that Google have been working on new algorithms to detect link spam, and it seems that through this manual reporting process, Google users will be helping to &#8216;train&#8217; the system to be more effective.</p>
<p>It doesn&#8217;t say yet what action will be taken upon finding such a page, and whether Google will allow webmasters to make amends or defend themselves.  So look out for tales of woe from people removed from Google&#8217;s index for spurious reasons.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2010/03/google-calls-for-link-spam-reports/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django Tips &#8211; Unique Date Querysets</title>
		<link>http://www.beardygeek.com/2009/02/django-tips-unique-date-querysets/</link>
		<comments>http://www.beardygeek.com/2009/02/django-tips-unique-date-querysets/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 18:50:26 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=35</guid>
		<description><![CDATA[I swear this particular feature of querysets was made especially for the archive listing of a blog.  You know, the month and year listing in the side bar for all your previous posts. This solves that problem exactly.]]></description>
			<content:encoded><![CDATA[<p>I swear this particular feature of querysets was made especially for the archive listing of a blog.  You know, the month and year listing in the side bar for all your previous posts. This solves that problem exactly.</p>
<p>Let&#8217;s say you have a BlogPost model, and a post_date field within said model.  You want a list on the sidebar of all the unique month and year combinations.  Here&#8217;s what you do:</p>
<p><pre>
<code>
queryset = BlogPost.objects.dates('post_date', 'month')
</code>
</pre>
</p>
<p>And that&#8217;s it.  You&#8217;ll now have a query set full of datetime objects with all your unique months and years.</p>
<p>To get unique years only, substitute &#8216;year&#8217; for &#8216;month&#8217;, and for unique day, month and year, substitute &#8216;day&#8217; for &#8216;month&#8217;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2009/02/django-tips-unique-date-querysets/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>From Wordpress to Django &#8211; Part 2</title>
		<link>http://www.beardygeek.com/2009/01/from-wordpress-to-django-part-two/</link>
		<comments>http://www.beardygeek.com/2009/01/from-wordpress-to-django-part-two/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 18:59:08 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Blogging]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=46</guid>
		<description><![CDATA[Welcome back.  In part 2 I'll be getting to the meat of the issue, which is retrieving the data from an existing Wordpress blog, and feeding the data into my own models.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.foundrylabs.co.uk/blog/2009/1/from-wordpress-to-django-part-one/" onclick="pageTracker._trackPageview('/outgoing/www.foundrylabs.co.uk/blog/2009/1/from-wordpress-to-django-part-one/?referer=');">View Part 1</a><br />
<a href="http://github.com/beardygeek/beardygeek-website" onclick="pageTracker._trackPageview('/outgoing/github.com/beardygeek/beardygeek-website?referer=');">Beardy Geek Git Hub Repository</a></p>
<p>Welcome back.  In part 2 I&#8217;ll be getting to the meat of the issue, which is retrieving the data from an existing Wordpress blog, and feeding the data into my own models.</p>
<p>
<h4>Models</h4>
<p>I&#8217;ve decided to start the models from scratch, rather than trying to copy the way Wordpress has laid them out. It should keep things simpler that way.  I&#8217;ll be using the contrib comments system for the post comments, and I&#8217;ll also be creating 3 other models, Category, Tag, and Post. Here&#8217;s the code for the models:</p>
<pre><code>
from django.db import models
from django.contrib.auth.models import User
from datetime import datetime

POST_STATUS = (
               ('P', 'Published'),
               ('U', 'Unpublished'),
)

class Tag(models.Model):
    text = models.CharField(max_length=75)
    slug = models.CharField(max_length=75)

    def __unicode__(self):
        return self.text

class Category(models.Model):
    text = models.CharField(max_length=75)
    slug = models.CharField(max_length=75)

    def __unicode__(self):
        return self.text

    class Meta:
        verbose_name_plural = "categories"

class Post(models.Model):
    title = models.CharField(max_length=75)
    slug = models.CharField(max_length=75)
    content = models.TextField()
    author = models.ForeignKey(User)
    post_date = models.DateTimeField(default=datetime.now)
    status = models.CharField(max_length=1, choices=POST_STATUS)
    categories = models.ManyToManyField(Category)
    tags = models.ManyToManyField(Tag)

    def __unicode__(self):
        return self.title
</code></pre>
</p>
<p>
<h4>Wordpress Export</h4>
<p>Just a quick note: I am using Wordpress Version 2.6.1. Things may be different in other versions, but the code here works on this version. I&#8217;ll go through the code so you should see where the problem is if it doesn&#8217;t work with your version.</p>
<p>OK, if you didn&#8217;t already know, you can export all your Wordpress data into an xml file. Go to your dashboard, click &#8216;Manage&#8217;, and then &#8216;Export&#8217;. Select which authors to restrict (if any) and hit the download button. You should now have the data in an xml file.</p>
<p>
<h4>XML File Editing</h4>
<p>When I first tried to parse this file, I got an error as one of the namespaces used in the document is undeclared. To rectify this, you need to open up the file in a text editor (not an xml editor, you may get the same parse error). Near the top of the file, you should see something like this:</p>
<pre><code>
&lt;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:wp="http://wordpress.org/export/1.0/"
&gt;
</code></pre>
<p>The missing namespace is &#8216;excerpt&#8217;, and we need to add this. It doesn&#8217;t matter what value you give it. I did this:</p>
<pre><code>
&lt;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:wp="http://wordpress.org/export/1.0/"
	xmlns:excerpt="mysite"
&gt;
</code></pre>
<p>Save the file and we&#8217;re ready to start parsing the data.</p>
<p>
<h4>XML Parsing</h4>
<p>To parse the XML I have used ElementTree. This is included in Python 2.5, but if you&#8217;re using an earlier version, you can get ElementTree from <a href="http://effbot.org" onclick="pageTracker._trackPageview('/outgoing/effbot.org?referer=');">Effbot.org</a>.</p>
<p>I won&#8217;t include all the code here, just some snippets as examples. To view the full source, please check out the <a href="http://github.com/beardygeek/beardygeek-website" onclick="pageTracker._trackPageview('/outgoing/github.com/beardygeek/beardygeek-website?referer=');">BeardyGeek Github Repository</a>.</p>
<p>First we need to load our xml file.</p>
<pre><code>
tree = ElementTree.parse('c:/wordpress.xml')
</code></pre>
<p>Then find the top level under which our data resides, which is the &#8216;channel&#8217; tag.</p>
<pre><code>
chan = tree.find('channel')
</code></pre>
<p>Now I want to create some shortcut variables for the namespaces that we will use when finding tags.</p>
<pre>
<code>
wp_ns = '{http://wordpress.org/export/1.0/}'
content_ns = '{http://purl.org/rss/1.0/modules/content/}'
</code>
</pre>
<p>Now we can get all the category, tag and item(post) entries:</p>
<pre><code>
cats = chan.findall('{http://wordpress.org/export/1.0/}category')
tags = chan.findall('{http://wordpress.org/export/1.0/}tag')
items = chan.findall('item')
</code></pre>
<p>This will give us lists of all the elements for those three items.</p>
<p>
<h4>Finding and Saving Data</h4>
<p>I&#8217;ll give an example of saving the data using the category tag.</p>
<pre>
<code>
for cat in cats:
        c = Category(text=cat.find(wp_ns + 'cat_name').text,
                 slug=cat.find(wp_ns + 'category_nicename').text)
        c.save()
</code>
</pre>
<p>The tag data is the same as the above.</p>
<p>The item data is a bit more complex. If you look at the xml you&#8217;ve exported, you&#8217;ll see that the item data includes both posts and pages. But it also gives all previous revisions of each post, which will include any drafts saved whilst writing a post. So we need to find all those with a status of &#8216;publish&#8217; and a page type of &#8216;post&#8217;. We&#8217;ll deal with the &#8216;page&#8217; data another time, using Flatpages.</p>
<pre>
<code>
if item.find(wp_ns + 'status').text == 'publish' and
               item.find(wp_ns + 'post_type').text == 'post':
            i = Post(title=item.find('title').text,
                     slug=item.find(wp_ns + 'post_name').text,
                     content=item.find(content_ns + 'encoded').text, author=u,
                     post_date=item.find(wp_ns + 'post_date').text,
                     status='P')
            i.save()
</code>
</pre>
<p>The &#8216;u&#8217; (value for author) is a User object I create earlier in the code that I&#8217;ve used as the default author of each post (see source).</p>
<p>
<h4>Post Categories</h4>
<p>Now we have to find out which categories and tags this post has. Within each &#8216;item&#8217; we have &#8216;category&#8217; data. A bit confusingly this &#8216;category&#8217; data also includes the tags, and to discover that you need to look at the &#8216;domain&#8217; attribute to see which it is. Plus we only need the category with the &#8216;nicename&#8217; in it (slugified).</p>
<pre>
<code>
post_cats = item.findall('category')

for pc in post_cats:
     #check for attributes
     if pc.get('nicename'):
         if pc.attrib['domain'] == 'category':
              c2 = Category.objects.get(slug=pc.attrib['nicename'])
              i.categories.add(c2)
         elif pc.attrib['domain'] == 'tag':
              t2 = Tag.objects.get(slug=pc.attrib['nicename'])
              i.tags.add(t2)
</code>
</pre>
</p>
<p>
<h4>Comments</h4>
<p>The last section deals with comments. I am using the django.contrib.comments module for this.</p>
<pre>
<code><br />
comments = item.findall(wp_ns + 'comment')</p>
<p>for comm in comments:<br />
    if not comm.find(wp_ns + 'comment_author_email').text:<br />
        comm_email = ''<br />
    else:<br />
        comm_email = comm.find(wp_ns + 'comment_author_email').text</p>
<p>        if not comm.find(wp_ns + 'comment_author_url').text:<br />
            comm_url = ''<br />
        else:<br />
            comm_url = comm.find(wp_ns + 'comment_author_url').text</p>
<p>        db_comm = Comment(comment=comm.find(wp_ns + 'comment_content').text,<br />
            ip_address=comm.find(wp_ns + 'comment_author_IP').text,<br />
            object_pk=i.id, submit_date=comm.find(wp_ns + 'comment_date').text,<br />
            user_email=comm_email,<br />
            user_name=comm.find(wp_ns + 'comment_author').text[:50],<br />
            user_url=comm_url,<br />
            content_type=ct, site=site)<br />
        db_comm.save()<br />
</code>
</pre<br />
</p>
<p>
<h4>Conclusion</h4>
<p>Well that wraps it up for this post. I'll cover extracting the data for Flatpages in the next post, but this should give you enough to get started. You can see how to extract the required data from the xml document, so if you want to extend the models beyond what I have, you shouldn't have any problems.  Again, check out the fully code, plus the other file changes (url.py etc) at <a href="http://github.com/beardygeek/beardygeek-website" onclick="pageTracker._trackPageview('/outgoing/github.com/beardygeek/beardygeek-website?referer=');">the Beardy Geek Git Hub Repository</a>. Have fun.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2009/01/from-wordpress-to-django-part-two/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>From Wordpress to Django &#8211; Part 1</title>
		<link>http://www.beardygeek.com/2009/01/from-wordpress-to-django-part-one/</link>
		<comments>http://www.beardygeek.com/2009/01/from-wordpress-to-django-part-one/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 18:55:00 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Blogging]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=43</guid>
		<description><![CDATA[Now don't get me wrong, there's nothing wrong with Wordpress.  It's just that I like to play with stuff, so I thought it would be fun to create a blog in Django, copy all my Wordpress posts across, and add at least some of the functionality that Wordpress has built in.]]></description>
			<content:encoded><![CDATA[<p>Now don&#8217;t get me wrong, there&#8217;s nothing wrong with Wordpress.  It&#8217;s just that I like to play with stuff, so I thought it would be fun to create a blog in Django, copy all my Wordpress posts across, and add at least some of the functionality that Wordpress has built in.</p>
<h4>Open Source</h4>
<p>Throughout this process, so that you can follow along, I will be storing the code in a GitHub repository.  <a href="http://github.com/beardygeek/beardygeek-website" target="_blank" onclick="pageTracker._trackPageview('/outgoing/github.com/beardygeek/beardygeek-website?referer=');">Click here to view the BeardyGeek repository</a></p>
<h4>A Few Considerations</h4>
<p>There are a few things to think about before getting started:</p>
<ol>
<li>Data Conversion &#8211; getting the data from Wordpress into my Django models.  Do I want to keep the same database structure as Wordpress, or create my own?  If I create my own, how will I get the data across?</li>
<li>Services &#8211; how much do I try and implement?  The main ones are comments, tags, pings, anti-spam.</li>
</ol>
<p>I&#8217;m sure more will come to mind as I go through this</p>
<h4>Conclusion</h4>
<p>Well, I&#8217;d better stop jabbering and get on with it then!  Keep an eye on the blog, or watch the Git repo for updates.  I&#8217;ll get done whatever my current workload allows.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2009/01/from-wordpress-to-django-part-one/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Call a .Net Webservice using Python</title>
		<link>http://www.beardygeek.com/2009/01/how-to-call-a-net-webservice-using-python/</link>
		<comments>http://www.beardygeek.com/2009/01/how-to-call-a-net-webservice-using-python/#comments</comments>
		<pubDate>Thu, 01 Jan 2009 12:51:46 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[web service]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=8</guid>
		<description><![CDATA[Learn how to consume a .net webservice using Python]]></description>
			<content:encoded><![CDATA[<p>My day job involves working with software that automatically creates webservices on the .Net platform. Up until now I have used C# to create web applications to use these webservices.</p>
<p>But it would be nice to have the flexibility to use another programming language to create a solutions, and consume the webservices from there.</p>
<p>So, here&#8217;s a short tutorial on calling your .net webservice using Python.</p>
<p>
<h4>Pre-requisites</h4>
<ol>
<li>I&#8217;m currently using Python 2.5, so I can&#8217;t speak for other versions</li>
<li>You will need the ElementSoap package from effbot.org.  <a href="http://effbot.org/downloads/#elementsoap" onclick="pageTracker._trackPageview('/outgoing/effbot.org/downloads/_elementsoap?referer=');">You can get it from here</a></li>
<li>You&#8217;re also going to need a .Net webservice with which to test this out. If you&#8217;re reading this tutorial, you probably already have one.</li>
</ol>
<p>
<h4>SOAP</h4>
<p>Firstly we need to look at the SOAP examples on your .Net webservice.  Go your webservice&#8217;s asmx page, and then click on one of your webservices to view the details.  You will see some example SOAP requests and responses.  The one we&#8217;re interested in here is SOAP 1.1.  Mine looks like this:</p>
<pre>
<code>
POST /lookserver/webservices.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/GetVersion"

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;
  &lt;soap:Body&gt;
    &lt;getVersion xmlns="http://tempuri.org/" /&gt;
  &lt;/soap:Body&gt;
&lt;/soap:Envelope&gt;

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

&lt;xml version="1.0" encoding="utf-8"?&gt;
&lt;soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;
  &lt;soap:Body&gt;
    &lt;getVersionResponse xmlns="http://tempuri.org/"&gt;
      &lt;getVersionResult&gt;string&lt;/getVersionResult&gt;
    &lt;/getVersionResponse&gt;
  &lt;/soap:Body&gt;
&lt;/soap:Envelope&gt;
</code>
</pre>
<p>As we can see here, I have a webservice called GetVersion, the namespace is http://tempuri.org, and the SOAPAction is http://tempuri.org/GetVersion.  Note these down for your webservice.
</p>
<p>
<h4>Into the Python</h4>
<p>Fire up an interactive session, and we&#8217;ll go through calling this service.</p>
<p>Firstly we need to import the ElementSOAP library:</p>
<pre>
<code>from elementsoap import ElementSOAP as ES</code>
</pre>
<p>
</p>
<p>If you get an error message, then you haven&#8217;t installed ElementSoap properly.
</p>
<p>Next we create a SoapRequest:</p>
<pre>
<code>sr = ES.SoapRequest("{http://tempuri.org/}GetVersion")</code>
</pre>
<p></p>
<p>And now we initialize a SoapService object:</p>
<pre>
<code>serv = ES.SoapService("http://localhost/lookserver/webservices.asmx")</code>
</pre>
<p></p>
<p>Obviously put in your own url for your webservice.</p>
<p>Now we call the webservice, using the SOAPAction value:</p>
<pre>
<code>result = serv.call("http://tempuri.org/GetVersion", sr)</code>
</pre>
<p></p>
<p>The result is an xml element which should contain the response from your webservice. When I type result I get:</p>
<pre>
<code>&lt;element '{http://tempuri.org/}GetVersionResponse' at 00A1A8A8&gt;</code>
</pre>
<p></p>
<p>If you look at the xml at the top of the article, you&#8217;ll see that the result returns inside a GetVersionResponse tag.  To get the value of the result we type:</p>
<pre>
<code>result.find("{http://tempuri.org/}GetVersionResult").text</code>
</pre>
<p></p>
<p>This finds the appropriate tag, and returns the text.
</p>
<p>&nbsp;</p>
<h4>Conclusion</h4>
<p>I hope this has helped.  When I searched, I found that the other tutorials were either confusing, or out of date.  Take a look at the various libraries at effbot.org, especially ElementTree for parsing XML, very useful.  Enjoy!</p>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2009/01/how-to-call-a-net-webservice-using-python/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Django and Ajax &#8211; using Prototype and Scriptaculous</title>
		<link>http://www.beardygeek.com/2008/12/django-and-ajax-using-prototype-and-scriptaculous/</link>
		<comments>http://www.beardygeek.com/2008/12/django-and-ajax-using-prototype-and-scriptaculous/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 18:53:00 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=39</guid>
		<description><![CDATA[I started adding a sprinkling of Ajax in one of my Django projects, so I thought I'd share a few snippets that might help you add some Ajax goodness into your app.]]></description>
			<content:encoded><![CDATA[<p>I started adding a sprinkling of Ajax in one of my Django projects, so I thought I&#8217;d share a few snippets that might help you add some Ajax goodness into your app.</p>
<p>To handle the Ajax callbacks, I&#8217;ll be using <a href="http://www.prototypejs.org" onclick="pageTracker._trackPageview('/outgoing/www.prototypejs.org?referer=');">Prototype</a>, a lightweight Ajax library.  And for a couple of effects, like fade-in, I&#8217;ll be using <a href="http://script.aculo.us/" onclick="pageTracker._trackPageview('/outgoing/script.aculo.us/?referer=');">Scriptaculous</a>.</p>
<p>
<h4>Ajax Voting</h4>
<p>I wanted to add a Digg-like voter to my app, where you have the number of votes showing with a vote button, and when you click on the vote button, the number disappears, then fades back in with an increase in the vote.  The new vote will be added to the database.  I also wanted to only allow each user to only vote on each item once (for obvious reasons!)</p>
<p>
<h4>Overview</h4>
<p>Here&#8217;s how it hangs together. The user presses the vote button. This calls back to a url, which has a view, which retrieves and/or stores data, which then renders the output to a template, which is then inserted by magic under the button with the new stored value.</p>
<p>Now on with some code.</p>
<p>
<h4>Urls</h4>
<p>First we need to define a url for the callback.</p>
<pre>
<code>url(r'^callback/vote/(?P<item_id>\d+)/$', 'vote', name='callback_vote'),</code>
</pre>
</p>
<p>
<h4>Models</h4>
<p>For the purposes of this post, I&#8217;ll create 2 models.  The first is an item model, where we can store an item description, and the number of the votes that item has:</p>
<pre>
<code>
class Item(models.Model):
    item_desc = models.CharField(max_length=200)
    votes = models.IntegerField()
</code>
</pre>
<p>Now we can create a Voter model, which stores who voted for which item, so we can prevent multiple voting for each user:</p>
<pre>
<code>
from django.contrib.auth.models import User

class Voter(models.Model):
    voter = models.ForeignKey(User)
    item = models.ForeignKey(Item)
</code>
</pre>
</p>
<p>
<h4>Script Tags</h4>
<p>Now we need to import the Javascript for Prototype and Scriptaculous. We can either do this in our base.html, which means the javascript will be loaded on every page, or we could add a block into the header, and just load the javascript on a per page basis. I have also stored the scripts in my MEDIA_URL.</p>
<pre>
<code>
&lt;script type="text/javascript" src="{{ MEDIA_URL }}scripts/prototype.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"
    src="{{ MEDIA_URL }}scripts/scriptaculous.js?load=effects"&gt;&lt;/script&gt;
</code>
</pre>
<p>You&#8217;ll see the load=effects option after the scriptaculous url. This is so it doesn&#8217;t load all of the modules. You can if you want, but for this example we only need the effect module.
</p>
<p>
<h4>Prototype Script</h4>
<p>For the prototype script to work, and update our vote number, we need to have a page element to update. You could have a div or a span, but you need to give the element an id and a name.</p>
<p>Now for the script.</p>
<pre>
<code>
&lt;script type="text/javascript"&gt;
	function addVote(item_id) {
		$('item').style.display = 'none';
		var ajax = new Ajax.Request('callback/vote/' + item_id + '/', {
				method: 'get',
				onSuccess: function(transport) {
					var result = $('item');
					result.update(transport.responseText);
				}
			});
		$('item').appear();
	}
&lt;/script&gt;
</code>
</pre>
<p>I&#8217;m assuming we&#8217;ve called the span or div id &#8216;item&#8217;. The $(&#8216;item&#8217;) is a short cut to get a reference to the element. Firstly we call the function with the item id as a parameter. Then we set the display to &#8216;none&#8217; before doing the callback. The callback is done, we update the div element using result.update, and the final line uses the Scriptaculous &#8216;appear()&#8217; function, which fades the div back in.</p>
<p>Don&#8217;t forget to add an onclick() or similar event to what ever you want to use to trigger the callback. In my case I used the tick image.</p>
<pre>
<code>
&lt;a onclick="addVote({{ n.id }})"&gt;&lt;img src"..." /&gt;&lt;/a&gt;
</code>
</pre>
<p>I used n as a context for my item on the view for this page, in case you&#8217;re wondering what the {{ n.id }} is for.</p>
<p>
<h4>Callback Code</h4>
<p>Now we have the client side script, we need to take that item id and do something with it, then return the result for display.</p>
<p>First we need to create the vote view.</p>
<pre>
<code>
def vote(request, item_id):
    i = Item.objects.get(pk=item_id)
    #see if user has voted
    voter = Voter.objects.filter(voter=request.user, item=i)

    if not voter:
        v = Voter(voter=request.user, item=i)
        v.save()
        i.votes += 1
        i.save()

    return render_to_response('item/callback_vote.html', {'votes':i.votes})
</code>
</pre>
<p>We get our item object first, then check the Voter model to see if the current logged in user has already voted for this item. If they haven&#8217;t, then we create a Voter entry, and increase the number of votes by one. We then return the number of votes in the context.</p>
<p>
<h4>Callback Template</h4>
<p>Now we create a simple template to display the vote view.</p>
<pre>
<code>
{{ votes }}
</code>
</pre>
</p>
<p>
<h4>Conclusion</h4>
<p>And there we have it. That&#8217;s the basics of Ajax in Django. There&#8217;s a lot more to Scriptaculous than just the fade and appear, so check it out.</p>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2008/12/django-and-ajax-using-prototype-and-scriptaculous/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating User Profiles with Image Thumbnails in Django</title>
		<link>http://www.beardygeek.com/2008/11/creating-user-profiles-with-image-thumbnails-in-django/</link>
		<comments>http://www.beardygeek.com/2008/11/creating-user-profiles-with-image-thumbnails-in-django/#comments</comments>
		<pubDate>Thu, 20 Nov 2008 18:48:18 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Featured]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=32</guid>
		<description><![CDATA[How to create user profiles with image thumbnails in Django]]></description>
			<content:encoded><![CDATA[<p>I am currently working on a django application that will include a profile page for each user.  Like many web apps, it will have the ability to upload a profile picture, and have this picture shrunk to a suitable thumbnail size.</p>
<p>To complicate matters, I want the photo uploaded to a directory which will be named after the user.</p>
<p>I&#8217;m fairly new to Django, so it took some time to piece this all together, but someone out there may have had the same problems and I hope this post helps.</p>
<h4>Prerequisites</h4>
<p>You must have the Python Imaging Library installed.  You can get this from the <a href="http://www.pythonware.com/products/pil/" onclick="pageTracker._trackPageview('/outgoing/www.pythonware.com/products/pil/?referer=');">PIL homepage</a>.
</p>
<h4>User Profiles</h4>
<p>The first thing we need to do is create a model for our user profile.</p>
<pre>
<code>from django.db import models
from django.contrib.auth.models import User</code>

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    nickname = models.CharField(max_length=50, blank=True, null=True)
    photo = models.ImageField(upload_to='profile_pics', blank=True, null=True)
    thumbnail = models.ImageField(upload_to='profile_thumb', blank=True, null=True,
          editable=False)
</code>
</pre>
<p>I&#8217;ve made the upload_to attributes static for the time being, but we will be changing this later.</p>
<h4>User Profile Setup</h4>
<p>So that Django knows which model to use for you user profile, you have to add a setting to your settings file.</p>
<pre><code>
AUTH_PROFILE_MODULE = 'appname.UserProfile'
</code></pre>
<p>Make sure that this uses your app name, not your project name.  I&#8217;ve used UserProfile for the model, but you can call it whatever you like.</p>
<h4>Dynamic Upload Directory</h4>
<p>To make the upload_to attribute dynamic based on the current user, we have to write a small function that returns the appropriately formed path.  My thanks to <a href="http://joshourisman.com" onclick="pageTracker._trackPageview('/outgoing/joshourisman.com?referer=');">Josh Ourisman</a> and <a href="http://joshourisman.com/2008/11/18/dynamic-upload-path-django-filefieldimagefield/" onclick="pageTracker._trackPageview('/outgoing/joshourisman.com/2008/11/18/dynamic-upload-path-django-filefieldimagefield/?referer=');">his post</a> for this part.</p>
<p>Create a file called files.py and save it in your application directory.</p>
<pre><code>
def get_profile_path(instance, filename)
    dir = "%s/profile_pics/%s" % (instance.user, filename)
    return dir
</code></pre>
<p>This will make the profile picture save in the directory &#8216;username/profile_pics/filename&#8217;.  You can move these around if you want a different directory structure.  The MEDIA_ROOT value from your settings file will be prepended to this path automatically, so make sure you set that.</p>
<h4>Amend the Model</h4>
<p>Now back to our model, where we call our new function from the upload_to attribute.</p>
<pre><code>
<b>from projname.appname.files import get_profile_path</b>

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    nickname = models.CharField(max_length=50, blank=True, null=True)
    photo = models.ImageField(<b>upload_to='get_profile_path'</b>, blank=True, null=True)
    thumbnail = models.ImageField(upload_to='profile_thumb', blank=True, null=True,
         editable=False)
</code></pre>
<p>We will leave the thumbnail upload_to field, as we will be dealing with that one manually.</p>
<h4>Creating the View</h4>
<p>I wanted to just create one view that would handle creating a new profile, and displaying and updating an existing profile.  First I&#8217;ll create a form to display in the view.</p>
<pre><code>
from django import forms
from django.forms import ModelForm
from projname.appname.models import UserProfile

class UserProfileForm(ModelForm):
    class Meta:
        model = UserProfile
        exclude = ('user')
</code></pre>
<p>Now to the view</p>
<pre><code>
from django.shortcuts import render_to_response
from django.template import RequestContext
from famblog.blog.forms import UserProfileForm
from famblog.blog.models import UserProfile

from django.contrib.auth.decorators import login_required

@login_required
def profile(request):
    try:
        myprofile = request.user.get_profile()
    except:
        up = UserProfile(user=request.user)
        up.save()
        myprofile = request.user.get_profile()

    if request.method == 'POST':
        f = UserProfileForm(request.POST, request.FILES, instance=myprofile)
        if f.is_valid():
            f.save()
    else:
        f = UserProfileForm(instance=myprofile)

    return render_to_response('appname/profile.html', {'f':f, 'profile':myprofile},
        context_instance = RequestContext(request))
</code></pre>
<p>This view will try and retrieve the user profile based on the current logged in user.  If the user profile doesn&#8217;t exist, then an exception is thrown.  If this happens, we create a profile with just the username and call get_profile() again.  We then deal either with a POST event, or we bind the retrieved profile instance to the form ready for updating by the user.</p>
<p>If you don&#8217;t want to create thumbnails of your images, you can leave it here.  The images will have been loaded</p>
<h4>Thumbnail Creation</h4>
<p>To create the thumbnail, we now need to override the save def in our model.</p>
<pre><code>
def save(self, force_insert=False, force_update=False):
        #get mtime stats from file
        thumb_update = False

        if self.thumbnail:
            statinfo1 = os.stat(self.photo.path)
            statinfo2 = os.stat(self.thumbnail.path)
            if statinfo1 > statinfo2:
                thumb_update = True

        if self.photo and not self.thumbnail or thumb_update:
            from PIL import Image

            THUMB_SIZE = (150, 150)

            #self.thumbnail = self.photo

            image = Image.open(self.photo.path)

            if image.mode not in ('L', 'RGB'):
                image = image.convert('RGB')

            image.thumbnail(THUMB_SIZE, Image.ANTIALIAS)
            (head, tail) = os.path.split(self.photo.path)
            (a, b) = os.path.split(self.photo.name)

            if not os.path.isdir(head + '/thumbs'):
                os.mkdir(head + '/thumbs')

            image.save(head + '\\thumbs\\' + tail)

            self.thumbnail = a + '/thumbs/' + b

        super(UserProfile, self).save()
</code></pre>
<p>First we set a thumb_update var to false.  Then, if the thumbnail exists, we check to see if the timestamp on the original image is newer than the existing thumbnail.  If we didn&#8217;t check for this, then when we changed the image, we wouldn&#8217;t know whether or not to create the thumbnail.</p>
<p>The rest of the code deals with using the Imaging Library to resize the image.  It also creates a &#8216;thumbs&#8217; directory if one doesn&#8217;t already exist, saves the image, and updates the &#8216;thumbnail&#8217; field in the model.</p>
<h4>Conclusion</h4>
<p>I hope this has been helpful.  Like I said, I haven&#8217;t been using Django or Python for more than a few weeks, so if anyone has any suggestions for improving this code, then please comment.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2008/11/creating-user-profiles-with-image-thumbnails-in-django/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Django Template Auto-completion in Eclipse</title>
		<link>http://www.beardygeek.com/2008/11/django-template-auto-completion-in-eclipse/</link>
		<comments>http://www.beardygeek.com/2008/11/django-template-auto-completion-in-eclipse/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 13:56:28 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[ide]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=16</guid>
		<description><![CDATA[How to setup Django Template auto-completion in Eclipse]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just recently started using <a href="http://www.djangoproject.com" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.djangoproject.com?referer=');">Django</a> and I wanted to set up an IDE for some coding niceties.</p>
<p>I already use Eclipse for PHP development, so I installed the PyDev plugin for Eclipse.</p>
<p>Now I get autocomplete in the py files, but when writing the Django html templates, there is no autocomplete for the various template tags.</p>
<p><strong>So here&#8217;s a quick guide to adding your own tags in Eclipse.</strong></p>
<ol>
<li>In Eclipse, go to Window-&gt;Preferences</li>
<li>Go down to Web and XML.</li>
<li>Then to HTML files and finally Templates</li>
<li>You will see a list of all the various HTML templates there.</li>
<li>Click on New.</li>
<li>Give your tag a name.  It can&#8217;t be one that&#8217;s already taken, but I found I didn&#8217;t have any issues.  If you want to keep them all together you could start your tag name with &#8216;DJ&#8217;.</li>
<li>Select HTML Tag from the drop down.</li>
<li>Give your tag a description.</li>
<li>Type in the the tag pattern.  If you want the full tag on autocomplete, you might type in {% block ${cursor} %}, otherwise you could start with block, which means you would need to type in the {% and then activate the autocomplete in the HTML editor.  The ${cursor} places the cursor where you want it after the tag has been inserted.</li>
<li>Click Apply and OK.</li>
<li>Test this out in the HTML editor.  Press CTRL and Space.  You should get a list of available tags.  Type b (or what ever the first character is for you tag name), and you&#8217;ll see your block tag with the description next to it.</li>
<li>Press enter, and your tag will appear.</li>
</ol>
<p>Hopefully this will make your Django coding a little easier.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2008/11/django-template-auto-completion-in-eclipse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web 3.0 &#8211; How to put Semantic Tags in your Blog</title>
		<link>http://www.beardygeek.com/2008/03/web-30-how-to-put-semantic-tags-in-your-blog/</link>
		<comments>http://www.beardygeek.com/2008/03/web-30-how-to-put-semantic-tags-in-your-blog/#comments</comments>
		<pubDate>Sat, 01 Mar 2008 12:00:05 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Web 3]]></category>
		<category><![CDATA[hatom]]></category>
		<category><![CDATA[semantic]]></category>
		<category><![CDATA[web3]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=1</guid>
		<description><![CDATA[Learn how to put semantic markup tags in your blog.]]></description>
			<content:encoded><![CDATA[<p>I read the other day how Yahoo was going to start <a href="http://www.ysearchblog.com/archives/000527.html" onclick="pageTracker._trackPageview('/outgoing/www.ysearchblog.com/archives/000527.html?referer=');">supporting semantic web standards</a>.</p>
<p>The semantic web is something that is often associated with Web 3.0 (if that&#8217;s what you want to call it!), and will allow greater data exchange, better and more targeted search, and generally open things up for a super mash-up.  Take a look at <a href="http://en.wikipedia.org/wiki/Web_3" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Web_3?referer=');">Wikipedia&#8217;s definition of Web 3.0</a> for more info.</p>
<p>One of the formats that Yahoo will initially support is <a href="http://microformats.org/wiki/hatom" onclick="pageTracker._trackPageview('/outgoing/microformats.org/wiki/hatom?referer=');">hAtom</a>, which is a <a href="http://microformats.org/" onclick="pageTracker._trackPageview('/outgoing/microformats.org/?referer=');">microformat</a> especially for blog entries.</p>
<p>So, I thought I&#8217;d take a look at it and try and implement it in the BeardyGeek blog.</p>
<p><u><strong>First Steps</strong></u></p>
<p>To add an hAtom feed to your blog, all you need to do is add some class names to what are probably existing divs or spans in your blog template.</p>
<p>For example, if you have a div around your entire content that looks like this:</p>
<p><font color="#008000">&lt;div class=&#8221;content&#8221;&gt;</font></p>
<p>you just need to add an extra class tag called hfeed:</p>
<p><font color="#008000">&lt;div class=&#8221;content hfeed&#8221;&gt;</font></p>
<p>To have more than one class, just separate them with a space.</p>
<p>There are 3 more main tags that you need.</p>
<ul>
<li><strong>hentry</strong> &#8211; the outer tag for each blog post</li>
<li><strong>entry-title </strong>- the tag for the post title</li>
<li><strong>entry-content</strong> &#8211; the tag for your post content</li>
</ul>
<p>And that&#8217;s it.  Easy as pie!</p>
<p><u><strong>How I changed my Wordpress Theme</strong></u></p>
<p>Ok, here&#8217;s what I changed in my theme.</p>
<p><strong>Header page</strong> &#8211; At or near the bottom is a div tag &#8211; <font color="#008000">&lt;div class=&#8221;content&#8221;&gt;</font> &#8211; I changed that to <font color="#008000">&lt;div class=&#8221;content hfeed&#8221;&gt;</font>.</p>
<p><strong>Single Post </strong>- I added the hentry tag to <font color="#008000">&lt;div class=&#8221;post&#8221;&gt;</font> so it now read <font color="#008000">&lt;div class=&#8221;post hentry&#8221;&gt;</font>.  I then added entry-title to the <font color="#008000">&lt;h2 class=&#8221;post-title&#8221;&gt;</font> so it read <font color="#008000">&lt;h2 class=&#8221;post-title entry-title&#8221;&gt;</font>.  And I also add entry-content to <font color="#008000">&lt;div class=&#8221;postentry&#8221;&gt;</font> so it read <font color="#008000">&lt;div class=&#8221;postentry entry-content&#8221;&gt;</font>.</p>
<p><strong>Main index template</strong> &#8211; pretty much the same as the single post page, as the tags are all the same.</p>
<p><u><strong>Testing</strong></u></p>
<p>To test the feed, I downloaded <a href="https://addons.mozilla.org/en-US/firefox/addon/748" onclick="pageTracker._trackPageview('/outgoing/addons.mozilla.org/en-US/firefox/addon/748?referer=');">Greasemonkey</a> plugin for Firefox.  I then downloaded the <a href="http://userscripts.org/scripts/show/6073" onclick="pageTracker._trackPageview('/outgoing/userscripts.org/scripts/show/6073?referer=');">RSS Panel X</a> script for Greasemonkey, which allows you to view a page&#8217;s feeds in a small JavaScript window.  This is ideal for testing in this case as it supports hAtom.</p>
<p>Once you have these installed and running (tip: install the plugin first, then the script installs automatically), just load up your blog page.  If all went according to plan, you should see your hAtom feed along with your RSS feed.</p>
<p>In fact, you can test it out here, as I have my hAtom feed up and running!</p>
<p>Good luck, let me know how you get on.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2008/03/web-30-how-to-put-semantic-tags-in-your-blog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
