<?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>Matt_ptr * &#187; Programming</title>
	<atom:link href="http://mattptr.net/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://mattptr.net</link>
	<description>Programming and stuff -- incoherent and unfocused since 1997</description>
	<lastBuildDate>Tue, 07 Sep 2010 18:35:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Replacing the jQuery Plugin site</title>
		<link>http://mattptr.net/2010/07/09/replacing-the-jquery-plugin-site/</link>
		<comments>http://mattptr.net/2010/07/09/replacing-the-jquery-plugin-site/#comments</comments>
		<pubDate>Fri, 09 Jul 2010 17:26:11 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[new project]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[redo the jquery plugin site]]></category>

		<guid isPermaLink="false">http://mattptr.net/?p=172</guid>
		<description><![CDATA[I&#8217;ve touched on this a while back, but I never followed through with it. Having some down time at work, I&#8217;ve decided to jump in. I want to replace http://plugins.jquery.com. There are numerous problems with it, and one of the reasons I got overwhelmed by this project originally is because I wanted to fix the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve touched on this a while back, but I never followed through with it. Having some down time at work, I&#8217;ve decided to jump in. I want to replace <a href="http://plugins.jquery.com">http://plugins.jquery.com</a>.</p>
<p>There are numerous problems with it, and one of the reasons I got overwhelmed by this project originally is because I wanted to fix the site, rather than replace it. So now, I&#8217;ve wised up and decided to start from scratch without considering any aspect of how the site currently works.</p>
<p>Here are the problem areas, as I see them, in no particular order.</p>
<h3>Browsing through plugins is ridiculously terrible</h3>
<p>First, when you get to the page, you get a bunch of categories. Compare this with <a href="http://pypi.python.org">http://pypi.python.org</a>. PyPi gives a tabular listing of 40 recently updated packages. For the Latest Releases, PJC (plugins.jquery.com) gives a full body of content for each item and goes on for a zillion pages.</p>
<p>Second, from the start page on PJC (with the category listing), the &#8220;Browse by Name&#8221; tab doesn&#8217;t work. The &#8220;Browse by Date&#8221; tab does work, but what date? The date the plugin was created, or the date of the last release? It turns out this is the same as the &#8220;Latest Releases&#8221; page, just the tab navigation at the top doesn&#8217;t disappear. The &#8220;All Plugins&#8221; link on the is the same as the &#8220;Browse by Name&#8221; tab and also doesn&#8217;t work.</p>
<p>Lastly, browsing plugins in a category gives a different layout from browsing by date. Why? It&#8217;s the same information, just sorted differently and filtered.</p>
<h3>Searching is basically useless</h3>
<p>Do you know why I&#8217;m surprised that people have actually used my timer plugin? Because I can&#8217;t even find it myself. Searching for &#8220;timer&#8221; yields 10 pages of results, and includes plain pages and issue tracker items.</p>
<p>I understand the appeal of having the bug tracker and plugin page tied together, but it&#8217;s terrible. A plugin like mine is so small that it doesn&#8217;t need a bug tracker. Not to mention that use of a bug tracker is annoying without the use of source control. The plugin author should bear the responsibility of setting up bug tracking, source control, etc. There are plenty of free sites to do that.</p>
<p>The search is easily bombed by adding keywords and tags (which are not moderated). So when I search for timer, the sixth result I get is for <a href="http://plugins.jquery.com/project/dualSlider">dualSlider</a> &#8212; perfect for managing timeouts and intervals.</p>
<h3>The Rating System</h3>
<p>There&#8217;s no point to this. The &#8220;Top Rated&#8221; plugins all have 1-3 votes. Plugins with more votes should have more clout. But it doesn&#8217;t really matter anyway. It&#8217;s not a popularity contest.</p>
<p>This particular part of PJC will have no part whatsoever in my new project. If there will be any spotlighting of plugins, it will be done by moderators.</p>
<h3>Other Data Formats</h3>
<p>Right now, there are no RSS feeds for plugins at all. Each plugin should have its own release feed, as well as a feed for all latest releases.</p>
<p>Writing a plugin manager currently would involve screen scraping the existing plugin page to see if there have been any changes. Of course, you have to know the URL of the plugin because searching basically gets no where, and if by some chance you were able to search, you&#8217;d have to scrape the search page as well.</p>
<p>That&#8217;s why I want to have everything available as JSON. Plugin details, list of plugins by category, search results&#8230; the new site has to be highly query-able. PyPi uses XML-RPC to expose their API. JSONRPC might be an option for this, or XML-RPC, but I&#8217;ll cross that bridge when I come to it.</p>
<h3>Categories</h3>
<p>The Categories on PJC are terrible. Not in the way that they aren&#8217;t descriptive, but they just suck. They should be hierarchical. For example, &#8220;Widgets&#8221; and &#8220;Windows and Overlays&#8221; could fall under &#8220;User Interface.&#8221; Menus could as well.</p>
<p>I&#8217;m not sure how Navigation and Menus are different.</p>
<p>DOM should probably be a child of Utilities.</p>
<p>I don&#8217;t know what AJAX means for a category. If the plugin is an AJAX request helper, it should go under &#8220;Utilities&#8221; or &#8220;jQuery Extension.&#8221; If it&#8217;s something like an auto-complete widget, well it should go under Widgets.</p>
<p>The point is, that categories aren&#8217;t very helpful in there current state. I put my Timer plugin under jQuery Extensions, Javascript, and Utilities, leading me to believe that they could all be the same category. I don&#8217;t know why Javascript is a category actually, since jQuery encapsulates, rather than extends.</p>
<h3>The New Site</h3>
<p>I&#8217;ve already started. <a href="http://code.google.com/p/jqpi">http://code.google.com/p/jqpi</a> (the app page will be http://jquerypi.appspot.com)</p>
<p>Basically, I want to create PyPi for jQuery plugins. I figured using Google App Engine would be nice. Also, knowing my penchant for dragging out projects, I&#8217;m coding it for HTML5, since it will probably be widely supported by the time I&#8217;m finished.</p>
<p>There are a few things that I don&#8217;t know how to do with GAE though. Hierarchical categories, searching, optimization, JSONRPC or XML-RPC. I&#8217;ll figure it out eventually, but help is always appreciated. Create an issue, create a wiki page, send patches, join the project, anything. We shouldn&#8217;t have to suffer the damned plugins.jquery.com any more.</p>
]]></content:encoded>
			<wfw:commentRss>http://mattptr.net/2010/07/09/replacing-the-jquery-plugin-site/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows output redirection bug</title>
		<link>http://mattptr.net/2010/05/21/windows-output-redirection-bug/</link>
		<comments>http://mattptr.net/2010/05/21/windows-output-redirection-bug/#comments</comments>
		<pubDate>Fri, 21 May 2010 16:48:10 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://mattptr.net/?p=169</guid>
		<description><![CDATA[While I was working on the SiteCrawler script, I had a problem getting it to redirect output to a file. In fact it&#8217;s one of the reasons I put it on the back burner. I thought it was a Python (on Windows) problem, but it turns it&#8217;s just a Windows® Issue™: http://support.microsoft.com/kb/321788 Even though the article [...]]]></description>
			<content:encoded><![CDATA[<p>While I was working on the SiteCrawler script, I had a problem getting it to redirect output to a file. In fact it&#8217;s one of the reasons I put it on the back burner. I thought it was a Python (on Windows) problem, but it turns it&#8217;s just a Windows® Issue™:</p>
<p><a href="http://support.microsoft.com/kb/321788">http://support.microsoft.com/kb/321788</a></p>
<p>Even though the article is about WinXP and 2k, I thought I&#8217;d try the registry fix. Sure enough &#8212; it works! So I will probably start adding stuff to the site crawler again and may actually release it!</p>
]]></content:encoded>
			<wfw:commentRss>http://mattptr.net/2010/05/21/windows-output-redirection-bug/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Site Crawler Chronicles &#8211; Part 3</title>
		<link>http://mattptr.net/2010/03/19/the-site-crawler-chronicles-part-3/</link>
		<comments>http://mattptr.net/2010/03/19/the-site-crawler-chronicles-part-3/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 14:33:05 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://mattptr.net/?p=150</guid>
		<description><![CDATA[I managed to find a solution for the problem I had yesterday, though I don&#8217;t particularly know if it&#8217;s ideal. Originally I had thought that I would need to store the entire hierarchy of the site in a tree like structure. I figured I could just store a list of the links on a page [...]]]></description>
			<content:encoded><![CDATA[<p>I managed to find a solution for the problem I had yesterday, though I don&#8217;t particularly know if it&#8217;s ideal.</p>
<p>Originally I had thought that I would need to store the entire hierarchy of the site in a tree like structure. I figured I could just store a list of the links on a page in a dict structure and then output all of the errors when the crawl was finished. I don&#8217;t know why I was hung up on the idea that errors had to be reported as they were come across.</p>
<p>I was worried that memory use would be a factor, but it seems to be ok.</p>
<p>But there&#8217;s another issue:</p>
<pre>    #taken from lxml.html.__init__
    def make_links_absolute(self, base, root):
        """This function exists because urljoin behaves obnoxiously.
        For example, if I'm on the page:
            http://www.example.com/some/directory/index.html, or just:

http://www.example.com/some/directory/

        And I join the relative URL: ../../abc.html
        I end up with: http://www.example.com/abc.html

        *But*
        If I'm on: http://www.example.com/some/directory  [no trailing slash]
        I end up with: http://www.example.com/../abc.html
        """</pre>
<p>My fix for it was stripping out one &#8220;../&#8221;. Yesterday I thought that it would be a good fix. Today, I can&#8217;t figure out why I thought it would fix all cases.</p>
]]></content:encoded>
			<wfw:commentRss>http://mattptr.net/2010/03/19/the-site-crawler-chronicles-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Site Crawler Chronicles</title>
		<link>http://mattptr.net/2010/03/18/the-site-crawler-chronicles/</link>
		<comments>http://mattptr.net/2010/03/18/the-site-crawler-chronicles/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 18:04:32 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://mattptr.net/?p=148</guid>
		<description><![CDATA[So I managed to stop v4 of my web crawler from opening up a billion connections in parallel. Turns out that gevent has a Pool object and that was exactly what I needed. Now my little script (137 lines, including a utility object and comments) will not be a sysadmin&#8217;s nightmare. However, I now have a [...]]]></description>
			<content:encoded><![CDATA[<p>So I managed to stop v4 of my web crawler from opening up a billion connections in parallel. Turns out that <a href="http://www.gevent.org">gevent</a> has a <a href="http://www.gevent.org/gevent.pool.html">Pool</a> object and that was exactly what I needed.</p>
<p>Now my little script (137 lines, including a utility object and comments) will not be a sysadmin&#8217;s nightmare.</p>
<p>However, I now have a new problem. I described how the older versions work in my <a href="http://mattptr.net/2010/03/17/new-old-ideas/">previous post</a>, but this version is quite a bit different. Instead of using a queue or stack data structure to figure out where to go next, this version has a greenlet scrape all links from a page, filters out stuff it&#8217;s already been to, then returns the rest. The main thread then accumulates the lists when all greenlets are finished. After the accumulation &#8212; and it&#8217;s ensured that there are no duplicate links &#8212; the main thread then spawns a greenlet <em>for each link</em> and the main thread waits until the greenlets finish again. When there are no links returned by the greenlets, the main thread is done, and the script terminates.</p>
<p>The problem is, if there&#8217;s a 404 or some kind of error retrieving the page, I have no way of knowing what page that link was found on.</p>
<p>The only solution that I see is using a custom data structure and hope that it doesn&#8217;t kill performance.</p>
]]></content:encoded>
			<wfw:commentRss>http://mattptr.net/2010/03/18/the-site-crawler-chronicles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Old Ideas</title>
		<link>http://mattptr.net/2010/03/17/new-old-ideas/</link>
		<comments>http://mattptr.net/2010/03/17/new-old-ideas/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 21:05:37 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://mattptr.net/?p=145</guid>
		<description><![CDATA[A little while ago, I wrote a post in which I was trying to figure out a way to improve a Web Crawler script I had written &#8212; it was one of those that I never published. Anyway, for some reason, I wrote it using Stackless Python, but I was pretty novice and didn&#8217;t make [...]]]></description>
			<content:encoded><![CDATA[<p>A little while ago, I wrote a post in which I was trying to figure out a way to improve a Web Crawler script I had written &#8212; it was one of those that I never published.</p>
<p>Anyway, for some reason, I wrote it using <a href="http://www.stackless.com">Stackless Python</a>, but I was pretty novice and didn&#8217;t make it as efficient as I could. This was version 1, and it basically went to each page, scraped all the valid links (ie, those that were on the same server and not a mailto: or something) and then went through recursively.</p>
<p>Version 2 was basically the same, just with cleaner code and no recursion. I decided to set up the library so I would extend the SiteCrawler class and get notified of what was going on through callbacks. While it wasn&#8217;t any faster than version 1, it did seem a bit more stable.</p>
<p>Version 3 I decided to change drastically and made it multithreaded. It is much, much, much faster. It works like this, there&#8217;s an input Queue, and an already checked Queue. There are 4 threads waiting for input on the input Queue, when they get it, they scrape the links, check to see if any of them are in the checked Queue, put what&#8217;s been filtered on the input Queue, and put what it just checked on the checked Queue. It seems more complicated than it is. Also the code is more complicated than it needs to be.</p>
<p>Anyway, version 3 works well for me when I need to test a site. It&#8217;s saved me so much time in going through and checking for broken URLs. There are a few clients with the number of pages on their site in the 300&#8242;s.</p>
<p>But, I recently found out about <a href="http://www.gevent.org">gevent</a>, and since I have some free time at work, I wanted to play with it a little bit. If you don&#8217;t know, gevent is a package that works with the <a href="http://pypi.python.org/pypi/greenlet">greenlet</a> package on top of libevent. I&#8217;m always interested in concurrent programming, and new technologies involved in it. This is why I had installed Stackless at one time.</p>
<p>So now there&#8217;s a version 4 of the SiteCrawler script, using &#8212; you guessed it &#8212; gevent. I haven&#8217;t ironed out all of the kinks yet. I was testing a non-pooled version of the script and it basically crawled through 200 links in a matter of seconds &#8212; hopefully none of the server admins look at the logs and see 100 simultaneous connections at 3:30 PM today. I did change how the crawl is done quite a bit too. So I&#8217;m going to stop there and probably have more tomorrow or in the next few days.</p>
<p>Good stuff!</p>
]]></content:encoded>
			<wfw:commentRss>http://mattptr.net/2010/03/17/new-old-ideas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I can&#8217;t figure out what to title this</title>
		<link>http://mattptr.net/2010/01/19/i-cant-figure-out-what-to-title-this/</link>
		<comments>http://mattptr.net/2010/01/19/i-cant-figure-out-what-to-title-this/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 16:29:34 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://mattptr.net/?p=135</guid>
		<description><![CDATA[This is my first update in quite a while. I&#8217;m not dead. I had a few posts in draft mode, but I never finished them. The topics were: A web crawler script I wrote and some design issues I was having with it. - I actually figured out some of the problems with it and [...]]]></description>
			<content:encoded><![CDATA[<p>This is my first update in quite a while. I&#8217;m not dead. I had a few posts in draft mode, but I never finished them. The topics were:</p>
<ul>
<li>A web crawler script I wrote and some design issues I was having with it.<br />
- I actually figured out some of the problems with it and made it much more efficient. So there really wasn&#8217;t any point in finishing the post. It was more of a thinking out loud kind of deal.</li>
<li>Why they should let MySQL die and why Monty Widenius should bite me.<br />
- This was going to be my response to Monty&#8217;s Plea to people to save MySQL from Oracle (I don&#8217;t feel like finding the link, just google it). The gist was that he probably shouldn&#8217;t have sold out to Sun, would be better concentrating on MariaDB &#8212; a supposed MySQL successor, and that generally MySQL sucks and there are better alternatives anyway. I also held him responsible for the countless headaches I endure while being forced to use MySQL, and thus decided he could bite me. :)</li>
<li>How awful the jQuery plugin site is and some thoughts on how to replace it.<br />
- I started writing this post because I have such a hard time keeping my plugins up-to-date due to the fact that the plugin directory is terrible. I started writing the post and just went through the site listing the problems I saw. The list became so massive that it clearly was something that I couldn&#8217;t handle on my own, so the post turned in to a call to action with the suggestion of using Google App Engine to run the site. But, the number of problems is depressing and thinking about spearheading a project of such magnitude in my free time was not at all appealing.</li>
</ul>
<p>So, the holidays came and went. The new year as well. I&#8217;ve been extraordinarily busy at work and at home, extraordinarily lazy and tired.</p>
<p>But I do have one small announcement. Off and on over the past year, I&#8217;ve been toying with ActionScript and Flash and Flex because a long, long time ago, I thought  I would pursue Flash as a game platform.</p>
<p>After some consideration, <strong>I will absolutely *NOT* be doing that</strong>.  While ActionScript, as a language, isn&#8217;t terrible, I don&#8217;t particularly like it. It&#8217;s similar to Javascript, but with more crap that you have to do. The real problem I have is with Flash as a platform. In short, it&#8217;s probably one of the worst I&#8217;ve ever seen. It&#8217;s slow, bloated, and full of <a href="http://secunia.com/advisories/37584/">known security holes</a>. I could make a whole blog dedicated to how much I hate Flash and problems with it.</p>
<p>The only positive thing I can say about Flash is that it&#8217;s everywhere. Though, with all of the security problems, it may not turn out to be a good thing.</p>
<p>Instead &#8212; I&#8217;m trying to stay positive &#8212; I plan on focusing on some of the emerging Web App technologies as a platform. I have a feeling in 6 months, I&#8217;ll be back here griping about how ridiculous canvas, WebGl, etc. are.</p>
<p>I may try to write a simple game to test, or redo a certain game with flying corpses. So, until then.</p>
]]></content:encoded>
			<wfw:commentRss>http://mattptr.net/2010/01/19/i-cant-figure-out-what-to-title-this/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Am I nuts?</title>
		<link>http://mattptr.net/2009/10/26/am-i-nuts/</link>
		<comments>http://mattptr.net/2009/10/26/am-i-nuts/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 20:21:20 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Rant]]></category>
		<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[die irc]]></category>
		<category><![CDATA[irc]]></category>
		<category><![CDATA[rfc1459]]></category>

		<guid isPermaLink="false">http://mattptr.net/?p=125</guid>
		<description><![CDATA[I&#8217;m starting to think I&#8217;m a masochist. Examine the evidence: I&#8217;ve been in 2 serious relationships with crazy (and I do mean crazy) girls &#8212; both ended crappily. I still hand wind my guitar strings. I&#8217;ve worked with PHP since version 3 and I&#8217;ve had a job doing it for 5 years. I actually gave [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m starting to think I&#8217;m a masochist. Examine the evidence:</p>
<ul>
<li>I&#8217;ve been in 2 serious relationships with crazy (and I do mean crazy) girls &#8212; both ended crappily.</li>
<li>I still hand wind my guitar strings.</li>
<li>I&#8217;ve worked with PHP since version 3 and I&#8217;ve had a job doing it for 5 years. I actually gave up a job doing embedded systems with C to keep doing PHP work.</li>
<li>I keep thinking I want to learn Erlang.</li>
<li>Lastly, and I think this is the big one, despite the fact that I&#8217;ve worked on no less than 3 failed IRC clients &#8212; I started working on an IRC bot project.</li>
</ul>
<p><span id="more-125"></span></p>
<p>If you didn&#8217;t know, IRC was invented in 1793 by the world-renouned horrible person, the Marquis De Sade. He was so horrible, in fact, that the term <em>sadism</em> comes from his name. The work I&#8217;m referring to is <a href="http://www.faqs.org/rfcs/rfc1459.html">RFC1459</a> &#8212; arguably his most notorious and mind-boggling work. RFC1459 is part of the reason some people consider De Sade to be the devil incarnate.</p>
<p>RFC1459 was so bad that the IETF has refused to standardize it. An attempt was made in 2000 to update it with RFCs 2810, 2811, <a href="http://irchelp.org/irchelp/rfc/rfc2812.txt">2812</a>, and 2813. After reading all of them, I can&#8217;t really tell what was updated. It&#8217;s more like someone took the original document of unholy sin and smeared it across 4 others. And even after this act of moral indecency, it&#8217;s still not standardized. It&#8217;s not helped by the fact that the &#8220;updates&#8221; <strong>weren&#8217;t even supposed to be considered a new standard </strong>and also pretty much every IRCd and client does whatever the hell they want.</p>
<p>Here are some things I really, really hate about IRC. I mean other than it being a complete total stab in the groin&#8230;</p>
<p><strong>Ident </strong><br />
Does anyone actually have an actual ident daemon running? And does it actually help anything? It&#8217;s pretty much a useless addition &#8212; and why it&#8217;s mentioned in the IRC protocol (and by protocol, I mean random suggestions) I could only speculate.</p>
<p><strong>Mode strings</strong><br />
This is probably the worst abomination of the entire spec (and by spec I mean loose collection of internet bowel movements).  So there are user modes and channels modes. A mode character can have parameters or not and a mode string can consist of any of the mode characters or a bunch of them. Because of that, you end up with this kind of crap:</p>
<p>MODE #liek :+om-v+b nick1 nick2 *.aol.com</p>
<p>Which sets nick1 as an operator, sets the channel to moderated, takes voice away from nick2, and bans aol users from the channel. Look at sections 3.1.5 and 3.2.3 in RFC2812 for some more awful ideas.  If you think parsing that is not so bad, then you should know that not every IRC-network is going to have the same modes. And to figure out what modes a channel might have&#8230;</p>
<p><strong>005<br />
</strong>RFC2812 says that numeric reply 005 is, &#8220;Sent by the server to a user to suggest an alternative server.&#8221; It&#8217;s just not true at all. In all my years of working with IRC, I&#8217;ve never seen 005 used in this capacity.</p>
<p>005 is used for relaying the server configuration to the client. This is a <a href="http://www.irc.org/tech_docs/005.html">separate, 5-year old document</a> that explains the ISUPPORT reply. Of course, it&#8217;s not official or anything. It&#8217;s not even really called ISUPPORT. The page I linked to at least tells you what IRCds are doing what. Keeping track of all that configuration info is unbelievably tedious.</p>
<p><strong>NAMES</strong><br />
Channels on IRC are usually small, but on the off-chance that you find yourself in a warez channel, you&#8217;ll be in a sea of people. When you join in the chat, the server will send you the list of other chatters, which can take quite a while depending on the legality of the channel you&#8217;re in. The problem:</p>
<p>The names list can be too large to fit in to one packet, so the server will break it up. The problem is that if you&#8217;re in a big room, there&#8217;s bound to be lots of activity and the server will broadcast whatever messages it&#8217;s supposed to no matter what it&#8217;s doing. So rather than queuing a JOIN notification while it&#8217;s processing the names reply, it&#8217;ll just send the notice right in-between packets.</p>
<p>Yeah, me too. I also have no idea what order the names list might be in. I have no idea if it&#8217;s random, alphabetized, or predicted by Nostradamus &#8212; there&#8217;s nothing in the spec (and by spec, I mean not-spec) about it.</p>
<p>So how do you know what the NAMES reply is? Unlike JOIN or QUIT or KICK, when you request information from the server, chances are you&#8217;ll get a numeric reply.</p>
<p><strong>Numeric Replies<br />
</strong>By numeric, they mean a string of numbers &#8212; not actually binary numerics. There are a few things I don&#8217;t understand about numeric replies.</p>
<p>Why do some things have a numeric reply instead of just the text? Take NAMES for instance or WHOIS. I thought it had something to do with if the client sent the message requesting a reply. But then why is 005 considered a numeric reply? Or 001? Both are sent by the server after a connection.</p>
<p>Where the hell did these numbers come from? There&#8217;s some basic organization &#8212; 0xx are informative, 4xx are errors, 3xx are requested info&#8230; sometimes&#8230; 2xx are used for&#8230; uh&#8230;</p>
<p>Beyond that, I can&#8217;t figure out why the NAMES reply is 353 and the &#8220;End of NAMES&#8221; message is 366. MOTD Starting is 375, the actual MOTD packet is 372 and MOTD Ending is 376.</p>
<p>Additionally, when mentioning what reply is generated from what message, the spec (and by spec, I mean gelatinous blob of useless goo) refers to the numeric codes <em>by a  name!</em> Sending a WHOIS on a user generates a numeric reply of RPL_WHOISUSER &#8212; which is actually numeric 311. This makes things exceptionally hard to follow and you&#8217;re better off experimenting with viewing the raw output from the server.</p>
<p><strong>Security</strong><br />
For a while, there seemed to be a trend in having SSL connections to servers. It makes sense for say, HTTP or FTP &#8212; *real* protocols I mean. But because SSL connections are not required  for every client, IT BASICALLY MAKES THE WHOLE THING POINTLESS!!! Yeah, now I&#8217;m yelling!</p>
<p>You know those popups that you get in your web browser that say, &#8220;This page contains both secure and non-secure items.&#8221; &#8212; You have the option to ignore the non-secure items. If you had that option on IRC, it would basically ignore 90% of the people on there.</p>
<p><strong>Packet Length</strong><br />
It bothers me when connection oriented protocols (and by protocol in this case, I mean&#8230;. you get the idea&#8230;) reimplement stuff that TCP already does. Actually, I think the IRC protocol is the only one that does this.</p>
<p>TCP already breaks up things in to packets and lets you know when the stream terminates. Think about HTTP, you send the GET request, then stream everything down and then it terminates and you&#8217;re done. If you&#8217;re getting a 2MB html doc (god forbid), you don&#8217;t get it all at once &#8212; but no HTTP client on earth has to check for a line termination every 512 chars and then check to see if it sent the &#8220;End of HTTP Stream&#8221; message.</p>
<p><strong>Unicode and I18N</strong><br />
The Marquis de Sade, being the awful, evil man that he was made no plans for IRC to ever be in anything but 8-bit ASCII. Which is weird because he said that hundreds of years before 8-bit ASCII encoding was invented. I have yet to find *any* information in 10 years, whether official or &#8220;official,&#8221; about how Unicode works with IRC. I&#8217;m sure non-ascii characters can be sent &#8212; but as for the server encoding, BOM, etc&#8230; it&#8217;s a mystery.</p>
<p><strong>CTCP and DCC</strong><br />
At some point, some genius decided that instead of extending the protocol that extensions could be added by a hack in to an existing message.</p>
<p>There is, of course, <a href="http://www.invlogic.com/irc/ctcp.html">yet another document</a> about this &#8220;part.&#8221;</p>
<p>Trying to add support for these basically makes your handler for PRIVMSG 9000x bigger than it was. Also, you give yourself a massive headache and you start to think, &#8220;I must be a friggin&#8217; masochist to be working on this.&#8221;</p>
<p>The biggest crap-sandwich that one must eat is that the Client-to-Client Protocol goes through the Server. I&#8217;m gonna start yelling again. How about a rule that says you can&#8217;t call it a protocol if all you do is wrap some capitalized letters with \001? I&#8217;m gonna make an HTTP variant called FATTP (Fucking Awesome Text Transfer Protocol) which takes regular HTTP verbs and wraps them with \001. Fuck you.</p>
<p>But DCC takes the cake. Not only is it ass-backwards and full of errors &#8212; once again, you must reimplement parts of TCP stream control in order for it to work right. DCC Send is the real culprit &#8212; and it was supposedly replaced by DCC XMIT in 1997, but good luck finding anything that uses it.</p>
<p>The CTCP-97 document intends to offer an official spec for formatting codes. The problem is&#8230;</p>
<p><strong>mIRC</strong><br />
Currently the biggest piece of crap in IRC today is mIRC. For some reason, it is the standard for IRC clients. It uses a <a href="http://www.ircle.com/colorfaq.shtml">broken color formatting scheme</a>, old DCC code, horrible scripting, a poor interface, and yet, you still have to pay for it. There were many, <strong>many</strong> times when during the development of Zephyr (the IRC client I was working on from 2002-2004), we came to a point and said, &#8220;We don&#8217;t really know what to do here&#8230; What does mIRC do?&#8221;</p>
<p>So, given all these reasons, why can&#8217;t I convince my friends to move to jabber or something? Don&#8217;t they know what kind of state it puts me in?</p>
<p>At least this time, I&#8217;m only writing a bot. And, aside from reading the IRC RFCs&#8230; *sigh* I&#8217;m enjoying it.</p>
<p>See? Masochism.</p>
]]></content:encoded>
			<wfw:commentRss>http://mattptr.net/2009/10/26/am-i-nuts/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>More fun with PHP ORM libraries</title>
		<link>http://mattptr.net/2009/10/14/more-fun-with-php-orm-libraries/</link>
		<comments>http://mattptr.net/2009/10/14/more-fun-with-php-orm-libraries/#comments</comments>
		<pubDate>Wed, 14 Oct 2009 15:09:50 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://mattptr.net/?p=116</guid>
		<description><![CDATA[A few months ago, I was contacted by the developer of Red Bean &#8212; a new PHP ORM library. He seems to share my dismay with the overall suckiness of every ORM library and he asked if I would give his project a looksee. Before that, I have a few thoughts on Kohana and it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago, I was contacted by the developer of <a href="http://www.redbeanphp.com/">Red Bean</a> &#8212; a new PHP ORM library. He seems to share my dismay with the overall suckiness of every ORM library and he asked if I would give his project a looksee.</p>
<p>Before that, I have a few thoughts on <a href="http://www.kohanaphp.com">Kohana</a> and it&#8217;s <a href="http://docs.kohanaphp.com/libraries/orm">ORM library</a>.</p>
<p><em><span id="more-116"></span> </em></p>
<h3>Kohana</h3>
<p>Kohana is a full-stack framework based on CodeIgniter, but ditches PHP4 compatibility for the sake of my sanity. Really, PHP4 style coding is the only reason I don&#8217;t use CakePHP for everything. But, I digress.</p>
<p>I&#8217;ll just start by saying Kohana is the best PHP framework I&#8217;ve used so far. I hit a few bumps in the road, but very few. It&#8217;s pretty quick (or Swift, as they would say) and is very straight-forward when it comes to extending the base functionality.</p>
<p>My biggest gripe about the framework as a whole, is that I ran in to limitations a lot. With the database library mostly, but with some of the other components as well. I&#8217;ve been finding that with most open source tools I&#8217;m using, that the next version, &#8220;will be way better.&#8221;</p>
<p>I had a major problem in the app I&#8217;m coding with session_start() sending out cache headers &#8212; overwriting what I was trying to send out manually. But, beyond that, it&#8217;s been pretty smooth sailing.</p>
<p>The ORM is actually pretty decent. I didn&#8217;t do any benchmarks, so I don&#8217;t know how efficient or deficient it is, but I do know that it does lazy loading on relations. That&#8217;s something I&#8217;ll just have to live with when it comes to PHP.</p>
<p>There are a few problems I have with it though.</p>
<ol>
<li>There&#8217;s no way to do aggregate functions with the Database Query Builder and adding them in seems to be a low priority. (But the next version might be AWESOME!)</li>
<li>There&#8217;s no way (that I know of) to wrap a database query() result with an ORM class.</li>
<li>There are some limitations in using a one-to-many relationship with a foreign key not having part of the referenced table name in the field name. In other words, it doesn&#8217;t read from FK references, but relies on the field name &#8212; i.e., Profiles.user_id is meant to reference Users.id. But if you want to have Profiles.creator_id reference a different Users.id (say the user didn&#8217;t create their own profile), there&#8217;s no way to do that with the way model relationships are defined &#8212; again, just for one-to-many relationships.</li>
</ol>
<p>Beyond that, it&#8217;s a pretty decent library. It&#8217;s not particularly difficult to figure out how to set up models.</p>
<h3>Let&#8217;s steam this Bean</h3>
<p>RedBean reminds me a bit of ADODB_Active_Record in that both are developed separately from a full-stack framework.  It&#8217;s slightly similar to Kohana&#8217;s ORM, but with a few key differences, which I&#8217;ll cover shortly. RedBean also reminds me of ADODB_Active_Record in the sense that the setup and usage are better and easier than other standalone PHP ORMs by several thousand trillion times over.</p>
<p>Now this is going to be unfair, because to me, the pinnacle of database abstraction and object-relation mapping is still <a href="http://www.sqlalchemy.org">SQLAlchemy</a>. I doubt PHP will ever have something similar, but  I will always hope. At least until PHP dies.</p>
<h4>Initialization</h4>
<p>Right off, there&#8217;s something I don&#8217;t like. The RedBean library  isn&#8217;t redbean.php &#8212; it&#8217;s oodb.php. I&#8217;m not really sure why, but I could see myself being confused by this if I used RedBean for a project. What can I say? I&#8217;m simple.</p>
<p>I think a lot of the naming scheme is something I&#8217;d want to be different.</p>
<p>RedBean_Setup::kickstartDev connects to the database and creates models. This is one of the features I like about RedBean.  With ADODB_Active_Record, I have to define classes and extend, etc. RedBean creates the Models for you. Unfortunately, I can&#8217;t figure out why RedBean_Setup is it&#8217;s own class and if I had never seen documents before, I would never guess that the initialization method would be called &#8216;kickstartDev&#8217;. Would RedBean::connect() be too easy?</p>
<h4>Table Creation</h4>
<p>Another neet feature of RedBean is that it will create a database schema for any model that doesn&#8217;t already have a table. Read the docs, you&#8217;ll see it.</p>
<p>SQLAlchemy has something similar with Metadata().<a href="http://www.sqlalchemy.org/docs/05/ormtutorial.html#define-and-create-a-table">create_all</a>(). Although with that, you create the model declaratively. RedBean will build the schema based on what fields you have set in the model. It sounds handy, but Python programmers would probably be unsettled &#8212; it&#8217;s just a different philosophy.</p>
<p>I didn&#8217;t have time to test this extensively, so as to what happens when you set a new field when the model is already defined, I can only speculate.</p>
<h4>The CRUDiness</h4>
<p>Overall, there aren&#8217;t many surprises when it comes to fetching records.</p>
<pre>//Load a user
$user = new User($id);

//Similarly with Kohana's ORM
$user = ORM::factory('user', $id);</pre>
<p>Kohana can also do the top syntax (i.e., new Users_Model($id)) &#8212; but the seemingly preferred way is the lower.</p>
<p>Inserting/Updating a row is done via Model::save(), as is the case with almost all Active Record implementations.</p>
<p>Fields can be accessed using properties: $object-&gt;field,  or using getters and setters (blah): $object-&gt;getField();</p>
<p>Deleting is somewhat inconsistent.</p>
<pre>//Delete user
User::delete($user);

//I would think this is more readable/consistent:
$user-&gt;delete();</pre>
<p>But it&#8217;s not a big deal.</p>
<h4>Other Things</h4>
<p>There are two cool functions that I think every ORM should consider &#8212; import and export. Import will set field values based on an array, and export will serialize the row to an array (note: Kohana has this too). An extension of import() is provided as importFromPost &#8212; which sure beats setting field names manually from forms.</p>
<h4>One last thing&#8230;</h4>
<p>RedBean has a &#8220;Locking&#8221; feature that I&#8217;ve been trying to figure out. No, I know what Locking is, but I&#8217;m just wondering why it would be necessary? A modern, transactional database is not going to have problems with multiple users. Even SQLite supports basic mutli-user functionality. Maybe someone can explain this to me?</p>
<p>Well, that&#8217;s about all I can think to say. There may never be a perfect ORM for PHP, but some are better than others. Based on API and not on performance, I can say in my biased, unfair, ridiculous opinion, that RedBean is better than most.</p>
<p>If I have a project that I might be able to use RedBean with, I&#8217;ll definitely give it a shot. So there may be a second review in the future. Who knows?</p>
<p>To Gabor de Mooij, RedBean&#8217;s author:<br />
Good luck with the project &#8212; hopefully RedBean destroys Propel. :)</p>
]]></content:encoded>
			<wfw:commentRss>http://mattptr.net/2009/10/14/more-fun-with-php-orm-libraries/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>So easy, a caveman can use it.</title>
		<link>http://mattptr.net/2009/08/19/so-easy-a-caveman-can-use-it/</link>
		<comments>http://mattptr.net/2009/08/19/so-easy-a-caveman-can-use-it/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 02:17:33 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[holy crap]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[timer]]></category>

		<guid isPermaLink="false">http://mattptr.net/?p=106</guid>
		<description><![CDATA[Someone pointed out to me today that if you look at the source of the front page on www.geico.com, you might see that they use a certain timer script for rotating banners&#8230; In fact, it&#8217;s this one: http://www.geico.com/public/scripts/jquery/jquery.timer.js Yeah! That&#8217;s me! And all this time I thought the script was pretty useless, but I guess [...]]]></description>
			<content:encoded><![CDATA[<p>Someone pointed out to me today that if you look at the source of the front page on <a href="http://www.geico.com">www.geico.com</a>, you might see that they use a certain timer script for rotating banners&#8230;</p>
<p>In fact, it&#8217;s this one: <a href="http://www.geico.com/public/scripts/jquery/jquery.timer.js">http://www.geico.com/public/scripts/jquery/jquery.timer.js</a></p>
<p>Yeah! That&#8217;s me! And all this time I thought the script was pretty useless, but I guess a certain Gecko found a good place for it.</p>
<p>Honestly, I may have used that script once or twice, but that&#8217;s it. I don&#8217;t use timers a lot. But, if there&#8217;s enough interest, I&#8217;m open to adding bug fixes and features and such. I&#8217;ll also accept patches, etc.</p>
<p>Thanks to Alex for pointing that out. Pretty neet! ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://mattptr.net/2009/08/19/so-easy-a-caveman-can-use-it/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP date stuff</title>
		<link>http://mattptr.net/2009/08/04/php-date-stuff/</link>
		<comments>http://mattptr.net/2009/08/04/php-date-stuff/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 04:38:37 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://mattptr.net/?p=102</guid>
		<description><![CDATA[I&#8217;ve talked before about how I thought PHP&#8217;s date handling is the best thing about PHP. Well, I kinda lied. It sucks&#8230; It works fine if you&#8217;re dealing with dates in the here and now, but say you&#8217;re accepting user input for a date-of-birth field. strtotime() returns a signed integer, and if you look carefully, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve talked before about how I thought PHP&#8217;s date handling is the best thing about PHP.</p>
<p>Well, I kinda lied. It sucks&#8230;</p>
<p>It works fine if you&#8217;re dealing with dates in the here and now, but say you&#8217;re accepting user input for a date-of-birth field. strtotime() returns a <em>signed</em> integer, and if you look carefully, you&#8217;ll see that strtotime() will fail on early PHP5 revisions on Windows for dates before 1/1/1970.</p>
<p>So that&#8217;s problem 1. Problem 2 is going past 1/19/2038.  You would think that it wouldn&#8217;t be a problem on 64-bit systems, but I have no idea if that&#8217;s the case or not &#8212; I can&#8217;t seem to find any documentation on 64-bit versions of PHP using 64-bit timestamps.</p>
<p>Luckily, there&#8217;s a new <a href="http://us.php.net/manual/en/class.datetime.php">DateTime</a> class for PHP 5.2 and up. The constructor of the DateTime class accepts anything that strtotime() can, and DateTime::format() accepts a date() style format. So that&#8217;s easy enough. Hopefully, you deduce by my lack of griping, that Pre-epoch and post-2038 dates will work. I didn&#8217;t test to see how far back or forward, it can go. Far enough for my uses.</p>
<p>Why the new class isn&#8217;t listed on the date() and strtotime() pages &#8212; I have no idea. Hopefully now I won&#8217;t have another <a href="http://xkcd.com/376/">Epoch Fail</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mattptr.net/2009/08/04/php-date-stuff/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
