VIVAHATE

Code

Installing PostgreSQL 8.4 in Ubuntu 10.04

X Window Manager Part 1 – Hello XCB

Minimal X Install

Debian net install. Base system only.

# aptitude install xorg
$ startx

Hello XCB

# aptitude install build-essential libx11-dev libxcb1-dev

Debian 6 Install Log Redux

System Install

[Configure Wifi]

# aptitude update
# aptitude install debian-multimedia-keyring
# aptitude update
# aptitude install sudo
# visudo
# aptitude install xorg openbox obconf menu

Add the following to ~/.xinitrc

exec openbox-session
$ startx

Appearance

# aptitude install gtk-theme-switch gtk2-engines

Use the gtk-theme-switch2 application to switch the GTK+ theme.

cp /etc/xdg/openbox/menu.xml ~/.config/openbox/menu.xml

Arch Linux – Macbook Pro

Install Arch

Basic Arch install without networking using the core CD image. Make sure to add wireless_tools from base-devel.

Configure Wifi

I had to blacklist the bcma module. YMMV. There’s some good info here: https://wiki.archlinux.org/index.php/Broadcom_wireless

The network uses WPA encryption

Verify that the kernel module has been loaded and the hardware is ready to use:

$ iwconfig

Bring the interface up:

$ ip link set wlan0 up

List available networks:

$ iwlist wlan0 scan

Rename the default wpa_supplicant.conf:

$ mv /etc/wpa_supplicant.conf /etc/wpa_supplicant.conf.original

Generate a new wpa_supplicant.conf:

$ wpa_passphrase "ESSID" "SECRET PASSKEY" > /etc/wpa_supplicant.conf

Associate adapter with access point:

$ wpa_supplicant -B -Dwext -i wlan0 -c /etc/wpa_supplicant.conf

Get an IP address via DHCP:

$ dhcpcd wlan0

Test:

$ ping -c 3 www.google.com

Add the following to /etc/rc.local:

$ ip link set wlan0 up
$ wpa_supplicant -B -Dwext -i wlan0 -c /etc/wpa_supplicant.conf
$ dhcpcd wlan0

Reboot and you should be connected to the wireless network.

Configure Pacman and Update the System

Edit /etc/pacman.d/mirrorlist and choose a mirror:

$ nano /etc/pacman.d/mirrorlist

Update the system:

$ pacman -Syu

Add a User

# useradd -m -g users -G audio,lp,optical,storage,video,wheel,games,power,scanner -s /bin/bash kyle
# passwd kyle

Sudo

# pacman -S sudo

Add your user to the sudoers list

# visudo

Add the following to the end of the file

kyle ALL=(ALL) ALL

ALSA

# pacman -S alsa-utils

Use alsamixer to unmute the channels

Packer

Install packer

sudo pacman -S git
cd ~/
mkdir src
cd src
git clone https://github.com/bruenig/packer.git
cd packer
chmod 755 packer
sudo ln -s /home/kyle/src/packer/packer /usr/bin/packer

X and Openbox

# pacman -S xorg-server xorg-apps xorg-xinit xterm openbox

Add exec openbox-session to ~/.xinitrc

Nvidia Driver

# pacman -S nvidia nvidia-utils

Reboot.

# nvidia-xconfig

Trackpad Driver

# packer -S xf86-input-mtrack-git

Add the following to your /etc/X11/xorg.conf

Section "InputClass"
  MatchIsTouchpad "on"
  Identifier "Touchpads"
  Driver "mtrack"
  Option "IgnoreThumb" "true"
  Option "IgnorePalm" "true"
  Option "Sensitivity" "0.7"
  Option "ButtonIntegrated" "false"
EndSection

More options here: https://github.com/BlueDragonX/xf86-input-mtrack

Freetype Configuration

TODO

Chromium and Flash

# pacman -S chromium flashplugin

Rails Development

Install RVM:

$ bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)

Close your terminal and open a new one.

Dropbox

Install Dropbox:

# pacman -S dropbox
$ dropbox start

Log in to Dropbox.

PostgreSQL

# pacman -S postgresql
$ createuser -s -U postgres
  Enter name of role to add: kyle
$ createdb

Login Redirection with Rails 3.1, Devise, and CanCan

This approach satisfies a few common requirements:

  • Requests by non-signed in users should redirect to the sign in page. Post sign in, the user should be redirected to their original destination.
  • Requests by signed in users to resources which they cannot access (CanCan::AccessDenied) should redirect to an error page.

Modify Application Controller

First, update your application controller.

Create Error View

Create app/views/error/403.html.erb. The contents of the file are unimportant.

Create Session Controller

Generate a new session controller:

rails g controller Sessions

Here’s how it should look:

Update Routes

Update your routes so Devise knows to make use of your new sessions controller.

Move New Session View

Move your new session view (if you generated them) from /app/views/devise/session/new.html.erb to /app/views/session/new.html.erb.

HINT: Set config.consider_all_requests_local in /config/environments/development.rb to false to test this while in development.

Rails REST Testing with cURL

Ralink RT2870/RT3070 in Debian 6 (Squeeze)

About a year ago, I got this cheap-o USB 802.1n wireless adapter for $15. lsusb reports the device as: Bus 002 Device 002: ID 148f:3070 Ralink Technology, Corp. RT2870/RT3070 Wireless Adapter. In theory, this adapter should be supported out of the box using the rt2870sta module. Of course, just working would be too easy.

To get the wireless adapter to work, we first have to blacklist a few kernel modules.

NOTE: While these instructions are for Debian 6, they should apply to most Debian-based distributions.

Create the following files in /etc/modprobe.d:

$ cd /etc/modprobe.d
$ touch rt2800lib.conf rt2800pci.conf rt2800usb.conf rt2x00lib.conf rt2x00pci.conf rt2x00usb.conf rt61pci.conf

Next, add the following to each file. replacing the name of the module you want to blacklist as necessary (the pattern here should be obvious):

$ cat rt2800lib.conf
blacklist rt2800lib

Next, we need a couple packages. First, install wireless-tools. This should be available on your install media.

$ sudo apt-get install wireless-tools

Next, install the firmware-ralink package. Assuming you don’t yet have an internet connection, you probably won’t find this on your install media as it’s in non-free. I downloaded the package on another computer, transfered it over on a flash drive, and installed it manually.

Reboot. Cross your fingers.

Connecting

# aptitude install wpasupplicant
# iwlist wlan0 scan
# nano /etc/network/interfaces

Add the following:

auto wlan0
iface wlan0 inet dhcp
        wpa-ssid ESSID
        wpa-psk PASSPHRASE

Bring up the interface.

# ifup wlan0

A Simple Chat Room in Node.js

In this post, we’ll be building a simple chat room using node.js. Here’s how it’ll look:

Getting Started

Install node, socket.io, and express

First, make sure you’ve installed node.js. You’ll also want to grab a copy of the socket.io library and the express framework. These can both be installed with npm via the express and socket.io packages.

Directory Structure

Before we cover each file in detail, here’s how everything fits together. Place the chat directory wherever you like, mine is in ~/projects/chat.

$ ls -R chat
chat/:
public  server.js

chat/public:
client  index.html

chat/public/client:
socket.io.js

server.js

index.html

Coming Soon…

Next time, we’ll bring canvas to the party. Here’s a preview of what we’ll be building in the next installment:

McMurdo

Lately, Cyclops and Max have been watching the McMurdo Station Webcam. They requested this script after they got sick of saving images manually and searching for ways to animate them.

Uses the excellent Beautiful Soup library, which makes HTML parsing a snap. The program saves images named 1.jpg, 2.jpg, etc. every few seconds. Because the filename on this partiular webcam changes with each new image, we have to rescrape the page each time we want a new image.

Cyclops runs Windows, but this stuff should run wherever Python and ffmpeg are available.

mcmurdo.py

encode.bat

Videos


Nyx 0.0.2

What’s New?

  • Nyx is now hosted on GitHub
  • Vertex buffer objects
  • Supports Python 3
  • OBJ model support

Example

Screenshots

304,135 triangles. The transparency is just so that we can see a little more detail.
Since there’s no support for lighting yet, without the transparency all we’d
see would be a silhouette.

Notes

The OBJ loader is implemented in 18 lines of Python. There is no error checking and it only supports vertices and triangles, but it loads models exported from Blender just fine. Neat.

Node.js on Mac OS X

Installation

First, install Mac OS X and Xcode. Install Homebrew:
$ sudo chown -R $USER /usr/local
$ curl -Lsf http://github.com/mxcl/homebrew/tarball/master | tar xz
  --strip 1 -C/usr/local
Install Node.js and Express:
$ brew install node
$ brew install npm
$ npm install express
Add the following to ~/.bash_profile:
export NODE_PATH="/usr/local/lib/node/"
You can verify that NODE_PATH has been set correctly by running the node program and inspecting require.paths. You should see something like this:
$ node
> require.paths
[ '/usr/local/lib/node/'
, '/Users/kyle/.node_libraries'
, '/usr/local/Cellar/node/0.2.3/lib/node'
]
> require('express');
{ version: '1.0.0rc3'
, Server:
   { [Function: Server]
     super_: { [Function: Server] super_: [Object] } }
, createServer: [Function]
}

Sample Program

Test it out. Put the following in a file named test.js:
var express = require('express');

var app = express.createServer();

app.get('/', function (req, res) {
    res.send('Hello World');
});

app.listen(3000);

Run It

Run using node:
$ node test.js
And visit http://localhost:3000/ in your browser.

Up Next…

Here’s what we’ll be building in the next post:

Node.js on WebFaction

Installing Node

I was able to build Node successfully on my WebFaction host using the following:

$ ./configure --jobs=1 --prefix=$HOME
$ make
$ make install

All set

$ node --version
v0.2.3

Testing Node.js

I created a custom app in the WebFaction control panel and mapped it to a subdomain, http://node.purslane.webfactional.com/.

I then dropped the following into a file named test.js:

This is simply the basic HTTP server example from the Node.js website, tweaked slightly to include the port that WebFactional chose for my custom app.

Where you put the code isn’t important. I saved it to ~/webapps/node/test.js. Seemed as good a place as any.

Running the server:

$ node test.js
Server running at http://node.purslane.webfactional.com/

Visiting the URL in my web browser resulted in the expected Hello World message.

Object Oriented JavaScript

The Constructor Invocation Pattern

function Greeter(opts) {
  this.who = opts.who;
};

Greeter.prototype.greet = function() {
  document.writeln("Hello " + this.who);
};

var g = new Greeter({who: "Kyle"});

g.greet();

Prototypal Inheritance

if(typeof Object.beget !== 'function') {
  Object.beget = function(o) {
    var F = function() {};
    F.prototype = o;
    return new F();
  };
}

var greeter = {
  who: "Kyle",
  greet: function() {
    document.writeln("Hello " + this.who);
  }
}

var anotherGreeter = Object.beget(greeter);
anotherGreeter.who = "Frank";
anotherGreeter.greet();

A Simple Node.js TCP Server in CoffeeScript

First Attempt

tcp: require 'tcp'

onConnect: ->
    socket.write 'hello\r\n'

onData: (data) ->
    socket.write data

onEnd: ->
   socket.write 'goodbye\r\n'
   socket.end()

server: tcp.createServer (socket) ->
    socket.setEncoding 'utf8'
    socket.addListener 'connect', onConnect
    socket.addListener 'data', onData
    socket.addListener 'end', onEnd

server.listen 7000, 'localhost'

Second Attempt

class Server
    constructor: ->
        @server: tcp.createServer (socket) ->
            socket.setEncoding 'utf8'
            socket.addListener 'connect', -> socket.write 'hello'
            socket.addListener 'data', (data) -> socket.write data
            socket.addListener 'end', -> socket.write 'goodbye'
        @server.listen 8000, 'localhost'

server: new Server()

Python Decorators

class decoratorWithoutArgs(object):
    def __init__(self, fn):
        self.fn = fn

    def __call__(self, *args):
        self.fn(*args)

class decoratorWithArgs(object):
    def __init__(self, arg):
        self.arg = arg

    def __call__(self, f):
        def wrapped(*args):
            f(*args)
        return wrapped

@decoratorWithoutArgs
def foo():
    pass

@decoratorWithArgs(10)
def bar():
    pass

if __name__ == "__main__":
    foo()
    bar()

Nyx 0.0.1

Nyx is a Python ctypes binding to a simple OpenGL rendering library written in C.

Example

Extending Python with ctypes

ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python.

This tutorial assumes a Debian based GNU/Linux distribution. You may have to install build-essential.

Writing your shared library

We’ll start by creating our shared library. Type the following into your favorite text editor and save the file as testlib.c:

const char *say_hello() {
    return "Hello, World\n";
}

Compile and link thusly:

gcc -g -c -Wall testlib.c
gcc -shared -Wl,-soname,libtestlib.so.1 -o libtestlib.so.1 testlib.o -lc

If you didn’t encounter any errors, you should be left with a file named libtestlib.so.1 in the same directory as your source.

Next, you’ll want to make sure that ldconfig can load your library. The easiest way to do this is to create a file named testlib.conf in /etc/ld.so.conf.d/ containing the path where your shared library can be found.

Run the following command to verify that ldconfig can see your library:

ldconfig -v | grep testlib

With luck you should see something like this:

/home/kyle/src/ctypes_test/testlib:
	libtestlib.so.1 -> libtestlib.so.1

Using your shared library with ctypes

Fire up the interactive interpreter and type the following:

>>> from ctypes import cdll, c_char_p
>>> testlib = cdll.LoadLibrary('libtestlib.so.1')
>>> testlib.say_hello.restype = c_char_p
>>> testlib.say_hello()
Hello, World
>>>

You should, of course, see Hello, World displayed as the return value.

A little abstraction never hurts

Here’s a quick example of making your ctypes bindings a little easier to use:

from ctypes import cdll, c_char_p

class TestLib:
    def __init__(self):
        self.lib = cdll.LoadLibrary("libtestlib.so.1")
        self.lib.say_hello.restype = c_char_p

    def say_hello(self):
        return self.lib.say_hello()

testlib = TestLib()
print testlib.say_hello()

OBJ Loader

Loads face and vertex data from .OBJ files. Doesn’t support groups, materials, texture coords, normals, etc… Not a particularly robust solution, but it’s simple and terse. This is a work in progress.

import re

def load_obj(filename):
    verts = []
    faces = []
    f = open(filename, 'r')
    lexemizer = re.compile(r'([^\s]+)')
    for l in f.readlines():
        if l[0] == '#': continue
        tokens = lexemizer.findall(l)
        if tokens:
            if tokens[0] == 'v':
                v = [float(tokens[1]), float(tokens[2]), float(tokens[3])]
                verts.append(v)
            if tokens[0] == 'g':
                pass
            if tokens[0] == 'f':
                f = []
                for v in tokens[1:]:
                    f.append(int(v))
                faces.append(f)

Rabbyt, Pymunk, and Pyglet

An introduction to Pymunk

For this tutorial, we’re putting pygame and rabbyt on the back burner and focusing our attention on pymunk. Pymunk is a pythonic wrapper around the Chipmunk 2d physics library. In this tutorial we create a simulation in which we drop a ball on to a flat surface. As the simulation runs, we periodically print the ball’s height. Graphing this value against time gives us the following:

pymunk_bounce

Astute readers will notice that the ball seems to bounce before it hits the floor. This is influenced by the value we pass to space.step. Calling space.step with a smaller value (i.e. higher resolution) would give us a more accurate graph. Of course, assuming we ran our higher resolution simulation for the same amount of time, we’d have a lot more values to graph.

In our next tutorial we’ll be combining pymunk, pyglet, and pygame and creating a full-fledged graphical physics simulation.

« Older Entries