development
Announcing TellOnTheBoss.com
Premise
We’ve all seen it or been a part of it before: your superiors at work are just not seeing the big picture and you just want to tell them what you really think. Whether it be a critical business opportunity, terrible personal habits that the rest of the office takes offense to, or in an extreme case, that the entire workplace thinks they’re a joke–there’s really no denying that it’s sometimes a very hard thing to get across.
All of that truth should come out, but how? That’s where TellOnTheBoss.com comes in. TOTB is grossly simplified way for employees to leave feedback for their bosses, past or present and most importantly, anonymously. The goal of the site is for employees to have an outlet to say the things they would normally withhold. Hopefully, it can help the leaders out there become better at what they do.
Background
This idea came to me after being in a similar situation and not knowing what to do to get my point across. It eventually boiled over into a weekend project which is now what you see at TellOnTheBoss.com.
Please let me know what you think–It’s still very much a work in progress.
Notes on Upgrading Django
I recently pushed a bunch of code to my staging server for various projects after upgrading to Django 1.2.4, and things got a little frustrating, so I figured I’d share. So, obviously, I had upgraded in my local dev environment, tests pass and, to be completely honest, these are pretty small sites that I had assumed made little use of things that were backwards incompatible. Which, as it turns out, I was correct in assuming, but I was getting errors like:
[Fri Jan 07 20:56:54 2011] [error] [client 192.168.2.102] Traceback (most recent call last):
[Fri Jan 07 20:56:54 2011] [error] [client 192.168.2.102] File "/usr/lib/pymodules/python2.6/django/core/handlers/wsgi.py", line 230, in __call__
[Fri Jan 07 20:56:54 2011] [error] [client 192.168.2.102] self.load_middleware()
[Fri Jan 07 20:56:54 2011] [error] [client 192.168.2.102] File "/usr/lib/pymodules/python2.6/django/core/handlers/base.py", line 42, in load_middleware
[Fri Jan 07 20:56:54 2011] [error] [client 192.168.2.102] raise exceptions.ImproperlyConfigured, 'Error importing middleware %s: "%s"' % (mw_module, e)
[Fri Jan 07 20:56:54 2011] [error] [client 192.168.2.102] ImproperlyConfigured: Error importing middleware django.middleware.csrf: "No module named csrf"
[Sat Jan 08 14:37:28 2011] [error] [client 192.168.2.102] mod_wsgi (pid=22250): Exception occurred processing WSGI script '/var/www/myproject/myproject/wsgi/app.py'.
It was obvious that by requiring a new feature (in this case CSRF), my app was parking because it was using an older version of Django.
Long story short, make sure that all previous versions of Django are gone before you re-install. Because I was a n00b when I set up my staging server, my Django install wasn’t sandboxed via a virtualenv and so I had artifacts of it in my PYTHONPATH which my apps were using. For me, I even found pieces in /usr/lib/pymodules/python2.6 on Ubuntu 10.04, weird considering global packages are usually installed in /usr/local/lib/python2.6/dist-packages. One way to get to the bottom of it all, is to grab your entire PYTHONPATH:
python -c 'import sys; print sys.path'
And make sure that Django is no where to be found before re-installing. Once I got all this cleared up, I went ahead and created virtualenvs for each of my projects so this wouldn’t happen again and so that I could isolate problems more effectively.
I guess this is just another little tidbit of being relatively new to python/django administration.
It’s all obvious in the end.
Hope this helps.
jQuery $.live() Equivalent in YUI 3
It’s been a while since I’ve posted and since I started at Yahoo! so I figured I’d give a little love to the new toys I’ve had the pleasure of playing with as of late. Clearly, we’re using YUI here at Yahoo! and because of that I’d had to adjust my thinking on a few goto front-end techniques that I relied on jQuery for. I hope to post more on these adjustments I’ve had to make, but we’ll see.
Aside from general patterns involving YUI loader, a major jQuery feature I realized that I had come to rely on is jQuery’s $.live() method.
Let’s say I have some markup like:
<div id="wrap">
<span id="button">Click Me!</span>
</div>
That’s being dynamically inserted into the DOM.
I got pretty used to doing something like:
$("#id").live("click", function() {
// do stuff
}
Super handy, but not exactly the best performance-wise. If you read the jQuery documentation (or even the jQuery source), you’ll soon find out that what’s going on behind the scenes is an implied event delegation to the root of the DOM. But, not to get too far off topic, there’s a lot of overhead that comes at the expense of this convenience.
YUI provides the same sort of functionality, albeit in a more explicit fashion via the Event delegate() method. I personally like the design decision that was made by the YUI team considering the performance hits that can be involved with using jQuery’s live method incorrectly, but to be completely fair, you can’t really mind the cleanliness of jQuery’s API. Anyways, you can always read the YUI 3 Event docs, but the above simply becomes:
YUI().use('node', 'node-event-delegate', function(Y) {
Y.one('#wrap').delegate('click', function(e) {
// do stuff
}, '#id');
});
I really like the cleanliness of jQuery, but sometimes, you gotta make a little lemonade outta the lemons you were given, even if they’re a little bit rounder and less yellow than the ones you’ve seen before.
There are definitely some caveats in the jQuery way of doing things as well as in YUI, but I feel like it’s a whole lot harder to screw it up in YUI.
Now, go try it yourself.
More Node.js + Comet Tomfoolery
I know there have been quite a few people out there that have messed around with node and comet already, but I figured I’d give it a go perhaps if only to familiarize myself more with the awesomeness that is node.js. I was originally inspired by this post on Ajaxian, so you’ll notice that I too am basing this off of Faye’s implementation of the Bayeux protocol for publish/subscribe. Only real difference is that in my example, messages are passed to the client via stdin.
Here’s the code: http://github.com/eculver/node_comet
I also read in a few other places where people were using fs.watchFile or node’s process.createChildProcess to create a public activity log of sorts. Maybe I’m just a nerd, but it would be kind of cool to go to a high-trafficked site and see some of the server log data (origin, user-agent, etc) in real-time. Something to that effect.
Filtering Special Characters Injected by Microsoft Word
I have been having trouble with users pasting content directly from M$ Word into admin fields, so I set out to create some sort of filter that replaces these little terds with something more HTML friendly. Here’s what I came up with, efficiency aside:
Please fork and enhance if you find more of these evil demon characters anywhere.
I guess it should also be noted that this can be called from any model save method on fields that you wish to filter.
UPDATE:
Just use SmartyPants: http://pypi.python.org/pypi/smartypants/
Simple Fix for python-memcached MemcachedKeyLengthError and MemcachedKeyCharacterError
Here at work, we recently ripped out cmemcache and replaced it with the more apache+mod_wsgi friendly python-memcached, only to be innundated with a bunch of these:
MemcachedKeyCharacterError: Control characters not allowed
as well as these:
MemcachedKeyLengthError: Key length is > 250
The good news was that we knew it was definitely related to our new memcache library that Django was falling back on, but the bad news was that we didn’t want to go through all of our code and filter/hash our keys for every call to cache.get() or cache.set(). My simple solution was to write a set of overrides to the default Django memcached backend. I went ahead and gist’d it if anyone is interested:
This solution truncates and filters the keys as opposed to hashing them like some would suggest. I believe either method should work fine for the most part, hashing offering a far lesser chance of key collisions, but I was a little scared to start hashing keys after reading how it bit Reddit in the ass:
http://www.royans.net/arch/reddit-learning-from-mistakes/
This seems to work well at alleviating our python-memcached woes since our keys should be safely unique after truncating. One thing to note though, that took me for a sec (because I was referring to Django trunk) is that `set_many` and `delete_many` are added in Django 1.2, so they will not work unless using 1.2 or unless your backend already implements them. All others methods should work though.
Cheers.
Notes on PIL + virtualenv + Ubuntu
Just some quick notes on installing PIL in a virtualenv in Ubuntu:
Most forums or message boards suggest:
sudo apt-get install python-imaging
to install PIL, but that doesn’t exactly do when you’re trying to install into a virtualenv with –no-site-packages, so… you try to install from source by downloading the tarball and doing the usual:
wget http://effbot.org/downloads/Imaging-1.1.7.tar.gz
tar -xzf Imaging-1.1.7.tar.gz
cd Imaging
sudo python setup.py install
In some cases this works, but other times build will fail with this:
...
_imaging.c:3138: warning: return type defaults to ‘int’
_imaging.c: In function ‘DL_EXPORT’:
_imaging.c:3138: error: expected declaration specifiers before ‘init_imaging’
_imaging.c:3149: error: expected ‘{’ at end of input
A little known fact is that if you first install python developer tools, the build will go smoothly:
sudo apt-get install python-dev
This may install a few packages other than just python2.6-dev, but whatever. You should now be able to build and install as usual:
sudo python setup.py install
Took me some poking around, so I figured I’d share, maybe save someone some time.
Handy One-Liners
It’s been a while since I’ve posted, so I figured I’d just go with something that I found to have been pretty useful as of late. Peteris Krumins recently posted a great article about one-liners, so I figured I’d add a few of my own to that list:
- Python SMTP Server
python -m smtpd -n -c DebuggingServer localhost:1025This just starts an email consumer on your localhost on port 1025. When emails are sent to it, they are echoed to STDOUT instead of being routed. Handy when developing features that require email.
- Git Graph ‘Pretty Print’
git log --graph --abbrev-commit --pretty=oneline --decorateThis really just serves as a replacement to gitk or GitX in a (command-line) pinch.
- Remove .pyc
find . -name '*.pyc' -exec rm {} \;Does just what you’d think it does: removes all .pyc files from the current directory you are in.
These are all pretty much just great candidates for bash aliases, but I figured I’d share since I was inspired. Thanks Peteris, and if you haven’t checked out his article, do so IMMEDIATELY:
Getting Started with Rails – ERROR: could not find rails locally or in a repository
Just wanted to share this with everyone directly since I had a little bit of a delay getting Rails installed and up to date. Per the “Getting Started” docs, I tried to install rails:
sudo gem install rails
But was stopped in my tracks with this bad boy:
ERROR: could not find rails locally or in a repository
After some googling around, I fixed it by first doing:
sudo gem update --system
And then:
sudo gem install rails
Just thought I’d share that, maybe save someone some time.
Django 1.1 upgrade causes TypeError: __init__() takes exactly 1 argument (2 given)
Another Django 1.1 gotcha: So, I was just upgrading another project to Django 1.1 (actually 1.1.1) and it didn’t go smoothly. I installed and immediately tried to runserver but was promptly halted by this bad boy:
Traceback (most recent call last):
File "manage.py", line 11, in
execute_manager(settings)
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/core/management/__init__.py", line 362, in execute_manager
utility.execute()
...
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/contrib/admin/options.py", line 5, in
from django.contrib.contenttypes.models import ContentType
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/contrib/contenttypes/models.py", line 1, in
from django.db import models
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/db/__init__.py", line 57, in
'TIME_ZONE': settings.TIME_ZONE,
TypeError: __init__() takes exactly 1 argument (2 given)
So, I went right to the source to understand what was going on. After looking through the source and some Django bug reports/tickets, I was no nearer to a solution, in fact, I was more baffled than ever. Things just didn’t add up. After modifying some Django source (eeeek!) I got to point where I had to call bullshit: module references were gone from the source. Something was up. But, to make a long story short, I said screw it, I’m gonna blow away my entire Django installation and start from scratch. Aaaand…. voilà! Things worked.
My advice for those who said TL;DR: just re-install Django from scratch
That is all for now… good day.
Search
What I'm Doing...
- Everyone that considers themselves a Mizzou fan can... well, go fsck themselves. #checkyofilesystem 13 hrs ago
- Missouri sucks. Period. 13 hrs ago
- @aaronky seat's taken brah! You're not welcome in these parts. in reply to aaronky 15 hrs ago
- More updates...
Powered by Twitter Tools

Social Links