Thursday, March 31, 2011

The File Server

I was recently tasked with sending a friend a file the other day.  It was too large for email, he was on Windows and I on Ubuntu, so we couldn't netcat it, and the network we were on disallowed SMB (windows share) traffic.  So I pulled out my trusty USB drive, and gave him the file.  Honestly though, I don't want strange USB drives being stuck in my computer.

Solution:  Build a python web-server that can upload and download files :)


A while back I built a CGI Python webserver by hand, this is not the story of that, but rather of my personal file server.

First things first, I needed a way to upload files, index.py would work:

self.send_200()
self.wfile.write('''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Upload/Download</title>
<style TYPE="text/css">
body {
background-color:#ADD8E6;
text-align:center;
margin:0px;
padding:0px;
font-family:airal,helvetica;
}
.main{
display:block;
background-color:#E5E5E5;
margin-left:auto;
margin-right:auto;
padding:10px;
width:800px;
}

</style>

<script type="text/javascript">
function getNameFromPath(strFilepath) {
var objRE = new RegExp(/([^\\/\\\\]+)$/);
var strName = objRE.exec(strFilepath);

if (strName == null) {
return null;
}
else {
return strName[0];
}
}

function setName()
{
document.getElementById('filename').value = getNameFromPath(document.getElementById('up').value);
}
</script>
</head>

<body>
<div class="main">
<H1>Upload / Download Files</H1>
<form action="upload.py" enctype="multipart/form-data" method="post">
<input type="file" name="myfile" size="chars" id="up">
<input name="filename" id="filename" type="hidden"></input>
<input type="submit" value="Send" onclick="setName()">
</form>


<hr>
<h2>Download</h2>
<ul>
''')

import os
j = os.listdir("Downloads")
for item in j:
self.wfile.write("<li><a href='download.py?f=%s'>%s</a></li>" % (item,item))


self.wfile.write('''
</ul>

</div>
</body>
</html>''')

Essentially all of the HTML is echoed back to the user, however there is also a list of previously uploaded files that needed to be available for download, so that was auto-generated from a directory (not web accessible).

Next I needed the upload script to actually save files that people uplodad:
if POST_DICT:
try:
print POST_DICT.keys()
print POST_DICT['filename']
path = os.path.join("Downloads", POST_DICT['filename'])
print path

with open(path, 'wb') as f:
f.write(POST_DICT['myfile'])
except Exception, e:
print e

self.redirect("index.py")

This script checks to see if the POST variable is set, if so it saves the file as the filename (remember to do it binary otherwise we could get a mess when non text files are uploaded). Then redirect the user back to the index so they can instantly see their newly uploaded file.

Download.py
The last, and most difficult part was the download script:
import os
import mimetypes

if QUERY_DICT:
filename = QUERY_DICT['f'][0]

mime = mimetypes.guess_type(filename)

path = os.path.join("Downloads", filename)
head={'Content-Disposition':'attachment; filename="%s"' %(filename)}
self.send_200(mime_type=mime, headers=head)
with open(path) as f:
self.wfile.write(f.read())

else:
self.redirect("index.py")

This was because unless the content-type was set properly, and the proper filename was given, a file would be saved to the drive every time named "download.py".

Finished Product

Saturday, March 19, 2011

The Polygraph Machine

A few months ago I was rummaging though a box and found some electronics components.  To immediately digress I can never throw such things away, and when old electronics are being tossed, I'm there with a soldering iron to rescue parts.  Anyhow, I had found a small amplification chip, a headphone jack and some DIY PCB.  A long time ago, the specifications for the OLPC XO-1 laptop had a curious feature, they were going to use the microphone in port as something other than just a microphone, Geiger counters, conductivity checkers, and a whole slew of things that wouldn't have needed a driver that were just basic I/O systems.


A very simple polygraph just registers the resistance of skin (you can see where I'm going now, can't you?)  By itself the microphone port wouldn't have had enough power to check conductivity, but if you used a battery and an amplifier, well, that is another story.

Around midnight, after drawing a quick schematic (and I'm sure an improper one), and having a poison scare dealing with Ferric Chloride (accidental ingestion), I came up with this:

The Polygraph


To finish off here, I installed Audacity hoping that it would work rather than building some PyGame/Matplotlib/Python monstrosity for a simple test of the equipment.  Some scary sounds came in when I placed my fingers on the terminal.  Attached here is the first sample I took, some features to note:
  • High buzzing sound
  • Second 27?
  • Seconds 21-24, Cannon in D?

 



Friday, March 4, 2011

Gnome 3 - The red-headed stepchild.

Yesterday I grabbed a Gnome 3 livecd from their website.  While the project may not have the fanfare of Ubuntu, or even the excitement that Elementary brings to the table, it was the most beautiful OS I've used in years.

When I began using Ubuntu about four years ago I was amazed, everything seemed to be right were I would have put it, the interface was remarkably ugly though, yet it was free, stable, and ran great on my old Toshiba.  Gnome 3 takes the usability of Ubuntu and makes it top notch.

Some quickly noticeable things about the UI made it very intuitive:
  • There is no need to click the menu, just bump the corner which makes it blindingly fast.
  • The clock is right in the middle, making it significantly easier for your eyes to find the time than when the clock was in with the jumble of icons.
  • The gnome-panel is dark and the windows are light, drawing your focus away from the panel, it disappears in your vision making the whole thing application-centric.
  • Workspaces are incredibly easy to use and I might actually use them now.
  • Opening applications and documents can be done from the keyboard much easier than now, the super key is actually used for something important.
  • Windows don't have a minimize or maximize button (windows don't need to be minimized to the tray due to the fast window and workspace switcher) and maximize functions can be performed by double clicking the title bar, or by an aero-snap type functionality.  The lack of buttons makes the whole thing clean.
  • The few panel menus that exist are clean and consistent behaving in the same way and providing very useful menus.
  • The control panel is finally integrated and looks amazing.
  • There is an easy way to mark applications as trusted (chmod +x) from the GUI.
Downsides:
  • It runs from a livecd, but doesn't like my nvidia graphics card when installed to the hard-drive (after the first time)  The same goes for Ubuntu 11.04.
  • There were no icons on the desktop (perhaps the desktop doesn't support them?)  It was therefore hard to find the "Install to disk" .desktop file as it was on the desktop.