PySVN on Mac OS X 10.5 Leopard 1

Posted by Justin Lilly Thu, 17 Apr 2008 04:38:00 GMT

Holy Goodness. I spent 2 days trying to get PySVN installed on Leopard. The .pkg doesn’t work, the source wouldn’t compile… Here are the steps I used to get everything working.

sudo port install subversion // Installs subversion 1.4.6

sudo port install db44 // it was already installed

cd pysvn-1.5.1 // get into the pysvn directory

python setup.py configure // run the configuration file (I missed this step, apparently)

make // Errored: Couldn’t find libdb-4.3.a // Edited Makefile to point /opt/local/lib/libdb-4.3.a to /opt/local/lib/db44/lib-db-4.4.a

make // Success!

Webfaction is wonderful 1

Posted by Justin Lilly Tue, 01 Apr 2008 16:27:00 GMT

A few of you may have noticed that the blog was down for the majority of this morning. There was an issue where my payment was being applied to the wrong account. This requires a bit of explanation, I think.

Webfaction enforces a database name maximum to around 15-16 characters. My username, when I started this blog, was justinlilly. Following their naming conventions, my databases were named justinlilly_blog – only allowing me 4 characters to describe my databases. Thankfully, they helped me switch over to a shorter username which allows me sufficient room to describe databases properly.

Now that everything is fixed, just wanted to send a big thank you to the Webfaction support team and issue another recommendation for their services. Great job guys!

Python Keyword Expansion 1

Posted by Justin Lilly Sat, 29 Mar 2008 15:40:00 GMT

I’ve recently been introduced to keyword expansion by way of Magus- in IRC. Its a pretty simple formula, though powerful in its ability to create generic code. For instance:

foo(bar=baz)

is the same as

foo(**{bar:baz})

For me, this was particularly useful as I found myself building a generic filtering view.

def filter(request, filter_on, filter_by)
    MyModel.objects.filter(**{filter_on:filter_by})

instead of having to create each filter permeation by hand, I can abstract it and just pass in the correct information. A pretty useful trick.

My first real use of *args

Posted by Justin Lilly Thu, 27 Mar 2008 21:31:00 GMT

So I used *args for the first time today. Having read over *args several times, it never really clicked. I got myself into a situation where it occurred to me that maybe it is what I want. A brief google search brought me to Sofeng’s blog post on the subject, which was just what I needed for a quick refresher.

This was the code I was working on:

def personprofile_by_race():
    from django.db import connection
    cursor = connection.cursor()
    cursor.execute("SELECT race, sum(count) as count FROM \
        traffic_personprofile GROUP BY race")
    row = cursor.fetchall()
    return row
def personprofile_by_gender():
    ... etc * 5+ times ...

And here is what it turned into:

def personprofile_by(*args):
    from django.db import connection
    cursor = connection.cursor()
    cursor.execute("SELECT %s, sum(count) as count FROM traffic_personprofile \
        GROUP BY %s" % ((",").join(args), (",").join(args)))
    row = cursor.fetchall()
    return row

Which runs with the syntax:

    personprofile_by('race', 'gender')

Man. I love me some python.

Plans and Problems

Posted by Justin Lilly Thu, 27 Mar 2008 01:15:00 GMT

In an effort to further drive people my blog and offer a little more direction for my writing (beyond “random thoughts”), I’m strongly considering specializing the blog. My first thought was a django for newbies blog that will is a glorified and more in depth irc ad nauseum a la TWiD. The other suggestion by Michael was to browse the source of django projects and offer suggestions to their code. While I am by no means a coding master, I’m willing to make a go of it. I figured I’d ask the few people who have previously commented and any others who may be listening.. which would you visit?

Django-GenCal: How does it work?

Posted by Justin Lilly Fri, 21 Mar 2008 06:43:00 GMT

Alright, so Gencal is now quite a bit more stable thanks to working with James Tauber and the talk given by James Bennett. Thanks guys.

The overall sort of required input is much the same as the previous version. It still expects a datetime passed to render a proper calendar. That being the only required parameter passed to the template tag, the requirements are pretty light. To get anything useful (ie: other date-based items) rendered in the calendar, you’ll have to pass it a second parameter of a list of dicts. This is where the big change occurred. Instead of a loosely coupled tie in to the models, I think I’ve gotten the templatetag completely decoupled from any models. The last little bit of work to get it completely decoupled involved named url patterns for the backward and forward months links.

The new format of the list item is:

  • day is the datetime of the day you’d like to reference
  • url is the url to the object you’d like to reference
  • title is the text of the event that will be rendered
  • class is a non-necessary field that will apply class=”your_entry” to the list item

An example of this:

 cal_items = [{ 'day':datetime(2008,1,30), 'title':"Concert at Huckelberries", 'class':"concert", 'url':'/foo/2' }, 
              { 'day':datetime(2008,2,4), 'title':"BBQ at Mom\'s house", 'calendar':"restaurant", 'url':'/restaurants/9' }]

As I stated in the comments of my previous post, there is now a docstring for the templatetag (as well as the original liberal inline comments). Overall, I think this will be a nice drop-in solution for basic calendaring. Anything super advanced (such as ical syncing, events spanning multiple days (so far at least) You’ll probably want to head over to Google Calendar.

Now its official.. django-gencal

Posted by Justin Lilly Sun, 16 Mar 2008 16:40:00 GMT

I just uploaded django-gencal on Google Code this morning. It supports even more generic functionality, but now requires a named url pattern. I’ll have a forthcoming how to once I get a sample application up for perusal.

-justin

Quick Update on Gencal 1

Posted by Justin Lilly Thu, 13 Mar 2008 20:32:00 GMT

Just wanted to let everyone know that I haven’t forgotten about gencal or the write up I’m going to do on it. I’ll be attending django code-lab at PyCon 2008 in 3-4 hours and the format of the app will almost definitely change. Hopefully after Jacob and crew wail on it for a bit, it will be a strong more useable application.

Generic Calendar App: Explained 2

Posted by Justin Lilly Sun, 09 Mar 2008 21:16:00 GMT

I’ve been asked a few times for some example code for my Generic Calendar App. I haven’t put anything into visible production with it as I’ve only used it for an internal project. Instead of making up some example code, I’m going to create an rss feed monitor. This application will import data from a feed and plot it on the calendar app.

First Step: Initialize Project

So the first step is to gather the bits and pieces we’ll need to make this work. As we’re working with RSS, we’ll grab the amazingly awesome FeedParser. After that, its time to build our project.

bash$ django-admin.py startproject feedplotter
bash$ cd feedplotter
# editing necessary edits to settings.py -- media information, sqlite.db and where template location
bash$ ./manage.py startapp feedgrabber
# editing models.py and urls.py
bash$ ./manage.py syncdb
    # returns date and time from a Time object
    def date_time(self):
        print "FOO!"

Now that we have everything set up, here is the code I used in my Model:

# model.py
from django.db import models
import datetime
import time
import feedparser

# Create your models here.
class Blog(models.Model):
    """ Blog Roll Tracker """
    name = models.CharField(max_length=250)
    blog_url = models.URLField(blank=True, verify_exists=True)
    feed_url = models.URLField(verify_exists=True)
    last_updated = models.DateTimeField(blank=True, null=True)
    last_checked = models.DateTimeField(default=datetime.datetime.now(), blank=True, null=True)
    last_post = models.CharField(max_length=250, blank=True, null=True)

    class Admin:
        pass

    def __unicode__(self):
        return self.name

def updateBlogs():
    # Get list of blogs
    blogs = Blog.objects.all()

    # Parse URL's into list
    url_list = []
    for blog in blogs:
        url_list.append(blog.feed_url)

    # Get rss feed as list
    feed_list = []
    for url in url_list:
        # parse rss feed getting..
        feed_data = feedparser.parse(url)

        print "Updating: %s" % feed_data.feed.title

        timestamp = feed_data.entries[0].updated_parsed

        feed_dict = {
            # blog name
            'title':feed_data.feed.title,
            # blog url
            'blog_url':feed_data.feed.link,
            # feed url
            'feed_url':url,
            # last post title
            'last_post':feed_data.entries[0].title,
            # last post's post datetime
            # have to manually create it b/c feedparser just returns a len(9) tuple
            'last_post_time':datetime.datetime(timestamp[0], timestamp[1], timestamp[2], timestamp[3], timestamp[4], timestamp[5]),

            'last_checked':datetime.datetime.now(),
        }
        print "Adding: %s" % feed_dict
        feed_list.append(feed_dict)
        # should now be in the format of:   feed_list[0]['title'] etc

    # Save each of the feeds
    for feed in feed_list:
        blog = Blog.objects.get(feed_url=feed['feed_url'])
        blog.blog_url = feed['blog_url']
        blog.last_post = feed['last_post']
        blog.last_updated = feed['last_post_time']
        blog.last_checked = feed['last_checked']
        blog.save()

Note: A bit of explanation about the rather large function inside. I am basically using that to manually update the feeds. Far from the ideal solution, but one that works fairly well as a stop-gap measure to properly update the admin interface. Also, I’m currently only grabbing the most current entry, not a full list. This would be preferred if this were an actual application.

And here is the code in my urls.py

# urls.py
from django.conf.urls.defaults import * 
from feedplotter.feedgrabber.models import Blog

info_dict = {
    'queryset': Blog.objects.order_by('last_updated'),
}

urlpatterns = patterns('',
    # Example:
    # (r'^online_department/', include('online_department.foo.urls')),

    # Uncomment this for admin:
    (r'^$', 'django.views.generic.list_detail.object_list', dict(info_dict) ),
)

Second Step: Grab the feeds

To grab the feeds, we drop into the shell given to us for free by Django.

./manage.py shell
# Now in a python interactive shell
from feedplotter.feedgrabber.models import updateBlogs
updateBlogs()

And all done! The blogs in our database should have the proper values in them now.

Third Step: Show the feeds

Twitter: Explained

Posted by Justin Lilly Tue, 04 Mar 2008 15:47:00 GMT

What is it?

Twitter is the IM protocol of the moment. It lives on the web and its contents are typically publicly accessible. Its super-unobtrusive and will only bug you if you want it to.

What’s so great about it?

For me, the best feature about Twitter is it’s unobtrusive. I turn my updates to trigger every 30 minutes so I’m only updated about what my friends are saying every half hour. There is a lot less interruption in my workflow. Also, I can subscribe to people like The State Sports and get updates on sport scores or The State to get local breaking news. There are also equivalents to NYTimes and various other papers. For instance, I learned about Brett Farve’s Retirement today from twitter before I even bothered to look at any news websites.

What are the downsides?

Well, the biggest downside (only?) is it isn’t instant. For real-time communication, nothing really beats the current standards of MSN/AIM/gTalk/your favorite. That being said, the number of times I find myself needing instant communication is getting less and less. I believe the saying goes:

“When you only have a hammer, all your problems start to look like nails”

Why do I need it?

Well, like any other social network / instant messaging client, you don’t. There’s nothing so awesome about twitter that everyone should sign up today. It _is_ a fantastic way to keep up to date with friends that I don’t necessarily want to talk with. Its also good for small “value-added” things like a cookbook that releases one recipe at a time in 140 Characters (its surprisingly readable).

How do I get it?

First, sign up for an account at twitter.com. Once you’ve done that, you can either use their web interface (found at the same link). There are mobile solutions ( I use treoTwit and for windows, your best options live on the Adobe AIR platform. The two main players in this arena are Twhirl and Snitter.

Older posts: 1 2