<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Zero Wind - Jamie Wong &#187; Projects</title>
	<atom:link href="http://jamie-wong.com/category/projects/feed/" rel="self" type="application/rss+xml" />
	<link>http://jamie-wong.com</link>
	<description>Inside the mind of a Waterloo Software Engineering student</description>
	<lastBuildDate>Sun, 15 Aug 2010 05:25:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>JSONimal &#8211; Elegant DOM Contruction with jQuery</title>
		<link>http://jamie-wong.com/2010/07/16/jsonimal-elegant-dom-contruction-with-jquery/</link>
		<comments>http://jamie-wong.com/2010/07/16/jsonimal-elegant-dom-contruction-with-jquery/#comments</comments>
		<pubDate>Fri, 16 Jul 2010 15:57:43 +0000</pubDate>
		<dc:creator>Jamie Wong</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://jamie-wong.com/?p=342</guid>
		<description><![CDATA[Occasionally for Javascript projects, I found myself building a lot of HTML programatically, and I wasn't satisfied with any of the techniques available, so I built JSONimal. I was originally going to just call it JSONML, but that was taken. What's it do? This example should demonstrate my goal fairly well. $(function() { $.mktag("#demo").jsonimal([ ["h1", [...]]]></description>
			<content:encoded><![CDATA[<p>Occasionally for Javascript projects, I found myself building a lot of HTML programatically, and I wasn't satisfied with any of the techniques available, so I built JSONimal. I was originally going to just call it JSONML, but that was taken.</p>

<p>What's it do? This example should demonstrate my goal fairly well.</p>

<pre class='prettyprint'><code>$(function() {
    $.mktag("#demo").jsonimal([
        ["h1", {text: "JSONimal!"}],
        ["table",{style: 'border: 1px solid black'},[
            ["thead",[
                ["tr",{style: 'text-transform: uppercase'},[
                    ["th", {text: "one"}],
                    ["th", {text: "two"}],
                    ["th", {text: "three"}]
                ]]
            ]],
            ["tbody", [
                ["tr",[
                    ["td", {html: "&lt;u&gt;a&lt;/u&gt;"}],
                    ["td", {text: "b"}],
                    ["td", {text: "c"}]
                ]],
                ["tr",[
                    ["td",[
                        ["a", {href: "http://www.google.ca", text: "Google"}]
                    ]],
                    ["td", {text: "b"}],
                    ["td", {text: "c"}]
                ]],
                ["tr",[
                    ["td", {text: "a"}],
                    ["td", {text: "b"}],
                    ["td", {text: "c"}]
                ]]
            ]]
        ]]
    ]).appendTo("body");
});
</code></pre>

<p>Which will add this to the body:</p>

<h1>JSONimal!</h1>

<table style="border: 1px solid black;"><thead><tr style="text-transform: uppercase;"><th>one</th><th>two</th><th>three</th></tr></thead><tbody><tr><td><u>a</u></td><td>b</td><td>c</td></tr><tr><td><a href="http://www.google.ca">Google</a></td><td>b</td><td>c</td></tr><tr><td>a</td><td>b</td><td>c</td></tr></tbody></table>

<p>For more information and examples, check out the github page: <a href="http://github.com/phleet/JSONimal">JSONimal @ github</a>.</p>

<p>I also posted it as on the jQuery plugins page - but that just points to the github page anyway. <a href="http://plugins.jquery.com/project/jsonimal">JSONimal @ plugins.jquery.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jamie-wong.com/2010/07/16/jsonimal-elegant-dom-contruction-with-jquery/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>AJAX Method Callbacks and Omegle Voyeur Update</title>
		<link>http://jamie-wong.com/2010/04/19/ajax-method-callbacks-and-omegle-voyeur-update/</link>
		<comments>http://jamie-wong.com/2010/04/19/ajax-method-callbacks-and-omegle-voyeur-update/#comments</comments>
		<pubDate>Tue, 20 Apr 2010 01:46:11 +0000</pubDate>
		<dc:creator>Jamie Wong</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[callbacks]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[method]]></category>
		<category><![CDATA[omegle]]></category>
		<category><![CDATA[omegle voyeur]]></category>

		<guid isPermaLink="false">http://jamie-wong.com/?p=200</guid>
		<description><![CDATA[I finally got back around to updating Omegle Voyeur with the ability to interfere, and decided to re-implement the whole thing in jQuery while I'm at it. Since jQuery doesn't come with a built-in method of building classes, I used lowpro for jQuery. It's a port of a class building scheme from Prototype. It doesn't [...]]]></description>
			<content:encoded><![CDATA[<p>I finally got back around to updating Omegle Voyeur with the ability to interfere, and decided to re-implement the whole thing in jQuery while I'm at it. Since jQuery doesn't come with a built-in method of building classes, I used <a href="http://www.danwebb.net/2008/1/31/low-pro-for-jquery">lowpro for jQuery</a>. It's a port of a class building scheme from Prototype. It doesn't do everything I could have hoped for, but it served most of my needs.</p>

<p>The other thing I implemented was a way of knowing when Omegle is blocking requests. They have a more robust form of detection now - it isn't just manual IP ban. Once you request too many things from them too fast, they start requesting a captcha. Locally, this isn't a problem - I simply embed an iframe with Omegle in it and provide instructions to the user. Hosted, this is a more troublesome problem, since the captcha is directed towards an IP, so it must be responded to from that IP. I have no solution to this problem at the moment, but I'm going to look into implementing the whole thing using Greasemonkey so this isn't an issue at all.</p>

<p>For now, you can see the latest version here: <a href="http://jamie-wong.com/omegle/">Omegle Voyeur</a>. 
Don't be surprised if it's down, and please go grab your own copy: <a href="http://github.com/phleet/Omegle-Voyeur">Omegle-Voyeur @ github</a>.</p>

<p>Now on to the customary technical concept to go along with my own self promotion.</p>

<h1>AJAX Method Callbacks</h1>

<p>While passing functions as arguments is a pretty standard thing among almost all languages, attempting to pass methods of specific instances as arguments in Javascript presents an interesting problem. Consider the following:</p>


<div class="wp_codebox"><table style='width:99%;margin:0px;border:0;' ><tr id="p2006"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code" id="p200code6"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> car<span style="color: #009900;">&#40;</span>price<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">price</span> <span style="color: #339933;">=</span> price<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPrice</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>price<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">price</span> <span style="color: #339933;">=</span> price<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> pass666<span style="color: #009900;">&#40;</span>func<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    func<span style="color: #009900;">&#40;</span>666<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> redcar <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> car<span style="color: #009900;">&#40;</span>2000<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>redcar.<span style="color: #660066;">price</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
redcar.<span style="color: #660066;">setPrice</span><span style="color: #009900;">&#40;</span>123<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>redcar.<span style="color: #660066;">price</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
pass666<span style="color: #009900;">&#40;</span>redcar.<span style="color: #660066;">setPrice</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>redcar.<span style="color: #660066;">price</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


<p>As you might expect, the first two alerts will say 2000 and 123 respectively. But the last one also says 123. Why?
It all has to do with what "this" refers to. Both in the initialization of redcar and the modifier call redcar.setPrice, "this" refers to the instance of the function car given the identifier name "redcar". In the pass666 version, "this" refers to the function pass666. As a result, it does nothing to modify the properties of the car because it isn't told anything about redcar.</p>

<p>One way to fix this is to use a placeholder variable. I used "self". Change the definition of car to the following yields the desired result.</p>


<div class="wp_codebox"><table style='width:99%;margin:0px;border:0;' ><tr id="p2007"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p200code7"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> car<span style="color: #009900;">&#40;</span>price<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">price</span> <span style="color: #339933;">=</span> price<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #003366; font-weight: bold;">var</span> self <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPrice</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>price<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		self.<span style="color: #660066;">price</span> <span style="color: #339933;">=</span> price<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<p>In this example, it's difficult to see why you would ever want to use this in the first place. The reason I encountered this problem is my need to use instance methods as callback functions for AJAX calls. Here's an excerpt of the jQuery version of Omegle Voyeur to see what I'm talking about.</p>


<div class="wp_codebox"><table style='width:99%;margin:0px;border:0;' ><tr id="p2008"><td class="line_numbers"><pre>106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
</pre></td><td class="code" id="p200code8"><pre class="javascript" style="font-family:monospace;">sendQuery<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>target<span style="color: #339933;">,</span>respFunc<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #006600; font-style: italic;">// Send a query to the omegle server</span>
	<span style="color: #006600; font-style: italic;">//log('sending');</span>
	<span style="color: #003366; font-weight: bold;">var</span> self <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>respFunc <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		respFunc <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>self<span style="color: #339933;">,</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
	$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
		url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'omegle.php?'</span><span style="color: #339933;">+</span>target<span style="color: #339933;">,</span>
		type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'GET'</span><span style="color: #339933;">,</span>
		dataType<span style="color: #339933;">:</span> <span style="color: #3366CC;">'json'</span><span style="color: #339933;">,</span>
		success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			respFunc<span style="color: #009900;">&#40;</span>self<span style="color: #339933;">,</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></td></tr></table></div>


<p>Sending a request to the Omegle server is a very common task in Omegle Voyeur, so I wanted all the AJAX requests leaving from the same method. This means I have to accept the callback function as a parameter. I've written all the callback methods to accept a parameter "self" which will refer to the instance of interest.</p>

<p>This aspect is one of the many things that makes Prototype's class system superior to jQuery's. However, since jQuery makes a lot of other things nicer and the two libraries don't play together very well, I decided to port over to jQuery nonetheless. In Prototype, there's a function called <a href="http://www.prototypejs.org/api/function/bind">bind</a> (not to be confused with <a href="http://api.jquery.com/bind/">jQuery's bind</a> which does something completely different,) which solves this problem elegantly.</p>

<p>To fix the redcar problem with the aid of Prototype without having to use a placeholder variable, you can use bind like so:</p>


<div class="wp_codebox"><table style='width:99%;margin:0px;border:0;' ><tr id="p2009"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code" id="p200code9"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> car<span style="color: #009900;">&#40;</span>price<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">price</span> <span style="color: #339933;">=</span> price<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPrice</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>price<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">price</span> <span style="color: #339933;">=</span> price<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> pass666<span style="color: #009900;">&#40;</span>func<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    func<span style="color: #009900;">&#40;</span>666<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> redcar <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> car<span style="color: #009900;">&#40;</span>2000<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>redcar.<span style="color: #660066;">price</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
redcar.<span style="color: #660066;">setPrice</span><span style="color: #009900;">&#40;</span>123<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>redcar.<span style="color: #660066;">price</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
pass666<span style="color: #009900;">&#40;</span>redcar.<span style="color: #660066;">setPrice</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span>redcar<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>redcar.<span style="color: #660066;">price</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


<p>The line</p>


<div class="wp_codebox"><table style='width:99%;margin:0px;border:0;' ><tr id="p20010"><td class="line_numbers"><pre>18
</pre></td><td class="code" id="p200code10"><pre class="javascript" style="font-family:monospace;">pass666<span style="color: #009900;">&#40;</span>redcar.<span style="color: #660066;">setPrice</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span>redcar<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


<p>is what makes this work out. We're explicitly saying that we want setPrice executed from the scope of the instance.</p>

<p>If I ever have to hire someone for a web development job, I'll be sure to ask something about this.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamie-wong.com/2010/04/19/ajax-method-callbacks-and-omegle-voyeur-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jobmine Improved (Greasemonkey &amp; jQuery)</title>
		<link>http://jamie-wong.com/2010/02/05/jobmine-improved-greasemonkey-jquery/</link>
		<comments>http://jamie-wong.com/2010/02/05/jobmine-improved-greasemonkey-jquery/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 05:41:43 +0000</pubDate>
		<dc:creator>Jamie Wong</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[greasemonkey]]></category>
		<category><![CDATA[jobmine]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://jamie-wong.com/?p=183</guid>
		<description><![CDATA[I, like many (most) Waterloo Co-op students, am forced to use Jobmine and am extremely dissatisfied with its functionality. So I decided to kill three birds with one stone: improve Jobmine, learn Greasemonkey and learn jQuery all at the same time. The result is, unsurprisingly, a Greasemonkey script written using jQuery that improves on some [...]]]></description>
			<content:encoded><![CDATA[<div style='text-align: center'><img src="http://jamie-wong.com/wordpress/wp-content/uploads/2010/02/JobmineImproved.png" alt="JobmineImproved" title="JobmineImproved" width="482" height="263" class="alignnone size-full wp-image-184" /></div>

<p>I, like many (most) Waterloo Co-op students, am forced to use Jobmine and am extremely dissatisfied with its functionality. So I decided to kill three birds with one stone: improve Jobmine, learn Greasemonkey and learn jQuery all at the same time.</p>

<p>The result is, unsurprisingly, a Greasemonkey script written using jQuery that improves on some features of Jobmine.</p>

<p><strong>Features</strong></p>

<ul>
<li><strong>Table sorting</strong> - all major tables are now sortable (Interviews, Job Short List, Applications)</li>
<li><strong>Improved navigation</strong> - no more Student -> Use ridiculousness</li>
<li><strong>No more frames</strong> - you can refresh and it will stay on the same page!</li>
<li><strong>Colour highlighting for tables</strong> -  pictured above, you see the applications page with various statuses highlighted. Selected is green, not selected is red.</li>
<li><strong>No more spacers</strong> - the Jobmine page is riddled with spacer images just sitting there, stealing screen real estate</li>
</ul>

<p><strong>How to Install</strong>
You'll either need Firefox &amp; Greasemonkey, or a recent build of Chrome (Windows only?).
You can get Greasemonkey here: <a href="https://addons.mozilla.org/en-US/firefox/addon/748">Greasemonkey @ addons.mozilla.org</a></p>

<p>Once you've done that, navigate to the script and click install.
You can get the script here: <a href="http://userscripts.org/scripts/show/67574">Jobmine Upgrade @ userscripts.org</a></p>

<p>Now for the part where I explain the tech I used.</p>

<h1>Greasemonkey</h1>

<p>Greasemonkey is a tool for customizing the way a web page displays and interacts using javascript. More or less, it overlays javascript you write on top of pages you specify by URLs with wildcards (*). It doesn't overlay it directly, but wraps it in some way as to prevent it from messing things up in the global scope. It also seems to run once the page is done loading, not when the page head is loaded. There are plenty of tutorials out there for doing cool stuff with Greasemonkey, but I started here: <a href="http://diveintogreasemonkey.org/helloworld/index.html">Dive into Greasemonkey</a>. I know it says it's hideously outdated, but the metadata information it provides is still good enough. If you want more up to date information, go here: <a href="http://wiki.greasespot.net/Main_Page">GreaseSpot (Greasemonkey Wiki)</a>.</p>

<h1>jQuery</h1>

<p>jQuery is a javascript framework specifically designed for doing things involving the DOM tree absurdly quickly. Example: highlighting alternating rows of a table (zebra-striping).</p>


<div class="wp_codebox"><table style='width:99%;margin:0px;border:0;' ><tr id="p18312"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code" id="p183code12"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Standard Javascript method:</span>
<span style="color: #003366; font-weight: bold;">var</span> tables <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;table&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> tables.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> rows <span style="color: #339933;">=</span> tables<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">tBodies</span><span style="color: #009900;">&#91;</span>0<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">rows</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> j <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> j <span style="color: #339933;">&lt;</span> rows.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> rowColor<span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>j <span style="color: #339933;">%</span> <span style="color: #CC0000;">2</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            rowColor <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;#eef&quot;</span><span style="color: #339933;">;</span> 
        <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
            rowColor <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;#fff&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #003366; font-weight: bold;">var</span> cells <span style="color: #339933;">=</span> rows<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">cells</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> k <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> k <span style="color: #339933;">&lt;</span> cells.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> k<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            cells<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">backgroundColor</span> <span style="color: #339933;">=</span> rowColor<span style="color: #339933;">;</span>
            cells<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">borderBottom</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;1px solid #ccc&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span> 
&nbsp;
<span style="color: #006600; font-style: italic;">// jQuery way:</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;td&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;border-bottom&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;1px solid #ccc&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;tr:even &gt; td&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;background-color&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;#fff&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;tr:odd &gt; td&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;background-color&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;#eef&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


<p>Now before someone says it, I know usually you can set the background-color for the whole row, and the cells will inherit it. But since, for some crazy reason, each cell is assigned a background colour on Jobmine, each cell needs to be set individually. In any case, you can see that things are made substantially easier with jQuery. I figured out jQuery mostly just using the API and looking at other people's code, but this is a decent place to start: <a href="http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery">Getting Started with jQuery</a>.</p>

<p>For the table sorting functionality, I decided to use a jQuery plugin as opposed to write my own (I'd rather be able to distribute this sooner). You can read all about it here: <a href="http://tablesorter.com/docs/">jQuery Plugin: Tablesorter 2.0</a></p>

<p>What features do you want to see in this? By the way, the source is all available on the userscripts site, so feel free to tinker with it yourself.</p>

<p><strong>EDIT:</strong> As <a href="http://trevorcreech.com/">Trevor</a> points out, the script in its current state won't work in Chrome due to the @require. You can grab his fix to make it work in chrome here: <a href="http://trevorcreech.com/files/jobmine_improved_chome.user.js">Jobmine Improved (Chrome)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jamie-wong.com/2010/02/05/jobmine-improved-greasemonkey-jquery/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>UWAngel-CLI</title>
		<link>http://jamie-wong.com/2009/12/27/uwangel-cli/</link>
		<comments>http://jamie-wong.com/2009/12/27/uwangel-cli/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 07:10:03 +0000</pubDate>
		<dc:creator>Jamie Wong</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[stty]]></category>
		<category><![CDATA[UWAce]]></category>
		<category><![CDATA[UWAngel]]></category>

		<guid isPermaLink="false">http://jamie-wong.com/?p=131</guid>
		<description><![CDATA[Near the end of the semester, I was getting kind of tired of navigating UW-ACE so frequently through my browsing and opening all the different tabs to grab all the files I wanted. While all the pretty graphics make for a decent user interface, it reduces the speed of the service. But aside from that, [...]]]></description>
			<content:encoded><![CDATA[<div style='text-align:center'><img src="http://jamie-wong.com/wordpress/wp-content/uploads/2009/12/Screen-shot-2009-12-27-at-1.39.50-AM.png" alt="Screen shot 2009-12-27 at 1.39.50 AM" title="Screen shot 2009-12-27 at 1.39.50 AM" width="480" height="244" class="alignnone size-full wp-image-132" /></div>

<p>Near the end of the semester, I was getting kind of tired of navigating UW-ACE so frequently through my browsing and opening all the different tabs to grab all the files I wanted. While all the pretty graphics make for a decent user interface, it reduces the speed of the service.</p>

<p>But aside from that, I like being able to do as much as I possibly can from the console.</p>

<p>So I made a Command Line Interface (CLI) for UW-ACE in php using cUrl. I built in on my Macbook Pro in Snow Leopard, but it should work just fine on any *nix machine, and possibly in Cygwin or other emulators.</p>

<p>As always, source is available on github: <a href="http://github.com/phleet/UWAngel-CLI">UWAngel-CLI @ Github</a>.</p>

<p>Since I always like to post snippets of code from my projects that may be universally useful, I'll do that here too.</p>

<p><strong>CLI Colour in PHP</strong>
cli_colours.php included in the UWAngel-CLI source is just a collection of constants which allow you to print out colours in your CLI scripts.</p>


<div class="wp_codebox"><table style='width:99%;margin:0px;border:0;' ><tr id="p13115"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code" id="p131code15"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?</span>
<span style="color: #000088;">$COLOR_BLACK</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[0;30m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_DARKGRAY</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[1;30m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_BLUE</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[0;34m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_LIGHTBLUE</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[1;34m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_GREEN</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[0;32m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_LIGHTGREEN</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[1;32m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_CYAN</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[0;36m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_LIGHTCYAN</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[1;36m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_RED</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[0;31m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_LIGHTRED</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[1;31m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_PURPLE</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[0;35m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_LIGHTPURPLE</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[1;35m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_BROWN</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[0;33m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_YELLOW</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[1;33m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_LIGHTGRAY</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[0;37m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_WHITE</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[1;37m&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$COLOR_DEFAULT</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;<span style="color: #660099; font-weight: bold;">\033</span>[0;37m&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #0000cc; font-style: italic;">&lt;&lt;&lt; EOT
One fish, 
two fish, 
{$COLOR_RED}red{$COLOR_DEFAULT} fish, 
{$COLOR_BLUE}blue{$COLOR_DEFAULT} fish.
&nbsp;
EOT</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>


<p>The only gripe I have about this is that COLOR_DEFAULT it's the same colour as I have on by default in iTerm. Anyone know the escape code to make it actually revert to what it was before instead of just making an assumption about what color is being used?</p>

<p><strong>Hide Commandline Input</strong>
One of the first things I looked up when I started this project today was how to hide user input from the command line. I sure as hell didn't want people typing their passwords for UWACE on screen and having it actually display.
It turns out you can do this by temporarily telling your TTY to stop echoing what you type. The command for this is "stty -echo" and can be re-enabled using "stty echo". Below is how I implemented as part of the AngelAccess class to meet my needs.</p>


<div class="wp_codebox"><table style='width:99%;margin:0px;border:0;' ><tr id="p13116"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code" id="p131code16"><pre class="php" style="font-family:monospace;"> <span style="color: #000000; font-weight: bold;">function</span> Prompt<span style="color: #009900;">&#40;</span><span style="color: #000088;">$prompt_text</span><span style="color: #339933;">,</span><span style="color: #000088;">$hide</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
     <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$prompt_text</span><span style="color: #339933;">;</span>
     <span style="color: #000088;">$input</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>
     <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$hide</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #000088;">$input</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/trim"><span style="color: #990000;">trim</span></a><span style="color: #009900;">&#40;</span>`stty <span style="color: #339933;">-</span><span style="color: #b1b100;">echo</span><span style="color: #339933;">;</span>head <span style="color: #339933;">-</span>n1<span style="color: #339933;">;</span>stty <span style="color: #b1b100;">echo</span>`<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
     <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #000088;">$input</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/trim"><span style="color: #990000;">trim</span></a><span style="color: #009900;">&#40;</span><a href="http://www.php.net/fgets"><span style="color: #990000;">fgets</span></a><span style="color: #009900;">&#40;</span>STDIN<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <span style="color: #009900;">&#125;</span>
     <span style="color: #b1b100;">return</span> <span style="color: #000088;">$input</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<p>As a complete side note, thanks to a boot-camped installation of Windows 7 (or at least I'm fairly sure that's the culprit,) my Macbook Pro is now stuck on Digital Out. This means I can't use the internal speakers on my computer under Mac OS X. Well... what I should say is that I can't use them without some annoying tricks. If I plug in my headphones, then tell my mac to use the input jack for audio input, then my internal speakers appear under the output options and let me use them. The speakers then work perfectly fine. They also work fine under Windows 7. A direct side effect of digital out being stuck on is a read light emanating from the audio jack.</p>

<p>The problem is apparently fairly common, unfortunately the only confirmed fixes for it are sending it back to Apple or <a href="http://forums.macrumors.com/showthread.php?t=239287">wiggling a toothpick around</a> in the audio jack. I had absolutely no luck with the toothpick, or precision screwdriver, or pen cartridge, or paintbrush handle. If anyone knows how to fix this problem, I would love to know. Otherwise, I'm just going to take it into the Apple store in Rideau some time this week and hope they can fix the problem. I really don't want to have to send my Mac in during my first week at Velocity.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamie-wong.com/2009/12/27/uwangel-cli/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Game of Life</title>
		<link>http://jamie-wong.com/2009/12/01/game-of-life/</link>
		<comments>http://jamie-wong.com/2009/12/01/game-of-life/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 00:10:10 +0000</pubDate>
		<dc:creator>Jamie Wong</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[conway]]></category>
		<category><![CDATA[gif]]></category>
		<category><![CDATA[gifsicle]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[optparse]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://jamie-wong.com/?p=86</guid>
		<description><![CDATA[For my latest project, I'm implementing Conway's Game of Life in python into animated GIFs. Before I even explain what Conway's Game of Life is, be amused by the below, generated animation: As always, the code I'm using here is open source: Game Of Life @ Github. In addition to the source code, there's also [...]]]></description>
			<content:encoded><![CDATA[<p>For my latest project, I'm implementing Conway's Game of Life in python into animated GIFs.</p>

<p>Before I even explain what Conway's Game of Life is, be amused by the below, generated animation:
<img src="/images/queenbee.gif" alt="Queenbee"></p>

<p>As always, the code I'm using here is open source: <a href="http://www.github.com/phleet/GameOfLife/">Game Of Life @ Github</a>.
In addition to the source code, there's also a few animation demos such as the one above.</p>

<p>Conway's Game of Life is a cellular automaton following very simple rules, as outlined in the Wikipedia article.It is a zero player game played on a 2 dimensional grid of squares, each holding either a state of dead or alive. The state of any cell is dependent on the state of the 8 cells neighbouring it in the previous generation. There are only 4 rules.</p>

<p>From the Wikipedia article <a href="http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Conway's Game of Life</a>:</p>

<blockquote>
   1. Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.
   2. Any live cell with more than three live neighbours dies, as if by overcrowding.
   3. Any live cell with two or three live neighbours lives on to the next generation.
   4. Any dead cell with exactly three live neighbours becomes a live cell.
</blockquote>

<p>The colours you see in the above animation represent the alive status of each cell and also how many neighbours that cell has if it's alive.</p>

<p>This project is my first time making use of two utilities: optparse in python, and gifsicle.</p>

<p><b>optparse</b> is a python library designed to make the creation of command line application much simpler. Specifically it's targeted towards making application with many possible flags easy to maintain. lifeImage.py falls into this category. From the commandline, you can control the source of input, the colour scheme, the number of generations to output, the scaling of the image and various other things to produce the exact animation or image you want.</p>

<p>You can take a look at optparse here: <a href="http://docs.python.org/library/optparse.html">optparse @ docs.python.org</a>.
The tutorial included there was enough for me to create this application.</p>

<p><b>gifsicle</b> is a command line application for the creation and modification of animated gifs. It can create gifs out of a sequence of images, convert an image into a sequence of images, or even modify replace a single frame of an animated gif with an external image.</p>

<p>You can see and download gifsicle here: <a href="http://www.lcdf.org/gifsicle/">Official Gifsicle Page</a></p>

<p>Why did I use gifsicle instead of the much more universal convert in ImageMagick? Simply put: gifsicle is faster. If someone would like to do a benchmark to (dis)prove this, I'd be happy to post the results, but from simple experimentation, it seemed obvious to me that gifsicle took less time to make the animation.</p>

<p><b>What's Next?</b>
Now that I have a working command line utility, my next goal is to make an AJAX powered web interface for the thing. This might explain why I have ProcMonitor in the github for Game of Life. The web interface was another key motivator behind using gifs for the output medium. People may want to use these things for avatar, and they're simply easier to share and move around than a java applet, or a flash swf, or some database stored simulation. It also helps that gifs are designed for palette based images, which works out nicely for optimizing the file size of these animations. The first 1000 generations of acorn is 2.5 MB as it is.</p>

<p>Another thing I want to do is make lifeImage.py read the .cells format from the <a href="http://www.bitstorm.org/gameoflife/lexicon/">Life Lexicon</a>. This would save me a lot of time having to code all the states myself. This will be a very straightforward process, as the .cells files are simply plaintext with 2 lines of header.</p>

<p>Suggestions/bug fixes for my implementation of Game of Life are welcomed.</p>

<p>I'm almost 100% sure that some combination of the command line flags of lifeImage.py don't work nicely together, and would like to know what they are.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamie-wong.com/2009/12/01/game-of-life/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Omegle Voyeur &#8211; Multiple Connections</title>
		<link>http://jamie-wong.com/2009/11/14/omegle-voyeur-multiple-connections/</link>
		<comments>http://jamie-wong.com/2009/11/14/omegle-voyeur-multiple-connections/#comments</comments>
		<pubDate>Sat, 14 Nov 2009 09:52:12 +0000</pubDate>
		<dc:creator>Jamie Wong</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[omegle]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[prototype]]></category>

		<guid isPermaLink="false">http://jamie-wong.com/me/?p=76</guid>
		<description><![CDATA[In case you haven't read the post about all my projects, here's a description of what Omegle Voyeur is: Omegle is a website where you are connected to a stranger for a chat. It is dominated mostly by trolls whose primary purpose is to coerce you into a cyber session and then switch genders or [...]]]></description>
			<content:encoded><![CDATA[<p>In case you haven't read the post about all my projects, here's a description of what Omegle Voyeur is:</p>

<blockquote>
Omegle is a website where you are connected to a stranger for a chat. It is dominated mostly by trolls whose primary purpose is to coerce you into a cyber session and then switch genders or to make you lose the game. Talking to these people is a rather tiresome endeavour, but seeing exactly what happens in these conversations is interesting. Omegle Voyeur is a way of watching a conversation which you aren't part of. What Voyeur does is form two simultaneous connections and then pass the input of one to the output of the other. This sets you up as a conversation proxy, allowing you to watch. Currently, this is exclusively a "sit and watch" program. Later I intend to add functionality to add more than 2 people into a conversation, automatically name the participants so it will be obvious that there are more than 2 people in the conversation, and allow the ability to interfere (mute participants/say things yourself) with a conversation. This concept was spawned during discussion (read: boredom) at CCC Stage 2, 2009.
</blockquote>

<p>In terms of technology, Omegle Voyeur is primarily one big Javascript Prototype class. <a href='http://www.prototypejs.org/'>Prototype</a> is a Javascript Framework which makes the creation and maintenance of classes, conversion of data into JSON for transfer, and sending AJAX requests much, much easier.</p>

<p>There's also a very small bit of code in php which is able to be so short because it uses the incredible program cUrl. <a href="http://curl.haxx.se/">cUrl</a> is a command line utility for grabbing data from websites using their URL. libcurl facilititates the use of curl in php without having to write your own wrapper.</p>

<p>Below is some php code I use to make curl even easier than it already is. simple_get($url) will return the HTTP GET result from the url specified. simple_post works similarly, but delivers data using the payload.</p>


<div class="wp_codebox"><table style='width:99%;margin:0px;border:0;' ><tr id="p7618"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code" id="p76code18"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?</span>
<span style="color: #666666; font-style: italic;">// Simple cUrl</span>
<span style="color: #666666; font-style: italic;">// Simple get and post requests </span>
<span style="color: #000000; font-weight: bold;">function</span> simple_get<span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/curl_init"><span style="color: #990000;">curl_init</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <a href="http://www.php.net/curl_setopt"><span style="color: #990000;">curl_setopt</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #339933;">,</span> CURLOPT_URL<span style="color: #339933;">,</span> <span style="color: #000088;">$url</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <a href="http://www.php.net/curl_setopt"><span style="color: #990000;">curl_setopt</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #339933;">,</span> CURLOPT_RETURNTRANSFER<span style="color: #339933;">,</span> 1<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/curl_exec"><span style="color: #990000;">curl_exec</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <a href="http://www.php.net/curl_close"><span style="color: #990000;">curl_close</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$result</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> simple_post<span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #339933;">,</span><span style="color: #000088;">$payload</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/curl_init"><span style="color: #990000;">curl_init</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <a href="http://www.php.net/curl_setopt"><span style="color: #990000;">curl_setopt</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #339933;">,</span> CURLOPT_URL<span style="color: #339933;">,</span> <span style="color: #000088;">$url</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <a href="http://www.php.net/curl_setopt"><span style="color: #990000;">curl_setopt</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #339933;">,</span> CURLOPT_POST<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <a href="http://www.php.net/curl_setopt"><span style="color: #990000;">curl_setopt</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #339933;">,</span> CURLOPT_POSTFIELDS<span style="color: #339933;">,</span> <span style="color: #000088;">$payload</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <a href="http://www.php.net/curl_setopt"><span style="color: #990000;">curl_setopt</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #339933;">,</span> CURLOPT_RETURNTRANSFER<span style="color: #339933;">,</span> 1<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/curl_exec"><span style="color: #990000;">curl_exec</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <a href="http://www.php.net/curl_close"><span style="color: #990000;">curl_close</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$result</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>


<p>When I started working on this project today (well, I suppose that would be last night now... wonder if I'll see the sunrise) I figured it would be a good time to get used to using git, so I made a repository using github.
So far I'm enjoying git. Everything seems to act pretty much the way you'd expect to, and I already had to do a revert once I realized my logic was wrong for the way I was structuring my code.</p>

<p>You can see the github for Omegle Voyeur here: <a href="http://github.com/phleet/Omegle-Voyeur">http://github.com/phleet/Omegle-Voyeur</a>
Feel free to design your own stuff with the all the code there - just be sure to link back here, or to the github page.</p>

<p>In any case, the thing the majority of the people reading this are probably interested in are the result.
Things I've updated since last time are primarily aesthetic and behind the scenes, but I did add the ability to connect one person to more than one other person, and the connections don't have to be mutual. In the first 3 way conversation example, 1 can only speak to 2, 2 can only speak to 3 and 3 can only speak to 1. It leads to some rather confused people.</p>

<p><del datetime="2009-11-26T06:58:15+00:00">You can see the current running version here: <a href="/omegle/">Omegle Voyeur</a>.</del>
EDIT: It seems that after being posted on reddit, omegle has (manually?) IP blocked me. The source should still work, so feel free to try it out yourself.
You can go grab <a href="http://www.apachefriends.org/en/xampp.html">XAMPP</a> to run it locally.
For the time being, you can view it here: <a href="http://petersobot.com/omegle/">Omegle Voyeur</a></p>

<p>A quick note on how I figured out the Omegle communication protocol. 
The entire code governing the process is conveniently kept here: <a href="http://omegle.com/static/omegle.js?27">http://omegle.com/static/omegle.js?27</a>
Unless you enjoy reading 1000s of characters on a single line, you can use the <a href='http://jsbeautifier.org/'>JS Beautifier</a> to clean it up to a readable state.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamie-wong.com/2009/11/14/omegle-voyeur-multiple-connections/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Projects</title>
		<link>http://jamie-wong.com/2009/11/05/projects/</link>
		<comments>http://jamie-wong.com/2009/11/05/projects/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 18:32:48 +0000</pubDate>
		<dc:creator>Jamie Wong</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://jamie-wong.com/me/?p=20</guid>
		<description><![CDATA[Part of the reason I made this website was to document my progress thinking of and working on various projects of mine. I claim these ideas as my own intellectual property. If you intend to implement one of them, you must contact me for permission first. If you're interested though, contact me. Projects in Progress [...]]]></description>
			<content:encoded><![CDATA[<p>Part of the reason I made this website was to document my progress thinking of and working on various projects of mine. I claim these ideas as my own intellectual property. If you intend to implement one of them, you <strong>must</strong> contact me for permission first. If you're interested though, contact me.</p>

<p>Projects in Progress (Read: on Hiatus)</p>

<ul>
<li><strong>Budgyt</strong> When I came to University, I had to start considering how I was going to handle budgeting. There was a bunch of free software available all over the place which let you enter in all your expenses and get summaries of that data. The problem with many of these pieces of software was the extreme tedium associated with entering in all your transactions. It normally meant many many mouse clicks, which I would rather avoid. Budgyt was my solution to this. The idea behind it was to construct a web based application in which transaction entry could be done with only a few presses of keyboard keys. Instead of selecting menus and click "next", you would simply have to hit a hotkey associated with each category of menu. After seeing how some banks (TD) provide transactions as downloadable CSV files, it would be great to incorporate those somehow. This project is in the early development phase and I may restart it, since the code for it is a little messy at the moment.</li>

<li><strong>Omegle Voyeur</strong> <a href="http://www.omegle.com">Omegle</a> is a website where you are connected to a stranger for a chat. It is dominated mostly by trolls whose primary purpose is to coerce you into a cyber session and then switch genders or to make you lose the game. Talking to these people is a rather tiresome endeavour, but seeing exactly what happens in these conversations is interesting. Omegle Voyeur is a way of watching a conversation which you aren't part of. What Voyeur does is form two simultaneous connections and then pass the input of one to the output of the other. This sets you up as a conversation proxy, allowing you to watch. Currently, this is exclusively a "sit and watch" program. Later I intend to add functionality to add more than 2 people into a conversation, automatically name the participants so it will be obvious that there are more than 2 people in the conversation, and allow the ability to interfere (mute participants/say things yourself) with a conversation. This concept was spawned during discussion (read: boredom) at CCC Stage 2, 2009. You can see the current project here: <a href="http://jamie-wong.com/omegle">Omegle Voyeur</a></li>

<li><strong>wwwpaper</strong> This idea came about when I was looking at desktop customization options like <a href="http://rainmeter.net/RainCMS/">Rainmeter</a> and <a href="http://www.samurize.com/modules/news/">Samurize</a> (website down at the time of the post.) The really really cool thing about these applications was not only the basic abilities provided by them such as analog clocks and calendars, but the ability to modify them and add cool things like frequently updating website information retrieved via regular expressions. I wanted something that would be even more customizable and more web integrated. The idea was to make a website full of widgets which could be used as an active desktop. In Windows, this means using a website as your wallpaper - hence the name wwwpaper. I began working on this to do various things, but this was heavily damaged when the gumblar.cn virus came around. The idea was to provide users with accounts which they could log into which would load up all of their widgets on their desktop. This way, they could switch between computers with NO change to the setup of their widgets, so long as they had the same URL set up as their active desktop. </li>
</ul>

<p>Past Projects (Finished/Need Restarting)</p>

<ul>
<li><strong>Kwizr</strong> Something I started back in grade 10 because I was tiring of studying for French vocabulary tests by staring at a huge list of words. Kwizr (originally Quizulator) was my way of making this process less excruciating. It would take input as a CSV file containing columns with common elements. In the case of French vocab, column 1 would contain French words and column 2 would contain English words. These would be plugged in to user defined expressions, causing the quizzing program to ask "How to you say _____ in French?" or "Comment dit-on ______ en Anglais?". This data would be stored in a MySQL database. The program would quiz the user via an AJAX prompt, in which they would type in answers and the program would give immediate feedback of "correct" or "wrong answer". If the answer was wrong, it would spit out the correct answer. I had this whole system working fairly well, but unfortunately it was on a friend's server when their hosting service went under. Should have backed it up. I need to restart this project anyway, because the way I read the CVS data didn't follow the real CVS standard - which I didn't know existed when I started working on it.</li>

<li><strong>ASCII Converter</strong> Picture to image converters are by no means a new idea on the internet. The thing I didn't like about many of them was the inability to modify settings on the fly. If you made a mistake in settings at the beginning, you couldn't modify them without restarting. Also, some of them cheated and simply coloured individual characters. I wanted to make a much more comprehensive system which would scale the image, use an ASCII gradient, and allow the user to grab the source code without actually having to go to "view source". The result can be seen here: <a href="http://jamie-wong.com/asciiconvert/">ASCII Convert</a></li>
</ul>

<p>Future Projects/Concepts</p>

<ul>
<li><strong>WXML</strong> One of the reasons I'm so fond of web applications is the code structure used to make them. The complete separation of backend processing and user interface, and the construction of the user interface using markup greatly appeals to me. The real power comes from the interaction of these two things, such as running some javascript script when a certain triggering event happens - like a key press. I want to build something that provides this power and structure to the desktop. I want to have some custom defined XML files that will create a GUI and have an instruction set for handling events. So I want to implement functionality similar to the HTML/Javascript code of
<div style='text-align: center'>&lt;input type='button' value='click me' onclick='solve()' /&gt;</div>
in desktop computing. This is in the future projects/concepts section because I haven't yet planned on how exactly I would want to go about implementing this, but I'm leaning towards a python implementation using TkInter or wxPython.</li>
<li><strong>Learning Alarm Clock</strong> This concept came about in a discussion with David Hu on the way to the 2009 ACM Regionals at McMaster University. I, personally, am a horrible abuser of the snooze button. I've heard of various solutions to this, like the <a href="http://gizmodo.com/157999/puzzle-alarm-clock-presents-mild-challenge-wakes-you-up">Puzzle Alarm Clock</a>, but I wanted to take a slightly different route. The discussion started with the idea that you could have a Rubik's Cube alarm clock which would not turn off until it was solved. The idea was that you would have to wake up to be able to do it. But what if you eventually got SO good at it that you could do it in your sleep, thereby reverting to the cycle of snooze abuse. Well, that would mean that you were learn how to solve it really really fast. Now apply this concept to learning to do something else. Problem: I can't wake up in the morning and linear algebra is roundhouse kicking me in the face. Solution: Make your alarm stay on until you can diagonalize a matrix successfully. Problems would be randomly generated following a certain template, so you would have new input every morning. Continue solving the same variety of problems every morning until you can solve the problem instinctively, as a matter of urgency. Granted, this might make you panic even more on midterms - but atleast you'll be correctly solving problems while panicking.</li>
</ul>

<p>So these are my ghosts of projects past, present and future.</p>

<p>Have you heard of any of these projects being implemented by anyone else? Are any of these problems already solved somehow? Which of these projects are you most interested in seeing completed/updated?</p>
]]></content:encoded>
			<wfw:commentRss>http://jamie-wong.com/2009/11/05/projects/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
