Gnewt's Blag http://www.gnewt.at/blog She turned me into a Gnewt! I got better... Mon, 14 Apr 2014 16:59:55 +0000 en-US hourly 1 https://wordpress.org/?v=4.7.2 BHS Shirt Sales with Django http://www.gnewt.at/blog/2014/04/bhs-shirt-sales-with-django/ http://www.gnewt.at/blog/2014/04/bhs-shirt-sales-with-django/#comments Mon, 14 Apr 2014 16:59:41 +0000 http://www.gnewt.at/blog/?p=291 This is a project I’ve been working on for the past week or so. It’s live now, and I wanted to share the codebase. This post is more or less exactly the README from the GitHub repo bhs_sales, so head there if you want to get right to it.

Intro

The BHS Class of 2014 needs some money for prom. We came up with the idea of selling senior shirts as a fundraiser, but the process for organizing an order for ~300 people is incredibly complex and comes with the headaches of having to lend money to make an order, collecting money afterward, over-ordering, etc.

This is our solution: a Stripe-based marketplace to preorder shirts. This lets us record the name/size/selection of everyone who wants a shirt, and then aggregate that data later. Payments are processed through Stripe.

Technical Stuff

This is a Django project. It currently only has one application, “shirts.” Data is stored by default in SQLite, but that can be changed easily. Database migrations are handled through South.

I have included some deployment scripts, namely:

  • Makefile
    • Provides automated deployment, but will require changing of paths
  • hup_bhssales
    • Used in my git post-receive hook to restart the server process automatically when I push new changes to production
  • bin/gunicorn_start
    • The script called by supervisord to start gunicorn — will also require changing of paths for custom deployment

Supervisor keeps a gunicorn instance running with a socket in /tmp. I have set up nginx to proxy_pass to that socket, more or less just like any other Django project.

Architecture

There are only two models. 1. StoreItem contains a name/description/summary/price of a certain item 2. Order contains the name of the customer, a timestamp, the purchase price (in case the price in the future changes), and the Stripe ID of the charge. The Stripe ID is optional — I’ve allowed a separate “in person” payment type.

When the order form is submitted, /charge will use the Stripe Checkout token to attempt to make the charge through Stripe. If it’s successful, an Order instance will be saved and the user redirected to a confirmation page. A public list of all orders is included.

The sizes are stored as a constant in shirts/models.py. I’m not sure this is the best way to do it.

Configuration

I have included my Dev configuration. I manage configurations using django-configurations. You’ll notice the end of settings.py tries to import all from local_settings.py. You’ll need to create a local_settings.py in the same format as settings.py, containing a:

class Production(Configuration):

Put your live Stripe keys in that configuration, without committing it to Git.

Also, run this in a venv. A requirements.txt is included.

]]>
http://www.gnewt.at/blog/2014/04/bhs-shirt-sales-with-django/feed/ 1
What Would the Bhagavad Gita Say? http://www.gnewt.at/blog/2014/01/what-would-the-bhagavad-gita-say-2/ http://www.gnewt.at/blog/2014/01/what-would-the-bhagavad-gita-say-2/#respond Wed, 15 Jan 2014 02:34:40 +0000 http://www.gnewt.at/blog/?p=276 Note: I wrote this post in Ghost originally, check it out!

You are the evil

This year I’m in a Humanities class. To finalize the semester, each student presents a “Creative Project.” The project includes a 10-15 line recitation from one of the texts we’ve read, a supplement (art piece, sculpture, song, dance, etc.), and a 5-7 minutes talk.

I’m reciting a passage from the Bhagavad Gita and was at a loss of what to include as a supplement until I remembered What Would I Say.

What Would I Say is a project by HackPrinceton which creates a Markov chain from your Facebook statuses and uses it to generate sentences that sound like you. The results are “often hilarious (and sometimes nonsensical).” I decided that as my supplement I wanted to create a Markov chain of the Bhagavad Gita, the goal being to generate phrases that sound like they were pulled from the text but really make little to no sense. This ended up being easier than I expected. Steps are as follows.

  • Extract the text from the Bhagavad Gita into plaintext
    • I had a PDF copy so extracting just the text was tough, but after half an hour or so of regular expressions and manual editing, it was fine
  • Create a Markov chain from the result
    • I used codebox’s markov-chain project from GitHub
    • I initially only generated the chain with a depth of 3, but added chains of depth 2 and 4 later — depth 2 produces far more disjointed and ridiculous sentences, depth 4 produces almost verbatim sentences with occasional changes
  • Get a nice template
    • Shamelessly copied from What Would I Say
  • Programatically make random sentences available through an API
    • I modified the markov-chain project slightly and put it inside a Flask wrapper
  • Write some JavaScript to grab new results from the API when the big button is clicked

That’s it! The final result can be seen at instantgita.com and works pretty nicely. The Markov chain depth defaults to 3, but it’s worth playing with 2 and 4 as well.

]]>
http://www.gnewt.at/blog/2014/01/what-would-the-bhagavad-gita-say-2/feed/ 0
Weekend Project: Web-controlled Christmas Lights with Node.js, Arduino, and Raspberry Pi http://www.gnewt.at/blog/2013/09/christmas-lights-with-node-js-arduino-raspberry-pi/ http://www.gnewt.at/blog/2013/09/christmas-lights-with-node-js-arduino-raspberry-pi/#comments Sun, 15 Sep 2013 20:03:38 +0000 http://www.gnewt.at/blog/?p=250 Christmas Lights

This is my Node.js “hello world.” It’s a weekend project that allows you to control GE Color Effects lights over the internet through the use of a Raspberry Pi (running nginx and a Node.js application) connected to an Arduino. Like I say in the video, I think it may be possible to control the data line of these lights directly from the Raspberry Pi’s GPIO pins, but I already wrote an Arduino library to handle that and it works nicely.

Tech Stuff

The setup is fairly simple. The Raspberry Pi runs a frontend with my webserver of choice, nginx. It serves up a static page on / and proxies to my Node.js application on /api. Post data sent to /api is decoded by the Node application and matched with a hex value (assuming the color sent was valid). This hex value is then packed into the two-byte serial format I developed for my Arduino library, and sent over serial to the Arduino. Internally the Arduino uses a data structure called a circular buffer. Circular buffers are especially cool for this usage, because when I ‘push’ a light onto the string of lights, every single light needs to be updated (as each color is ‘moving’ down the line). With a circular buffer, the data structure remains a constant size, and all that’s required to update it is to write a new value at the ‘head’ location and then increment the location of the head. More specifics about how this works can be found in the linked Wikipedia article as well as the source code for the aforementioned Arduino library.

I had a lot of fun with this project. One thing I really like about Node.js is how simple it makes creating APIs that can do Really Cool Things. Using just the JavaScript environment available in my web browser, I can package the color data in the format Node needs it, and let Node handle the rest. Node.js is not for everything, but the ease of communication between browser and application makes it a joy to work with.

Do It Yourself

Get a Raspberry Pi set up with Node.js installed, and an Arduino with the sketch linked below flashed to it. To flash the Arduino, you need the GEColorEffects library as a dependency.  Connection to the lights themselves is outside of the scope of this post, but more info can be found in darco’s original post. Clone the nodejs-christmas-lights git repository onto the Raspberry Pi. Ensure that the Arduino manifests as a serial port (usually /dev/ttyACM0) on the RPi, and chmod it to be accessible by your user. A simple ‘chmod 777 /dev/ttyACM0’ should do, since (hopefully…) your Raspberry Pi isn’t a production box.

Set up nginx on your Raspberry Pi, and put the contents of the nodejs-christmas-lights repository’s www folder in your webroot. Again, this is more or less outside the scope of this post, but the following config should act as a starting point. Important to note is that the /api path must forward to the host/port of your Node.js application.

server {
    listen 80;
    server_name lights;

    root /var/www/vhosts/lights/htdocs;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    location /api {
        proxy_pass http://localhost:8080;
    }
}

If all is set up correctly, navigate to the Raspberry Pi in your browser, choose a color, and hit the ‘Go!’ button.

Resources

Feel free to ask questions in the comments. If you do something cool with this code, I’d love to hear about it!

]]>
http://www.gnewt.at/blog/2013/09/christmas-lights-with-node-js-arduino-raspberry-pi/feed/ 5
Publishing Data to Redis with Django Signals http://www.gnewt.at/blog/2013/08/publishing-data-to-redis-with-django-signals/ http://www.gnewt.at/blog/2013/08/publishing-data-to-redis-with-django-signals/#respond Mon, 19 Aug 2013 04:37:29 +0000 http://www.gnewt.at/blog/?p=244 Just something I found and thought was kind of cool. I’m currently working on a project that uses Django for its frontend, but eventually passes the user to a JavaScript frontend that talks to the Node.js / Redis backend with Socket.IO. I needed a way to store data in Redis whenever a specific Django model was saved. I looked up ‘Django + redis’ beforehand, but the existing projects seem to be mostly cache-oriented, and as far as I know Django doesn’t have a standard adapter for Redis. No worries — it’s all Python!

Django signals let you execute functions whenever a signal is emitted, but specifically in my case, when a model is saved. You can put your signals code anywhere, but I like to make a ‘signals.py’ in the app directory and then just add the line ‘import signals’ to the app’s __init__.py. I subscribed to the Django model saved and model deleted signals with functions that connect to Redis and add some of the relevant data to a hash. Hashes in Redis are very much like dicts in Python, and Andy McCurdy’s redis-py library allows you to pass dicts directly to the hmset function.

Here’s the relevant code (adapted for the example) in signals.py:

import redis
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from yourapp.models import YourModel

@receiver(post_save, sender=YourModel, dispatch_uid="yourmodel_create")
def addYourModelToRedis(sender, instance, **kwargs):
	r = redis.StrictRedis(host='localhost', port=6379, db=0)
	yourmodel_dict = {
		'uid': instance.user.id,
		'number1': instance.number_1,
		'number2': instance.number_2,
		'status': instance.status
	}
	r.hmset('yourmodel:' + instance.uniqueKey, yourmodel_dict)

@receiver(post_delete, sender=YourModel, dispatch_uid="yourmodel_delete")
def removeYourModelFromRedis(sender, instance, **kwargs):
	r = redis.StrictRedis(host='localhost', port=6379, db=0)
	r.delete('yourmodel:' + instance.uniqueKey)

The “dispatch_uid” parameter passed to the receiver decorator is intended to keep the signal from being acted upon more than once per save/deletion of a model. All the Django documentation says is to use a unique string; they don’t recommend that you use a specific format and it doesn’t seem to matter as long as it’s unique. Another thing to note is that the ‘instance’ parameter for my handler functions is specific to the post_save and post_delete signals. In general signal handlers are expected to take “sender” and “**kwargs.” However it’s safe to extract the ‘instance’ variable from **kwargs in the function definition when only being used for these specific signals. More information about signals and handling signals can be found in the Django documentation.

]]>
http://www.gnewt.at/blog/2013/08/publishing-data-to-redis-with-django-signals/feed/ 0
Scripting an Ice Cream Delivery with the Android SDK http://www.gnewt.at/blog/2012/07/scripting-an-ice-cream-delivery-with-the-android-sdk/ http://www.gnewt.at/blog/2012/07/scripting-an-ice-cream-delivery-with-the-android-sdk/#comments Fri, 13 Jul 2012 23:15:20 +0000 http://www.gnewt.at/blog/?p=235 Today, a smartphone-connected taxi company called Uber is operating five ice cream trucks in Seattle. You click a button in the Uber app and select your location, and an ice cream truck comes to you. Or at least that’s what should happen. Even with today’s weather (read: periodic torrential rain), people are clamoring to get their ice cream due to the fact that it’s only available for one day… meaning almost nobody is actually able to get a spot in the queue. Uber’s Twitter feed is full of advice telling customers just keep hitting the button, but man, I have work to do. I can’t sit here and press the little ice cream icon all day. Something has got to give.

The Android SDK contains a tool called monkeyrunner. Monkeyrunner lets you simulate touch events, take screenshots, etc… and it does it through a very simple Python library. I decided to see if I could write a little script to keep pressing the ice cream button in Uber’s app, and it only took a few minutes.

from time import sleep
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

# Attach to Android device
d = MonkeyRunner.waitForConnection()

# Take a screenshot of the "sorry, keep trying" screen for reference
raw_input("Get to the error screen, then hit enter.\n")
oldpic = d.takeSnapshot()

while True:
    # Touch the ice cream button
    d.touch(540, 200, MonkeyDevice.DOWN_AND_UP)
    sleep(4)
    newpic = d.takeSnapshot()
	# If the screen looks like our old error
	# screen (95%), hit OK and just keep going (in 10 seconds)
    if newpic.sameAs(oldpic, .95):
        d.touch(460, 700, MonkeyDevice.DOWN_AND_UP)
        sleep(10)
	# But if the screen has changed, stop running the loop.
    else:
		break

I still don’t have ice cream, but the script is running and working.

]]>
http://www.gnewt.at/blog/2012/07/scripting-an-ice-cream-delivery-with-the-android-sdk/feed/ 4
Bi-directional Caller ID Spoofing with Asterisk http://www.gnewt.at/blog/2012/07/asterisk-bidirectional-cid-spoofing/ http://www.gnewt.at/blog/2012/07/asterisk-bidirectional-cid-spoofing/#comments Wed, 04 Jul 2012 02:04:20 +0000 http://www.gnewt.at/blog/?p=225 Caller ID spoofing has been around for a long time. Way back when (well, 2004), an article was published on rootsecure.net with an included Perl script, detailing how to use Asterisk to change your caller ID information, in order to pretend to be somebody else. I had some fun toying with that (heh...), and noticed that some commercial services began to pop up which offered the same capability for a price. SpoofCard is the one that I’ve seen around the most, but many exist. Bah. Setting up an Asterisk server is free if you have access to a Linux box, and outbound SIP trunking is dead cheap. With flowroute.com, I pay less than a cent per minute to place calls within the U.S. The perl script, obviously, is also free.

The other day I saw something as part of a commercial spoofing service that I hadn’t seen before: bidirectional caller ID spoofing. Basically, it will call friend A from friend B’s number, friend B from friend A’s number, and record the result. This leads to something along the lines of “You called me!” “No, you called me!” As fun as that is, websites like PrankDial are charging a lot of money to do something that is, in practice, very simple.

I haven’t seen a script to do this posted on the internet yet, so I created one and put it on github. You’ll have to set up the Asterisk server by yourself, but implementing the script is easy.

  1. Put dual_cid_spoof.py in the /usr/share/asterisk/agi-bin directory
  2. Make it executable to the asterisk user
  3. Add an extension to extensions.conf that calls the script, using pattern matching to give it arguments. For example:
[spoof]
exten => _37NXXNXXXXXXNXXNXXXXXX,1,Answer
exten => _37NXXNXXXXXXNXXNXXXXXX,2,AGI(dualcidspoof.py,${EXTEN:2:10},${EXTEN:12:10})

This uses the extension 37, but that part can be changed. This pattern matches any calls that have the number 37 followed by two 10-digit phone numbers, and then pulls those numbers out and uses them as arguments to the AGI script ${EXTEN:2:10} means take the extension, at index 2, and pull out 10 digits. To execute it with phone numbers 123-123-1111 and 222-202-2020, I would dial 3712312311112222022020.

MeetMe is required to use this script, since it works by placing both users into a conference room together. The default conference room number is 1234, but that can be changed in the script. Also necessary is changing the outgoing SIP trunk in the Python script from “flowroute” to whatever the name of your outgoing SIP trunk is. Both of these are variables at the top of the script. Execution flow works like this:

  • Create two .call files, each with opposite CID/destination info. These files are set to dump the callees into a conference room when they answer.
  • Place the files in /var/spool/outgoing/asterisk, to be automatically processed by the Asterisk spooler.
  • Connect you into the same conference room as a muted admin, giving you the ability to kick users and listen without being heard.

Enjoy, and feel free to ask questions. Again, you can get the script here.

]]>
http://www.gnewt.at/blog/2012/07/asterisk-bidirectional-cid-spoofing/feed/ 5
Arduino, Circular Linked Lists, and Christmas Lights http://www.gnewt.at/blog/2012/06/christmas-lights-linked-lists/ http://www.gnewt.at/blog/2012/06/christmas-lights-linked-lists/#comments Wed, 27 Jun 2012 06:33:40 +0000 http://www.gnewt.at/blog/?p=192 EDIT: Yes, the linked list solution is not the most efficient one (and in fact could be dangerous if used with much more memory than this when malloc’d on a small chip like the Arduino). The “right” way is using a circular buffer. A sketch utilizing a circular buffer has been added to the github project.

Around two years ago, a fellow by the name of darco posted an article called “Hacking Christmas Lights” on his blog. He was nice enough to reverse engineer the LED data bus protocol of the GE Color Effects christmas lights, as well as release some code for an ATMel microcontroller. This was of course turned into an Arduino library soon after.

I had an idea for something to do with these lights: I wanted a network service I could connect to which would pick a random color from a pre-defined list, tell me which color it picked, and then “push” that color onto the string of lights. Each time the service was hit, a new color would enter the string of lights. Each other color would move to the next light until it was at the end of the string, where it would “fall off.”

I decided to do all the networking and color choosing in a Python script on my laptop, leaving the Arduino with just the task of controlling the lights and storing their colors. The GEColorEffects library would handle the control, so all I needed to do on that end was find a data structure to store the colors in. Usually I would just use an array, but this approach gets ugly when you want to “move” each color to the next light. It would involve copying every single color value in the array to the next location before adding the new color.

// colors are 12 bits, so can be stored in a 16-bit type easily
uint16_t lights[NUMLIGHTS]; // populated somewhere else in code
int i;

--snip--

for (i = NUMLIGHTS; i > 1; i--) {
    lights[i-1] = lights[i-2];
}

lights[0] = newcolor;

The previous code would have to be called every time I wanted to add a new color to the string of lights. It would probably work just fine (meaning sufficiently fast) considering that it’s only copying 72 bytes, but it feels clunky. I wanted an approach which felt elegant. The thing that came to mind after some shower-aided thinking (all good programming ideas happen in the shower) was a circular linked list. A linked list is a collection of structures, 0r collections of data, with the unique characteristic that each structure contains a pointer to the next one. In a doubly-linked list, each structure contains a pointer to the previous and the next one. In a circular linked list, the last structure points to the first, effectively making it act like a circle. If you were to follow the path forever, you’d never reach an end.

The nice part of using circular linked lists is that you can just choose where the “beginning” is dynamically.

struct RGB
{
    // each color is only 4 bits but stored as an 8-bit type
    uint8_t r;
    uint8_t g;
    uint8_t b;
    struct RGB *next; // pointer to the next RGB structure
};
typedef struct RGB rgb;

rgb *head;

void populate_linked_list()
{
  int i;
  rgb *curr;
  curr = head = (rgb*)malloc(sizeof(rgb)); // allocate first struct as head

  for (i = 0; i < lightCount-1; i++) { // allocate 35 more (36 lights total)
      curr->r = 15; // they all start out red
      curr->g = curr->b = 0;
      curr->next = (rgb*)malloc(sizeof(rgb));
      curr = curr->next;
  }
  // and finally, the last struct
  curr->r = 15;
  curr->g = curr->b = 0;
  curr->next = head; // the "next" after the last, is the first
  curr = head;
}

The lights are set by iterating through the list and using the GEColorEffects library to set each light to the color represented by each structure. Here comes the fun part. To “push” a color onto the set of lights (and move each other color to the next light), all you have to do is write the color values to the current head of the list, and then move the head to point to the next structure. Keep in mind that we’re pushing colors onto the end of the list, and each color at the very beginning of the list falls off when we do that.

void add_color(uint8_t r, uint8_t g, uint8_t b)
{
  head->r = r;
  head->g = g;
  head->b = b;
  head = head->next;
}

We’ve just moved the beginning/head of the list one light forward (meaning the 2nd color on the string of lights moves to the 1st, 3rd moves to 2nd etc.) and put the data for the new color in the previous location of the head, which is now the very end of the list. The colors of the lights appear to move accordingly.

I put the code on github here. It comes with the Arduino sketch which implements the linked list setup as well as a simple serial interface. Read the README for more info about that.

]]>
http://www.gnewt.at/blog/2012/06/christmas-lights-linked-lists/feed/ 4
The Energy of Making http://www.gnewt.at/blog/2011/05/the-energy-of-making/ http://www.gnewt.at/blog/2011/05/the-energy-of-making/#respond Wed, 25 May 2011 03:35:33 +0000 http://www.gnewt.at/blog/?p=183 I returned from Maker Faire Bay Area yesterday. The wonderful mix of conference, expo, and fair always fills me with a lot of energy to make things. Just being around people like the members of Noisebridge, the inventors of sugru, Mitch Altman (inventor of the TV-B-Gone), etc., osmotically sparks my creativity and leaves me thinking: it feels so good to make things. There are people out there who haven’t made a thing in their life, and they need to be exposed to it.

Cory Doctorow captures what I’m saying in a quote from his book Little Brother:

If you’ve never programmed a computer, you should. There’s nothing like it in the whole world. When you program a computer, it does exactly what you tell it to do. It’s like designing a machine — any machine, like a car, like a faucet, like a gas-hinge for a door — using math and instructions. It’s awesome in the truest sense: it can fill you with awe.

A computer is the most complicated machine you’ll ever use. It’s made of billions of micro-miniaturized transistors that can be configured to run any program you can imagine. But when you sit down at the keyboard and write a line of code, those transistors do what you tell them to.

Most of us will never build a car. Pretty much none of us will ever create an aviation system. Design a building. Lay out a city.

While the quote discusses programming specifically, it explains the brilliance of using the tools available to you to invent new tools. Check out a hackerspace near you, or the MAKE homepage, or Hack-A-Day. Look at all the links in this single post: all people who make things and want to help others do the same.

Go make something.

]]>
http://www.gnewt.at/blog/2011/05/the-energy-of-making/feed/ 0
Noisebridge http://www.gnewt.at/blog/2010/05/noisebridge/ http://www.gnewt.at/blog/2010/05/noisebridge/#respond Sun, 23 May 2010 18:06:48 +0000 http://www.gnewt.at/blog/2010/05/noisebridge/ image

I’d like to extend a thank you to San Francisco’s Noisebridge hackerspace for being so hospitable and friendly towards me during my time here. On Friday when I arrived in SFO, I took the BART straight to Noisebridge and hung out there till that night. It was nice to be in an environment where I could work, learn, and talk, despite being a stranger in this city.

I’ve met a lot of interesting people and was even invited out to dinner that night. San Franciscans really love their lights, I’ve found. Our crepe restaraunt had fancy fading rainbow lights.

I’ve included a picture of Noisebridge at a fairly dormant time.

]]>
http://www.gnewt.at/blog/2010/05/noisebridge/feed/ 0
Making Fulgurites http://www.gnewt.at/blog/2010/05/making-fulgurites/ http://www.gnewt.at/blog/2010/05/making-fulgurites/#comments Wed, 19 May 2010 02:34:18 +0000 http://www.gnewt.at/blog/?p=122 We recently acquired a pole pig at the lab. We bought it off a guy who didn’t have time for a high voltage hobby any more, and so far we’ve made a Jacob’s ladder with it, and used it to make fulgurites.

Fulgurites are the figures made by lightning hitting sand (or other melty grainy materials). We don’t have lightning but we can definitely simulate it with the pole pig. We start by putting sand (100lb for $7 at Home Depot) in a terracotta pot. We stick electrodes from the transformer straight into the pot and turn it on. The result comes out like this.

They're beautiful and fractally.

We then epoxy them into nice solid pieces of art. I made a video about the process for my science class.

Fulgurite Production at Hackerbot Labs from Nick Mooney on Vimeo.

Credits to Pip aka @yoyojedi for helping me out with this. He’s the fulgurite master and was nice enough to teach me how.

]]>
http://www.gnewt.at/blog/2010/05/making-fulgurites/feed/ 2