Proudly ProcrasDonating

Technology Thoughts

ProcrasDoCoder Conversation Starter

Welcome to Proudly ProcrasDonating :-)
Subscribe to my RSS feed and
visit ProcrasDonate.com

The ProcrasDoCoder Ring is

  • a conversation starter for my startup, ProcrasDonate
  • gives the team a warm fuzzy feeling while we’re working
  • a fun introduction to microcontrollers

The ring, or possibly a pin next to one’s name tag or attached to one’s hat, consists of a bright BlinkM RGB LED with long wires to an arduino unit hidden in one’s pocket or belt loop. The LED lights up colorfully and brilliantly for a few seconds whenever a user of ProcrasDonate donates to a charity, makes a pledge, downloads our software or participates in some user test.

Currently, the code to do all this has been written, but the hardware housing is still in prototype phase. I’ll update the following videos and pictures soon; hopefully with a real use case in the wild.

This video shows a simple demo of the WiShield and BlinkM.

How it works

The ProcrasDoCoderRing is a simple mashup that stands on the shoulders of 4 giants:

Arduino + WiShield + BlinkM + ProcrasDonate web server

In case it’s not clear: much of the WiShield and BlinkM code is copied from relevant examples.

  • Arduino – Arduino starter pack from AdaFruit, snap.
  • WiShield – from AsyncLabs

    Nice library. Needed to hack a few config lines in the C code for WEP 5 byte passcode (see section below), but otherwise comes with good documentation.

  • BlinkM – RGB LED kit from ThingM

    Comes with a nice arduino library that abstracts fading the LED to a specific RGB or HSB.

  • ProcrasDonate web server - python Django website

There are two different ways this could work:

  1. The arduino registers itself with the ProcrasDonate site, which then pushes information to the arduino using HTTP web requests to the WiShield webpage server.
  2. Instead, the arduino regularly pings a small Django app running on ProcrasDonate. The app has a single webpage, which returns the donation counts, etc.

To view the code and more detailed documentation, see the ProcrasDoCoder github repository.

Proudly ProcrasDonating,

Lucy.

RescueTime integration test: donations as time management incentive

Check out the test app —> give feedback

Today I broke from solidifying and bug-fixing the ProcrasDonate Firefox extension in order to test donations as a time management incentive.

I created a small app that uses RescueTime’s API to retrieve a user’s RescueTime time tracking data.

The user authorizes ProcrasDonate to donate to their selected charity at the indicated $/hr rate for all hours spent on activities with a negative RescueTime productivity score.

Keep in mind: this is a barebones minimal test app. Try it out and tell us what you think.

Proudly ProcrasDonating,

Lucy.

Django Tricks, Part 7 – Django from shell

This post is the seventh and last in a series on Django tricks that began with automating Admin Model creation.

This is one of my favorite tricks: setup the Django environment from the Python interpreter.

(master) $ python >>> from lib.django_from_shell import start_django as sd >>> sd() >>> from procrasdonate.models import User >>> User.objects.count() 22

All we need to do is wrap a few Django calls like so:

def start_django():     import sys     #Now the nearest ancestor directory with a 'settings.py' file     settings_dir = find_file_in_ancestors("settings.py")     sys.path.append(settings_dir)         from django.core.management import setup_environ     import settings     setup_environ(settings)

By being flexible about finding the global settings.py file, we can call start_django from other scripts buried in bin or cron directories:

def find_file_in_ancestors(filename):     """     For each parent directory, check if 'filename' exists.  If found, return     the path; otherwise raise RuntimeError.     """     import os     path = os.path.realpath(os.path.curdir)     while not filename in os.listdir(path):         #if filename in os.listdir(path):         #    return path         newpath = os.path.split(path)[0]         if path == newpath:             raise RuntimeError("No file '%s' found in ancestor directories." % filename)         path = newpath     return path

Conclusion

The goal of these tricks is to reduce copy/past/alter drudgery. It’s rewarding to automate the creation of fluff code, even easy fluff that knocked my socks off when I first learned Django.

Of course, it’s hard to stay impressed with myself or Dan for long since I quickly forget that the fluff code even existed. I suppose that’s part of the point. I can forget about creating Admin Models, and new models still show up in the Admin app as I thoughtlessly expected.

Still, even if I’m not impressed, I do notice how often I get to write new, interesting code. That’s why I’m Proudly ProcrasDonating,

Lucy.

Django Tricks, Part 6 – View Utilities

This post is the sixth in a series on Django tricks.

We started with automating Admin Model creation, and continued with automating initialization and installation, model mixins, forms and app settings.

This post diverges from automation to point out some useful view utilities.

Render Response

This trick is more like standard Django practice: wrap render_to_response with your own function that uses your own RequestContext.

def render_response(request, template, dictionary=None):     """     Return render_to_response with context_instance=RequestContext(request).     """     dictionary = dictionary or {}     return render_to_response(template, dictionary, context_instance=RequestContext(request)) def render_string(request, template, dictionary=None):     dictionary = dictionary or {}     return render_to_string(template, dictionary, context_instance=RequestContext(request))

One small thing sometimes forgotten is that when you call render_response from your view, you don’t have to write out the dictionary, which is really just a copy/double-paste of local variable names. Instead, call locals().

some_view.py

def info(request):     user_count = User.objects.count()     visitor_count = Visitor.objects.count()     pledge_count = ...     donation_count = RecipientPayment.objects.count()     return render_response(request, 'procrasdocoder/info.html', locals())

Extract Parameters

Another useful convenience function is extract_parameters, which extracts expected and optional parameters from a request’s POST and GET objects, as well as reporting appropriate errors.

Here’s an example use:

def receive_data(request):     expected_parameters = ["private_key",                            "prefs"]     optional_parameters = ["foo",                            "bar"]     response = extract_parameters(request, "POST", expected_parameters)     if not response['success']:         Log.Error(response['reason'], "communication_error")         return json_failure(message)     parameters = response['parameters']     private_key = parameters['private_key']     ...

Here is the definition for extract_parameters:

def extract_parameters(request, method_type, expected_parameters, optional_parameters=None):     ret = {}         if not getattr(request, method_type):         return {'success': False,                 'reason': "Expected %s parameters" % method_type}         for p in expected_parameters:         try:             v = getattr(request, method_type).get(p, None)             if v == None:                 return {'success': False,                         'reason': "Missing expected parameter: %s" % p}             ret[p] = v         except:             return {'success': False,                     'reason': "Something unexpected happened while extracting parameters"}         optional_parameters = optional_parameters or {}     for p in optional_parameters:         try:             v = getattr(request, method_type).get(p, None)             if v:                 ret[p] = v         except:             return {'success': False,                     'reason': "Something unexpected happened while extracting optional parameters"}               return {'success': True,             'parameters': ret}

This is a marathon super-bowl blogging experience for me, and the English to Code ratio is quickly approaching zero. I’ve left the best for last, though, so check it out: Part 7 – Django from shell.

Proudly ProcrasDonating,

Lucy.

Older entries »