Lance Wicks
Kiwi,
Judoka,
Geek,
Husband
Daddy!

JudoGeek Blog

One for my wife... Aha the "literal" video. 

My wife loves this video (and secretly so do I), this video is a brilliant homage! And damned funny too.


[ view entry ] ( 2036 views ) permalink
TDD with Perl, Episode 1 - Introduction. 

Welcome to Episode one of my soon to be series of posts on becoming a test driven developer in/with Perl. Before we begin let me explain that this is not going to be a l33t uber-programmer guide; this is for people with some familiarity with writing code, with Perl and want to get better.

This series of posts has been inspired by the scary fact that if you Google PerlCritic this blog is/was the seventh entry. Which tells me that there is a lack of information out there if the small stuff I wrote is ranked so high.

So... Test Driven Development (TDD), what the heck is it?
Test Driven Development or TDD is a increasingly common phrase and idea that you need to get your head around. The concept here is that you write pieces of software that test the actual software you are writing.

The idea is that for every subroutine you write, you write a test (or several tests actually) that proves it works. In the purest methodology you write the test first, then the code. But for someone new to it, this is not realistic. That said, the sooner you start writing tests, the more sense it makes and the easier the process.

So how do you start?
That is what this series of posts is going to cover. The series of posts will (hopefully) help you begin to use TDD and appropriate tools in your development with Perl (and maybe even with other languages).

Some of the tools in you toolkit will be:
* Perlcritic
* Perltidy
* Test::More
* Test::Harness

Basically, here is what we shall be covering.
We shall start with creating a "smoketest" script, and discuss why they rock! How to build one and how it can help you. In our smoke test we will be doing things like testing your code is formatted nicely using Test::PerlTidy, testing that you are follow "Best Practices" with PerlCritic and also some other basic testing. We will also look at how you test components of your own code, etc.

Basic ideas, expressed in a basic way, to help you get started. Once you get started it gets easier and easier and your skills improve and you spend less time fixing silly problems and more on creating new features. Why? because your test suite checks everything and tells you when you have done something silly and tells you early.

So, please stay tuned and wait for the second episode in this series where we'll start building a smoke test and your basic test tool kit.



[ view entry ] ( 2997 views ) permalink
Dumb Coffee Lifehack. 

Okay, is this little hack something that just I do, or is it something that other people do too... please? ;-)

In office's the traditional tea/coffee run is a common occurance. Grab the ol' tray collect mugs and go make a bunch of teas and coffees. Now folks that have the same thing all the time are not the problem. It's those folks who have tea sometimes, coffee others.

Me I have the memory of a goldfish, so by the time I get from the office to the kitchen I can't remember what people wanted.

It is very David Allen GTD, basically I don't want to have to remember what people want. So here's how I solve my problem, not sure when I started doing it, but it saves me a few brain cells.

Basically... my simple (and stupid) hack is to organise the handles of the mugs to tell me if it's Tea or Coffee. So just point the handle of all the coffee mugs one way, tea the other. Simple, Stupid, works perfectly.




[ view entry ] ( 1829 views ) permalink
More tweaking of the Snarl Twitter script (including Identi.ca support). 

I have done a little refactoring of the script I use to pop-up messages when I get new messages from both Twitter and now Identi.ca too.

Comments on my bad scripting welcomed.

use strict;
use warnings;
use XML::Simple;
use Array::Diff;
use Data::Dumper;
use OfficeLaunch;
use IPC::Open3;
use LWP::UserAgent;

use English qw( -no_match_vars );
local $OUTPUT_AUTOFLUSH = 1;

use version; our $VERSION = qv('0.0.2');
# -----------------------------------------------------------
# parse_rss.pl
#
# Created by Lance Wicks ( www.lancewicks.com)
#
# This simple script polls Twitter and identica
# and lets you now if there are new posts via
# Snarl, using Snarl_CMD.
#
# -----------------------------------------------------------

print "Twitter & Identi.ca alerter Version:$VERSION\n\n";
my $twitter_url = 'http://twitter.com/statuses/friends_timeline/73963.rss';
my $twitter_user = 'USERNAME';
my $twitter_pass = 'PASS';
my $twitter_icon = 'c:\lwtemp\LH\twitter.png';
my $identica_url = 'http://identi.ca/lancew/all/rss';
my $identica_user = 'USER';
my $identica_pass = 'PASS';
my $identica_icon = 'c:\lwtemp\LH\speaker.png';


sub parse_feed{
my($feed,$id,$pass) = @_;
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => $feed);
$req->authorization_basic($id, $pass);
my $rss_new = $ua->request($req)->as_string;
return $rss_new;
}

sub compare_feeds{
my($old,$new,$icon) = @_;
my @old_feed = split /<item/, $old;
my @new_feed = split /<item/, $new;
my $diff = Array::Diff->diff( \@old_feed, \@new_feed );
if ($diff->count > 0){
foreach (reverse(@{$diff->added})) {
$_ =~ /<title>(.+)<\/title>/;
if ($1 =~ /^(.*?): (.*)/) {
print "\n$1\n";
my $cmd = "\"C:\\Program Files\\Snarl_CMD_0.1\\Snarl_CMD.exe\" snShowMessage 8 \"$1\" \"$2\" \"$icon\"";
my $pid = open3(my $wtr, my $rdr, my $err, $cmd);
my @response = <$rdr>;
}

}
}

}

print "Obtaining initial feeds...\n";
my $twitter_orig = parse_feed($twitter_url, $twitter_user, $twitter_pass);
my $identica_orig = parse_feed($identica_url, $identica_user, $identica_pass);


# -----------------------------------------------------
# MAIN LOOP
# -----------------------------------------------------
while(1) {
print "Pausing";
for (my $count = 200; $count >= 1; $count--) {
print ".";
sleep(1);
}
my $twitter_new = parse_feed($twitter_url, $twitter_user, $twitter_pass);
my $identica_new = parse_feed($identica_url, $identica_user, $identica_pass);

compare_feeds($twitter_orig,$twitter_new,$twitter_icon);
compare_feeds($identica_orig,$identica_new,$identica_icon);

$twitter_orig = $twitter_new;
$identica_orig = $identica_new;
}


[ view entry ] ( 5878 views ) permalink
How to add a new service to NoseRub... an eediot's Guide. ;-) 

How to add a new service to NoseRub... an eediot's Guide. ;-)



Below is a basic guide as to how to add a new service to NoseRub. By adding a new service to NoseRub you enable automatic discovery of RSS feeds and correct classification and handling of information from the new service.

This is an initial draft, so please give me your feedback. Some services will require more than this so your "mileage may vary" so to speak.

Enjoy...

To create a new service is a 4 step process.

STEP 1
Create a new file called myapp.php in /app/models/services.
You may decide to copy an existing similar service file to act as a template, for example if the service you are adding is a bookmarking service you might like to use the delicious.php file as a template for your service.
The contents of the delicious.php file are as follows:
<?php
class DeliciousService extends AbstractService {
public function detectService($url) {
return $this->extractUsername($url, array('#del.icio.us/(.+)#'));
}

public function getAccountUrl($username) {
return 'http://del.icio.us/'.$username;
}

public function getContacts($username) {
return ContactExtractor::getContactsFromSinglePage('http://del.icio.us/network/' . $username . '/', '/<a class="uname" href="\/(.*)">.*<\/a>/iU');
}

public function getContent($feeditem) {
return $feeditem->get_link();
}

public function getFeedUrl($username) {
return 'http://feeds.delicious.com/rss/'.$username;
}
}
?>

1a. You need to change the class name to MyappService
1b. Alter the detectService function so it refers to the url of your app, this is a REGEX. (This function is used to autodetect the username from an url)
1c. Alter the GetAccountUrl function so that it too knows where the username is. (This is used if you add the service and put your username, it creates an url)
1d. If the service has friends or contacts that you can connect to, alter getContacts to find contacts. If not you can remove this function.
1e. Alter getFeedUrl so that it has the correct path to the RSS feed for this new service.
Below is a example of how the myapp.php file might look:
<?php
class MyappService extends AbstractService {
public function detectService($url) {
return $this->extractUsername($url, array('#myapp.com/user/(.+)#'));
}

public function getAccountUrl($username) {
return 'http://myapp.com/user/'.$username;
}

public function getContacts($username) {
return ContactExtractor::getContactsFromSinglePage('http://myapp.com/users/' . $username . '/friends', '/<a class="Buddy" href="\/(.*)">.*<\/a>/iU');
}

public function getContent($feeditem) {
return $feeditem->get_link();
}

public function getFeedUrl($username) {
return 'http://rss.myapp.com/rss/'.$username;
}
}
?>


Step2.
Create a .GIF icon for this service and put it in the /app/webroot/images/icons/services directory. Please make it the right size etc.

Step 3.
Having created the php file you need to add an entry for this service in the NoseRub database. To ensure that everyone is able to benefit from your hard work database modifications are included in the SVN and are placed in individual files in /app/config/sql/migrations directory.
Create a SQL command similar to the one below (as a single line)
INSERT INTO `services` (`id` ,`internal_name` ,`name` ,`url` ,`service_type_id` ,`help` ,`icon` ,`has_feed` ,`is_contact` ,`minutes_between_updates` ,`created` ,`modified`)VALUES ('42' , 'Myapp', 'MyApp.com', 'http://www.myapp.com', '2', '', 'myapp.gif', '1', '0', '30', NOW( ) , NOW( ));
** The id field value (42 in this example). You need to select a unique ID, so check what services exist in the database already before choosing. You need to specify it so that the service ID will be consistent across installations.
** The internal_name field is case sensitive and is tied to the name of the class in step 1
** service_type_id. This is the type of service (bookmark, blog, picture, etc) the ID relates to the service_types table in the NoseRub database. In this example we have set the field to '2', which is a Bookmarking service.
** has_feed. Set to this is the service has a RSS feed. So in this case it does so it is set to '1'
** minutes_between_updates. This is the minimum time before noserub will check the RSS feed again. it will help prevent overloading of the service. In this example we have set it to thirty minutes.
You might want to cheat and add the record manually using something like phpmyadmin ( I know I do), you can then copy and paste the SQL command from the screen. If you do this however, be sure to edit the command so that it is one line and remove the name of your database. Also make sure you have added a ID field and it is not NULL.
Step 4.
Go to http://<server_name>/noserub/jobs ... tem/update to update the database with your new entry.

Hopefully everything is now working happily. So all there is left to do is send your changes to NoseRub.com (myapp.php and your migration SQL file).

Please also send an example username so that we can quickly test everything and get it into the code base.

*** Please note that you'll need to remove the service before you do an update from noserub.com as update will try and re add your new service and fail.




[ view entry ] ( 4995 views ) permalink

<<First <Back | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Next> Last>>