Fun with Digg’s API

Digg’s api was released about a week ago a while ago, and since that time, various flash projects have surfaced, probably due to that pesky contest. But I don’t have any flash experience, so PHP, here we come.

We’re going to make various tag clouds, a Reddit clone, Reddit/Better RSS feed, and a live diggs app.

Update - 05/09/07 - 3 PM - Stupid host seems to be having database issues. Great. I wish I could afford a dedicated, or I guess VPS, so I don’t have to put with this crap.

Update - 05/09/07 - 6 PM - It seems that it was a combination of their db sucking and the fact they got rid of some essential pear packages. WTF?

Update - 05/12/07 - 11 AM - Yup. They cut off my MySQL abilities. I can’t connect to any of my databases on xrho.com. This site is fine however. I guess inserting 100+ entries a minute might have annoyed them?

Update - 05/17/07 - 7 PM - The MySQL abilities are still cut off. Fucking netfirms. Also, it seems in one of my updates, it cut off the bottom, which also happened to include the download links. You can download a ZIP or Gzip of the files. Since I’m having problems with that, feel free to download them and run them on your own site. Let me know if you do so I can add the link.

Demos of most of the scripts are available here, and more specifically:

Due to the length of this post, I’m splitting it. I hate making people click through, but it’s long enough to constitute it.

Part A: The Setup

First, we need the Pear package, from http://bugs.joestump.net/code/Services_Digg/Services_Digg-0.0.2.tgz. You can install it using the Pear install command, but I just copied the folder into my directory.

We’re going to be using MySQL database, so create a new database and here is the table structure I used:

-- 
-- Table structure for table `diggslive`
-- 
 
CREATE TABLE `diggslive` (
  `digging_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `story_id` INT(10) UNSIGNED NOT NULL,
  `id` INT(10) UNSIGNED NOT NULL,
  `username` VARCHAR(250) COLLATE latin1_general_ci NOT NULL,
  `TIME` INT(10) NOT NULL,
  `status` VARCHAR(45) COLLATE latin1_general_ci NOT NULL,
  PRIMARY KEY  (`digging_id`),
  UNIQUE KEY `id` (`id`),
  KEY `username` (`username`),
  KEY `story_id` (`story_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=137897 ;
 
-- --------------------------------------------------------
 
-- 
-- Table structure for table `diggstories`
-- 
 
CREATE TABLE `diggstories` (
  `digg_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `title` TEXT character SET latin1 COLLATE latin1_general_ci NOT NULL,
  `description` TEXT character SET latin1 COLLATE latin1_general_ci NOT NULL,
  `diggs` INT(5) NOT NULL,
  `comments` INT(4) NOT NULL,
  `id` INT(10) UNSIGNED NOT NULL,
  `link` VARCHAR(1000) character SET latin1 COLLATE latin1_general_ci NOT NULL,
  `submitted` INT(10) NOT NULL,
  `promoted` INT(10) NOT NULL,
  `href` VARCHAR(1000) character SET latin1 COLLATE latin1_general_ci NOT NULL,
  `status` VARCHAR(45) character SET latin1 COLLATE latin1_general_ci NOT NULL,
  `user_id` INT(10) UNSIGNED NOT NULL,
  `username` VARCHAR(250) character SET latin1 COLLATE latin1_general_ci NOT NULL,
  `icon` TEXT character SET latin1 COLLATE latin1_general_ci NOT NULL,
  `registered` INT(10) NOT NULL,
  `profileviews` INT(10) UNSIGNED NOT NULL,
  `topic_long` VARCHAR(100) character SET latin1 COLLATE latin1_general_ci NOT NULL,
  `topic_short` VARCHAR(100) character SET latin1 COLLATE latin1_general_ci NOT NULL,
  `container_long` VARCHAR(100) character SET latin1 COLLATE latin1_general_ci NOT NULL,
  `container_short` VARCHAR(100) character SET latin1 COLLATE latin1_general_ci NOT NULL,
  `host` VARCHAR(250) COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY  (`digg_id`),
  UNIQUE KEY `href` (`href`),
  FULLTEXT KEY `title` (`title`),
  FULLTEXT KEY `description` (`description`),
  FULLTEXT KEY `title_2` (`title`,`description`),
  FULLTEXT KEY `link` (`link`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=3818 ;
 
-- --------------------------------------------------------
 
-- 
-- Table structure for table `diggusers`
-- 
 
CREATE TABLE `diggusers` (
  `user_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(250) COLLATE latin1_general_ci NOT NULL,
  `icon` TEXT COLLATE latin1_general_ci,
  `registered` INT(10) NOT NULL,
  `profileviews` INT(10) UNSIGNED NOT NULL DEFAULT '0',
  PRIMARY KEY  (`user_id`),
  UNIQUE KEY `username` (`username`),
  KEY `username_2` (`username`)
) ENGINE=INNODB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=2550 ;

There are 3 tables. Table diggstories will store the all the info about the the popular stories that is given to us through the api. There are 3 FULLTEXT indecies to enable a better search as shown later.

Now for the config file. Edit as necessary for your setup:
config.php:

<?php
 
$dbhost = "localhost";
$dbuser = "root";
$dbpass = "";
$dbname = "digg";
 
// Connect to DB, now!
// Regular connection
@mysql_connect($dbhost,$dbuser,$dbpass) or die("MySQL Connection error");
// Persistent conenction
// @mysql_pconnect($dbhost,$dbuser,$dbpass) or deadlyerror("MySQL Connection error (persistent) ");
@mysql_select_db($dbname) or die("Unable to select database");
 
?>

Here are some functions that we’ll use later.
functions.php:

<?php
 
function sqlquote($value) {
    if(get_magic_quotes_gpc()) {
          $value = stripslashes($value);
    }
    //check if this function exists
    if( function_exists("mysql_real_escape_string") ) {
          $value = mysql_real_escape_string($value);
    }
    //for PHP version < 4.3.0 use addslashes
    else {
          $value = addslashes($value);
    }
    return $value;
}
 
function dehtml($content) {
	$content = preg_replace("/&(?!(amp|[#0-9]+|lt|gt|quot|copy|nbsp);)/ix","&amp;",$content);
	$content = str_replace(array("&#160;","&#173;","&#8205;","&#8204;","&#8237;","&#8238;"),"",$content);
	//$content = preg_replace('/&(?![a-z0-9]+;)/i', '&amp;', $content); 
	return str_replace(array("<",">","'","""),array("&lt;","&gt;","&#39;","&quot;"),$content);
}
 
function timeparse($time) {
	$since = time() - $time;
	if($since < 60) {
		return ($since == 1) ? "$since second ago" : "$since seconds ago";
	}
	elseif($since < 3600) {
		$since = floor($since/60);
		return ($since == 1) ? "$since minute ago" : "$since minutes ago";
	}
	elseif($since < 86400) {
		$since = floor($since/3600);
		return ($since == 1) ? "$since hour ago" : "$since hours ago";
	}
	else {
		$since = floor($since/86400);
		return ($since == 1) ? "$since day ago" : "$since days ago";
	}
}
 
 
function toshort($text) {
	return strtolower(str_replace(" ","_",$text));
}
 
 
function host($url) {
	$exploded = explode("/",$url);
	return str_replace("www.","",$exploded[2]);
}
 
?>

Part B: Getting data

Getting the stories

First off, let’s populate our database with stories. This will take as many stories as possible and inserts them into out `diggstories` table. We are also going to insert our user info that it finds.

insert.php:

<?php
 
 
ini_set('user_agent', 'Trendds/1.0');
ini_set('max_execution_time', 3600);
 
require 'config.php';
 
include 'functions.php';
require_once 'Services/Digg.php';
Services_Digg::$appKey = 'http://www.nothingoutoftheordinary.com/Services_Digg_Proxy.php';
Services_Digg::$uri = 'http://services.digg.com';
$count = 3525;
$offset = 0;
while($offset<$count) {
	$params = array('count' => 100,'offset' => $offset);
	$request = Services_Digg::factory('Stories')->popular($params);
	foreach ($request->stories as $story) {
 
		$userinfo = mysql_query("SELECT `user_id`, `profileviews` FROM `diggusers` WHERE `username` = '".sqlquote($story->user->name)."' LIMIT 1");
		if(mysql_numrows($userinfo) != 1) {
			mysql_query("INSERT INTO `diggusers`
				( `user_id` , `username`, `icon`, `registered`, `profileviews` )
				VALUES ( 
					NULL, 
					'".sqlquote($story->user->name)."', 
					'".sqlquote($story->user->icon)."', 
					'".sqlquote($story->user->registered)."',
					'".sqlquote($story->user->profileviews)."'
				) ") or die("Inserting user: ".mysql_error());
			$user_id = mysql_insert_id();
		}
		else {
			$user_id = mysql_result($userinfo,0,"user_id");
		}
		mysql_query("INSERT INTO `diggstories` ( 
		`digg_id`, `title`, `description`, `diggs`, `comments`, `id`, `link`, `submitted`, `promoted`, `href`, `status`, 
			`user_id` , `username`, `icon`, `registered`, `profileviews`, `topic_long`, `topic_short`, `container_long`, `container_short`, `host`
		)
		VALUES (
			NULL, 
			'".sqlquote($story->title)."', 
			'".sqlquote($story->description)."', 
			'".sqlquote($story->diggs)."',
			'".sqlquote($story->comments)."',
			'".sqlquote($story->id)."',
			'".sqlquote($story->link)."', 
			'".sqlquote($story->submit_date)."',
			'".sqlquote($story->promote_date)."',
			'".sqlquote($story->href)."',
			'".sqlquote($story->status)."',
			'".sqlquote($user_id)."',
			'".sqlquote($story->user->name)."',
			'".sqlquote($story->user->icon)."',
			'".sqlquote($story->user->registered)."',
			'".sqlquote($story->user->profileviews)."',
			'".sqlquote($story->topic->name)."',
			'".sqlquote($story->topic->short_name)."',
			'".sqlquote($story->container->name)."',
			'".sqlquote($story->container->short_name)."',
			'".sqlquote(host($story->link))."'
		) ") or mysql_query("UPDATE `diggstories` 
			SET `diggs` = '".sqlquote($story->diggs)."', `comments` = '".sqlquote($story->comments)."'
			WHERE `id` = '".sqlquote($story->id)."' 
			LIMIT 1
			") or die(mysql_error());
	}
	echo "<br />".$offset;
	$offset += 100;
	$count = $request->total;
}
 
 
?>

The first lines,
ini_set('user_agent', 'Trendds/1.0');
ini_set('max_execution_time', 3600);

set the User-Agent and increases the max execution time, since getting over 3000 stories takes some time, and setting a user agent is required.

Services_Digg::$appKey = 'http://www.nothingoutoftheordinary.com/Services_Digg_Proxy.php';
Services_Digg::$uri = 'http://services.digg.com';

set the api key and uri, as shown in the Pear tests.

Next, we start requesting and inserting the info. This runs through a while and for each loop inserting each story.

After running that, you should now have about a 3000 entry `diggstories` table along with a couple thousand entry `diggusers` table.

In order to keep these updated, we can run update.php every so often. I did 5 minutes, but that seems to be a bit overkill.

update.php:

<?php
 
 
ini_set('user_agent', 'Trendds/1.0');
ini_set('max_execution_time', 3600);
 
require 'config.php';
 
include 'functions.php';
require_once 'Services/Digg.php';
Services_Digg::$appKey = 'http://www.nothingoutoftheordinary.com/Services_Digg_Proxy.php';
Services_Digg::$uri = 'http://services.digg.com';
 
 
$params = array('count' => 100);
$request = Services_Digg::factory('Stories')->popular($params);
//print_r($request);
//exit;
foreach ($request->stories as $story) {
 
	$userinfo = mysql_query("SELECT `user_id`, `profileviews` FROM `diggusers` WHERE `username` = '".sqlquote($story->user->name)."' LIMIT 1");
	if(mysql_numrows($userinfo) != 1) {
		mysql_query("INSERT INTO `diggusers`
			( `user_id` , `username`, `icon`, `registered`, `profileviews` )
			VALUES ( 
				NULL, 
				'".sqlquote($story->user->name)."', 
				'".sqlquote($story->user->icon)."', 
				'".sqlquote($story->user->registered)."',
				'".sqlquote($story->user->profileviews)."'
			) ") or die("Inserting user: ".mysql_error());
		$user_id = mysql_insert_id();
	}
	else {
		$user_id = mysql_result($userinfo,0,"user_id");
	}
	mysql_query("INSERT INTO `diggstories` ( 
	`digg_id`, `title`, `description`, `diggs`, `comments`, `id`, `link`, `submitted`, `promoted`, `href`, `status`, 
		`user_id` , `username`, `icon`, `registered`, `profileviews`, `topic_long`, `topic_short`, `container_long`, `container_short`, `host`
	)
	VALUES (
		NULL, 
		'".sqlquote($story->title)."', 
		'".sqlquote($story->description)."', 
		'".sqlquote($story->diggs)."',
		'".sqlquote($story->comments)."',
		'".sqlquote($story->id)."',
		'".sqlquote($story->link)."', 
		'".sqlquote($story->submit_date)."',
		'".sqlquote($story->promote_date)."',
		'".sqlquote($story->href)."',
		'".sqlquote($story->status)."',
		'".sqlquote($user_id)."',
		'".sqlquote($story->user->name)."',
		'".sqlquote($story->user->icon)."',
		'".sqlquote($story->user->registered)."',
		'".sqlquote($story->user->profileviews)."',
		'".sqlquote($story->topic->name)."',
		'".sqlquote($story->topic->short_name)."',
		'".sqlquote($story->container->name)."',
		'".sqlquote($story->container->short_name)."',
		'".sqlquote(host($story->link))."'
	) ") or mysql_query("UPDATE `diggstories` 
		SET `diggs` = '".sqlquote($story->diggs)."', `comments` = '".sqlquote($story->comments)."'
		WHERE `id` = '".sqlquote($story->id)."' 
		LIMIT 1
		") or die(mysql_error());
}
 
 
 
 
?>

In order to not refresh or have a cron job (though if you plan on using this more, a cron job would be good), you can just run crondigg.py, or crondigg.pyw if you don’t want to see a window, to keep the database updated. You will need to edit value for url to point to the location of your update.php.

crondigg.py

#! /usr/bin/env python
 
url = 'http://localhost/digg/update.php'
wait = 300
 
import urllib,time
 
while 1:
	try:
		print 'Requesting %s \r' % url,
		urllib.urlopen(url).read()
		print " " * (len(url)+12),'\r',
		count = 0
		while count < wait:
			print 'Waiting %d seconds \r' % (wait-count),
			count+=1
			time.sleep(1)
	except KeyboardInterrupt:
		import sys
		sys.exit(2)

Note: This python script was written on Windows, where it works fine. On linux however, it’s a different story. It still works, just the output doesn’t.

Gettings diggs

Next, we’re going to get individual diggs. We’re not going to go back in time and get as many diggs as possible. The database will get really big pretty quickly, so don’t worry about it.

updatediggs.php:

<?php
 
 
ini_set('user_agent', 'Trendds/1.0');
ini_set('max_execution_time', 3600);
 
 
require 'config.php';
 
include 'functions.php';
require_once 'Services/Digg.php';
Services_Digg::$appKey = 'http://www.nothingoutoftheordinary.com/Services_Digg_Proxy.php';
Services_Digg::$uri = 'http://services.digg.com';
 
 
$api = Services_Digg::factory('Stories');
 
// To keep track of the current timestamp. This could just be mysql_result(mysql_query("SELECT `time` FROM `diggslive` ORDER BY `time` DESC LIMIT 1"),0,"time")  but a txt file is easier.
//$mindate = file_get_contents('lastdiggs.txt')-1;
$mindate = mysql_result(mysql_query("SELECT `time` FROM `diggslive` ORDER BY `time` DESC LIMIT 1"),0,"time")-1 ;
//$mindate = time() - 3600;
 
$offset = 0;
$total = 1;
$runs = 0;
 
// Get as many diggs as possible since the last update
while ($offset < $total) {
	$params = array('count' => 100,'min_date' => $mindate,'offset'=>$offset);
	$diggs = $api->diggs($params);
	// Go through each digg
	//print_r($diggs);
	foreach ($diggs->diggs as $digg) {
		// This is pretty annoying. It's true if the insert failed. It might not be the most sensible thing, but it's about 2 in the morning, and I like it
		$inserted = false;
		// Insert the digg
		mysql_query("INSERT INTO `diggslive` 
			(`digging_id`, `story_id`, `id`, `username`, `time`, `status`)
			VALUES (
				NULL,
				'".sqlquote($digg->story)."',
				'".sqlquote($digg->id)."',
				'".sqlquote($digg->user)."',
				'".sqlquote($digg->date)."',
				'".sqlquote($digg->status)."'
			)") or setcheck(true);
		if(!$inserted) {
			// Increase the digg count of the story, since it just got dugg
			mysql_query("UPDATE `diggstories` SET `diggs` = `diggs`+1 WHERE `id` = '".sqlquote($digg->id)."' LIMIT 1") or die(mysql_error());
		}
	}
	// If this is the first run, update the timestamp. We could use time(), but it might be slightly off. If we take the timestamp of a later run, it'll be later than what we got back.
	if($runs == 0 AND $diggs->timestamp != "") {
		$timestamp = $diggs->timestamp;
		$runs = 1;
	}
	$total = $diggs->total;
	print $offset."<br />";
	$offset += 100;
}
 
 
// If the timestamp isn't foobared, update the file. If there are network problems or something, this can be wrong. I don't think I've still truely fixed that, but whatever.
if(isset($timestamp) AND $timestamp != "" AND is_numeric($timestamp) AND $timestamp > 1000000) {
	$file = fopen('lastdiggs.txt','w');
	fwrite($file,$timestamp);
	fclose($file);
}
 
 
// This will change the variable to say if it inserted successfully or not, because doing ... or $inserted = true;   doesn't work. -_-
function setcheck($bool) {
	global $inserted;
	$inserted = $bool;
}
 
 
?>

Before you can use this, you need to insert some digg or something into `diggslive` with `time` set to the current timestamp. After another digg gets inserted, you can get rid of this entry.

This just gets the diggs of all the stories since the last digg we got. The timestamp is one less than the time of the last digg. This is to make sure we got the diggs that occureed at the same second as the previous one.

This also edits a file called lastdigg.txt, which is just an alternative to the sql query.

As I said earlier, the table gets big. Mine was at around 330k entries before I started running deletes. Let’s get rid of any diggs older than a day. We don’t really need them.

removediggs.p:

<?php
 
require 'config.php';
 
$query = "DELETE FROM `diggslive` WHERE `time` < ".(time() - 24*60*60)."";
mysql_query($query)or die(mysql_error());
mysql_query("OPTIMIZE TABLE `diggslive` ") or die(mysql_error());
 
?>

To keep this updated, you can run crondiggs.py. This requests your updatediggs.php file every 30 seconds.

crondiggs.py

#! /usr/bin/env python
 
url = 'http://localhost/digg/updatediggs.php'
url2 = 'http://localhost/digg/removediggs.php'
wait = 30
 
import urllib,time
 
while 1:
	try:
		print 'Requesting %s \r' % url,
		urllib.urlopen(url).read()
		if int(time.time()) % 10 == 0:
			print 'Requesting %s \r' % url2,
			urllib.urlopen(url2).read()
		print " " * (len(url)+12),'\r',
		count = 0
		while count < wait:
			print 'Waiting %d seconds \r' % (wait-count),
			count+=1
			time.sleep(1)
	except KeyboardInterrupt:
		import sys
		sys.exit(2)

Part Gamma: Tag Clouds

Now it’s time to use all this new fangled data we’re collecting, and what’s more Web 2.0 than tag clouds? And since we’re lazy, we’re going to use this tag cloud script.

First cloud set, the container cloud set. The containers are the main topics, like Technology, Science, Sports, etc.

concloud.png

concloud.php:

<?php
 
// most from: http://prism-perfect.net/archive/php-tag-cloud-tutorial/
 
// connect to database at some point
 
// In the SQL below, change these three things:
// thing is the column name that you are making a tag cloud for
// id is the primary key
// my_table is the name of the database table
 
require 'config.php';
 
$query = "SELECT container_long AS tag, COUNT(digg_id) AS quantity, container_short
  FROM diggstories
  GROUP BY container_long
  ORDER BY container_long ASC";
 
$result = mysql_query($query);
 
// here we loop through the results and put them into a simple array:
// $tag['thing1'] = 12;
// $tag['thing2'] = 25;
// etc. so we can use all the nifty array functions
// to calculate the font-size of each tag
while ($row = mysql_fetch_array($result)) {
	$shortname[$row['tag']] = $row['container_short'];
    $tags[$row['tag']] = $row['quantity'];
}
 
// change these font sizes if you will
$max_size = 250; // max font size in %
$min_size = 100; // min font size in %
 
// get the largest and smallest array values
$max_qty = max(array_values($tags));
$min_qty = min(array_values($tags));
 
// find the range of values
$spread = $max_qty - $min_qty;
if (0 == $spread) { // we don't want to divide by zero
    $spread = 1;
}
 
// determine the font-size increment
// this is the increase per tag quantity (times used)
$step = ($max_size - $min_size)/($spread);
 
// loop through our tag array
foreach ($tags as $key => $value) {
 
    // calculate CSS font-size
    // find the $value in excess of $min_qty
    // multiply by the font-size increment ($size)
    // and add the $min_size set above
    $size = $min_size + (($value - $min_qty) * $step);
    // uncomment if you want sizes in whole %:
    // $size = ceil($size);
 
    // you'll need to put the link destination in place of the #
    // (assuming your tag links to some sort of details page)
    echo '<a href="'.$shortname[$key].'" style="font-size: '.$size.'%"';
    // perhaps adjust this title attribute for the things that are tagged
    echo ' title="'.$value.' things tagged with '.$key.'"';
    echo '>'.$key.'</a> ';
    // notice the space at the end of the link
}
 
 
 
?>

That’s pretty boring though. Maybe regular categories, like Apple, Linux/Unix, Playable Web Games, etc, will be more interesting.

catcloud.png

catcloud.php

<?php
 
// most from: http://prism-perfect.net/archive/php-tag-cloud-tutorial/
 
// connect to database at some point
 
// In the SQL below, change these three things:
// thing is the column name that you are making a tag cloud for
// id is the primary key
// my_table is the name of the database table
 
require 'config.php';
require 'functions.php';
 
$query = "SELECT topic_long AS tag, COUNT(digg_id) AS quantity, topic_short
  FROM diggstories
  GROUP BY topic_long
  ORDER BY topic_long ASC";
 
$result = mysql_query($query);
 
// here we loop through the results and put them into a simple array:
// $tag['thing1'] = 12;
// $tag['thing2'] = 25;
// etc. so we can use all the nifty array functions
// to calculate the font-size of each tag
while ($row = mysql_fetch_array($result)) {
	$shortname[$row['tag']] = $row['topic_short'];
    $tags[$row['tag']] = $row['quantity'];
}
 
// change these font sizes if you will
$max_size = 250; // max font size in %
$min_size = 100; // min font size in %
 
// get the largest and smallest array values
$max_qty = max(array_values($tags));
$min_qty = min(array_values($tags));
 
// find the range of values
$spread = $max_qty - $min_qty;
if (0 == $spread) { // we don't want to divide by zero
    $spread = 1;
}
 
// determine the font-size increment
// this is the increase per tag quantity (times used)
$step = ($max_size - $min_size)/($spread);
 
// loop through our tag array
foreach ($tags as $key => $value) {
 
    // calculate CSS font-size
    // find the $value in excess of $min_qty
    // multiply by the font-size increment ($size)
    // and add the $min_size set above
    $size = $min_size + (($value - $min_qty) * $step);
    // uncomment if you want sizes in whole %:
    // $size = ceil($size);
 
    // you'll need to put the link destination in place of the #
    // (assuming your tag links to some sort of details page)
    echo '<a href="http://digg.com/'.$shortname[$key].'" style="font-size: '.$size.'%"';
    // perhaps adjust this title attribute for the things that are tagged
    echo ' title="'.$value.' things tagged with '.$key.'"';
    echo '>'.$key.'</a> ';
    // notice the space at the end of the link
}
 
 
 
?>

A little better. How about a user cloud based on submissions?

usercloud.png

usercloud.php:

<?php
 
// most from: http://prism-perfect.net/archive/php-tag-cloud-tutorial/
 
// connect to database at some point
 
// In the SQL below, change these three things:
// thing is the column name that you are making a tag cloud for
// id is the primary key
// my_table is the name of the database table
 
require 'config.php';
 
$query = "SELECT username AS tag, COUNT(digg_id) AS quantity
  FROM diggstories
  GROUP BY username
  ORDER BY username ASC";
 
$result = mysql_query($query);
 
// here we loop through the results and put them into a simple array:
// $tag['thing1'] = 12;
// $tag['thing2'] = 25;
// etc. so we can use all the nifty array functions
// to calculate the font-size of each tag
while ($row = mysql_fetch_array($result)) {
	//$shortname[$row['tag']] = $row['container_short'];
    $tags[$row['tag']] = $row['quantity'];
}
 
// change these font sizes if you will
$max_size = 250; // max font size in %
$min_size = 100; // min font size in %
 
// get the largest and smallest array values
$max_qty = max(array_values($tags));
$min_qty = min(array_values($tags));
 
// find the range of values
$spread = $max_qty - $min_qty;
if (0 == $spread) { // we don't want to divide by zero
    $spread = 1;
}
 
// determine the font-size increment
// this is the increase per tag quantity (times used)
$step = ($max_size - $min_size)/($spread);
 
// loop through our tag array
foreach ($tags as $key => $value) {
 
    // calculate CSS font-size
    // find the $value in excess of $min_qty
    // multiply by the font-size increment ($size)
    // and add the $min_size set above
    $size = $min_size + (($value - $min_qty) * $step);
    // uncomment if you want sizes in whole %:
    // $size = ceil($size);
 
    // you'll need to put the link destination in place of the #
    // (assuming your tag links to some sort of details page)
    echo '<a href="http://digg.com/users/'.urlencode($key).'" style="font-size: '.$size.'%"';
    // perhaps adjust this title attribute for the things that are tagged
    echo ' title="'.$value.' things tagged with '.$key.'"';
    echo '>'.$key.'</a> ';
    // notice the space at the end of the link
}
 
 
 
?>

Pretty big, but let’s try bigger. A user cloud based on number of diggs.

diggusercloud.png

diggusercloud.php:

<?php
 
// most from: http://prism-perfect.net/archive/php-tag-cloud-tutorial/
 
// connect to database at some point
 
// In the SQL below, change these three things:
// thing is the column name that you are making a tag cloud for
// id is the primary key
// my_table is the name of the database table
 
require 'config.php';
 
$query = "SELECT username AS tag, COUNT(digging_id) AS quantity
  FROM diggslive
  GROUP BY username
  ORDER BY username ASC";
 
$result = mysql_query($query);
 
// here we loop through the results and put them into a simple array:
// $tag['thing1'] = 12;
// $tag['thing2'] = 25;
// etc. so we can use all the nifty array functions
// to calculate the font-size of each tag
while ($row = mysql_fetch_array($result)) {
	$href[$row['tag']] = $row['href'];
    $tags[$row['tag']] = $row['quantity'];
}
 
// change these font sizes if you will
$max_size = 250; // max font size in %
$min_size = 100; // min font size in %
 
// get the largest and smallest array values
$max_qty = max(array_values($tags));
$min_qty = min(array_values($tags));
 
// find the range of values
$spread = $max_qty - $min_qty;
if (0 == $spread) { // we don't want to divide by zero
    $spread = 1;
}
 
// determine the font-size increment
// this is the increase per tag quantity (times used)
$step = ($max_size - $min_size)/($spread);
 
// loop through our tag array
foreach ($tags as $key => $value) {
 
    // calculate CSS font-size
    // find the $value in excess of $min_qty
    // multiply by the font-size increment ($size)
    // and add the $min_size set above
    $size = $min_size + (($value - $min_qty) * $step);
    // uncomment if you want sizes in whole %:
    // $size = ceil($size);
 
    // you'll need to put the link destination in place of the #
    // (assuming your tag links to some sort of details page)
    echo '<a href="http://digg.com/users/'.$key.'" style="font-size: '.$size.'%"';
    // perhaps adjust this title attribute for the things that are tagged
    echo ' title="'.$value.' things tagged with '.$key.'"';
    echo '>'.$key.'</a> ';
    // notice the space at the end of the link
}
 
 
 
?>

Great. How about a story cloud based on the number of diggs?

diggcloud.png

diggcloud.php:

<?php
 
// most from: http://prism-perfect.net/archive/php-tag-cloud-tutorial/
 
// connect to database at some point
 
// In the SQL below, change these three things:
// thing is the column name that you are making a tag cloud for
// id is the primary key
// my_table is the name of the database table
 
require 'config.php';
 
$query = "SELECT title AS tag, COUNT(digg_id) AS quantity, href
  FROM diggstories
  GROUP BY diggs
  ORDER BY diggs ASC";
 
$result = mysql_query($query);
 
// here we loop through the results and put them into a simple array:
// $tag['thing1'] = 12;
// $tag['thing2'] = 25;
// etc. so we can use all the nifty array functions
// to calculate the font-size of each tag
while ($row = mysql_fetch_array($result)) {
	$href[$row['tag']] = $row['href'];
    $tags[$row['tag']] = $row['quantity'];
}
 
// change these font sizes if you will
$max_size = 250; // max font size in %
$min_size = 100; // min font size in %
 
// get the largest and smallest array values
$max_qty = max(array_values($tags));
$min_qty = min(array_values($tags));
 
// find the range of values
$spread = $max_qty - $min_qty;
if (0 == $spread) { // we don't want to divide by zero
    $spread = 1;
}
 
// determine the font-size increment
// this is the increase per tag quantity (times used)
$step = ($max_size - $min_size)/($spread);
 
// loop through our tag array
foreach ($tags as $key => $value) {
 
    // calculate CSS font-size
    // find the $value in excess of $min_qty
    // multiply by the font-size increment ($size)
    // and add the $min_size set above
    $size = $min_size + (($value - $min_qty) * $step);
    // uncomment if you want sizes in whole %:
    // $size = ceil($size);
 
    // you'll need to put the link destination in place of the #
    // (assuming your tag links to some sort of details page)
    echo '<a href="'.$href[$key].'" style="font-size: '.$size.'%"';
    // perhaps adjust this title attribute for the things that are tagged
    echo ' title="'.$value.' things tagged with '.$key.'"';
    echo '>'.$key.'</a> ';
    // notice the space at the end of the link
}
 
 
 
?>

But wait, that doesn’t look right. That’s because we can’t use basically the same SQL query as before. It’s grouping the stories by the amount of diggs, so that if there are 3 stories with 750 diggs, and only 1 story with 751 diggs, the 3 stories will be larger. Since the weight of the story is already set as an entry, we don’t need to group it, so we can just use this SQL query:

SELECT title AS tag, diggs, href
  FROM diggstories
  ORDER BY title ASC

realdiggcloud.png

<?php
 
// most from: http://prism-perfect.net/archive/php-tag-cloud-tutorial/
 
// connect to database at some point