Saturday, October 25, 2008

Tuesday, October 21, 2008

A Brief Pyjamas + Django Tutorial

Update: (June 19, 2009) Since the writing of this post, Pyjamas has been updated and the below code no longer works, though the principles discussed are still valid. The example code is now being maintained in the pyjamas Sourceforge repo, located here.


Intro:


Django is a web framework written in Python. Pyjamas is a Python port of the google web toolkit (written in Java). Pyjamas can be used with Django to create web applications.

In terms of an MVC framework, Django acts as the Model and Pyjamas acts as the Views and Controller.

The "Todo List" Application:

In this brief tutorial, we will create a very simple todo list. The primary purpose of this tutorial is to briefly demonstrate how to serve data with Django, how to create and display widgets with Pyjamas, and how to handle user events with Pyjamas.

Prerequesits:

Here is the software that is needed:
This tutorial will not go into how to install each of these components, nor their basic usage. Hopefully, some of them can be downloaded as packages for your linux distribution. One reader recommended that you have a fairly recent Django version. > 1.0 should work.

The Code:

pyjsDemo/urls.py:
from django.conf.urls.defaults import *
from django.conf import settings

urlpatterns = patterns('',
(r'^services/$', 'todo.views.service'),
(r'^site_media/(?P.*)$', 'django.views.static.serve',
{'document_root': settings.STATIC}),
)

pyjsDemo/settings.py


# ADD THIS
import os
STATIC = str(os.path.join(os.path.dirname(__file__), 'media').replace('\\','/'))

# MODIFY THIS
DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
DATABASE_NAME = 'todo' # Or path to database file if using sqlite3.
DATABASE_USER = 'todo' # Not used with sqlite3.
DATABASE_PASSWORD = '' # Not used with sqlite3.
DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.

# MODIFY THIS
INSTALLED_APPS = (
'pyjsDemo.todo',
)

pyjsDemo/todo/models.py:

from django.db import models

class Todo(models.Model):
task = models.CharField(max_length=30)

def __unicode__(self):
return str(self.task)


pyjsDemo/todo/views.py:


from django.pimentech.network import *
from todo.models import Todo

service = JSONRPCService()

@jsonremote(service)
def getTasks (request):
return [(str(task),task.id) for task in Todo.objects.all()]


@jsonremote(service)
def addTask (request, taskFromJson):
t = Todo()
t.task = taskFromJson
t.save()
return getTasks(request)

@jsonremote(service)
def deleteTask (request,idFromJson):
t = Todo.objects.get(id=idFromJson)
t.delete()
return getTasks(request)


pyjsDemo/media/TodoApp.html:



See the download for this. It's short, but I can't figure out how to paste html into my blog. I'm lazy.



pyjsDemo/media/TodoApp.py:


from ui import Label, RootPanel, VerticalPanel, TextBox, KeyboardListener, ListBox
from JSONService import JSONProxy

class TodoApp:
def onModuleLoad(self):
self.remote = DataService()
panel = VerticalPanel()

self.todoTextBox = TextBox()
self.todoTextBox.addKeyboardListener(self)

self.todoList = ListBox()
self.todoList.setVisibleItemCount(7)
self.todoList.setWidth("200px")
self.todoList.addClickListener(self)

panel.add(Label("Add New Todo:"))
panel.add(self.todoTextBox)
panel.add(Label("Click to Remove:"))
panel.add(self.todoList)
RootPanel().add(panel)


def onKeyUp(self, sender, keyCode, modifiers):
pass

def onKeyDown(self, sender, keyCode, modifiers):
pass

def onKeyPress(self, sender, keyCode, modifiers):
"""
This functon handles the onKeyPress event, and will add the item in the text box to the list when the user presses the enter key. In the future, this method will also handle the auto complete feature.
"""
if keyCode == KeyboardListener.KEY_ENTER and sender == self.todoTextBox:
id = self.remote.addTask(sender.getText(),self)
sender.setText("")
if id<0: id =" self.remote.deleteTask(sender.getValue(sender.getSelectedIndex()),self)" method ="=" method ="=" method ="=">

pyjsDemo/media/build.sh

python ~/python/pyjamas-0.3/builder/build.py TodoApp.py



A very brief walk through of how to get this running:

Extract the demo:
  • tar -xvvzf pyjamasDjango.tar.gz
Create the db:
  • mysql -u root
  • > CREATE DATABASE todo;
  • > grant all privilages to todo.* to 'todo'@'localhost'; (or possibly > grant all on todo.* to 'todo'@'localhost';)
  • > exit;
Create the tables:
  • cd pyjsDemo
  • python manage.py syncdb
Build the javascript:
  • vim media/build.sh
  • (edit this so that it points to the build.py of pyjamas)
  • media/build.sh
Run the server:
  • python manage.py runserver
Test it out:
  • In your browser, goto: http://127.0.0.1:8000/site_media/output/TodoApp.html

Here are the demo source files:

Saturday, October 18, 2008

Java to Python conversion

Pyjamas is for python, what Google Web Tooklit is for Java. Pyjamas takes python code and some widget libraries and runs it through a python-to-javascript translator. The result: Coding web appliations has never been easier! JSON calls and event handling is a breeze. Little projects that I've attempted doing in the past, using libaries such as jquery, have left me writing a lot of javascript by hand, which get's ugly.

While I absolutley love pyjamas (and gwt for that matter), I really like the looks of extjs. The good news is that they have come out with extjs-gwt, which is "a Java library for building rich internet applications with GWT."

In talking with some of the folks on the pyjamas mailing list, I've gathered that the process of making pyjamas involved hand-converting the java libaries (ie widgets) of gwt from java to python. (If you look at the source code of both pyjamas and gwt, you can see that it's a pretty straight-forward conversion).

Surprisingly, pyjamas is only about 8000 lines of source code, which is relatively long. Extjs-gwt, on the other hand, as one person on the mailing list commented, has over 33,000 lines of java code in widgets alone!

The task of hand-translating extjs-gwt would be daunting.

I'm currently investigating the possiblity of writing a java to python converter to at least help out with the translation. A google search let me to a blog post which led me to an unmaintained project called java2python.

Because I'm personally interested in the workings of such technologies, and because I couldn't get java2python to work, I've decided to write my own translator.

I found a great article by the author of antlr (the same lexer/parser/tree_generator that java2python uses) on how to do such a translation between languages.

I hope that my efforts prove fruitful!

Wednesday, October 15, 2008

Remote Building on Eclipse

I recently had a need, or desire, to develop c++ code on Eclipse in windows, but have it build remotely on a specially configured linux box. Here's how I did it:

  • Get Cygwin and make sure ssh.exe and rsync.exe are installed with it.
  • I created a make.exe file out of the following (which I put in C:\WINDOWS):


#include
#include

main(int argc, char * argv[])
{

char str[200] = "make.bat";
int i = 0;
for (i = 1; i < tmp =" argv[i];">


  • I created a make.bat out of the following (which I put in C:\WINDOWS):


@echo off
set CURDIR=%cd%
chdir C:\Documents and Settings\g...ROOT OF PROJECT HERE
C:\cygwin\bin\rsync.exe -rave C:\cygwin\bin\ssh.exe . guser@192.168.0.1:~/remoteBuild
C:\cygwin\bin\ssh.exe guser@192.168.0.1 python remoteBuild.py """%CURDIR% --- %*"""

  • On the remote machine, I created a remoteBuild.py with the following (left in my homedir). This code is highly customized, so you will probably need to modify it. What it basically does is it converts C:\.... to a linux style path.

def main():
args = sys.argv

argsFromWindows = args[1]
print "received: " + argsFromWindows

path, buildArgs = argsFromWindows.split("---")

relPath = path.split("CUST")[2].replace("\\","/").strip("/")

print "relPath: " + relPath
print "buildArgs: " + buildArgs

curDir = os.popen('cd remoteBuild/%s; make %s' % (relPath, buildArgs))
print curDir.read()

if __name__ == "__main__":
main()



  • Now I can use eclipse's build button. It creates the makefiles locally on the machine, rsync's them over, builds them, and then spits back any errors/warnings to me.

Monday, September 15, 2008

Sunday, September 14, 2008

ryncing

rsync -rave ssh USER@HOST:DIR/ ./

Tuesday, August 12, 2008

It's all about the process

It's all about the process. Maybe IDEO is so great, because of their process. Viasat is great, because of VGate, their process. Processes are like investments. You pay more now, but reap greater benefit down the road.

Sunday, July 27, 2008

Backing up ArchLinux to USB Thumb Drive

I have to say, I'm loving ArchLinux. In my opinion, it has wonderful package management, a rolling-release model (you never have to download the latest ISO to upgrade), wonderfully community docs and support, etc.

But, like any distro, it's required a few tweaks to get things working properly with my particular laptop, an Everex StepNote ST5340T. Over the last few months, I've made tweaks here and there, and if I had to start over with a fresh install, I'd be sad. In particular, the laptop's wireless and suspend features needed tweaking to get them to work right.

This post is about backup solutions. After a little research, I came accross this site, and decided to go with dar. Here is my bash script which will backup everything (except for that which I don't want backed up) to my usb thumb drive. It's a 2GB thumb drive, and the backup takes 1.4GB. Pretty cool huh? I'm impressed.


#!/bin/bash
pacman -Scc
dar -v --alter=atime --empty-dir --fs-root / --noconf --create /media/usb/ backup08-Jul-27 -z6 -an -X "*.ogg" -X "*.avi" -X "*.mp?" -X "*.pk3" -X "*. flac" -Z "*.zip" -Z "*.tgz" -Z "*.gz" -Z "*.gzip" -Z "*.bz2" -Z "*.bzip2" -Z "*.mov" -Z "*.rar" -Z "*.jar" --prune lost+found --prune media --prune proc -- prune mnt --prune sys --prune home/gdw/music --prune home/gdw/pics

Friday, July 25, 2008

Dynamically getting fields from a Django Model Object

Response to my question on #django> gdw2: see get_* in django.db.models and then see model._meta.fields

> Package._meta.fields

... does the trick

Everex Suspend in Linux

I got my Everex StepNote ST5340T to suspend today in ArchLinux! Yea! Suspending is a very important feature, especially when you're on the road, because it allows you to turn the computer off and on quickly. Here is my little script:

#!/bin/bash
modprobe -r rt73usb
sleep .7
modprobe -r ehci_hcd
sleep .7
modprobe -r ohci_hcd
sleep .7
modprobe -r rt73usb
sleep .7
echo "mem" > /sys/power/state
sleep .7
modprobe rt73usb
sleep .7
modprobe ehci_hcd
sleep .7
modprobe ohci_hcd
sleep .7
modprobe rt73usb
sleep .7
/usr/bin/netcfg2 -a
sleep .7
/usr/bin/netcfg-auto-wireless wlan0

I'm confident that it could be optimized greatly, but it works for now. If you have any questions, send and email or post a comment.

Tuesday, July 08, 2008

svn commit all new files

svn add * --force
svn commit -m "blah blah blah"

Thursday, June 26, 2008

Dropping all Tables in a DB

mysqldump -u pykillian --add-drop-table --no-data pykillian | grep ^DROP | mysql -u pykillian pykillian

Wednesday, May 28, 2008

Deleteing all of Vim's swap files

Every once in a while one of my ssh sessions will timeout and when I log back in and use vim, it complains about all my leftover swap files.

Problem solved:

find ./ -name \*.swp | xargs rm


This recursively removes all swp files!

Thursday, May 08, 2008

joining mpg's to one giant flv using ffmpeg

I have a bunch of mpg's (extention avi) from my cannon digital elph which I would like to combine to make one giant flv suitable for web viewing.

This was a good start: http://ffmpeg.mplayerhq.hu/faq.html#TOC29

but in the end, it became as simple as doing the following

cat *.AVI > bigcahuna.mpg
ffmpeg -i bigcahuna.mpg -f flv -s 640x480 priderock.flv

That's it!

for more possibly relevant material, see: http://del.icio.us/gdw/flv

Thursday, April 24, 2008

Temporarily Share Internet Connection on Ubunty Gutsy (Linux)

On host machine:

(this machine has wireless internet connection over wlan0 and wants to share it over eth0)

sudo ifconfig eth0 192.168.10.1 netmask 255.255.255.0
sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
sudo su
echo 1 > /proc/sys/net/ipv4/ip_forward

On client machine:
(this machine wants to connect to host over eth0)

sudo ifconfig eth0 192.168.10.2
sudo route add default gw 192.168.10.1 eth0

Source: http://wiki.steenbe.nl/?p=29#more-29

Wednesday, April 09, 2008

Save interactive python history to file

import readline
readline.write_history_file('lds_calendar.py')

Tuesday, April 01, 2008

Batch croping images in Linux

I used this blog post: http://www.kriyayoga.com/love_blog/post.php/853

I was having a hard time with the for loop because of spaces in my file names. I tried this alternative and it worked. I'm not sure that I couldn't have gotten the for loop to work though, had I added the proper quotes.


find ./ -name '* *' | while read FILE; do convert "$FILE" -crop 487x370+386+281 "$FILE-cropped.jpg"; done

487x370 are the new image sizes. 386 and 281 are the offsets from the left and top borders.

Wednesday, March 12, 2008

Red, Green, White LEDs

Our original circuit design used a dual-colored LED (red/green) as an idicator to signal the crossover of a voltage on the comparitor (if that makes any sense). The problem, as seen in the graph below, was that for a given voltage, the currents across the different colors varied significantly. This caused a problem in that when the red/green LED switched colors, it would cause the white LED on the end of the shaft to dim or go brighter. For obvious reasons, this is not good. We need a constant light source.



So I decided to use two discrete LEDs in hopes that I could put different resistor values in series with each of them, thus providing equal current drain.

This last week we got the LEDs and I built the circuit and it works. Previous current drains were up in the ~20mA (for green) and ~30mA (for red). Now it's closer to 6mA for both colors.

Just a note: The opamp swings different amounts in both directions. I don't know if this is a problem or what exactly is causing it. My guess would be that the resistor values on the voltage dividers aren't exactly equal, resulting in the power supplies being skewed.

So I hooked the two leds up (separately) to a variable resistor, set the resistor value to yield an appropriate3 intensity and current measurement, and then measured the variable resistor to figure out what value of discrete resistor I should use to yield the desired results.

Red: ~8k
Green: ~3.3k

Using these values, like alluded to above, I measure the current drain of the entire circuit and found it to be very stable.

---

Now a note about white LEDs. The white LEDs we have are super bright and they only draw 1-2mA (compared to ~3mA for the red and green ones). It makes me wonder if we should (can) use a coupled of white LEDs with cheap filters over them (think red cellophane) instead of the colored ones.

Thursday, March 06, 2008

Django on Ubuntu Gutsy

My first steps at Django

sudo apt-get install libapache2-mod-python python-django
sudo apt-get install mysql-server python-mysqldb
sudo /etc/init.d/mysql start (the previous line upgraded mysql and didn't restart it)

cd /home/username_here
django-admin startproject mysite
cd mysite
./manage.py runserver

[I opened up a putty session forwarding my localport 7145 over to localhost:8000 on the ubuntu box]

in firefox: http://localhost:7145

Wednesday, March 05, 2008

Simulations

For my ME Capstone course, I'm building a distance sensing circuit which will throw a dual colored LED on way or the other depending on which site of a distance threshold the tip of the device is at.

Currently, we have a potentiometer to calibrate the device in one location and we're thinking of moving to another location with the hopes of making the device 'totally calibratable'. This is in an effort to compensate for variances in photoresistor performance.


So, I'm going to run a parametric sweep simulation to show my how the device switches for the configuration we have now, and then I will run the same simulation, moving the pot as shown above.

Here are the results from my first simulation.

Pyjamas