May 21, 2012

Lighttpd 1.5 prerelease doesn't like Django

Whew. I spent quite a bit more time debugging this problem than it really should have taken. Django just wasn’t playing nice with the latest Lighttpd pre-release.

Long story short

Don’t use the prerelease, use the most recent 1.4.x stable. Save yourself hours of cursing and trace-debugging.

Analysis

Lighttpd had the following problems:

  • No request PATH_INFO. Django hates that. I hacked my testing version of Django to get past that, but no luck because.
  • Lighttpd just wouldn’t accept the response. I put in trace logs and found that my app was sending a perfect response, but Lighty just wouldn’t listen to it.

[tags]lighhtpd,django,python[/tags]

Semitransparent rollovers made easy with JQuery

I’m continuing to enjoy working with jQuery. This article shows a simple method for enabling semi-transparent rollovers which actually work on IE 6. Yes, you could use a .gif file for a crude version, but many effects, especially “glowing” effects just look much better if you use a format which supports alpha channel transparency.

[Read more...]

Howto use Satchmo as an App

Note: This article is out of date. Since I wrote it, I’ve become a core developer on the Satchmo project, and Satchmo is usable by default as an App (or rather a collection of apps) rather than as the whole project.

I’m going to be using Satchmo to power the backend of a highly customized store that I’m building for a new client. This is an early-stage, yet strong Python ecommerce framework, which gets much of its power by being built on Django.

Of course, anyone reading my site can clearly see that I am strong in favor of that choice.

I ran into one little issue when I was first setting it up according to the directions. I was told to modify files in the Satchmo directory itself. No! I won’t do it! Not on an actively developed application like that. How would I keep my modified branch in sync with the development branch?

Why is that wrong?

In general, you never want to modify something that is a moving target. Even if it is a hassle, you should set things up so that the thing-which-will-be-getting-updated is isolated from your own code. Otherwise you’ll certainly have to face that most annoying of development tasks, merging someone else’s code.

Well, luckily it wasn’t so hard to set up Satchmo for use as an App, rather than as the base site.
[Read more...]

Django Formatter Mixin Class

guitar Django Formatter Mixin ClassI’ve always disliked having to write __repr__ methods for my classes. It isn’t hard, it is just tedious. In Django, it is especially important to make them, since the admin pages use that method when listing objects from the data model.

However, since Python allows classes to have multiple inheritance, I have long since made a helper “Mixin” class to remove most of the pain from writing my __repr__ methods. If you haven’t heard the term, a “Mixin” is a class which adds functionality to classes which inherit from it. The philosophy is that it shouldn’t change base functionality, thus avoiding many of the problems with multiple inheritance.

Philosophy aside, mixins can be extremely useful, and I love this one. [Read more...]

Pgrep and Pkill for OSX

happy Pgrep and Pkill for OSXUsually I am satisfied by the commandline tools available in OSX. However, one itch that has been unfulfilled for quite a while since my permanent conversion to the Mac is the lack of “pgrep” and “pkill”, two of my favorite time savers from Linux.

Solution

sourceforge.net/projects/proctools/

Works like a dream.

[tags]osx,utilities[/tags]

The best python url_join routine ever

thumbs up The best python url join routine everI don’t know how many times I’ve had to write a function to safely join url path components. It seems so simple, “Just join the strings together with forward slashes.”

But, then I think, “Oh, and don’t strip the leading forward slash, if any”. And “oh, also don’t strip the trailing one”. Also, “make sure not to double up any slashes.”

It is an annoying routine to write, and to be honest, I’ve never really liked any of my implementations. They always failed on some edge case. But tonight, I conquered.

So, without further delay, here is my perfect url_join routine. It hasn’t failed any reasonable edge case I’ve thrown at it yet! The backslash replacement parts are to make it windows compatible, but of course I haven’t tested those.


def url_join(*args):
    """Join any arbitrary strings into a forward-slash delimited list.
    Do not strip leading / from first element, nor trailing / from last element."""
    if len(args) == 0:
        return ""

    if len(args) == 1:
        return str(args[0])

    else:
        args = [str(arg).replace("\\", "/") for arg in args]

        work = [args[0]]
        for arg in args[1:]:
            if arg.startswith("/"):
                work.append(arg[1:])
            else:
                work.append(arg)

        joined = reduce(os.path.join, work)

    return joined.replace("\\", "/")

[tags]python[/tags]

AWeber Joomla Module

adapter AWeber Joomla ModuleI’m using Joomla with VirtueCart for a new business venture. One thing that Joomla couldn’t do out of the box for me was to easily integrate with AWeber.

(The site is not fully set up yet, so don’t expect much if you go looking at it.)

If you don’t know about AWeber, you haven’t done much online marketing. They’re the best autoresponder/list-management service out there. Much much better than any self-hosted script. They manage all the legal compliance stuff, all the double-opt-in & unsubscribe requirements, and they go to the huge lengths needed to get "whitelisted" by all the big providers. Basically, if you use a self-hosted list, you are looking at a delivery rate of 60-70% tops, with AWeber, you’ll get 95-99%.

So you see why I want to use AWeber rather than the (very nice) built-in script Joomla provides. Yet, it isn’t just a matter of hacking it into the templates. I suppose I could’ve done that, but it would have been annoying and I wouldn’t have been able to manage things via the admin console inside Joomla.

The plugin

Instead of hacking it in, I wrote a plugin component/module set for Joomla. Feel free to use the GPL package joomla-awresponder 1. Note that you must unpack the zip, as there are two packages inside, also do read the very short INSTALL.txt file, since you must take one manual step to make it work.

Enjoy! The Joomla package system is very nice, and only took an evening to figure out. I’m sure I’ll be writing more as my store requires it.

Related posts

Technorati Tags: , , , ,

Django and multipart emails

handshake 2 Django and multipart emailsAs part of the Django storefront app I am writing, I need to send multipart messages. The base Django mail functionality doesn’t seem to do this, at least not with my version of Python. It could be a Python bug (actually I am pretty sure it is a bug, and I’m going to followup on that as well) but I need it solved now, not at the next point release of the language.

In the meantime, I’ve made a multipart aware patch and submitted it to the Django project. They accepted my last patch so quickly, I’m curious to see whether this more "debatable need" one will be accepted.

[tags]django,MIMEMultipart[/tags]

Related Posts plugin modifications

adapter Related Posts plugin modificationsI’ve been delaying using a related entries plugin because it didn’t fit with my normal way of posting. See, it uses a WordPress custom field "keywords" to do its matching. That’s OK, but I already have all my posts marked up with inline keywords, for the Technorati plugin Simpletags.

So, when I have an itch for long enough, I scratch it. So, I’ve written an extension to the related-posts plugin which reads keywords from the post text inside [tags] [/tags] markers. In other words, it leverages the use of the Simpletags plugin. You can see it in action by clicking the post title of any entry on this site.

I’ll be submitting the code additions to the original plugin author, but I don’t know if he’ll take them, since it is sort of an edge-case. In the meantime, feel free to comment here.

Here’s my modified plugin: Related Posts Mod 2.02.

Related posts

Technorati Tags: , , ,

IPython brings joy

jump joy IPython brings joyAfter my rant yesterday, it is time to share another programming tool I find absolutely indispensable. IPython is an enhanced command-line shell for Python.

By itself, that may not sound like much, but you really get a lot. You get command history, tab-completion, and automatic introspection of classes. That means you can look up the specific code any function will call, at any time. It has all sorts of automatic and “magic” things it can do, all of which make it a must-try for the working Python programmer.

Yes, but what has it done for me lately?

Since installing IPython last year, I find myself using it for all sorts of tiny tasks which I would have done in a more fragile, cumbersome, or laborious way in the past. Last week, I needed to insert 50,000 records into a database. They were very simple insertions, so I could have just run an Emacs macro to do make all my Sql. But now with IPython, I just pop into a shell, load the unformatted records from a CSV file, and build the SQL in three lines or less of code. Sweet!.

Today, I needed to find the missing item in the haystack. I had two lists, one text and one from a database. The database was missing one of the items from the list. But which one? That was a trivial thing to conquer using a little 1 minute IPython session. Like so:

In [1]: f = open('cc_tables','r')
In [2]: tables = f.readlines()
In [3]: f.close()
In [4]: f = open('cc_list','r')
In [5]: dump = f.readlines()
In [6]: f.close()
In [7]: len(tables)
Out[7]: 104
In [8]: len(dump)
Out[8]: 103
In [9]: [x for x in tables if x not in dump]
Out[9]: ['DataExtractionStatus\n']

The answer, in 9 lines, 4 of which were unneeded, was “DataExtractionStatus”. I could’ve done that in OpenOffice Calc, but the thing would have still been loading in the time it took me to bang out the answer with IPython. Thank you IPython, for making my job that much easier and faster.

[tags]Ipython,python[/tags]