Saltycrane logo

Sofeng's Blog

Notes on Python, Django, and web development on Ubuntu Linux

     Posts for August 2008

Notes on Django and MySql on Amazon's EC2


Install Elasticfox

Install the Elasticfox Firefox Extension for Amazon EC2: http://developer.amazonwebservices.com/connect/entry.jspa?externalID=609

Set up Amazon EC2 accounts and Elasticfox

Follow Arope's instructions for setting up Amazon EC2 accounts and Elasticfox. I used the alestic/ubuntu-8.04-hardy-base-20080628.manifest.xml machine image.

view standard apache page

In Elasticfox, right-click on your running instance and select "Copy Public DNS Name to clipboard". Then, paste that address in your browser. You should see Apache's "It works!" page.

ssh into instance

In Elasticfox, right-click on your running instance and select "SSH to Public Domain Name"

install ...
Read more...

How to conditionally replace items in a list


I wanted to replace items in a list based on a specific condition. For example, given a list of numbers, I want to replace all items that are negative with zero.

Naive way

At first, I thought of something like this:

mylist = [111, -222, 333, -444]
newlist = []
for item in mylist:
    if item < 0:
        item = 0
    newlist.append(item)
mylist = newlist
print mylist

Which gave me the expected results:

[111, 0, 333, 0]
Better way?

Then I tried using Python's enumerate (see my previous example) built-in function to replace the item in-line. This seems to be a more elegant ...

Read more...

Django Blog Project #12: Adding Pygments syntax highlighting


I've finally added automatic code highlighting to my blog. It uses Pygments to do the syntax highlighting and Beautiful Soup to find all the <pre> blocks to highlight. I still write my blog posts in HTML, but now add a class attribute to my <pre> tags to specify the Pygments lexer to use. For example, for python code, I use:

<pre class="python">
import this
def demo():
    pass</pre>

Which turns into:

import this
def demo():
    pass

I bought James Bennett's book, Practical Django Projects about a month ago and it has good information about creating a blog ...

Read more...

Notes on users and groups on Linux


Here are some notes on some basic tasks dealing with users, groups, and permissions on Ubuntu Linux. All these commands (except passwd) are done as root. If you are not root, prepend sudo to all the commands.

  • Add a user, sofeng
    # adduser sofeng
  • Change your password:
    $ passwd
  • Create a developer group
    # addgroup developer
  • Add user sofeng to the developer group
    # adduser sofeng developer
  • Give developer group sudo power:
    Add the following line to /etc/sudoers:
    %developer ALL=(ALL) ALL
  • Change owner to sofeng, and group to developer, of directory, mydir, and all its subdirectories:
    # chown -R sofeng:developer mydir
  • Change ...
Read more...

Python recursion example to navigate tree data


Here is a simple Python example using recursion to navigate a nested Python data structure. Each node in the data structure contains 0 or more children. In this simple example, I look at each node and print the "text" indented according to the nesting level within the data structure.

Update 2008-09-15: Nihiliad posted an improvement to my example in the comments. It is much simpler. I have updated my example below.

Nihiliad's (improved) method
data = {'count': 2,
        'text': '1',
        'kids': [{'count': 3,
                  'text': '1.1',
                  'kids': [{'count': 1,
                            'text': '1.1.1',
                            'kids': [{'count':0,
                                      'text': '1.1.1 ...
Read more...

On using Python, the Digg API, and simplejson


Here are some quick notes on using the Digg API with a Python script. Note, there is a Python toolkit for Digg but I just used urllib2 and the Digg API endpoints for the sake of simplicity.

I wanted the output in JSON format so I specified the response type as JSON. To decode JSON directly to a Python data structure, I used simplejson.

Here is a simple example which returns the JSON output for the Digg story Dell vs. Apple: This Time it's Personal which has a "clean title" of Dell_vs_Apple_This_Time_it_s_Personal.

#!/usr/bin/env python

import urllib2

APPKEY ...
Read more...

http://www.saltycrane.com is my new OpenID


Open ID is a new technology that allows you to use one set of login credentials to access many sites. This is good because you don't have to remember yet another password or go through yet another Web 2.0 community registration process.

Simon Willison wrote a simple, clear explanation on how to turn your blog in to an OpenID. I followed his instructions, and now http://www.saltycrane.com/ is my new Open ID! I look forward to putting it to good use. (In case you're wondering, yes, I am planning to add Open ID support to ...

Read more...

Somewhere on your Python path


As I install new python packages, I sometimes see instructions which say something like "check out the code, and place it somewhere on your Python path". These are very simple instructions, but since it is not automatic like a Windows installer, or Ubuntu's package management system, it causes me to pause. Where on my Python path should I put it? I could put all my packages in random places and update my PYTHONPATH environment variable every time. I also thought about putting new packages in Python's site-packages directory. This is probably a good option. However, I tend to ...

Read more...

Django Blog Project #11: Migrating from Django 0.96 to SVN Trunk


I've been using the Django 0.96 release for this blog, but I've been thinking about switching to the SVN trunk version since it is recommended by the Django community. Django 1.0 alpha was released a couple weeks ago, so now seems like a good time to migrate.

Here are the changes I had to make. There were suprisingly few changes required-- probably because I'm not using a lot of the Django functionality. For a complete list of changes, see the Backwards-incompatible changes documentation.

Note, I am using trunk revision 8210. (2 weeks post Alpha).

Model ...
Read more...

Notes on moving Ubuntu Wubi to a standard ext3 partition using LVPM


Here are my notes for moving my wubi Ubuntu install to a dedicated ext3 partition. I used the Loopmounted Virtual Partition Manager (LVPM) to do the transfer. From the webpage:

The Loopmounted Virtual Partition Manager allows users to upgrade their existing Wubi or Lubi installation to a standard Ubuntu system by transferring all data, settings, and applications from the original install to a dedicated partition. The advantages of upgrading using LVPM are better disk performance and reliability, and the ability to replace the original operating system with Ubuntu.

Add 2 new partitions

My hard disk had only 1 partition containing ...

Read more...

How to use gnip-python to retrieve activity from Twitter, Delicious, Digg, etc.


  • Create an account at http://www.gnipcentral.com/
  • Download gnip-python from github.com.
  • Unpack it:
    $ tar -zxvf gnip-gnip-python-028364a70bd40dda0069ecdd3e7f6fff23bb985e.tar.gz
    
  • Move it to your example directory:
    $ mkdir ~/src/python/gnip-example
    $ mv gnip-gnip-python-028364a70bd40dda0069ecdd3e7f6fff23bb985e/*.py ~/src/python/gnip-example
  • Create an example file called ~/src/python/gnip-example/gnip-example.py:
    #!/usr/bin/env python
    
    from gnip import *
    
    gnip = Gnip("yourgniplogin@email.com", "yourpassword")
    
    for publisher in ["twitter", "digg", "delicious"]:
        activities = gnip.get_publisher_activities(publisher)
        print
        print publisher
        for activity in activities[:5]:
            print activity
    
  • Run it:
    $ python gnip-example.py

    And get the following results:
    twitter
    [derricklo, 2008-08-01T22:49:59+00:00, tweet, http://twitter.com ...
Read more...

Django Blog Project #10: Adding support for multiple authors


Here is a quick post on how I added support for multiple users on my blog.

Modfiy the model
Excerpt from ~/src/django/myblogsite/myblogapp/models.py:
import re
from django.db import models
from django.contrib.auth.models import User

class Post(models.Model):
    author = models.ForeignKey(User)
    title = models.CharField(maxlength=200)
    slug = models.SlugField(maxlength=200,
                            prepopulate_from=['title'],
                            unique_for_month='date_created')
    date_created = models.DateTimeField(auto_now_add=True)
    date_modified = models.DateTimeField(auto_now=True)
    tags = models.CharField(maxlength=200, help_text="Space separated.")
    body = models.TextField()
    body_html = models.TextField(editable=False, blank=True)
    lc_count = models.IntegerField(default=0, editable=False)

    def get_tag_list ...
Read more...
Created with Django | Hosted by Webfaction