Brightkite maps with Sweetcron

I've gotten a few pings on how I generate the maps for my Brightkite entries in my lifestream with Sweetcron. It's pretty simple and straight forward. Looking out on the Google group for Sweetcron, I see that no one really shared what they had done in the past, so here's my implementation. You'll need to get a Google Maps API Key for this to work on your site. If you don't already have one, you can get one here.

First things first. For some reason (I haven't had a chance to dig into it yet) Sweetcron won't import a BK feed directly (at the time of this entry). To work around this just run your BK feed through Feedburner, and then use that as the feed URL in Sweetcron.

Secondly, we'll need to pull some additional information when Sweetcron pulls in the feed. To accomplish this one, we'll create a new class. You can download the class here or just copy out the code below. To install this, simply drop it into your system/application/plugins directory. Make sure to edit the file and update your GOOGLE_MAPS_API_KEY for image generation. (You'll also want to rename the extension from .phps to .php if you download it.)

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
 
/**
 * @todo: Change these to match your setup
 */
define('GOOGLE_MAPS_API_KEY', '!!CHANGE THIS TO YOUR GOOGLE MAPS API KEY!!');
define('IMG_SIZE_CHECKIN', '230x200');
define('IMG_SIZE_MESSAGE', '230x100');
 
/**
 * Namespaces that we'll be working with
 */
define('NS_GEORSS', 'http://www.georss.org/georss');
define('NS_BKITE', 'http://brightkite.com/placeFeed');
define('NS_MEDIA', 'http://search.yahoo.com/mrss');
 
/**
 * Simple Brightkite class for Sweetcron
 */
class Brightkite_com {
 
	function pre_db($item, $original)
	{
		// First let's pull out the GeoRSS
		$_coords = $original->get_item_tags( NS_GEORSS, 'point');
		$_name = $original->get_item_tags( NS_GEORSS, 'featurename' );
 
		// Pull the BrightKite Feed info
		$_placelink = $original->get_item_tags( NS_BKITE, 'placeLink');
		$_type = $original->get_item_tags( NS_BKITE, 'eventType');
 
		// Convert to something we can use
		// @todo: Find another way to do this, SimplePie should include a default way.
		list( $lat, $long ) = split( " ", $_coords[0]['data'] );
		$name = $_name[0]['data'];
		$type = $_type[0]['data'];
 
		// Populate data to be saved along with the item.
		$item->item_data['geo']['name'] = $name;
		$item->item_data['geo']['lat'] = $lat;
		$item->item_data['geo']['long'] = $long;
		$item->item_data['bk']['placelink'] = $_placelink[0]['data'];
		$item->item_data['bk']['type'] = $type;
 
		// Check to see what type of pose this is.
		// $type will be set to one of 'photo', 'message', or 'checkin'
		if ( $type == "photo" ) {
			$_caption = $original->get_item_tags( NS_BKITE, 'photoCaption');
			$_imglink = $original->get_item_tags( NS_BKITE, 'photoLink');
 
			$imglink = $_imglink[0]['data'];
 
			$item->item_data['bk']['caption'] = $_caption[0]['data'];
			$item->item_data['bk']['imglink'] = $imglink;
		}
		elseif ( $type == "message" ) {
			// @todo: Figure out why SC doesn't pull this by default.
			$item->item_data['description'] = $original->get_description();
		}
		elseif ( $type == "checkin" ) {
			// Don't need any additional info.  It's just a checkin.
		}
 
		return $item;
	}
 
	function pre_display($item)
	{
		// Generate the URL for our image
		$mapimg = 'http://maps.google.com/staticmap?center=';
		$mapimg .= $item->item_data['geo']['lat'] . ',' . $item->item_data['geo']['long'];
		$mapimg .= '&zoom=12&sensor=false&markers=';
		$mapimg .= $item->item_data['geo']['lat'] . ',' . $item->item_data['geo']['long'];
		$mapimg .= '&key=' . GOOGLE_MAPS_API_KEY . '&size=';
 
		// Make sure to choose the correct size for the image
		if ( $item->item_data['bk']['type'] == "message" ) {
			$item->item_data['gmapimg'] = $mapimg . IMG_SIZE_MESSAGE;
		} else {
			$item->item_data['gmapimg'] = $mapimg . IMG_SIZE_CHECKIN;
		}
 
		return $item;
	}
}
?>

So what does this class give us? It gives us access to all of the GeoRSS information along with some extras that we can use in our _activity_feed.php. The following are now available to you in _activity_feed.php in your theme:

/**
 * Returns 'type' of BK entry
 * This will be 'photo', 'message', or 'checkin'
 */
$item->item_data['bk']['type'];
 
/**
 * For type 'photo'
 */
 
// URL to image
$item->item_data['bk']['imglink'];
// Caption for image
$item->item_data['bk']['caption'];
 
/**
 * For type 'message'
 */
 
// Text of our note that we posted
$item->item_data['description']
 
/**
 * For all types
 */
 
// Link to Brightkite object
$item->item_data['bk']['placelink'];
// Place Name
$item->item_data['geo']['name'];
// Google map image URL
$item->item_data['gmapimg'];

So if you're still wondering how to use this at this point, pretty simple. You just need to modify your _activity_feed.php file (located in your theme directory) to handle the additional data. Here's the loop in mine that builds my lifestream:

// ...
 
<?php elseif ($item->get_feed_domain() == 'brightkite.com'): ?>
 
	<?php if ( $item->item_data['bk']['type'] == 'photo' ): ?>
 
		<p class="activity_image_text">
			<a href="<?php echo $item->get_permalink(); ?>/<?php echo $item->get_name(); ?>">
				<?php echo $item->item_data['bk']['caption']; ?>
			</a>
			<span class="activity_image_content"></span>
		</p>
		<span class="type_label photo"></span>
		<a class="activity_image" href="<?php echo $item->get_original_permalink(); ?>" style="background: url(<?php echo $item->item_data['bk']['imglink']; ?>) center no-repeat;"></a>
 
	<?php elseif ( $item->item_data['bk']['type'] == 'message' ): ?>
 
		<a href="<?php echo $item->item_data['bk']['placelink']; ?>">
			<img class="bkite_note" alt="<?php echo $item->item_data['geo']['name']; ?>" src="<?php echo $item->item_data['gmapimg']; ?>">
		</a>
		<span class="type_label regular"></span>
		<div class="inner_container">
			<p class="bkite">"<?php echo $item->item_data['description']; ?>"</p>
		</div>
 
	<?php elseif ( $item->item_data['bk']['type'] == 'checkin' ): ?>
 
		<p class="checkin">
			<a class="checkin" href="<?php echo $item->item_data['bk']['placelink']; ?>">
				<img alt="<?php echo $item->item_data['geo']['name']; ?>" src="<?php echo $item->item_data['gmapimg']; ?>">
			</a>
			Checked in @ <a href="<?php echo $item->item_data['bk']['placelink']; ?>"><?php echo $item->item_data['geo']['name']; ?></a>
			<br>
		</p>
 
	<?php endif; ?>
 
<?php elseif (!$item->feed_id): ?>
 
// ...

This is obviously not the only way to do it, nor the best, but just the way I have it running here. Have fun!

 
 

Cisco Mobile Supervisor

While the Cisco Mobile Supervisor Application has been out for over a month now for the iPhone/iPod Touch, my site was down, and I didn't get to post about it, so I'm doing it now, as a few people have been asking me about it, and wanting to see a few of the screens.

Mobile Supervisor provides a pretty basic interface to monitor the call center, and it's a free download from the App Store. While most call centers that I've done in the past use some sort of wall board for this type of functionality, from a Supervisors standpoint this is still pretty neat when sitting in meetings all day away from the call center. (Of course, if you have a laptop, you can still just fire up CSD there, but if you've got an iPhone, why wouldn't you geek out and do this?!)

Once you've downloaded the app, you configure it from the iPhone Settings screen. Scroll to the bottom and the configuration will show up along with your other apps. You'll need to fill out your UCCX server information here and as you can see, the app does support HA deployments. You can also setup your thresholds for "alert" status on the screens: (Click on any of the thumbnails for a larger image.)

iPhone-Settings.jpgiPhone-Settings-2.jpgiPhone-Settings-3.jpg

Upon launch of the application, you'll need to login to your UCCX server (Don't worry, it will remember your login between sessions):

iPhone-App Screen.jpgiPhone-MS-Screen2.jpgiPhone-MS-Screen3.jpg

Once you're logged in, you'll see your teams listed that you're configured for. Under each of those, you'll be able to break down into the CSQs, or individual agents. My one complaint here is that even if agents are not logged into the system, it still shows all of them.

iPhone-MS-Screen4.jpgiPhone-MS-Screen5.jpgiPhone-MS-Screen12.jpg

Under the CSQs, you can get the same information that you could from the Supervisor Desktop:

iPhone-MS-Screen6.jpgiPhone-MS-Screen7.jpgiPhone-MS-Screen8.jpgiPhone-MS-Screen9.jpgiPhone-MS-Screen11.jpg

Overall, cool little app. Not sure that it will see a lot of use out in the field (as I don't know of a lot of call center supervisors running around with iPhones), but I love the fact that Cisco is actually putting out these types of apps for their users.

Cisco's Quick Start Guide can be found here and their video datasheet for Mobile Supervisor can be found here (no iphone demo in the video).

 
 

Progressing slowly

Sorry to the one or two people who actually visit my site about the (seemingly) lack of progress here lately. I actually have been working on the site. (No - really! I have!) I've just been trying to get things to a point that I might even leave alone for a few years aside from upgrades required due to Habari changes.

My lifestream is now up and semi-operational. (There's still a few tweaks to the theme that I need to finish up.) I went back and forth on this one a few times about writing my own plugin, or fixing the existing lifestream plugin. Needless to say, I couldn't come up with a really functional way of doing it that just seemed to flow. So, I went ahead and installed SweetCron to manage it.

I've also been writing up a few plugins for use here. Once I get them done, I'll put them up to the projects page. The now playing plugin to your right in the sidebar is one of them.

 
 

Excuse the mess

As is normal for me, instead of just cleaning up my theme, I've gone ahead and started on changing everything instead. (The site's needed a face lift for quite some time.) If you're stopping by and catch a strange filler post, or something looking completely crazy, don't worry about it. It's just me working on the site layout.

I've got it to a point that I'm just going to leave up the new layout now. All that's left at this point are a few tweaks here and there. RIP to the old theme. :( <sniff>I'll miss you...</sniff>

Old Header

And as I *just* found out. Things might look just a little bit off for a bit. I'm disabling Habari's autop function for the time being until I can find out what all it will actually break for validation.

Update: I've gone ahead and changed the DOCTYPE here to be HTML 5 for the mean time and turned back on autop. I'll have to dig into this one a bit later. If you check the validation it seems to have no issue with the self closing tags that XHTML uses.

 
 

I'm back... Somewhat

I'm back! Sort of. I'm still in the process of setting things up around here. I've moved the site over to Media Temple for hosting (no longer hosted from my basement). I know the old placeholder was up forever, but there was a lot going on in real life for me. No. Really. There was! I got married! Ever since then, work's been insanely busy.

I won't be moving over any of the old article content as most of it is dated at this point. Anything that was considered personal content is most likely going to be moved somewhere else. (4/16: I keep going back and forth on this one.) So, if you're looking for IP Phone backgrounds, I'll put those pages back up soon. If you're here looking for the Habari XMPP Plugin, you can find it in the habari-extras repository. The help pages have been moved to the wiki and you can find them here.

As I'm starting from scratch again, if you have anything that you want to see as far as specific articles, let me know. I'll add it to my list.