Category: Web Services

Head first into javascript (and jQuery)

By m0j0, January 12, 2010 8:56 pm

So, I had to take a break from doing the Code Katas just as I was getting to the really cool one about Bloom Filters. The reason for the unexpected break from kata-ing was that I had a project thrown into my lap. I say “project” not because it was some huge thing that needed doing — lots of people reading this could probably have done it in a matter of a few hours — but because it involved two things I’ve never done any real work with: javascript, and jQuery.

My task? Well, first I had to recreate a page from a graphic designer’s mockup. So, take a JPEG image and create the CSS and stuff to make that happen. Already I’m out of my comfort zone, because historically I’m a back-end developer more comfortable with threading than CSS (95% of my code is written in Python and is daemonized/threaded/multiprocess/all-of-the-above or worse), but at least I’ve done enough CSS to get by.

Once the CSS was done, I was informed that I’d now need to take the tabular reporting table I just created and make it sort on any of the columns, get the data via AJAX calls to a flat file that would store the JSON for the dummy data, create nice drop-down date pickers so date ranges in the report could be chosen by the end user, page the data using a flickr-style pager so only 20 lines would show up on a page, and alternate the row colors in the table (and make sure that doesn’t break when you sort!).

How to learn javascript and/or jQuery REALLY fast

How exactly do you learn enough javascript and jQuery to get this done in a matter of a few days (counting from *after* the CSS part was done)? Here are some links you should keep handy if you have a situation like this arise:

  • If Douglas Crockford says it, listen. I’d advise you start here (part I of a 4-part intro to javascript). That site also has his ‘Advanced Javascript’ series. He also wrote a book, which is small enough to read quickly, and well done.
  • Packt has a lot of decent resources for jQuery. Specifically, this article helped me organize what I was doing in my head. The code itself had some rather glaring issues — you’re not going to cut-n-paste this code and deploy it to production, but coming from scorched earth, I really learned a lot.
  • After the project was already over I found this nice writeup that covers quick code snippets and demos illustrating some niceties like sliding panels and disappearing table rows and how to do them with jQuery.
  • jQuery itself has some pretty decent documentation for those times when your cut-n-pasted code looks a little suspect or you’re just sure there’s a better way. Easy to read and concise.

Why I Wrote My Own Sorting/Paging in jQuery

Inevitably, someone out there is wondering why I didn’t just use tablesorter and tablesorter.pager, or Flexigrid, or something like that. The answer, in a nutshell, is paging. Sorting and paging operations, I learned both by experience and in my reading, *NEED* to know about each other. If they don’t, you’ll get lots of weird results, like sorting on just one page (or, sorting on just one page until you click to another page, which will look as expected, and then click back), or pages with rows on them that are just plain wrong, or… the list goes on. This is precisely the problem that the integrated “all-sorting-all-paging” tools like tablesorter try to solve. The issue is that I could not find a SINGLE ONE that did not have a narrow definition of what a pager was, and what it looked like.

I wanted (well, I was required to mimic the mockup, so “needed”) a flickr-style pager — modified. I needed to have each page of the report represented at the bottom of the report table by a block with the proper number in the block. The block would be clickable, and clicking it would show the corresponding page of data. This is more or less what Flickr does, but I didn’t need the “previous” and “next” buttons, and I didn’t need the “…” they use (rather effectively) to cut down on the number of required pager elements. So… just some blocks with page numbers. That’s it.

I started out using tablesorter for jQuery, and it worked great — it does the sorting for you, manages the alternating row colors, and is a pretty flexible sorter. Then I got to the paging part, and things went South pretty fast. While tablesorter.pager has a ‘moveToPage’ function, it’s not exposed so you can bind it to a CSS selector like the ‘moveToPrevious’, ‘moveToLast’, ‘moveToNext’ and other functions are. So, I tried to hack it into the pager code myself. I got weird results (though I feel more confident about approaching that now than I did even three days ago). There wasn’t any obvious way to do anything but give the user *only* first/last/previous/next buttons to control the paging. I moved on. I googled, I asked on jQuery IRC, I even wrote the developer of tablesorter. I got nothing.

I looked at 4 or 5 different tools, and was shocked to find the same thing! I didn’t go digging into the code of all of them, but their documentation all seemed to be in some kind of weird denial about the existence of flickr-style paging altogether!

So, I wrote my own. It wasn’t all that difficult, really. The code that worked was only slightly different from the code I’d fought with early on in the process. It just took some reading to get some of the basic tricks of the trade under my belt, and I got a tip or two from one of the gurus at work as well, and I was off to the races!

Lessons Learned

So, one thing I have to say for my boss is that he knows better than to throw *all* of those things at me at once. Had he come to me and said he wanted an uber-ajaxian reporting interface from outer space from the get-go, I might not have responded even as positively as I did (and I would rate my response as ‘tepid, but attempting a positive outlook’) . It’s best to draw me in slowly, a task at a time, so I can get some sense of accomplishment and some feedback along the way instead of feeling like I still have this mountain to climb before it’s over.

I certainly learned that this javascript and jQuery (and AJAX) stuff isn’t really black magic. Once you get your hands dirty with it it’s kinda fun. I still don’t ever want to become a front end developer on a full-time basis (browser testing is where I *really* have zero patience, either for myself or the browsers), but this experience will serve me well in making my own projects a little prettier and slicker, and nicer to use. It’ll also help me understand more about what the front end folks are dealing with, since there’s tons of javascript at myYearbook.

So, I hope this post keeps some back end scalability engineer’s face from turning white when they’re given a front-end AJAX project to do. If you’ve ever had a similar situation happen to you (not necessarily related to javascript, but other technologies you didn’t know until you were thrown into a project), let’s hear the war stories!!

Python, Creating XML, Recursion, and Order

By m0j0, November 4, 2009 9:05 pm

I love being challenged every day. Today I ran across a challenge that has several solutions. However, most of them are hacks, and I never feel like I really solved the problem when I implement a hack. There’s also that eerie feeling that this hack is going to bite me later.

I have an API I need to talk to. It’s pure XML-over-HTTP (henceforth XHTTP). Actually, the first issue I had was just dealing with XHTTP. All of the APIs I’ve dealt with in the past were either XMLRPC, SOAP, which have ready-made libraries ready to use, or they used GET parameters and the like, which are pretty simple to deal with. I’ve never had to actually construct an HTTP request and just POST raw XML.

It’s as easy as it should be, really. I code in Python, so once you actually have an XML message ready to send, you can use urllib2 to send it in about 2 lines of code.

The more interesting part is putting the request together. I thought I had this beat. I decided to use the xml.dom.minidom module and create my Document object by going through the DOMImplementation object, because it was the only thing I found that allowed me to actually specify a DTD programmatically instead of hackishly tacking on hard-coded text. No big deal.

Now that I had a document, I needed to add elements to it. Some of these XML queries I’m sending can get too long to write a function that manually creates all the elements, then adds them to the document, then creates the text nodes, then adds them to the proper element… it’s amazingly tedious to do. I really wish Python had something like PHP’s XMLWriter, which lets you create an element and its text in one line of code.

Tedium drives me nuts, so rather than code this all out, I decided to create a dictionary that mirrored the structure of my query, with the data for the text nodes filled in by variables.

query_params = {'super_special_query':
                   {
                      'credentials': {'username': user, 'password': password, 'data_realm': realm},
                      'result_params': {'num_results': setsize, 'order_by': order_by},
                       query_type: query_dict
                    }
                }

def makeDoc():
    impl = getDOMImplementation()
    dt = impl.createDocumentType("super_special", None, 'super_special.dtd')
    doc = impl.createDocument(None, "super_special", dt)
    return doc

def makeQuery(doc, query_params, tag=None):
    """
        @doc is an xml.minidom.Document object
        @query_params is a dictionary structure that mirrors the structure of the xml.
        @tag used in recursion to keep track of the node to append things to next time through.

    """

    if tag is None:
        root = doc.documentElement
    else:
        root = tag

    for key, value in query_params.iteritems():
        tag = doc.createElement(key)
        root.appendChild(tag)
        if isinstance(value, dict):
            makeQuery(doc, value, tag)
        else:
            root.appendChild(tag)
            tag_txt = doc.createTextNode(value)
            tag.appendChild(tag_txt)

    return doc.toxml()

doc = makeDoc()
qxml = makeQuery(doc, query_params)

This is simplistic, really. I don’t need to deal with attributes in my queries, for example. But it is generic enough that if I need to send different types of queries, all that’s required is creating another dictionary to represent it, and passing that through the same makeQuery function to create the query.

Initial testing indicated success, but that’s why you can’t rely on only simple initial tests. Switching things up immediately exposed a problem: The API server validated my query against a DTD that enforced strict ordering of the elements, and Python dictionaries do not have the same notion of “order” that you and I do.

So there’s the code. If nothing else, it’s a less-contrived example of what you might actually use recursion for. Tomorrow I have to figure out how to enforce the ordering. One idea is to have a separate list to consult for the ordering of the elements. It requires an extra outer loop to go through the list, get the name of the next tag, then use that value to ask the dictionary for any related values. Seemed like a good way to go, but I had a bit of difficulty figuring out how to make that work at all. Maybe with fresh eyes in the AM it’ll be more obvious — that happens a lot, and is always a nice surprise.

Ideas, as always, are hereby solicited!

Lessons Learned While Creating a Generic Taxonomy App for Django

By m0j0, August 21, 2009 1:31 pm

So, when I first picked up a guitar, the first song I sat down to learn, by ear, was Stairway to Heaven, not “Twinkle, Twinkle, Little Star”. So goes my experience with Django :)

The Background

I was humming along on my recreation of LinuxLaboratory.org. I got a simple blog in place in just a couple of days, a code-sharing app in place a few days later (if that), and a very simple CMS I threw together using flatpages. A good bit of the base code I used came from the 2nd edition of “Practical Django Projects”, but I soon veered off in other directions, and started analyzing the work I’d already done a bit more closely.

One of the things that was glaringly obvious to me was that my method of classifying content was a little schizophrenic. I had three separate apps to represent different types of content, which is great, but each separate app had its own “Category” model. Yuck. On top of that, I was using django-tagging to enable tagging in addition to the categorization each app supported.

The Problem

So… for one type of classification (Categories), it’s built into the specific application, and for the other (tagging), it’s not built in, but it’s pretty tightly coupled. There are a few fundamental drawbacks to this approach:

First, you have to make a pretty big commitment to these things. The easiest way to implement them in your app is to add support for them at the outset, because adding them in later is going to be a bit of a headache. Categories aren’t quite so bad — I implemented them the way the book does, which is with a ManyToMany field. In Django, when you create a ManyToMany field in a model, there’s no corresponding field in that model’s table in the database. Instead, Django creates a lookup table for you, which is nice, because it means you *could* add categories at a later time without *too* much trouble. Tags use the django-tagging app, which implements tags as a multi-valued field in the database table representing the model that will use the tags. So adding this in later is a little bit more of a hassle.

The second issue is that this approach doesn’t treat classification in a consistent manner. One is in the app, the other is a separate app, one is a field, the other is a model, one affects the model’s table, the other doesn’t, etc. One place where this inconsistency becomes obvious is in your templates, where you’re likely to want to give users the ability to browse by category, or browse by tag. Browsing by category across all the different content types is going to be pretty tough if they all have their own implementation. Tags are a little easier, but it’s still a little cumbersome.

The third issue is specific to Categories, and has to do with maintenance: if I come up with some fantastic idea for the Category implementation (like, I dunno, subcategories?), I have to implement it separately in all of the apps that are using categories. No Bueno™.

The Dream

Wouldn’t it be nice if you could just say “give me a list of the taxonomy types used to classify this piece of content, whatever it is, whichever app it comes from, and also a list of the taxonomy terms involved”? Wouldn’t it be nice if you could just add support for categories and tags using a single app that doesn’t add anything to your existing tables? Wouldn’t it be nice to be able to come up with your own taxonomies and, perhaps, hierarchical taxonomies and more complex relationships? Wouldn’t it be nice to be able to say “here’s a category name, show me all of the content associated with it, sorted by content type” and then change your mind and say “no wait, show it to me sorted by title, with a content type indicator over here”, and then change your mind again and say “er, how about showing the taxonomy type, then the term, then all of the content objects under that type:term pairing”?

The Solution

I think it would, so I started creating this beast that I just call “taxonomy”. Right now it’s pretty simplistic, and it’ll likely change slightly based on some things I’ve learned, but surprisingly, I think my first shot at it is really darn close! I’ve stopped being surprised at how quickly I’m able to prototype in Django: getting this together, including the creation of the models, getting it into the admin interface, and getting it linked with any random content type from any app that wants to use it within the admin interface (to add taxonomies and labels to a piece of content in the ‘edit’ interface) took probably 4 hours, including time to read documentation and fall down a few times.

The admin interface for taxonomy lets you create a taxonomy, so if none of your apps currently don’t support the notion of a “Category”, you can go create a taxonomy called “Category”. Once that’s there, you can create a “taxonomy term”, where you’d select the “type” for this term (your new Category), and then a term. So if your term was “Django”, then you would have just created a category called “Django” that could be used by any other app/model in your project. The same, of course, would go for tags, and whatever other classification devices you want.

There’s support for parent-child relationships at the taxonomy term level (so you can have subcategories, or even subtags if you want, etc. I guess you could even categorize tags, and tag categories! They’re coming to take me away!!!). I haven’t given much thought to having hierarchical relationships for the taxonomies themselves. That would be a little overboard, no? I’m interested to hear realistic use cases for that :)

Once you’ve created a taxonomy and a term, the next thing to do is figure out how to associate your actual content to it. So, if our taxonomy is “Category” and the category name (the “term”) is “Django”, the way I’ve implemented it is that you’d go into the edit interface for the article, and a form for associating it with your category appears. This was created using a GenericInlineModelAdmin, which was a gem of a find in the documentation. Inlines let you easily create a form to update a piece of content using concepts and attributes from other models, and even other applications. If you don’t know much about Django, this sounds like a big mess, but in reality, it’s fairly elegant.

I’ve done some testing to see that I can pull things out of the database and associate things properly in the presentation layer, but I’d like to work on making it smoother before I go releasing code or anything like that…. which reminds me that I *did* look and ask around about an app that maybe already did this and came up dry. If anyone sees this and says “why not just use x”, let me know, because it’s not really a goal to write code for the sake of coding. I actually thought this was an interesting feature and couldn’t find it.

Lessons Learned #1: URLConf is a Choice, Not a Requirement

First, I learned that it’s completely possible to create an application that doesn’t have a URLConf at all. Currently, taxonomies actually work in testing, and there’s no URLConf. There actually *will* be one when I figure out how I want the data to be used on my own site, and how to enable users to do whatever they want with it as well. One thought, for example, is that it would be really awesome to be able to go to “/categories/django” and have my app somehow “just know” that “categories”, when singularized, is “category”, which is a taxonomy. From there, the taxonomy app takes over, and magic happens. I have faith that I can make this happen without having the word “taxonomy” in the url. We’ll see.

Anyway, the point is that you don’t have to have a URLconf, and that hadn’t really occurred to me. For the record, django-tagging also doesn’t have a URLconf.

Lessons Learned #2: ContentTypes Let Your Models Be All-Knowing

The second thing I learned was that, using the ContentTypes framework within Django, it’s possible to create a model that will deal with data, and relationships to data, in a dynamic way, such that you don’t have to know what type of data your models will be working with at the time you create them.

For example, my taxonomy app can be used with my blog’s “Entry” model, my code-sharing app’s “Snippet” model, and my CMSs “Page” model. If I pass the app to you, you can use it for your news site’s “Story” model, your ad network’s “Ad” model, and your Twitter clone’s “Tweet” model. No problem. This is in the docs, but here’s what I’ve done:

class Taxonomy(models.Model):
 """A facility for creating custom content classification types"""
 type = models.CharField(max_length=50, unique=True)

class TaxonomyTerm(models.Model):
 """Terms are associated with a specific Taxonomy, and should be generically usable with any contenttype"""
 type = models.ForeignKey(Taxonomy)
 term = models.CharField(max_length=50)
 parent = models.ForeignKey('self', null=True,blank=True)

class TaxonomyMap(models.Model):
 """Mappings between content and any taxonomy types/terms used to classify it"""
 term        = models.ForeignKey(TaxonomyTerm, db_index=True)
 type        = models.ForeignKey(Taxonomy, db_index=True)
 content_type = models.ForeignKey(ContentType, verbose_name='content type', db_index=True)
 object_id      = models.PositiveIntegerField(db_index=True)   
 object         = generic.GenericForeignKey('content_type', 'object_id')

Note that I’ve removed some stuff from the model defs — what you see here are just the fields, which are the relevant bit for what I’m explaining.

The TaxonomyMap model (a model is a class definition, by the way) has foreign keys to map to a human readable ‘term’ and ‘type’ in the other models. TaxonomyMap is just to store mappings between content objects and taxonomies (lower-level details of this might change to make it cleaner/more efficient – I know it’s not perfect). So, how does my app know that I’m storing a mapping to an “Entry” from my blog app? How does it get the id for that Entry? What’s going on?

Well, Django stores a list of every content type used by Django and any installed apps, and I’ve made a foreign key to ContentType so I can access the content type of the object that’s being dealt with and get its ID. I also have a “GenericForeignKey” field, which essentially creates a “dynamic” foreign key to the table that represents the object that’s being dealt with, so if I’m dealing with an “Entry” object from “monk” (which is the name of my blog app), then the foreign key will point to “monk_entry”, which is the table that stores my blog entries. When you create a taxonomy, and a term, and associate them to a piece of content, the resulting rows in the affected tables look like this:

mysql> select * from taxonomy_taxonomy;
+----+--------------+
| id | type         |
+----+--------------+
|  1 | TestCategory |
+----+--------------+
1 row in set (0.01 sec)

mysql> select * from taxonomy_taxonomyterm;
+----+---------+----------+-----------+
| id | type_id | term     | parent_id |
+----+---------+----------+-----------+
|  1 |       1 | TestTerm |      NULL |
+----+---------+----------+-----------+
1 row in set (0.00 sec)

mysql> select * from taxonomy_taxonomymap;
+----+---------+---------+-----------------+-----------+
| id | term_id | type_id | content_type_id | object_id |
+----+---------+---------+-----------------+-----------+
|  1 |       1 |       1 |              10 |         2 |
+----+---------+---------+-----------------+-----------+
1 row in set (0.00 sec)

Note that the table for the model that’s using the taxonomy app is untouched. Only taxonomy tables are used.

Seeing this, you might think that it’d be hard to put a form in the admin interface for arbitrary content types to classify them with taxonomies. Not so — which brings me to more lessons I learned.

Lessons Learned #3: Collecting Data About a Model Without Extending the Model and Creating Database Badness

If you have a model (we’ll use “Entry” again), and it has a core set of attributes, but you want to associate data with instances of this model not represented in the model definition (like, say, a taxonomy, for an arbitrary example), you can add a form to the admin interface for that model in about 5 minutes. This rocks, for those who didn’t know, because the alternative would either involve really ugly code, or really ugly data (you’d have to store the taxonomies in the table for the model, creating either tons of duplicate data, or multi-valued fields… and you’d still have duplicate data).

Typically, it seems that the normal use case for this is to relate models in the admin interface that are part of the same application and are explicitly related through a direct foreign key reference. This might even be enforced in the case of “InlineModelAdmin” objects, but I haven’t dealt with those personally. However, while reading about “GenericInlineModelAdmin” objects, it occurred to me that it shouldn’t matter that the related items are from different apps. I tried it, and it worked. Here’s what I did:

from django.contrib import admin
from django.contrib.contenttypes import generic
from monk.models import Entry
from taxonomy.models import TaxonomyMap

class TaxonomyMapInline(generic.GenericTabularInline):
   model = TaxonomyMap

class EntryAdmin(admin.ModelAdmin):
   prepopulated_fields = { 'slug': ['title'] }
   inlines = [ TaxonomyMapInline, ]

admin.site.register(Entry, EntryAdmin)

Again, I’ve edited out the irrelevant bits. The above comes from my blog app’s admin.py file. What I did was created an “inline” called “TaxonomyMapInline”, and then associated that inline with the “EntryAdmin” ModelAdmin object using ModelAdmin’s ‘inlines’ attribute, which takes a Python list, which means you can keep adding more inlines all day long if you like.

The result is that, when I go to edit a blog entry, there’s now a form at the bottom that lets the user select a taxonomy type and term (i.e. “Category” “Django”), and associate it with the post. When I added the inline to the admin.py file, it was a test to see what would happen. Since TaxonomyMap doesn’t hold anything but numeric IDs, I assumed I would have to go back and manually map the IDs to human readable values. Not true. Apparently, if the field being presented in the admin form maps to a ForeignKey field, Django automagically does the lookup for you and presents the human-readable text! And, when you save, it converts everything back to numeric IDs before going to the database, so everything “just works”. So the work I thought I’d be doing myself was already done for me!

LinuxLaboratory => Django – Now with Comments, Akismet, and 404.html

By m0j0, August 6, 2009 11:48 am

I stayed up a little late last night, because I wanted to get comments working on Linuxlaboratory.org. Comments *are* working, and I *do* get email notification of new comments, which is nice. Akismet is installed, and is no longer throwing errors, but to be honest, I’m not quite sure how to test it. I tried creating a comment that looked like spam, but it got posted publicly anyway. I’ll have to figure out how to log the Akismet processing operations and results.

I also set up email notification not just for comments, but for errors. And once I did that, I started getting slammed with emails. There’s a setting you can use to avoid being emailed for 404 (File Not Found) errors, but the problem I had was that, for every 404 error, there was also a TemplateNotFound error, because there was no 404.html file anywhere. So I created a 404.html file. It extends my base template, so it looks like the rest of the site, complete with the sidebar and stuff, and just has a note letting the user know what happened. This is nice because it’s an opportunity to rescue the user’s session by providing lots of links back to the home page, or to other content on the site. I haven’t gotten to it in the book yet (for those just tuning in, the site is being built in part using the 2nd Edition of “Practical Django Projects”).

Next up is RSS feeds. Once that works I might break from the book, because in the course of looking around and setting things up, I’m discovering that there’s a good bit of functionality I’d like to use, more apps I’d like to plug in, and a couple I’d like to write. I’d also like to put a horizontal navigation bar and make an “Articles” section of the site using a CMS, and have it be separate from the “Blog” part of the site. Then I’ll make a “Tools” section and start coding my own versions of tools like subnet calculators and a “CLI Hacks” application which will let me post one-liners I’ve found useful (kinda like commandlinefu.com).

Who knows what else — but first things first. RSS!

LinuxLaboratory woes, Drupal -> Django?

By m0j0, July 21, 2009 2:33 pm

Ugh…

So, today I tried browsing to one of my sites, linuxlaboratory.org, and found a 403 “Forbidden” error. Calling support, they said it was a “billing issue”. Well, I pay my bills, and I haven’t received any new credit cards, so I’m not sure what that’s about. Further, they haven’t contacted me in any way shape or form at all in a very long time, and I’ve had the same email addresses for years now. Last time they failed to contact me, it was because they were sending all of the mail to “root@localhost” on the web server.

What’s more, the tech support guy, having determined that this wasn’t a technical but an administrative problem, transferred me to a sales person who was not there. I left a message. That was 3 hours ago. So I took matters into my own hands and changed the name server records to my webfaction account, and linuxlaboratory.org now points to an old test version of the site that uses Drupal.

It’s Over Between Us…

Drupal holds the record for the CMS that has run LinuxLaboratory the longest. Since its launch in 2001, LinuxLaboratory has used all of the major, and some of the minor open source PHP CMSes. Drupal gave me something very close to what I wanted, out of the box. Nowadays, Drupal is even nicer since they redid some of the back end APIs and attracted theme and module developers to the project. I’ve even done some coding in Drupal myself, and have to say that it really is a breeze.

But the problem is this: I’m a consultant, trainer, and author/editor. I am an experienced system admin, database admin, and infrastructure architect who makes a living solving other peoples’ problems. I really can’t afford to have something that is super high overhead to maintain running my sites. With Drupal releasing new versions with major security fixes once per month on average, and no automated update mechanism (and no built-in automated backup either), it becomes pretty cumbersome just to keep it updated.

This is in addition to my experiences trying to do e-commerce with Drupal. I tried to use one plugin, but soon found myself in dependency hell — a situation I’m not used to being in unless I’m on a command line somewhere. So, out with Drupal. I know it well and I’m sure I’ll find a use for it somewhere in my travels, but not now, and not for this.

Is Django the Future of LinuxLaboratory?

So I’m thinking of giving Django another shot. In fact, I thought I might try something new and interesting. Maybe I’ll build my Django app right in front of everyone, so that anyone who is interested can follow along, and so people can give me feedback and tips along the way. It also lets me share with people who have questions about a feature I’m implementing or something like that.

For fanboys of <insert technology here>, know this: I’m a technology whore. I consume technology like some people consume oxygen. I love technology, and I get on kicks, and every now and then, a “kick” turns into a more permanent part of my tool chest. Python is one such example. I’ve done lots with Python, but have never really made friends with it for web development. I got a webfaction account specifically because they support Python (and Django). I’ve done nothing with it. Now I think I might.

But not to worry! I own lots of domains that are sitting idle right now, and I’m considering doing a Ruby on Rails app for one of them, and I’m dying to do more with Lua. There’s only so much time!

Webfaction Django Users: Advice Hereby Solicited

So if you’re a webfaction customer using Django, please share your tips with me about the best way to deploy it. I’ve used nothing but PHP apps so far, and found that rather than use the one-click installs webfaction provides, it’s a lot easier to just choose the generic “CGI/PHP” app type and install the code myself. This allows me to, for example, install and update wordpress using SVN. Is Django a similar story, or does webfaction actually have an auto-upgrade mechanism for this? How are you keeping Django up to date?

Thanks!

I’m Offering Pro-Bono Consulting

By m0j0, July 20, 2009 11:10 pm

I started my company about a year ago, but I’ve been doing consulting for a long time. In fact, my first job in the IT industry was working for a consulting firm. Before that, starting as far back as grade school, I was involved in a lot of volunteer civic and community service activities. I admire companies who get involved in their communities, or even outside of their communities, wherever help is needed.

As part of my business plan, I’ve put in place a policy of accepting one pro-bono consulting project per year. So far, I haven’t gotten any requests for free consulting work, so here’s my public shout out to let you know what types of services are available:

1. Speaking or Training. My specialties are things like advanced Linux administration and SQL, but I’m perfectly capable of delivering content for people who just need to know how the internet works, or want to know more about social media.Training, funny enough, has been the bulk of my business for the past year.

2. I can help with MySQL performance tuning on *nix systems, including finding hotspots related to the design of the database itself, or how your application code interacts with the database. If it happens that your MySQL server is performing poorly due to an underpowered system, I can also pinpoint which resource is dragging on the performance of your database.

3. If you just need random scripts written to perform *nix system administration tasks, I can consult with you about the requirements and write them for you. Note that while I can script in several languages, my preference for anything longer than 40 lines of code is Python.

4. I can build PC’s, install networks, set up firewalls and wireless routers, and all of the normal “office IT” functions, but note that my consulting is Linux consulting. I don’t work with Windows (well, I do, but not for free) ;-)

5. If there’s some other thing you’ve seen me blog about here, chances are I’ll be willing to perform a pro-bono consulting engagement to do it for you, or show you how to approach a problem, a large project, a migration, automation, monitoring, security or whatever.

Unless you happen to live within commuting distance to Princeton, NJ, work will be done remotely :)

Please email your request to jonesy at owladvisors dot com. Include your organization’s name, your contact info, and as much detail about the project and what your organization does as possible. The decision of which project to take on will be based solely on the information in your request!

Ex-Googlers Score with Likaholix.com

By m0j0, March 5, 2009 8:25 am

Last night I discovered likaholix.com and was able to get an account during their beta phase testing. You can see my likaholix page here, but I thought I’d take a few minutes to jot down some initial thoughts about it, because I do think it’s interesting.

Likaholix makes it Mind Numbingly Easy™ to quickly “like” something. To do that, all you do is type in a title for the thing you like, and then type a short description telling people why you like it. Then, add a couple of tags so the site can easily categorize your likes, making them easier for visitors to find.

Why is this cool? Well, a few reasons:

  1. The huge masses of internet users happen to really like reading reviews. This is pretty easy to prove. Go to technorati.com and you’ll see that sites like Engadget and Gizmodo and other sites that do reviews are among the most highly trafficked sites. Other sites that aren’t blogs, like CNET, are also enormously popular. And what’s your favorite feature of Amazon? I know what mine is: customer reviews!!
  2. The huge masses of internet users don’t really write thorough reviews, because they’re long and take time and more effort than you might think. However, just about anyone can tell you in 5 seconds or less why they like something, and are usually happy to do so.
  3. The huge masses of internet users don’t really read thorough reviews, because they’re just too damn long. I mean, sure, if you’re making a major purchase in your life, you might read every letter you can find about a product, but for many things, people just want the bullet points. I’m not aware of a limit on the number of characters you can use in your descriptions on likaholics, but it certainly doesn’t encourage you to ramble on, like, say, this Wordpress interface does :-)
  4. The huge masses of internet users love the idea of being a trend setter, which likaholix facilitates. Perhaps even more, they tend to follow and respond to trends, and likaholix facilitates that, too, by making it really easy to connect with other people, assigning credibility points to users making them “tastemakers” in certain areas, and making it really easy to find recommendations for whatever you’re interested in.
  5. It’s appealing to huge masses of internet users, because it is, by definition, not specialized. You can like anything, and so this becomes sort of the internet equivalent to the “show about nothing”, Seinfeld, which if you remember, was hugely popular.

Of course, with the good comes the bad. There’s nothing really bad about likaholix, and the product is still in beta, so it’s very likely that it’ll change, but here are some quirks I noted:

  1. There’s no feedback link! Why have people sign up for a beta if they have no interface to tell you what’s going on, why they like/don’t like, etc? That’s goes beyond bad into this really bizarro world of… bizarreness.
  2. When you put in a title for your new like, likaholix tries to find a URL for what you’re about to describe. If you pick one of those URL’s, it changes your title to whatever the page title is of the URL you chose. That’s bad, because a) I would say most sites don’t pay proper attention to what their page titles should look like, and b) I typed in my title for a reason. Please don’t subvert my attempt to communicate through the use of an effective title.
  3. Also, when you type in a title, while you’re typing, there’s a drop down that’ll appear with suggested completions. This is, unfortunately, too clunky and slow to be effective. Several times something would appear, and the right choice would barely have time to catch my eye before disappearing again. This is probably due to lag between results being generated and my typing. This means I’m sitting there pushing the back button, maybe a few times, then typing letter by letter very slowly until it comes back. At least the results are cached; I was usually able to get back to the right set of results and pick what I intended.
  4. You can only be a tastemaker in two categories, and that kinda sucks, but I think I understand why that is: they’d probably like you to focus on one or two areas and “own the topic”, which is a big catch-phrase in the blogosphere. I think it’s kind of lame, but it’s not a big deal, and it’ll probably change anyway.
  5. likaholix will post your likes to twitter, but with no link back to the site, and no indication that the tweet came from likaholix whatsoever! What’s the point? I’m sure this will change. I’ve disabled the feature on my account for the time being, and opted to post my likes to facebook, where people are less likely to have a real-time interface spamming them with my likes all day.

In the end, I think likaholix is a hit. I’ve never used a single site to get product reviews and recommendations, but now I might. I understand that this site only shows good reviews, but bad reviews are so easy to find that I don’t really care, and if the masses tend not to like something, then the fact that a site with (someday) millions of users mentions a product a mere 3 times will be indication enough. “If you have nothing nice to say…” and all that.

Also, if I want to know if some gadget, we’ll call it ‘foo’, sucks, Googling for “foo sucks” still works like a charm.

Marc Andreessen on Everything

By m0j0, February 20, 2009 10:53 pm

Marc Andreessen was on Charlie Rose last night, and I missed it. A buddy told me about it, and I wanted to watch, but things just got in the way. So here it is.

So, this is the very first time I’ve ever embedded video into a blog post. I couldn’t help myself.

Why?

I’ve never even heard Marc Andreessen talk until tonight, to be honest. I’ve been a huge fan of his actual technical work, and I’ve read some of his writings, and you almost can’t help but follow his career if you work with internet-related things directly, but I’ve somehow missed him at all of the conferences, never seen an interview… until now. And you know, it turns out that in this interview, he validates several posts that have been lying around on this blog for some time.

He talks about the evolution of web commerce and cloud computing and how it lowers the bar for startups.

He talks about news, newspapers and how they absolutely must kill the print edition, now.

He talks about social media, where it came from, where it’s going, “viral”, etc.

This is not to compare myself to Andreessen in any way — that’s ludicrous. But it’s nice to get some validation from on high for some of the thoughts and ideas I’ve had. Now if only I could write a tool that will lay the foundation for the next generation of human interaction, I’ll be all set ;-)

It should go without saying that I learned some things, but the biggest thing I learned came from just a tiny little quip buried in the middle of the video somewhere. He says, while talking about the iPhone, that it was “beamed in from 5 years in the future”. I think problems should be thought about that way in general. I’ve adopted a new way of thinking about products and services from pondering on this for all of 5 minutes. Find a service that solves a problem now, or find a problem that exists now — either one. Now think about how that problem will be solved in 5 years. Now set a deadline for solving that problem in 1 year.

Sounds impossible? Not a chance. Impossible is just another excuse to get creative, change your perspective, rethink the problem, and produce a solution. Listening to really smart people talk can be inadvertently inspiring. Thanks Marc!

2009: Waiting to Exhale

By m0j0, December 29, 2008 12:27 am

Lots of blogs list a bunch of stuff that happened in the year just past, and I have done a year-in-review post before, but in looking back at posts on this blog and elsewhere, what strikes me most is not the big achievements that took place in technology in 2008, but rather the questions that remain unanswered. So much got started in 2008 — I’m really excited to see what happens with it all in 2009!

Cloud Computing

Technically, the various utility or ‘cloud’ computing initiatives started prior to 2008, but in my observation, they gained more traction in 2008 than at any other time. At the beginning of 2008, I was using Amazon’s S3, and testing to expand into more wide use of EC2 during my time as Technology Director for AddThis.com (pre-buyout). I was also investigating tons of other technologies that take different approaches to the higher-level problem these things all try to solve: owning, and housing (and cooling… and powering…) equipment. Professionally, I’ve used or tested heavily AppLogic, GoGrid, and all of the Amazon services. Personally, I’ve also tried Google App Engine.

2008 was a banner year for getting people to start tinkering with these technologies, and we’ve seen the launch of ‘helper’ services like RightScale, which puts a very pretty (and quite powerful) face on the Amazon services. The question now is whether the cost-benefit analyses, and the security and availability story is going to be compeling enough to lure in more and bigger users. I think 2009 is going to be the year that makes or breaks some of these initiatives.

The other question I have about cloud computing, which I’ve been asking since the last half of 2007, is “where does all of this leave the sysadmin?” It seems to me that a great many of the services being trotted out for users to play with seek to provide either user-level GUI interfaces, or low-level developer-centric interfaces to solve problems that historically have been the purview of system administrators. I’ve been wondering if it will force sysadmins to become more dev-centric, developers to become more system-savvy, if it will force more interaction between the two camps, or if it means death to sysadmins on some level, to some degree, or for some purposes.

I really think there’s a lot of hype surrounding the services, but I also think there’s enough good work being done here that 2009 could begin to reveal a sea change in how services are delivered and deployed on the web.

Drizzle

If you’re working in the web 2.0, uber-scaling space, and you’re using MySQL, chances are your relationship with your database is less ideal than it was when you were using it to run your blog or your recipe database. As you try to scale MySQL through various means, you find that there are lots of things that could be handled better to make MySQL scale more gracefully. Some extra internal accounting and instrumentation would also be nice. In many cases, it would also be nice to just cut out all of the crap you know you’re not going to use. If you’re looking to sharding, it would be good if there was a database that was born after the notion of sharding became widely understood.

Drizzle is a project started by some MySQL gurus to take a great experimental leap toward what could become a beacon in the dark sea of high scalability. At the very least, it will serve as a foundation for future work in creating databases that are more flexible, more manageable, and, more easily scaled. Of course, it’s also likely that Drizzle will be tied more closely to a slightly narrower audience, but I can say from experience that had the ideals of the Drizzle team been fully realized in an open source product prior to 2008, I may not have even installed MySQL in the first place. I had at least a passing familiarity with what I was getting myself into, and pulled the trigger to use MySQL based on criteria that deviated somewhat from pure technological merit. ;-)

I don’t believe Drizzle has announced any kind of timeline for releases. I wouldn’t expect them to. Instead, the first release will probably be announced on blogs in various places with links to downloads or something. The Cirrus Milestone for the project seems to focus quite a bit on cleanup, standardization, and things that, to prospective deployers, are relatively uninteresting. But I think 2009 will at least see Drizzle getting to the point where it can support more developers, and make more progress, more quickly. In 2009, I think we’ll see people doing testing with Drizzle with more serious goals in mind than just tinkering, and I think in 2010 we’ll see production employments. Call me crazy – it’s my prediction.

Microsoft

Windows market share on the desktop, it was recently reported by IDC, has dropped below 90% for the first time in something like 15 years, to 89.6%. Mac users now represent 9.1% of the market, and the rest is owned by Linux, at a paltry 0.9%.

It would seem that OS X has eaten away a few percentage points from Windows, and done perhaps more damage to the Linux space. I have no data to back that up at the moment – I’m going by the enormous shift from Linux to OS X between OSCON 2006 and OSCON 2008. I’ll let you know what I see at LISA 2009, which I plan to attend.

But what about Microsoft? Sure, they’re the company IT wonks love to hate, but the question of how their apparent (marketed) direction will affect their products and business is one that truly fascinates me. Microsoft has become the Herbert Hoover of American software companies, while Apple is FDR, perceived as having saved many of us from the utter depression and despair of the Hoover years (insert joke about sucking here).

Microsoft is enormous. It moves horribly slowly. It has shown a stubborness in the past that would seem difficult for something so large to shake off. Their products reflect this big, slow, obstinacy. What end users need is a software company that is going to lead its users in the direction they’re all moving in already on their own. It can no longer be about “allowing users” to do things (Ballmer has used such phrasing in the past). It needs to be about enabling and empowering, and getting the hell out of the user’s way.

The big question I think 2009 will answer is whether or not Ray Ozzie can affect change to either the culture, or the mechanics of how Microsoft does business (either one is likely to have a drastic effect on the other).

Python 3.0

It’s here already. I, for one, am quite excited about it. I think that GvR, Alex Martelli, Steve Holden, and others have put forth a very admirable effort to communicate with users and developers about what changes are imminent, what they mean, and how to prepare to move forward. I think 2009 is going to require 100% of the communication effort expended in 2008 in order to continue to rally the troops. I don’t know, but would imagine that the powers that be can see that as well, and so it will be. Assuming I’m right there, adoption will increase in the community, and the community buzz resulting from the wider adoption will begin to take some of the pressure off of the really big names, who quite honestly have craploads of other things to work on!

I believe that by summer 2009 we’ll see Python 2.6 migrations happening more rapidly, and a year out from that point we’ll start to see the wave of 3.0 migrations building to more tsunami-like proportions.

Another question: is there sufficien new adoption of Python going on to register 3.0 on the usage scale? Probably not now, but hopefully in 2009…

USA Gets a CTO

I’ve read a few articles about this, but all I’ve read really just amounts to noise and speculation. What, exactly, will the CTO be charged with? I’ve seen Ed Felten floated as a candidate for the position, but he’s not a person who’s going to want to run in and try to herd cats to try to standardize their desktop computing platform. I think if the CTO position is going to take charge of the things Felten has already shown a keen interest in (namely, high-level IT policy, the effect of technology on society, privacy and security… as it relates to the former two items, etc), then there could be nobody better for the job. Princeton’s Center for Information Technology Policy is one of the few places (maybe the only place) I’d actually take a pay cut to join ;-P

I imagine that 2009 will answer the questions surrounding the nation’s very first CTO.

It’s The Economy!

I’m a freelance technology consultant and trainer. Anyone who is making a living freelancing is probably wondering about the state of the economy, no matter where they live (incidentally, I live in the US). The numbers aren’t good. The S&P is down something like 41% this year – the largest drop on record. The state of the markets in general, along with the failing of the banks and their subsequent appearance in Senate committee hearings, as well as the deflationary spiral in the housing market (and predicted more general deflationary spiral) invoke images of bread lines and soup kitchens… or at least very little work for freelancers.

Personally, I have a lot to lose if things *really* go south to the degree that they did in the 1930’s, but I have to say that I don’t think it’ll happen. If you’re worried about this becoming the next Great Depression and are really losing sleep over it, I recommend you read a book called “The Great Depression” by Robert S. McElvaine. There are probably tons of books you can read, but this is one I happen to like. It’s full of both fact and opinion, but the opinions are well-reasoned, and loudly advertised as being opinions (you’re not likely to find a book about any topic relating to economics that isn’t full of opinions anyway).

What I think you’ll find is that, while there are a lot of parallels between now and then, there are lots of things that *aren’t* parallel as well (partly as a result of the depression – for example, the US is no longer on the gold standard, and both banks and securities trading are infinitely more regulated now). Also, not all of the parallels are bad. For example, things began to improve (though slightly at first) almost the day a new Democratic leader replaced the outgoing Republican regime.

My advice (which I hope I can follow myself): If the market numbers bother you, don’t look. Service your customers, don’t burn any bridges, rebuild the ones you can, build new ones where you can, and above all, Do Good Work. When you don’t have work, market, volunteer, and build your network and friendships. Don’t eat lunch alone, as they say.

What are you wondering about?

My list is necessarily one-sided. A person can be into only so many things at once. What kinds of tech-related questions are you searching for answers on as we enter the new year?

Holiday Project: Plot Google Calendar Events on Google Map

By m0j0, December 23, 2008 9:48 am

[UPDATE: 2009/08/08]: I’ve now gotten stuck on two separate projects, trying to find a bridge between Python code that generates data, and javascript code that is apparently required in order to present it. I haven’t found such a bridge. For one project, I was able to do what I needed with ReportLab (there was no webification requirement). For this project, it’s pretty useless if it’s not on the web, imho. So until I either break down and decide to deal with the monstrosity that *is* javascript, or someone else takes this code and runs with it, here it sits. There is only a slight chance I’ll decide Javascript is something I want to deal with. I’ve written some code in javascript. I’ve never enjoyed it, and I’m not very good at it.

While putting together the US Technical Conferences calendar over the past week or two, I noticed that the location of probably 80% of them (I’m guessing – it’s probably higher) is somewhere in California. I’ve always noticed that there is this trend to hold technical conferences in California, because there’s an enormous concentration of technology workers there. But c’mon! How about an OSCON East or something?

Anyway, I have more going on this holiday season than usual, but I always try to spend some of the downtime doing something interesting, and the Google Maps API is probably one of the few Google APIs I’ve never used. What better way to expose the inequity in conference locales than to plot all of my Tech Conference calendar events on a Google Map? Oh, and it’d be useful for people to be able to visually see where conferences are, and maybe color-code the markers according to Q1 2009, Q2 2009, etc.

I’ll be doing this in Python, by the way, though I’m pretty sure I’ve decided to go ahead and use javascript for the Maps portion. There *is* a Python utility that attempts to relieve you of the hellhound that is javascript, but it’s not documented at all that I’ve seen, and wrappers that attempt to generate javascript tend to be flaky (including one I wrote myself – I’m not picking here). I’m also using geopy for the geocoding, because it provides more flexibility than hard-coding calls against the Google Maps API.

By the way, this isn’t like some new fantastic idea I had. Someone else came up with a solution that works quite some time ago, but it involved several steps including Yahoo pipes and stuff. I really just wanted a script that, called with a parameter or two, would dump the appropriate .html file into a directory, or better, would just be called directly from the browser and take input (baby steps). Later, there are aspirations of plugging it into Django, an area where Google Maps has already seen some integration work, and another victim of my recent exploration/experimentation.

So, I already have some prototype code that might be useful for others who are maybe just starting out with the Calendar API. This bit of code will create an authenticated CalendarService object and dump the title and location of events on a calendar of your choosing. The assumption here is that the location is in some form that is parseable by whatever geocoding service you decide to use. For me (for now), I’m just using city and state locations – not addresses. Here goes:

#!/usr/bin/env python

try:
  from xml.etree import ElementTree # for Python 2.5 users
except ImportError:
  from elementtree import ElementTree
import gdata.calendar.service
import gdata.service
import atom.service
import gdata.calendar
import getpass
import atom
import getopt
import sys
import string
import time
import geopy

calendar_service = gdata.calendar.service.CalendarService()
calendar_service.email = 'you@gmail.com'
calendar_service.password = getpass.getpass()
calendar_service.ProgrammaticLogin()
cal_id = 'id_from_calendar_settings_page_or_email_for_your_default_cal'
feed = calendar_service.GetCalendarEventFeed('/calendar/feeds/'+cal_id+'/private/full')
geo = geopy.geocoders.Google('your_google_api_key')

print feed.title.text  # the name of the calendar we're sucking feeds out of.
for event in feed.entry:
  print event.title.text, event.where[0].value_string # The event name, and location.
  (lat,lon) = geo.geocode(event.where[0].value_string)
  print lat,lon

It’s a start. Next I need to figure out the steps between this stage and making the actual cool stuff happen. Hopefully I’ll be back with an update right around the new year.

Panorama Theme by Themocracy