Made of Everything You're Not

Writing code... well, forever really. Sigh...
  • Home
  • Projects
  • Portfolio
  • Resume

Archive for March, 2009

Google Visualization API Primer

Posted in Code, Programming on March 30th, 2009 by Eric Lamb – Be the first to comment

The Google Visualization API is a JavaScript API for creating those fancy graphs and charts Google displays in all their cool toys like Google Analytics. There’s just an obnoxious amount of chart types available in the Visualization API Gallery that include code samples along with every example. There’s also the incredible Google Ajax API Playground which lets you play with the API and see real-time output.

Google Visualization

Google Visualization

According the official website:

The Google Visualization API lets you access multiple sources of structured data that you can display, choosing from a large selection of visualizations. Google Visualization API enables you to expose your own data, stored on any data-store that is connected to the web, as a Visualization compliant datasource. Thus you can create reports and dashboards as well as analyze and display your data through the wealth of available visualization applications. The Google Visualization API also provides a platform that can be used to create, share and reuse visualizations written by the developer community at large.

I have no real interest in publishing public widgets and I’ve only used the API by generating the data declarations; so far anyway. That’s actually what’s so compelling about the API; since it’s JavaScript based the API can be used with any server side language.

I’m mostly interested in using the charts and graphs for displaying data from a database on a website so that’s all this article is going to focus on.

One more thing to keep in mind; the API is just JavaScript. There’s nothing too fancy or random being done so even though the below may look complicated don’t forget; IT’S JUST JAVASCRIPT.

Examples

Line Chart

Line Chart

Line Chart

<script type="text/javascript">
	google.load("visualization", "1", {packages:["linechart"]});
	google.setOnLoadCallback(drawChart);
	function drawChart() {
		var data = new google.visualization.DataTable();
		data.addColumn('string', 'Date');
		data.addColumn('number', 'Clicks');
		data.addRows(15);
		data.setCell(0, 0, 'March 14, 2009');
		data.setCell(1, 0, 'March 15, 2009');
		data.setCell(2, 0, 'March 16, 2009');
		data.setCell(3, 0, 'March 17, 2009');
		data.setCell(4, 0, 'March 18, 2009');
		data.setCell(5, 0, 'March 19, 2009');
		data.setCell(6, 0, 'March 20, 2009');
		data.setCell(7, 0, 'March 21, 2009');
		data.setCell(8, 0, 'March 22, 2009');
		data.setCell(9, 0, 'March 23, 2009');
		data.setCell(10, 0, 'March 24, 2009');
		data.setCell(11, 0, 'March 25, 2009');
		data.setCell(12, 0, 'March 26, 2009');
		data.setCell(13, 0, 'March 27, 2009');
		data.setCell(14, 0, 'March 28, 2009');	  
                data.setCell(0, 1, 5);
		data.setCell(1, 1, 13);
		data.setCell(2, 1, 27);
		data.setCell(3, 1, 15);
		data.setCell(4, 1, 12);
		data.setCell(5, 1, 15);
		data.setCell(6, 1, 8);
		data.setCell(7, 1, 9);
		data.setCell(8, 1, 15);
		data.setCell(9, 1, 12);
		data.setCell(10, 1, 8);
		data.setCell(11, 1, 21);
		data.setCell(12, 1, 10);
		data.setCell(13, 1, 7);
		data.setCell(14, 1, 3);
 
		var chart = new google.visualization.LineChart(document.getElementById('click_chart_div'));
		chart.draw(data, {width: 500, height: 240, legend: 'bottom', title: 'Click Tracks by Date'});
	}
</script>
<div id='click_chart_div' style='width: 650px; height: 240px;'></div>

Pie Chart

Pie Chart

Pie Chart

<script type="text/javascript">
google.load("visualization", "1", {packages:["piechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
	var data = new google.visualization.DataTable();
	data.addColumn('string', 'Day');
	data.addColumn('number', 'Clicks');
	data.addRows(7);
	data.setValue(0, 0, 'Monday');
	data.setValue(0, 1, 56);
	data.setValue(1, 0, 'Tuesday');
	data.setValue(1, 1, 93);
	data.setValue(2, 0, 'Wednesday');
	data.setValue(2, 1, 21);
	data.setValue(3, 0, 'Thursday');
	data.setValue(3, 1, 28);
	data.setValue(4, 0, 'Friday');
	data.setValue(4, 1, 14);
	data.setValue(5, 0, 'Saturday');
	data.setValue(5, 1, 17);
	data.setValue(6, 0, 'Sunday');
	data.setValue(6, 1, 24);
 
	var chart = new google.visualization.PieChart(document.getElementById('day_chart_div'));
	chart.draw(data, {width: 500, height: 400, is3D: true, title: 'Clicks By Day', backgroundColor: '#f9f9f9', legend: 'top', legendBackgroundColor: '#f1f1f1'});
}
</script>
Bookmark and Share

PhpDelicious: Wrapper for del.icio.us API

Posted in Code, Programming on March 27th, 2009 by Eric Lamb – 5 Comments

Here’s a cool little php class for managing a delicious feed; PhpDelicious. According to the official site:

PhpDelicious is a PHP 5 library for accessing the del.icio.us API. It combines data from the main REST and JSON APIs and presents a consolidated interface. It also implements a file based caching system which eliminates the need to query on every request and ensures access to the API won’t be throttled due to excessive requests.

delicous

delicous

The class is really well written for php5 only but it could be rewritten in php4 with a bit of work and third-party modules. phpDelicious does have some requirements though:

  • PHP 5
  • CURL (or can use normal file reading functions if suitable URL wrappers installed)
  • json_decode function for JSON API based methods (native in PHP 5.2 and above)
  • XML Parser Functions

phpDelicious started in 2006 and has quite a few updates up to July of 2008 (I don’t know if it’s dying or if there’s nothing left to do…).

The class includes an example script that shows how to pull everything and add a single item that should get anyone up and running ASAP.

Usage Examples

Here are a couple examples to get you started:

Instantiate Session

<?php
require('php-delicious.inc.php');
define('DELICIOUS_USER', 'YOUR_USER');
define('DELICIOUS_PASS', 'YOUR_PASS');
$oDelicious = new PhpDelicious(DELICIOUS_USER, DELICIOUS_PASS);
?>

The above needs to be done before the below will work…

Add an Item to Bookmarks

<?php
$aPost = array();
$aPost['url'] = 'http://www.yahoo.com';
$aPost['description'] = 'Yahoo! home page';
$aPost['notes'] = 'Lame search engine'; 
$aPost['updated'] = date('Y-m-d H:i:s'); //mysql timestamp
$aTags = array('lame','dumb','search engine'); //must be array
$oDelicious->AddPost($aPost['url'], $aPost['description'], $aPost['notes'], $aTags, $aPost['updated'], true);
?>

Delete a Bookmark

<?php
$sUrl = 'http://www.yahoo.com';
$oDelicious->DeletePost($sUrl);
?>

Grab All Bookmarks

<?php
if ($aPosts = $oDelicious->GetAllPosts()) {
    foreach ($aPosts as $aPost) {
        echo '<a href="'.$aPost['url'].'">'.$aPost['desc'].'</a>';
        echo $aPost['notes'];
        echo $aPost['updated'];
    }
} else {
    echo $oDelicious->LastErrorString();
}
?>

Grab Some Bookmarks

<?php
$sTag = '', // filter by tag
$sDate = '', // filter by date - format YYYY-MM-DD HH:MM:SS
$sUrl = '' // filter by URL
if ($aPosts = $oDelicious->GetPosts($sTag,$sDate,$sUrl)) {
    foreach ($aPosts as $aPost) {
        echo '<a href="'.$aPost['url'].'">'.$aPost['desc'].'</a>';
        echo $aPost['notes'];
        echo $aPost['updated'];
    }
} else {
    echo $oDelicious->LastErrorString();
}
?>

Grab Recent Bookmarks

<?php
$sTag = '', // filter by tag
$iCount = 15 // number of posts to retrieve, min 15, max 100
if ($aPosts = $oDelicious->GetRecentPosts($sTag,$iCount)) {
    foreach ($aPosts as $aPost) {
        echo '<a href="'.$aPost['url'].'">'.$aPost['desc'].'</a>';
        echo $aPost['notes'];
        echo $aPost['updated'];
    }
} else {
    echo $oDelicious->LastErrorString();
}
?>

Grab All Tags

<?php
if ($aTags = $oDelicious->GetAllTags()) {
    foreach ($aTags as $Tag) {
        echo $Tag['tag'];
        echo $Tag['count'];
    }
} else {
    echo $oDelicious->LastErrorString();
}
?>

Rename a Tag

<?php
$sOld = 'foo';
$sNew = 'bar';
$oDelicious->RenameTag($sOld, $sNew);
?>

Grab All Dates

<?php
if ($dDates = $oDelicious->GetDates()) {
    foreach ($dDates AS $Date) {
        echo $Date['date'];
        echo $Date['count'];
    }
} else {
    echo $oDelicious->LastErrorString();
}
?>

Additional Functionality

After going through the class, it seems there’s some more functionality available. I have no idea what the purpose of the below calls are for though.

I tried looking through Delicious for references to “bundles”, “network” and “fans” but I couldn’t find anything about them though I was pretty lazy about it. Of course, I don’t really use Delicious too intensely so this could be standard, no brainer, stuff to the “real” users.

Please note though: I WAS NEVER ABLE TO GET THE BELOW TO RETURN ANYTHING BUT ERRORS. I only include them here for completeness.

Get Url Details

<?php
if ($dLinkDetails = $oDelicious->GetUrlDetails()) {
    //do something
} else {
    echo $oDelicious->LastErrorString();
}
?>

Get Network

<?php
$sUsername = 'USERNAME_TO_CHECK';
if ($dNetworkDetails = $oDelicious->GetNetwork($sUsername)) {
    //do something
} else {
    echo $oDelicious->LastErrorString();
}
?>

Get Your Network

<?php
if ($dMyNetworkDetails = $oDelicious->GetMyNetwork()) {
    //do something
} else {
    echo $oDelicious->LastErrorString();
}
?>

Get User Fans

<?php
$sUsername = 'USERNAME_TO_CHECK';
if ($dFansDetails = $oDelicious->GetFans($sUsername)) {
    //do something
} else {
    echo $oDelicious->LastErrorString();
}
?>

Get Your Fans

<?php
if ($dMyFansDetails = $oDelicious->GetMyFans()) {
    //do something
} else {
    echo $oDelicious->LastErrorString();
}
?>

Please keep in mind what I said above; I was never able to get the fans, bundle and URL details functionality to work properly.

Still, PhpDelicious makes it really easy to do minor jobs against your delicious data.

Bookmark and Share

AxCrypt File Encryption for Windows

Posted in IT on March 26th, 2009 by Eric Lamb – Be the first to comment

AxCrypt is a pretty nice open source (OSS) encryption program for Windows. What makes me want to write about it though is that it integrates directly with Windows Explorer and includes a right click context menu for easier manipulation of files so there isn’t a program that has to be started or opened (I always hate the wait for a program to start up…).

axcrypt

axcrypt

According to their site:

AxCrypt is the leading open source file encryption software for Windows. It integrates seamlessly with Windows to compress, encrypt, decrypt, store, send and work with individual files.

AxCrypt is pretty straight forward;

To encrypt:

  1. right click over a file
  2. choose “AxCrypt”
  3. choose “Encrypt”

    AxCrypt Encrypt

    AxCrypt Encrypt

  4. enter a passphrase

    AxCrypt Enter Passphrase

    AxCrypt Enter Passphrase

  5. click ok

To decrypt:

  1. right click over archive
  2. choose “AxCrypt”
  3. choose “Decrypt”

    AxCrypt Decrypt

    AxCrypt Decrypt

  4. enter passkey

    axcrypt_decrypt_enter_passphrase

    AxCrypt Enter Passphrase

  5. click ok

If you need to share sensitive files between people this is a really nice project.

Bookmark and Share

For your Perspective: My Email Hell

Posted in Rant on March 25th, 2009 by Eric Lamb – 1 Comment

I was walking down the hall the other day when I heard one of the employees complaining about how much email they get. Apparently, this particular employee gets over 50 legitimate emails a day!

That got me thinking about how much I get so I kept my email for an entire week. Usually, I’ll delete anything I don’t need to keep and file those I do, but instead I kept a gnarly Inbox for 7 whole days.

Gates of Hell

Gates of Hell

When 7 days had passed I compiled a list of the daily emails I get:

20 emails from my direct boss
10 emails from each member of my team
5 emails from the Creative Director
10 emails from Velvet Hammer employees (SW manages their IT)
10 emails from the CEO of StreetWise
4 emails notifying me backups have happened on my server*
around 100 emails warning me about suspicous activities on all my servers combined (around 4*)
4 emails notifying me about log changes to my servers*
1 Windows SBS Server Performance Report
4 emails notifying me of system changes on my Linux servers (if something changes that is)
3 email inbox quarantine summaries from Postini
20+ bounceback emails from random email campaigns
around 20 emails notifying me about the firewall banning an IP address
Task Reminder from my companies collaboration system
4 emails notifying me about cPanel changes on my servers
3 Website Pulse Daily Monitoring Log emails
4 cron.daily notification emails for various cron scripts I run
2 emails notifying me the firewall tried to update itself and the status of the attempt
4 emails notifying me that yum tried to update itself
3 emails notifying me cPanel updated it’s license ping

By my count that’s over 200 legitimate emails I get on a daily basis. This doesn’t include spam or any of the abnormal emails I can get.

I’m sure this isn’t any kind of record or anything but the next time you’re thinking you have it bad just remember me :)

Bookmark and Share

Smarty Relative Datetime Modifier

Posted in Code, Programming on March 24th, 2009 by Eric Lamb – Be the first to comment

In Extending the Smarty Template Engine I outlined the steps needed to create all the varieties of plugins for the Smarty template engine. Continuing with that tutorial, and to provide a little context, here’s a quick Smarty plugin for converting timestamps into relative timestamps.

Smarty Logo

Smarty Logo

This is a Smarty module plugin; notice how the name conforms to the naming conventions with the prefix “smarty_modifier_”

<?php
/**
 * Smarty plugin
 * @package Smarty
 * @subpackage plugins
 */
 
/**
 * Smarty relative date / time plugin
 *
 * Type:     modifier<br>
 * Name:     relative_datetime<br>
 * Date:     March 18, 2009
 * Purpose:  converts a date to a relative time
 * Input:    date to format
 * Example:  {$datetime|relative_datetime}
 * @author   Eric Lamb <eric@ericlamb.net>
 * @version 1.0
 * @param string
 * @return string
 */
function smarty_modifier_relative_datetime($timestamp)
{
	if(!$timestamp){
		return 'N/A';
	}
 
	$timestamp = (int)strtotime($timestamp);
	$difference = time() - $timestamp;
	$periods = array("sec", "min", "hour", "day", "week","month", "year", "decade");
	$lengths = array("60","60","24","7","4.35","12","10");
	$total_lengths = count($lengths);
 
	if ($difference > 0) { // this was in the past
		$ending = "ago";
	} else { // this was in the future
		$difference = -$difference;
		$ending = " from now";
	}
	//return;
 
	for($j = 0; $difference > $lengths[$j] && $total_lengths > $j; $j++) {
		$difference /= $lengths[$j];
	}
 
	$difference = round($difference);
	if($difference != 1) {
		$periods[$j].= "s";
	}
 
	$text = "$difference $periods[$j] $ending";
 
	return $text;
}

Installation

Just copy the contents above and paste into a file called:
modifier.relative_datetime.php

Place the file in your Smarty plugin directory and you’re good to go.

Usage Example:

{$item.timestamp|relative_datetime}
Bookmark and Share

Starting to Develop For Blackberries

Posted in Programming on March 23rd, 2009 by Eric Lamb – Be the first to comment

I’ve been using a Blackberry for a few years now; ever since I started working at StreetWise again. We use the Blackberry Enterprise Server (BES) to help keep everyone in touch; anyone in the company can use it if they own a Blackberry. Since I had to administer the BES it became pretty clear I needed to get on the bus and start using one.

Blackberry

Blackberry

Four hundred dollars later and I had my first Blackberry; a silver Curve 8300. It. Was. Awesome. I’ve since had another Curve and am now using the Bold.

I’d never had a “real” smart phone before and instantly became addicted to real time connectivity. I know a lot of developers resent this kind of availability but I love being able to respond immediately when needed. The way I see it I can, and do, respond on my terms so there’s no real issue with it.

The killer feature initially was email but is openness to 3rd party developers. There’s a crapload of stuff out there already but the fact that I can write my own programs is really nice. Unfortunately, Blackberry apps are written in Java.

I’ve never done any actual Java development, but I have done some basic debugging on some smaller applets, so I get the basic idea of Java. Java’s not too tough as a language but it kind of sucks setting up a development environment to work in (especially if you’ve never done it before). It’s definitely worth while to have some programming experience with another language before tackling Java. Either way, there’s a great tutorial on getting started with Java at SitePoint.

With the basics of Java out of the way it’s important to know what goes into a Blackberry application. Research In Motion (RIM) has a very extensive developer center that include quite a few tutorials that should help start the process.

Toni Westbrook has a detailed tutorial on how to create a Blackberry game and The Code Project has a tutorial series on how to create a Blackberry application

There’s a lot of information out there on how to develop for blackberries. Expect more about this topic in the future.

Bookmark and Share

Extending the Smarty Template Engine

Posted in Code, Programming on March 20th, 2009 by Eric Lamb – 1 Comment

One of the nicest parts about working with the Smarty Template Engine is it’s extensibility. The developers of Smarty had the foresight to recognize that their needs didn’t necessarily match the needs of all developers so they built into Smarty a plugin/module system to allow developers to extend Smarty to meet their needs.

Smarty Logo

Smarty Logo

There are plenty of options available when it comes to creating a Smarty plugin though I’ve only had to work with first 4 of the below 7 plugin types.

The available plugin types are template, modifiers, block functions, compiler functions, prefilters, postfilters, outputfilters, resources and inserts. Be sure to check out the Naming Conventions before attempting any of the techniques layed out here.

Naming Conventions

It’s important to note the naming convention for Smary Plugins. There are two conventions to pay attention to: files and functions.

An example of naming a file is:

type.name.php

where “type” is the plugin type and name is the name of the function in the file. Don’t worry about this too much though because Smarty will let you know when you mess up on the naming conventions. A couple examples of names for plugins would be:

function.plugin1.php 
modifier.plugin2.php 
block.plugin3.php
etc...

The convention for the functions is similar except all Smarty plugin functions must begin with “smarty” followed by the type then the name.

<?php
smarty_modifier_plugin_name(){
}
?>

Writing a Smarty Modifier Plugin

There’s a cool tutorial on Morning Caffeine that goes into a little detail on how to create a smarty modifier plugin.

Modifiers are basically php functions (custom or predefined) which work with variables, custom functions and strings. That means, you can actually call php functions as modifiers. Applying a modifier is very easy, all you need to specify the value followed by pipe and the modifier name.

Here’s an example Smarty Modifier Plugin:

<?php
/**
 * Smarty plugin
 * @package Smarty
 * @subpackage plugins
 */
 
function smarty_modifier_test_plugin($str)
{
	if(!$str){
		$str = 'N/A';
	}
	return $str;
}

In your Smarty template you just use it like so:

{'Hello Here!'|test_plugin}

Writing a Smarty Template Plugin

Writing a Smarty Template Plugin requires a little more planning than a Smarty Modifier Plugin. The Smarty Manual explains this pretty well:

The output (return value) of the function will be substituted in place of the function tag in the template (fetch() function, for example). Alternatively, the function can simply perform some other task without any output (assign() function).

So a Smarty Template Plugin essentially requires no variables or hooks from the Smarty object to work (unlike Smarty Modifier Plugins).

Here’s an example of how to create one:

function smarty_function_fun_with_string($params, &$smarty)
{
	if (empty($params['bad_word'])) {
		$smarty->_trigger_fatal_error("[fun_with_string] param 'bad_word' cannot be empty ");
		return;
	}
	return str_repeat($params['bad_word'].$params['delim'],$params['repeat']);
}
{fun_with_string bad_word='Fuck You!' delim='<br>' repeat='5'}

Smarty Block Functions

Block functions are functions of the form: {func} .. {/func}. In other words, they enclose a template block and operate on the contents of this block.

Smarty Block Functions are a lot more complicated than any of the other plugin types because of how they are parsed. Block functions are called twice to account for both the opening and closing tags so your function needs to take that into account or you’ll see some unexpected output :)

There’s a great example of one from the Smarty manual so I’m just going to use that:

<?php 
/* 
* Smarty plugin 
* ------------------------------------------------------------- 
* File:     block.translate.php 
* Type:     block 
* Name:     translate 
* Purpose:  translate a block of text 
* ------------------------------------------------------------- 
*/ 
function smarty_block_translate($params, $content, &$smarty, &$repeat) 
{ 
    if (isset($content)) { 
        $lang = $params['lang']; 
        // do some intelligent translation thing here with $content 
        return $translation; 
    } 
} 
?>

And you would call the plugin from the template like so:

{translate lang="br"}
Hello, world!
{/translate}

Smarty Compiler Functions

As the name suggests compiler functions are Smarty Plugins that get executed at compile time of the template. They’re good for executing time sensitive data into a template.

<?php 
/* 
* Smarty plugin 
* ------------------------------------------------------------- 
* File:     compiler.tplheader.php 
* Type:     compiler 
* Name:     tplheader 
* Purpose:  Output header containing the source file name and 
*           the time it was compiled. 
* ------------------------------------------------------------- 
*/ 
function smarty_compiler_tplheader($tag_arg, &$smarty) 
{ 
    return "\necho '" . $smarty->_current_file . " compiled at " . date('Y-m-d H:M'). "';"; 
} 
?>

And it get’s executed like:

{tplheader}

Smarty Prefilter Plugins

The Smarty Manual says it best:

Prefilters are used to process the source of the template immediately before compilation. The first parameter to the prefilter function is the template source, possibly modified by some other prefilters. The plugin is supposed to return the modified source. Note that this source is not saved anywhere, it is only used for compilation.

Prefilter Plugins don’t have any template variable to replace so they have to be initialized explicitly.

<?php
$smarty->register_prefilter('pre01');
?>

It’s important to note that the prefilter plugin has to be declared before registering the filter or you’ll get Smarty errors all over the place.

Smarty Postfilter Plugins

On the other side of the spectrum from Prefilter plugins are Smarty Postfilter Plugins. Postfilter plugins are exactly identical in every way to Prefilter plugins except for when they are executed. Postfilters are, as the name suggests, executed at the end of the template compilation.

Smarty Output Plugins

Output filter plugins operate on a template’s output, after the template is loaded and executed, but before the output is displayed.

<?php 
/* 
* Smarty plugin 
* ------------------------------------------------------------- 
* File:     outputfilter.protect_email.php 
* Type:     outputfilter 
* Name:     protect_email 
* Purpose:  Converts @ sign in email addresses to %40 as 
*           a simple protection against spambots 
* ------------------------------------------------------------- 
*/ 
function smarty_outputfilter_protect_email($output, &$smarty) 
{ 
     return preg_replace('!(\S+)@([a-zA-Z0-9\.\-]+\.([a-zA-Z]{2,3}|[0-9]{1,3}))!', 
                         '$1%40$2', $output); 
} 
?>

Smarty Resource Plugins

Resource plugins are useful for supplying Smarty with access to external resources like databases, shared memory, LDAP and sockets.

According to the Smarty manual:

There are a total of 4 functions that need to be registered for each type of resource. Every function will receive the requested resource as the first parameter and the Smarty object as the last parameter. The rest of parameters depend on the function.

bool smarty_resource_name_source (string $rsrc_name, string &$source, object &$smarty)

bool smarty_resource_name_timestamp (string $rsrc_name, int &$timestamp, object &$smarty)

bool smarty_resource_name_secure (string $rsrc_name, object &$smarty)

bool smarty_resource_name_trusted (string $rsrc_name, object &$smarty)

The first function is supposed to retrieve the resource. Its second parameter is a variable passed by reference where the result should be stored. The function is supposed to return true if it was able to successfully retrieve the resource and false otherwise.

The second function is supposed to retrieve the last modification time of the requested resource (as a UNIX timestamp). The second parameter is a variable passed by reference where the timestamp should be stored. The function is supposed to return true if the timestamp could be succesfully determined, and false otherwise.

The third function is supposed to return true or false, depending on whether the requested resource is secure or not. This function is used only for template resources but should still be defined.

The fourth function is supposed to return true or false, depending on whether the requested resource is trusted or not. This function is used for only for PHP script components requested by include_php tag or insert tag with src attribute. However, it should still be defined even for template resources.

With the code looking like so:

<?php 
/* 
* Smarty plugin 
* ------------------------------------------------------------- 
* File:     resource.db.php 
* Type:     resource 
* Name:     db 
* Purpose:  Fetches templates from a database 
* ------------------------------------------------------------- 
*/ 
function smarty_resource_db_source($tpl_name, &$tpl_source, &$smarty) 
{ 
    // do database call here to fetch your template, 
    // populating $tpl_source 
    $sql = new SQL; 
    $sql->query("select tpl_source 
                   from my_table 
                  where tpl_name='$tpl_name'"); 
    if ($sql->num_rows) { 
        $tpl_source = $sql->record['tpl_source']; 
        return true; 
    } else { 
        return false; 
    } 
} 
 
function smarty_resource_db_timestamp($tpl_name, &$tpl_timestamp, &$smarty) 
{ 
    // do database call here to populate $tpl_timestamp. 
    $sql = new SQL; 
    $sql->query("select tpl_timestamp 
                   from my_table 
                  where tpl_name='$tpl_name'"); 
    if ($sql->num_rows) { 
        $tpl_timestamp = $sql->record['tpl_timestamp']; 
        return true; 
    } else { 
        return false; 
    } 
} 
 
function smarty_resource_db_secure($tpl_name, &$smarty) 
{ 
    // assume all templates are secure 
    return true; 
} 
 
function smarty_resource_db_trusted($tpl_name, &$smarty) 
{ 
    // not used for templates 
} 
?>

Smarty Insert Plugins

Lastly, we have Smarty Insert Plugins. Insert plugins are only good for use in the Smarty Insert tag. For example:

{insert name="time" format="%A"}

With the php code:

<?php 
/* 
* Smarty plugin 
* ------------------------------------------------------------- 
* File:     insert.time.php 
* Type:     time 
* Name:     time 
* Purpose:  Inserts current date/time according to format 
* ------------------------------------------------------------- 
*/ 
function smarty_insert_time($params, &$smarty) 
{ 
    if (empty($params['format'])) { 
        $smarty->trigger_error("insert time: missing 'format' parameter"); 
        return; 
    } 
 
    $datetime = strftime($params['format']); 
    return $datetime; 
} 
?>
Bookmark and Share

Using the FriendFeed API with PHP

Posted in Code, Programming on March 18th, 2009 by Eric Lamb – Be the first to comment

Dissenting opinion: I don’t like social networking as a consumer. I just find the whole thing pretty stupid; meeting people online that I’ll never meet in real life, who I have only a vague similarity to,  makes me feel retarded. Facebook, MySpace, Twitter can all go to hell. Sorry, had to be said. (I’ll probably be writing a post on this soon.)

FriendFeed Logo

FriendFeed Logo

I do love building them though. They’re a joy to work on because of the complexities involved and right now it’s prettty exciting because of all the new stuff coming out daily.

Anyway, for an upcoming project I needed to integrate the FriendFeed API into a website. This was painful because, as I said above, I hate social networking sites. I didn’t belong to too any at the time so I had to spend about an hour signing up with a few of the  social networks FriendFeed supports.

After that though, working with the API was pretty painless. To get started all you have to do is

  1. Sign up with FriendFeed
  2. Import your sites
  3. Get API Key
  4. Download php API code

Try not to look too closely to the API code; there’s almost zero formatting. Just know it works. If you have php compiled with curl support that is; you HAVE to have curl support.

API Calls

Pull a user feed:

<?php
$friendfeed = new FriendFeed($friendfeed_nickname, $friendfeed_key);
$feed = $friendfeed->fetch_user_feed("$nickname", $service=null, $start=0,$num=30);
?>

Pull a user comment feed:

<?php
$friendfeed = new FriendFeed($friendfeed_nickname, $friendfeed_key);
$feed = $friendfeed->fetch_user_comments_feed($nickname, $service=null, $start=0,$num=30);
?>

Pull a user likes feed:

<?php
$friendfeed = new FriendFeed($friendfeed_nickname, $friendfeed_key);
$feed = $friendfeed->fetch_user_likes_feed($nickname, $service=null, $start=0,$num=30);
?>

Pull a user discussion feed:

<?php
$friendfeed = new FriendFeed($friendfeed_nickname, $friendfeed_key);
$feed = $friendfeed->fetch_user_discussion_feed($nickname, $service=null, $start=0,$num=30);
?>

Pull a merged feed with all of the given users’ entries. Note that authentication is required if any one of the users’ feeds isn’t public and that $nicknames is an array of users:

<?php
$feed = $friendfeed->fetch_multi_user_feed($nicknames, $service=null, $start=0,$num=30);
?>

Pull the entries the authenticated user sees on their home page:

<?php
$friendfeed = new FriendFeed($friendfeed_nickname, $friendfeed_key);
$feed = $friendfeed->fetch_home_feed($service=null, $start=0, $num=30);
?>

Perform a search. The format for $query is the same as the FriendFeed search. If you authenticate the request the search applies to the authenticated user. If it’s not authenticated the search is against all public feeds.

<?php
$friendfeed = new FriendFeed($friendfeed_nickname, $friendfeed_key);
$feed = $friendfeed->search($query, $service=null, $start=0, $num=30);
?>

Publishes the provided link/title to the authenticated users page:

<?php
// image_urls is a list of URLs that will be downloaded and included as
// thumbnails beneath the link. The thumbnails will all link to the
// destination link. If you would prefer that the images link somewhere
// else, you can specify images instead, which should be an array of
// name-associated arrays of the form array("url"=>...,"link"=>...).
// The thumbnail with the given url will link to the specified link.
//
// audio_urls is a list of MP3 URLs that will show up as a play
// button beneath the link. You can optionally supply audio[]
// instead, which should be a list of name-associated arrays of the 
// form ("url"=> ..., "title"=> ...). The given title will appear when
// the audio file is played.
//
// We return the parsed/published entry as returned from the server,
// which includes the final thumbnail URLs as well as the ID for the
$friendfeed = new FriendFeed($friendfeed_nickname, $friendfeed_key);
$feed = $friendfeed->publish_link($title, $link, $comment=null, $image_urls=null,$images=null, $via=null, $audio_urls=null, $audio=null, $room=null);
?>

Add a comment to a users page; returns the comment_id

<?php
$friendfeed = new FriendFeed($friendfeed_nickname, $friendfeed_key);
$feed = $friendfeed->add_comment($entry_id, $body);
?>

Edit a comment on a users page:

<?php
$friendfeed = new FriendFeed($friendfeed_nickname, $friendfeed_key);
$feed = $friendfeed->edit_comment($entry_id, $comment_id, $body);
?>

Delete a comment:

<?php
$friendfeed = new FriendFeed($friendfeed_nickname, $friendfeed_key);
$feed = $friendfeed->delete_comment($entry_id, $comment_id);
?>

Un-deletes a comment:

<?php
$friendfeed = new FriendFeed($friendfeed_nickname, $friendfeed_key);
$feed = $friendfeed->undelete_comment($entry_id, $comment_id);
?>

Add like for a given $entry_id:

<?php
$friendfeed = new FriendFeed($friendfeed_nickname, $friendfeed_key);
$feed = $friendfeed->add_like($entry_id);
?>

Deletes a like for a give $entry_id:

<?php
$friendfeed = new FriendFeed($friendfeed_nickname, $friendfeed_key);
$feed = $friendfeed->delete_like($entry_id);
?>

Further Reading

Getting started with the FriendFeed API and PHP
FriendFeed API Documentation

Bookmark and Share

Video Trace

Posted in Brain Dump on March 16th, 2009 by Eric Lamb – Be the first to comment

Here’s something quick from The Australian Centre for Visual Technologies that I’ve been keeping my eye on for over a year now; Video Trace, a system for interactively generating realistic 3D models of objects from video. Unfortunately, there hasn’t been an update on the project since then but it’s still a pretty cool idea.

Video Trace

Video Trace

The user interacts with VideoTrace by tracing the shape of the object to be modelled over one or more frames of the video. By interpreting the sketch drawn by the user in light of 3D information obtained from computer vision techniques, a small number of simple 2D interactions can be used to generate a realistic 3D model.

There are a number of applications of the VideoTrace technology, including modelling parts of the real world for insertion into virtual worlds. You may want to model your house, in order to put it into Google Earth, or your couch, in order to take it with you into Second Life, for example.

There’s a really cool video outlining the hows of Video Trace that’s definitely cool.

Bookmark and Share

iTunes Data WordPress Widget

Posted in Code on March 15th, 2009 by Eric Lamb – 2 Comments

Here’s just a quick announcement for a new WordPress widget I’ve written call iTunes Data. It’s a sidebar widget that displays snippets from an uploaded iTunes XML file.

iTunes

iTunes

Currently, the data that gets displayed in the widget is randomized to pull the following:

  1. Top Genres
  2. Latest Additions
  3. Top Artists
  4. Top Albums

I’ve actually had the basics done for quite some time. It’s been on my site, plugging along, which has helped me to make sure it was efficient and worked properly.

The cool thing about building the widget was learning about PclZip, something I’ll be writing more about soon. For now though, let me just say it’s a really nice zip file management class that allows for easy work.

The widget couldn’t have been built without the iTunes XML parser for PHP library written by Robert A. Wallis

Anyway, until I build a proper page for the widget and get it into the WordPress Plugin Repository, you can download it below.

Download iTunes Data Widget

Bookmark and Share
« Older Entries
  • Subscribe: Entries | Comments
  • About Me

    Email Email
    Twitter Twitter
    310.739.3322
  • Categories

    • Brain Dump
    • Business
    • Code
    • IT
    • Programming
    • Rant
    • Servers
  • Archives

    • August 2010
    • July 2010
    • June 2010
    • May 2010
    • April 2010
    • March 2010
    • February 2010
    • January 2010
    • December 2009
    • November 2009
    • October 2009
    • September 2009
    • August 2009
    • July 2009
    • June 2009
    • May 2009
    • April 2009
    • March 2009
    • February 2009
    • January 2009
    • December 2008
    • November 2008
    • October 2008

Copyright © 2008 - 2010 Eric Lamb - All rights reserved