Saturday, June 30, 2007

Sicko Criticisms?

I Just read Kurt Loder's criticism of Michael Moore's Sicko. I think Loder's argument against Moore is weak.

Moore's thesis in Sicko is that the U.S. system is busted and that there are better alternatives than an employer based for-profit system. To back up this thesis, Moore offers experiential accounts of how the U.S. system fails some people, as well as experiential accounts of how other systems do not suffer the same problems.

To my recollection, Moore never says that we need to adopt Canada's system exactly, nor France's nor Britain's. Moore also doesn't fail to mention that the U.S. system works just fine for a large portion of the population. He is simply offering examples of stark contrast -- like not needing to be employed to be covered, not being denied care to pad a corporation's bottom line, never needing to cut a check at the hospital, and free in-home doctor's visits -- to get his viewers to think 'wow, what if...?'

If I had to wager a guess, I'd bet Dead Meat handles Canada's system in a similar manner. Point out some horror stories of people waiting too long, mention that of course the system isn't totally busted in passing, and then show how the US gets something better in some cases (namely the ability to buy your way into great healthcare). Using Canada's Sicko to debunk Moore's Sicko doesn't make a whole lot of sense.

Really, Loder's primary argument is that socialized health care does not work. He offers good evidence of this, but this has little to do with Moore's filmmaking techniques. I agree with Loder's distrust of the U.S. government to execute such a system well. But Moore's message of disassembling the mega-insurance corporations, not letting people slip through the cracks, and expecting our elected officials to try harder resonates much more with me.

I will concede that Loder's criticism of Moore's Cuba portion is valid. I feel no need to defend Moore for his stunts like this, except that these criticisms seldom consider that Moore has a different prerogative.

This is Moore flexing his entertainer muscle. He could have simply cut a check out of his own pocket to pay for the care his subjects need in the U.S. Boring. Instead he attempts to diffuse 'Socialism' as a dirty word by showing that Cuba is not a totally evil regime deserving of the U.S. embargo, and might even be another country we can study to figure out how to fix our system.

Very questionable in the pure documentarian sense, but entertaining, effective, subversive, and uniquely Moore.

Friday, June 29, 2007

Django MySQL with InnoDB Tables

If you are using MySQL and want Django to create InnoDB tables on `syncdb`, use the following in your settings file:

DATABASE_ENGINE = 'mysql'
DATABASE_OPTIONS = {"init_command": "SET storage_engine=INNODB"}


This works on trunk, and isn't documented very well.

Calibration

I want 80 column wide <pre> blocks. Going to play with the CSS until this looks right...

12345678901234567890123456789012345678901234567890123456789012345678901234567890


There.

Thursday, June 28, 2007

Django MEDIA_ROOT Deployment Recipe

One problem I have always had with Django is handling different paths between my and other developers development environments and the production environment.

For development purposes, exploiting the fact that settings.py is Python code leads to an adequate solution:

import os
MEDIA_ROOT = '%s/uploads/' % os.getcwd()


So when you do `./manage.py runserver` from the project directory, this variable will reflect any local environment. Unfortunately, if you deploy this app under Apache / mod_python, os.getcwd() does not refer to the project directory like runserver does.

It is trivial to replace the dynamic string with the absolute path to the project on the deployment server, but occasionally I get burned by Subversion either overwriting or finding a conflict with the modified file.

So one day when editing the Apache conf to set up another Django project with mod_python, I had an insight. Now my settings.py looks like this:

import os, posix
PROJECT_ROOT = posix.environ.get('PROJECT_ROOT') or os.getcwd()
MEDIA_ROOT = '%s/uploads/' % PROJECT_ROOT


This works exactly the same as the former solution with runserver. Then for apache in the virtual host configuration, I do this:

<VirtualHost *>
DocumentRoot /home/project/project

ServerName project.com
ServerAdmin noah@project.com

<Directory "/home/project/project">
SetHandler mod_python
PythonHandler django.core.handlers.modpython
PythonPath "['/home/project'] + sys.path"
SetEnv DJANGO_SETTINGS_MODULE project.settings
SetEnv PROJECT_ROOT "/home/project/project"
</Directory>

LogLevel warn
CustomLog /home/project/log/access.log combined
ErrorLog /home/project/log/error.log
</VirtualHost>


This line does the magic:

SetEnv PROJECT_ROOT "/home/project/project"


This moves the deployment server-specific configuration outside of my Django project and into Apache.

Django Template Block Extraction

I have been building a CMS for my job, in order to empower the Editor to manage all of the web page content. A simple TextField for Textile formatted content was sufficient for the www site, which is only text information. But for the support site, the need to mix managed content with dynamic elements (especially forms) arose quickly.

So how to mix the two?

After discussing implementations with the Editor, we found this syntax agreeable:

h1. Contact Us

p. You can use this form to send us a message.

b(#form).

p. Thank you for you interest.


The magic here is the fake, Textile-like `b` tag, with an ID. This indicates to insert some sort of dynamic element in between the normal Textile content.

Why `b`? On the backend, I realized that I wanted to use the full power of Django templates for any of these dynamic elements. How do you segment off sections of content within a Django template? Blocks.

Now the trick is to render the template as normal, render the `form` block, then replace `b(#form).` with the rendered block.

Here is the view logic:

def render(request, section, template, context_vars={}):
"""
Renders a section with a template. Substitues any
textile-ish `b.` blocks with orphan blocks found in
said template.
"""

# resolve the template and render it to a string
content = render_to_string(template, context_vars)

# add a recursive flatten method to NodeList to make
# getting blocks easy
from django.template import NodeList

def flatten(self):
nodes = []
for node in self:
nodes.append(node)
if hasattr(node, 'nodelist'):
nodes.extend(node.nodelist.flatten())
return nodes

NodeList.flatten = flatten

# load the template
from django.template.loader import get_template
t = get_template(template)

# get all the block nodes, by flattening NodeList
from django.template.loader_tags import BlockNode
nodes = t.nodelist.flatten()

blocknodes = []
for node in nodes:
if node.__class__ is BlockNode:
blocknodes.append(node)

# render blocknodes with context into
# name => content dict
from django.template.context import Context
context = Context(context_vars)

blocks = {}
for blocknode in blocknodes:
blocks[blocknode.name] = blocknode.render(context)

# parse out textile-style block tags b(#block-name)
# and substitute rendered block
p = re.compile(r'(b\(#([^\)]+)\).)')
matches = p.findall(content)
for match in matches:
tag, name = match
try:
content = content.replace(tag, blocks[name])
except:
pass
return HttpResponse(content)


And here is the corresponding template:

{% extends 'layout/one-column.html' %}

{% comment %}
This node is an orphan, and would not be rendered
with a normal render_to_string. It is, however,
possible to render it with the same context, then
replace part of render_to_string and return the
resulting string.
{% endcomment %}

{% block form %}
<form action="" method="post">
<table>
{{ form }}
<tr><td colspan="2" align="right">
<input type="submit" name="submit" value="Submit" />
</td></tr>
</table>
</form>
{% endblock %}

First Post

My name is Noah and I am the founder, technical director, and lead developer of risotto, Inc. Basically it is a one man show, but I do have a couple friends that help now and again.

My recent projects:

My recent clients/employers:

Topics of interest will be Python, Django, Javascript, software engineering, and project management techniques, to name a few. Check back soon.