My wife says this is so me… the fact that I’m not allowed to touch her macbook says something… *big grin*
Listen to this podcast
My wife says this is so me… the fact that I’m not allowed to touch her macbook says something… *big grin*
Listen to this podcast
From Jeremy Fluhmann:
For all of you first time yapc attendees, I thought you might be interested in some of the photos from previous yapcs. I’m sure there are others, but some of the links from Flickr are:
Chicago in 2006 - http://www.flickr.com/photos/tags/yapcna2006/
Houston in 2007 - http://www.flickr.com/photos/tags/yapcna2007/
YAPC::NA in general - http://www.flickr.com/photos/tags/yapcna/
YAPC in general - http://www.flickr.com/photos/tags/yapc/And, I’m assuming that this year (as with the previous two years) someone will recommend tagging the 2008 photos with yapcna2008. I’d recommend also tagging them with yapcna and yapc.
Jeremy
Conferences Chair
The Perl Foundation
Listen to this podcast
SweeperBot is an application written by Paul Fenwick that plays Windows minesweeper for you automatically. It’s based upon code orignally written by Matt Sparks.
Get it at SweeperBot.org!
Listen to this podcast
35383: DBD::Sybase calls the broken sp_tables stored procedure
Centos 5
Linux dba-dev1 2.6.22.9-default #1 SMP Mon Oct 1 11:26:48 CDT 2007 i686
athlon i386 GNU/Linux
Perl v5.8.8 built for i386-linux-thread-multi
DBD::Sybase 1.07 but 1.08 also has the problem.
Due to Sybase CR 497173, sp_tables can not be relied upon to retrieve
table information correctly for ASE 15.
(ASE 15 stored procedure “sp_tables” doesn’t work with SQL UDFs)
We need to query the system tables instead. Obviously, the below code
would work in v12.0 and higher. A temp table could probably be used for
prior to 12.0 for the TABLE_TYPE to be filled correctly.
$ diff ../DBD-Sybase-1.07/Sybase.pm Sybase.pm
218c218
< my $sth = $dbh->prepare(”sp_tables $table, $schema, $catalog,
$type”);
—
$type”);
219a220,238
> my $sth = $dbh->prepare( q{
> select TABLE_QUALIFIER = db_name()
> , TABLE_OWNER = u.name
> , TABLE_NAME = o.name
> , TABLE_TYPE =
> case o.type
> when “U” then “TABLE”
> when “V” then “VIEW”
> when “S” then “SYSTEM TABLE”
> end
> , REMARKS = NULL
> from sysobjects o
> , sysusers u
> where o.type in (’U', ‘V’, ‘S’)
> and id >99
> and o.uid = u.uid
>
> });
>
Listen to this podcast
Centos 5
Linux dba-dev1 2.6.22.9-default #1 SMP Mon Oct 1 11:26:48 CDT 2007 i686
athlon i386 GNU/Linux
Perl v5.8.8 built for i386-linux-thread-multi
SQL::Translator::0.09000
Sybase ASE will often store the SQL text for stored procedures and views
with the carriage return embedded (\r). We need to strip that out else
we will receive “^M” in the output.
Sybase_orig.pm Sybase_new.pm
108a109
109a111,112
155a159,161
> $stuff->{procedures}->{$_->[0]}->{text} =~ s/\r//g
> if (defined ($stuff->{procedures}->{$_->[0]}->{text} ));
>
Listen to this podcast
35380: SQL::Translator::Parser::DBI::Sybase fails when sp_helpindex is empty
Centos 5
Linux dba-dev1 2.6.22.9-default #1 SMP Mon Oct 1 11:26:48 CDT 2007 i686
athlon i386 GNU/Linux
Perl v5.8.8 built for i386-linux-thread-multi
SQL::Translator::0.09000
Sybase ASE’s sp_helpindex will normally return a result set containing
the column “INDEX_NAME” which parse() requires. When no index exists,
sp_helpindex returns a error string similar to “Object does not have any
indexes.” but no result set.
The following workaround simply wraps the selectall_hash with an eval,
if the eval results in no error, then try to use the hash.
Listen to this podcast
I’m working on a Historical Server replacement. I need to check with my employer as to whether I can open source it or not but the guts of it consist of:
All of this goes into a VMWare Appliance running Ubuntu 7.10 Server… a drop-in solution that can even be run on a laptop. I’m hoping that my employer lets me release it as then I can zip it up and put it on sourceforge so everyone can benefit.
Listen to this podcast
This came over the wire from twitter:
Sterling Hanenkamp wrote a great response to the now-infamous TIOBE Index article about how Perl is on its way out. This article is the sort of thing I wish I’d done when I was doing PR for The Perl Foundation. Sterling’s given me permission to republish it here. Here’s a link to the original. — Andy (Lester)
I’ve been taking DDJ for a couple years now. It’s cheap and occasionally has something interesting in it, but it’s been less interesting than I remember it being when I read it in college. I’ve been much more enamored with the Communciations of the ACM. Today, I received my issue and there’s an interview with Paul Jansen of TIOBE Software.
Listen to this podcast
This year’s Flourish Conference was held at the University of Illinois in downtown Chicago (UIC). The Flourish web site describes Flourish as: 
The goal of the Flourish Conference is to promote the use and adoption of Free Libre Open Source Software (FLOSS) by demonstrating the practical applications of FLOSS in the business and academic world. While everyone is familiar with businesses that focus on creating non-free proprietary software, the same cannot be said for those who specialize in developing and supporting FLOSS software, and an Open Culture.
I missed a part of Bruce Perens’ Innovation Goes Public presentation due to
Chicago’s closing several sidewalks that go over or under the tristate. I’m not quite sure I agree with him that the road a head for open source is all rosey. Perhaps I misunderstood him but it seemed to me that the idea of simply giving the source of an application to the public would allow the programmers to still be paid via the support/service agreements. This may work for some applications, but for others there wouldn’t be a sufficient number of support contracts to financially support the programmers Personally, I prefer open source but I will also pay for commercial proprietary software. I use what works.
The company I work for, Sungard Investment Systems, uses open source for many internal projects. One such product uses VMware and Linux for a
portable monitoring system so I was highly interested in rBuilder Online from rPath. I attended the Appliance Development and Conary session presented by Stephanie Watson from rPath. I’m currently investigating on how well and easy it is to make a VMware appliance that would house a Sybase ASE server (DBMS) with no unnecessary os files. If the testing turns out well, I will ask my fellow Sybase ASE DBAs whether Sybase need certify it or whether we are ‘on our own’. The monitoring machine itself really doesn’t need Sybase ASE on it but since we have the license….
Dr. John Waclawsky, from Motorolla, gave a feel good presentation about the state of communication between wireless gadgets. The Revolution at the Edge of the Network Abstract. Short version: things are going to get very interesting in the next year
James Gray, from IBM, presented IBM’s Open Source Strategy - Turning Threat into Opportunity. While
essentially a case study of how IBM has interacted as a semi-liason between the business executives and the open source community. IBM, to me, has seemed to be stuck in a love/hate relationship with open source and a dislike/hate relationship with the Free Software Foundation. That being said, it is necessary to give IBM credit giving credence to the open source community with the business executives. The IT folks no longer had to quietly use open source in the business but were free to use it extensively in many places. Linux, in particular, is no longer the wild west in many CTOs’ eyes but a integral part of their business. 
I met Tony Wong in the Chicago Perl Mongers ‘booth’. We discussed the upcoming Yet Another Perl Conference (YAPC::NA 2008) that is being held in Chicago and the horrible documentation of the Catalyst MVC web framework. I informed him that the only way to learn Catalyst was the new book Catalyst by Jonathan Rockway (ISBN: 978-1-847190-95-6). I also warned him that the book should have gone through another round of proofreading prior to being published due to excessive example code errors, etc. I playfully suggested that Joshua McAdams be tormented because he wasn’t able to make it Friday morning.
The panel discussion on Friday afternoon was highly entertaining and a bit of a kangaroo court for Bobby
Moore of Microsoft. I do not believe Mr. Moore was expecting Bruce Perens to repeatedly ask very pointed and informed questions. Moore did an excellent job of remaining cool and listening with an open mind to the criticism of Microsoft as a company. He explained that, yes, Microsoft did some not so nice things in the past but they are attempting to work with the open source community. Bruce Perens, Jon “Maddog” Hall, and James Bottomley brought up the pending MS Office OpenXML standard format issue where much of the format is proprietary and the published format won’t actually be used by Microsoft.
Moore conceded that it was unlikely that Microsoft would use the published format as-is but the Office developers would likely base the actually used format off of the published format. Perens, Hall, Bottomley and James Gray all expressed their opinions that this was very typical of Microsoft. (side note: Microsoft has been accused of having the attitude of Embrace, Extend, Eliminate when it comes to industry standards.)
Perens, Hall and James Bottomley, as well as members of the audience, pummeled both James Gray of IBM and Bobby Moore of Microsoft for their companies’ approach and support of software patents.
Unfortunately, I was only able to attend the first day as my mother was in town from North Dakota to visit my three month old daughter (and the rest of us). If only I could have cloned myself… Don’t forget to check out the Flickr photo group for the Flourish 2008 Conference in Chicago!
Listen to this podcast
I’ve looked on Yahoo, Google, CPAN and on Perlmonks to no avail. I’m wanting to access my Yahoo Calendar from Perl so I can manipulate it, sync it, etc. So far, I’ve only found commercial or shareware applications that can access the calendar. Has anyone done this or know of a non-perl sdk I can look at to write a perl sdk to do it?
Listen to this podcast
From use Perl:
Open enrollment Perl classes in April in Chicago
Journal written by brian_d_foy (44) and posted by brian_d_foy on 2008.02.15 2:51
Stonehenge is offering open-enrollment Perl classes in downtown Chicago in April. These are the full Stonehenge courses in a slightly compressed-time format that we offer to the public only a couple times a year:
* Beginning Catalyst with Jon Rockway, April 14-15, 9am to 5pm, $500
* Test Driven Development with Josh McAdams, April 14-15, 6pm to 9pm, $250
* Learning Perl with brian d foy, April 16-18, 9am to 5pm, $750
We can also take purchase orders and alternate payment methods for any of there. We can also offer team discounts for people from the same group paying at the same time. Write to me (brian@stonehenge.com) with any questions about the classes.
Listen to this podcast
If you’ve ever tried to back up your Flickr account or download the public Flickr photos of other users, then your options were pretty limited on Linux. After trying and failing to get FlickrDown to work under wine, I decided to write my own… in perl
The various Flickr API’s on CPAN are incomplete with respect to obtaining the list of public/friends photos. I had to use XML::Parser::Lite::Tree::XPath to extract the photos from each Flickr page.
By default, we obtain the largest photo available (orginal -> large -> medium -> small), populate the EXIF comments field with the Flickr photo title, description and url. We verify the file type with File::MimeInfo::Magic and change/add the file extension as necessary.
During testing I received numerous duplicate files which were mostly resolved by adding a rudimentary duplicate file checker.
It should work on just about any platform that Perl does.
Thoughts?
FlickrDownload.pl
FlickrDownload.pl
use strict;
use warnings;
use Digest::MD5 qw(md5_hex);
use Config::Simple;
use Image::ExifTool;
use File::MimeInfo::Magic qw(mimetype extensions);
use Flickr::API::Photos;
use Flickr::Person;
use Getopt::Std;
use HTML::Entities ();
use File::MimeInfo::Magic;
use IO::Scalar;
use LWP;
use Tie::File::AsHash;
use XML::Parser::Lite::Tree::XPath;
##############################
my $cfg = new Config::Simple(‘FlickrDownload.ini’);
my $user_name;
my $id;
my $email;
my %arg_options;
my $photo_directory;
my $found;
getopts(‘e:i:u:’, \%arg_options);
$user_name = $arg_options{u};
$id = $arg_options{i};
$email = $arg_options{e};
my $flickr_api_key = $cfg->param(‘Flickr.API_KEY’);
my $flickr_secret = $cfg->param(‘Flickr.API_SHARED_SECRET’);
my $flickr_email = $cfg->param(‘Flickr.email’);
my $flickr_password = $cfg->param(‘Flickr.password’);
##############################
sub decode_html {
my $string = shift;
my $new_string = HTML::Entities::decode($string);
if ($string ne $new_string) {
$new_string = decode_html($new_string);
}
return $new_string;
}
##############################
my $flickr_person = Flickr::Person->new( {
api_key => $flickr_api_key,
email => $flickr_email,
password => $flickr_password
} );
if ($user_name) {
$found = $flickr_person->find( { username => $user_name } );
} elsif ($email) {
$found = $flickr_person->find( { email => $email } );
$user_name = $flickr_person->username();
$found = $flickr_person->find( { username => $user_name } );
} elsif ($id) {
$found = $flickr_person->id( {id => $id} );
$user_name = $flickr_person->username();
$found = $flickr_person->find( { username => $user_name } );
}
if ( $found ) {
my $page_num = 1;
my $more_pages = 1;
my $api = $flickr_person->{people_api}->{api};
$photo_directory = $cfg->param(‘Photos.directory’) . "/" . $user_name;
$api->{api_secret} = $flickr_secret;
my $flickr_photos = Flickr::API::Photos->new(
$flickr_api_key,
$flickr_email,
$flickr_password);
unless (-d $photo_directory) {
mkdir $photo_directory
or die (‘Unable to create directory "’ . $photo_directory . ‘"’ );
}
# for determine whether we might be downloading a duplicate, we need a hash with
# the MD5 sum & filename. We tie both hashes to a file in the flickr user’s
# directory
tie my %MD5_HASH, ‘Tie::File::AsHash’, $photo_directory . "/.md5s", split => ‘:’
or die "Problem tying %hash: $!\n";
tie my %FILES_HASH, ‘Tie::File::AsHash’, $photo_directory . "/.files_md5s", split => ‘:’
or die "Problem tying %hash: $!\n";
while ($more_pages) {
my $response = $api->execute_method(‘flickr.people.getPublicPhotos’, {
api_key => $flickr_api_key,
user_id => $flickr_person->id,
per_page => 500,
page => $page_num
} );
my $xpath = new XML::Parser::Lite::Tree::XPath($response->{tree});
my @nodes = $xpath->select_nodes(‘/photos/photo’);
if ($#nodes > 0) {
foreach my $node (@nodes) {
my $original_photo;
my $photo_id = $node->{attributes}->{id};
my $photo_hash = $flickr_photos->getInfo($photo_id);
my $photo_title =
$photo_hash->{‘title’}
? $photo_hash->{‘title’}
: "";
my $description =
$photo_hash->{‘description’}
? decode_html( $photo_hash->{‘description’} )
: "";
my %photo_sizes =
map { $_->{‘label’} => $_ }
@{ $flickr_photos->getSizes($photo_id)->{sizes} };
if (exists $photo_sizes{‘Original’}) {
$original_photo = $photo_sizes{‘Original’};
} elsif (exists $photo_sizes{‘Large’}) {
$original_photo = $photo_sizes{‘Large’};
} elsif (exists $photo_sizes{‘Medium’}) {
$original_photo = $photo_sizes{‘Medium’};
} elsif (exists $photo_sizes{‘Small’}) {
$original_photo = $photo_sizes{‘Small’};
} else {
warn "Unable to find url. Skipping photo."
}
printf "name: %s id: %s description: %s\n",
$photo_title,
$photo_hash->{‘id’},
$description;
my $photo_filename = $photo_directory . ‘/’ . $photo_title;
$photo_filename =~ s/\.\w+$//;
# Prepopulating the file extension will allow us to eliminate
# the vast majority of duplicate images by not downloading
# them in the first place.
if (exists $photo_hash->{‘originalformat’}) {
my $extension = $photo_hash->{‘originalformat’};
$photo_filename .= "_" . $photo_hash->{‘id’} . "." . $extension;
} else {
# if we don’t know at this point what format the image file is
# without downloading the image, we can assume it is a jpg
# because the vast majority of the photos are jpg.
$photo_filename .= "_" . $photo_hash->{‘id’} . ".jpeg";
}
if (-f $photo_filename && (stat($photo_filename))[7] > 2048) {
printf "We already have photo %s .. Skipping\n", $photo_title;
} else {
my $FH;
my $request = HTTP::Request->new(GET => $original_photo->{’source’} );
my $response = $api->request($request);
my $md5_sum = md5_hex($response->content);
# since we have downloaded the photo, let’s put the proper file
# extension on it.
if (my $file_ext = extensions( mimetype(new IO::Scalar \($response->content) ) ) ) {
$photo_filename =~ s/\.\w+$//;
$photo_filename .= "." . $file_ext;
}
if (exists $MD5_HASH{$md5_sum}) {
printf "We already have photo %s .. Skipping\n", $photo_title;
} else {
$MD5_HASH{$md5_sum} = $photo_filename;
$FILES_HASH{$photo_filename} = $md5_sum;
open($FH, ">", $photo_filename)
or warn ("Unable to write to $photo_filename.\n" );
binmode $FH;
print $FH $response->content;
close $FH;
# We’re going to use Image::ExifTool instead of the built in
# exif extracted information from Flickr::API::Photos because
# we want to write to the file.
my $exifTool = new Image::ExifTool;
my $info = $exifTool->ImageInfo($photo_filename);
unless ($info->{‘DateTimeOriginal’}) {
if ($photo_hash->{‘dates’}->{‘taken’}) {
my $taken_date = $photo_hash->{‘dates’}->{‘taken’};
$taken_date =~ s/\-/\:/g;
$exifTool->SetNewValue("DateTimeOriginal", $taken_date);
}
}
$exifTool->SetNewValue("Comment", $photo_title . ": " . $description . " " . $original_photo->{’source’});
my $result = $exifTool->WriteInfo($photo_filename);
}
}
}
$page_num++;
} else {
$more_pages = undef;
}
FlickrDownload.ini
[Photos]
# where you want to put the photos
directory=/home/jason/flickr
Listen to this podcast
From my email archives:
I was reading Higher Order Perl (ISBN 1-55860-701-3) last night at the local coffee shop while my fiancee had her knitting circle meeting when I discovered ‘dispatch tables’. While I have run across them while writing the various chat bots (Net::IRC), I didn’t actually put 2 and 2 together and realize that they were called dispatch tables. Back in North Dakota State University, we called them something else which I don’t remember. lol .. anyways, I quick overview:
Dispatch Tables
File to be read:
VERBOSITY 8
LOGFILE /home/froebeja/log/potatoes_on_steroids.log
CONFIG_FILE /home/froebeja/conf/potatoes_on_steroids.cfg
LOCAL_CONFIG /usr/local/app/sybase/conf/potatoes_on_steroids.cfg
Traditional readConfig() function:
DISPATCH TABLE implementation
The real advantage is when dealing with dozens, hundreds or thousands of items where an operation has to be performed. Instead of a massive if/else structure, the problem is nicely broken up into manageable bite sizes. This makes design and maintenance a lot easier.
Thought I would share this little tidbit.
Listen to this podcast
Back in March 2007, I consolidated the known list of Yet Another Perl Conference (YAPC) videos, MP3s, and podcasts.
I recently rediscovered the YAPC NA 2006 podcast and asked on Perlmonks if anyone had information on other videos, MP3s or podcasts that might be available:
cog: YAPC on Google Video, YAPC 2005 archive and YAPC::NA 2006 Video Presentations
lin0: YAPC::Europe 2002 has the proceedings and some movies available online. YAPC::Europe 2001 has some material available also. YAPC::Asia 2006 has some videos, slides, and audio files available online.
We’re now updating the list with videos from this year’s YAPC::Europe 2007.
Videos
In the meantime we managed to upload all video coverage to youtube.com:
- Day 0: The Preconf Meeting http://www.youtube.com/watch?v=4gXSXBiXVb4
- Day 1: http://www.youtube.com/watch?v=dXmKDkAAamc
- Day 2: http://www.youtube.com/watch?v=bUXSml6O_48
- Attendees Dinner: http://www.youtube.com/watch?v=h4egvmo8yIU
- Day 3: The Lightning Talks http://www.youtube.com/watch?v=scNqJ6OateM
- Day 3: http://www.youtube.com/watch?v=y3CGZSnBds0 (there’s a typo at the end which I cannot correct, because my external USB disk where the videos are stored on broke (iterally, the USB plug broke off the curcuit board…)
There are more videos available, tagged with yapceu07: http://www.youtube.com/results?search_query=yapceu07
Listen to this podcast
In the post Adding TCP Keepalive Support to DBD::Sybase perl module, I describe a patch that I submitted to Michael Peppler for his Perl DBD::Sybase driver. While he implemented it in DBD::Sybase version 1.08, I didn’t mention that for Linux distributions, TCP Keepalive is disabled by default for processes. That means, any application that is to use TCP Keepalive, must be specially built for it or wrapper code must be used.
In order to modify the system settings for TCP Keepalive on Linux, you need to make a change to your /etc/sysctl.conf file and then run /sbin/sysctl -p:
Listen to this podcast
git for Perl projects?
I recently listened to Randal Schwartz‘ (aka merlyn) and Leo Laporte’s podcast interview with Junio Hamano, maintainer of the git version control system, on FLOSS weekly episode 19. Mr. Schwartz revealed that he is using git for his source code management, either directly (”anything I get to choose, I use git”), or as a front-end to CVS or Subversion through git’s interface layers (”they don’t know I’m using git”).
I was intrigued by some of the features of git, for instance the ability to track the child-parent relationship for every commit using cryptographic hashes.
I’ve been using CVS up until now, but the way it prevents moving and renaming files makes me want to consider alternatives. Until I heard the above podcast that alternative has been Subversion only.
The Perl projects I work on are neither very large nor distributed. Should I consider git as my future SCM for Perl projects? What are the Monks’ experience with using git in Perl projects?
–
Andreas
Andreas brings up an interesting question: What should we use for Perl development. I replied to Andreas with:
Re: git for Perl projects?
by jfroebe on Sep 28, 2007 at 21:24 GMT-6For the most part, it really doesn’t matter which version control system you use. Think about it.. for most open source or even commercial projects, you have a small number of developers that are active on the project. Usually in the single digits. The level of sophistication required of the version control system isn’t pretty high - checkout/checkin/comment/etc. It isn’t until you have a lot more developers, a very complex project, or some other thing. Using CVS, Subversion, GIT, rcs, or even SCCS will work fine for most projects.
GIT is just the revision control system flavor of the week for primarily the Linux kernel developers. If you want to use it, do so. If not, don’t worry about it. Use what feels comfortable to you.
hope this helps,
Jason L. Froebe
Listen to this podcast
In How to read batches of SQL from a file in Perl, we learned how to read a SQL file and extract individual batches and created the Perl module dbS::Sybase::Parse::SQL_File. In How to colorize your code using Perl and Syntax::Highlight::Engine::Kate, we learned how to make HTML highlighted arbitrary code and created Perl module dbS::misc. Finally, in Sending email with attachments from Perl - the easy way, we learned how to send email with attachments and created Perl module dbS::EMail.
Now, we are going to tie them all together so we can send ourselves colorized SQL code and a screenshot of an application going screwy!
use strict;
use warnings;
use File::Basename;
use dbS::EMail;
use dbS::misc;
use dbS::Sybase::Parse::SQL_File;
our $PROC = basename($0);
$|++;
my $message = "";
if ( my $sql_batch = dbS::Sybase::Parse::SQL_File::get_batch("/dbms/sybase/ASE-15_0/scripts/installmontables", undef, 1) ) {
while (my $query = $sql_batch->next ) {
$message .= $query;
&nb