Not to long ago I made the decision to switch from primarily drinking coffee to drinking tea, especially in the afternoons and evenings. One of the first things that I noticed is that while most offices are equipped to easliy make coffee, tea is another matter. This is especially apparent when using loose leaf tea. This wasn't as much of an issue when I was working in a bigger office, they had hot water spickets that I could use to steep my tea of choice. However, when I moved to Stratasan and the smaller startup office, I also lost the typical hot water spicket. What was a tea drinker to do?

The first thing I tried was to reheat water using an empty coffee maker. This solution, however, was subomptimal. No matter how clean the maker seemed, there always seemed to be the slight hint of coffee in my tea. There began my search for a tea kettle I could use at the office.

After asking around, several people pointed me towards kettles like this one. As nice as that kettle is, I couldn't justify spending that much money on an apparatus whose purpose is to heat water. At the other end of the spectrum is this kettle. As you can see, there is quite a gap between these two kettles with the primary difference being that the high end kettle will automatically heat water to a specific temperature.

Luckily for me, people from long ago had a method for guaging the temperature of water. This allows me to use a cheap kettle, but also obtain the correct water temp for the tea that I'm drinking.

This afternoon I was trying to setup my work calendars from gmail in ical. The problem I kept running into was that I wanted to see my coworkers calendars, but didn't want to go to calendars.google.com everytime. These are some instructions for how I got it to work for me (I'm assuming that you've already setup your google calendar to sync with ical via CalDAV):

  1. Open up preferences, click on the account in question step 1
  2. Click on delegation step 2
  3. Check all the boxes of co-worker calendars you want to see. step 3

A few days ago I sent out tweet in reference to Barcamp Nashville 2011 that said, "My one struggle with #bcn11 is that I disagree with the description as an unconference and use of the BarCamp name" Much to my surprise, it got a lot more attention than I was expecting. Unfortunately, I didn't do a good job of explaining what I meant. If there was one part of my tweet I'd ammend, it would be the removal of the part about barcamp as an unconference. In a very general sense, BCN is an unconference and I mispoke when I said different. What follows is my attempt to clarify my meaning.

First and foremost, I want all the volunteers and organizers of bcn11 to know that I think they are doing a great job and trying their best to put on a community driven event. Let me also say that I think Nashville needs what BCN11 is and has become. We need a conference that brings together so many of the different facets of the Nashville tech community in such a relaxed atmosphere.

So if I think Nashville needs what BCN is and I think the volunteers are doing a good job, what did I mean by my comment? It's all in the name. What we have in Nashville isn't a barcamp and never has been a barcamp. What we have in Nashville is a great mini-conference (or unconference) that brings together a whole bunch of different people and only helps the community. It might be pedantic, but using the name Barcamp bothers me. I think it can and does lead to confusion when people see information about what a barcamp is and then experience something different here in Nashville. I think the conference would be better represented by a different name.

TLDR version:

  • Volunteers and organizers do a great job
  • BCN is a good event for Nashville
  • It's not a barcamp so why call it one?

reference: barcamp rules

Recently I had the experience of utilizing the django-oauth-access library from the team at Eldarion. The documentation is a work in progress, so I thought I would share some tips getting it to work.

The first step after following the installation instructions is creating the OAUTH_ACCESS_SETTINGS entry in settings.py:

OAUTH_ACCESS_SETTINGS = {
    'twitter':{
        'keys': {
            'KEY': '<Consumer Key>',
            'SECRET': '<Consumer Secret>'
        },
        'endpoints': {
            'access_token': 'https://api.twitter.com/oauth/access_token',
            'request_token':'https://api.twitter.com/oauth/request_token',
            'authorize': 'https://api.twitter.com/oauth/authenticate',
            'provider_scope':'',
            'callback': 'account.oauth_callbacks.twitter_callback'
        }
    },
    'facebook': {
        'keys': {
            'KEY': '<App ID>',
            'SECRET': '<App Secret>',
        },
        'endpoints': {
            'access_token': 'https://graph.facebook.com/oauth/access_token',
            'authorize': 'https://graph.facebook.com/oauth/authorize',
            'provider_scope': '',
            'callback': 'account.oauth_callbacks.facebook_callback',
        }
    },
}

So what's included in this setting? You can see that each oauth provider we want to connect with has a stanza and each stanza has two sections. First we have the key and secret provided by both twitter and facebook for connecting with their api. Usually this is application specific and will be different for each app you create. The second part are the endpoints for communication between your app and the oauth provider. The endpoint section also includes the important callback, which is the code that your application provides for local authentication and account creation. Let's head over to the callback section.

from oauth_access.callback import AuthenticationCallback
class BasicCallback(AuthenticationCallback):
    def handle_no_user(self, request, access, token, user_data):
        return self.create_user(request, access, token, user_data)
    def create_user(self, request, access, token, user_data):
        identifier = self.identifier_from_data(user_data)
        user = User(username=str(identifier))
        user.set_unusable_password()
        user.save()
        self.login_user(request, user)
        return user
    def redirect_url(self, request):
        return request.user.get_profile().get_absolute_url()

class TwitterCallback(BasicCallback): def identifier_from_data(self, data): return "twitter-%s" % data['id'] def fetch_user_data(self, request, access, token): url = 'https://twitter.com/account/verify_credentials.json' return access.make_api_call("json", url, token)

twitter_callback = TwitterCallback()

As you can see, it's not that complicated. I've created a base class that all my provider specific classes inherit from. In the base class, you can handle application specific logic like creating the user and redirecting urls. Django oauth access provides all the authentication details and uses your callbacks when no user exists and when it needs to redirect after authentication.

Finally, I'd like to thank the guys over at Eldarion for creating and releasing this package. It's made it a lot easier to integrate django projects with oauth providers.