<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Bill Ruppert</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/" />
    <link rel="self" type="application/atom+xml" href="http://www.billruppert.com/atom.xml" />
    <id>tag:www.billruppert.com,2009-04-17://4</id>
    <updated>2011-11-25T12:11:23Z</updated>
    <subtitle>Perl programming and whatever.</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.37</generator>

<entry>
    <title>Load an Access database</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/2011/11/load-an-access-database.html" />
    <id>tag:www.billruppert.com,2011://4.81</id>

    <published>2011-11-25T12:02:50Z</published>
    <updated>2011-11-25T12:11:23Z</updated>

    <summary>Here is a stripped down script to load a Microsoft Access database table using Win32::ODBC. This loaded about 100k rows per minute on my machine, which is WinXP, Access 2003, Active State Perl 5.8.8 and a Core 2 6600 processor...</summary>
    <author>
        <name>Bill Ruppert</name>
        <uri>http://www.billruppert.com</uri>
    </author>
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Script" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.billruppert.com/">
        <![CDATA[Here is a stripped down script to load a Microsoft Access database table using Win32::ODBC.  This loaded about 100k rows per minute on my machine, which is WinXP, Access 2003, Active State Perl 5.8.8 and a Core 2 6600 processor at 2.4GHz.

<pre><code>
use strict;
use warnings;

use Win32::ODBC;

$| = 1;

my $dsn = "LinkManagerTest";
my $db = new Win32::ODBC($dsn)
    or die "Connect to database $dsn failed: " . Win32::ODBC::Error();

my $rows_added = 0;
my $error_code;

while (&lt;&gt;) {
    chomp;

    print STDERR "."     unless $. % 100;
    print STDERR " $.\n" unless $. % 5000;

    my ($source, $source_link, $url, $site_name) = split /\t/;

    my $insert = qq{
        insert into Links (
            URL,
            SiteName,
            Source,
            SourceLink
        )
        values (
            '$url',
            '$site_name',
            '$source',
            '$source_link'
        )
    };

    $error_code = $db-&gt;Sql($insert);

    if ($error_code) {
        print "\nSQL update failed on line $. with error code $error_code\n";
        print "SQL statement:\n$insert\n\n";
        print "Error:\n" . $db-&gt;Error() . "\n\n";
    }
    else {
        $rows_added++;
    }

    $db-&gt;Transact('SQL_COMMIT') unless $. % 1000;
}

$db-&gt;Transact('SQL_COMMIT');
$db-&gt;Close();

print "\n";
print "Lines Read: $.\n";
print "Rows Added: $rows_added\n";

exit 0;
</code></pre>]]>
        
    </content>
</entry>

<entry>
    <title>Resources for Learning Perl</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/2011/10/resources-for-learning-perl.html" />
    <id>tag:www.billruppert.com,2011://4.80</id>

    <published>2011-10-26T13:18:53Z</published>
    <updated>2011-10-26T13:45:15Z</updated>

    <summary><![CDATA[Gabor Szabo just wrote a Learning Perl&nbsp;post on the issue of how beginners find good Perl learning materials. &nbsp;He suggested linking to some good material, so here we go.First up is&nbsp;Perl.org's&nbsp;own Learn Perl page. &nbsp;Lots of good starting info there.Next...]]></summary>
    <author>
        <name>Bill Ruppert</name>
        <uri>http://www.billruppert.com</uri>
    </author>
    
        <category term="General" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="learning" label="Learning" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perl" label="Perl" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="programming" label="Programming" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="tutorial" label="Tutorial" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-us" xml:base="http://www.billruppert.com/">
        <![CDATA[Gabor Szabo just wrote a <a href="http://blogs.perl.org/users/gabor_szabo/2011/10/perl-tutorial-and-the-internet.html">Learning Perl</a>&nbsp;post on the issue of how beginners find good Perl learning materials. &nbsp;He suggested linking to some good material, so here we go.<div><br /></div><div>First up is&nbsp;<a href="http://www.perl.org">Perl.org</a>'s&nbsp;own <a href="http://learn.perl.org">Learn Perl</a> page. &nbsp;Lots of good starting info there.</div><div><br /></div><div>Next we have chromatic's M<a href="http://www.onyxneon.com/books/modern_perl/index.html">odern Perl book</a>, an excellent resource. &nbsp;It is available in print or as a free PDF download. &nbsp;I sure wish this was available when I first started learning Perl!</div><div><br /></div><div>Finally we have Gabor's own <a href="http://szabgab.com/perl_tutorial.html">Perl Tutorial</a>.</div><div><br /></div><div>Perl is an awesome language, and great fun to program in. &nbsp;Dig in and have fun!</div>

<div class="zemanta-pixie" style="margin-top:10px;height:15px"><a class="zemanta-pixie-a" href="http://www.zemanta.com/" title="Enhanced by Zemanta"><img class="zemanta-pixie-img" src="http://img.zemanta.com/zemified_e.png?x-id=c3420050-b93a-4065-abb5-5074a65c3144" alt="Enhanced by Zemanta" style="border:none;float:right" /></a></div>]]>
        
    </content>
</entry>

<entry>
    <title>Net::Google::Analytics Extended Example</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/2011/10/netgoogleanalytics-extended-example.html" />
    <id>tag:www.billruppert.com,2011://4.79</id>

    <published>2011-10-15T03:22:06Z</published>
    <updated>2011-11-08T06:21:35Z</updated>

    <summary>I wanted to fetch visitors and page views by month for the past year for our website, and quickly found the Net::Google::Analytics module. It and Net::Google::AuthSub installed easily. However, the snippet in the synopsis did not compile ($i was undefined)...</summary>
    <author>
        <name>Bill Ruppert</name>
        <uri>http://www.billruppert.com</uri>
    </author>
    
        <category term="Script" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.billruppert.com/">
        <![CDATA[I wanted to fetch visitors and page views by month for the past year for our website, and quickly found the Net::Google::Analytics module.  It and Net::Google::AuthSub installed easily.  However, the snippet in the synopsis did not compile ($i was undefined) and was obviously missing a loop over the retrieved data.  Anyway, here is a working snippet that retrieves and formats some data for easy loading into a spreadsheet.&nbsp;<div><br /></div><div>The hardest thing for me was getting the correct profile number. &nbsp;I thought it was the number in the web page code that looked like UA-191234-1, but it's not. &nbsp;You have to go to account settings and thenedit the profile of the web site to see the magic number - it's the "Profle ID:" at the top of the page.<br />
<pre><code>

# Fetch some Google Analytics data

use strict;
use warnings;

use Net::Google::Analytics;
use Net::Google::AuthSub;

my $user    = 'you@gmail.com'; # your account user id here
my $pass    = 'xxxxxx';        # your password here!

my $profile    = '14883391';
my $start_date = '2010-10-01';
my $end_date   = '2011-09-30';

# Login

my $auth = Net::Google::AuthSub-&gt;new(service =&gt; 'analytics');
my $response = $auth-&gt;login($user, $pass);
if (!$response-&gt;is_success) {
    die 'Login failed: ' . $response-&gt;error . "\n";
}

# Datafeed request

my $analytics = Net::Google::Analytics-&gt;new();
$analytics-&gt;auth_params($auth-&gt;auth_params);

my $data_feed = $analytics-&gt;data_feed;
my $req = $data_feed-&gt;new_request();

$req-&gt;ids("ga:$profile");
$req-&gt;dimensions('ga:year,ga:month,ga:visitorType');
$req-&gt;metrics('ga:visits,ga:pageviews');
$req-&gt;start_date($start_date);
$req-&gt;end_date($end_date);

my $res = $data_feed-&gt;retrieve($req);

if (($res-&gt;{is_success} || 0) ne 1) {
    die "Lookup failed\n";
}

# Print tab separated header line

my $entry = $res-&gt;entries-&gt;[0];

for my $dimension (@{$entry-&gt;dimensions}) {
    my $name = $dimension-&gt;name;
    $name =~ s/^ga\://;
    print "$name\t";
}

for my $metric (@{$entry-&gt;metrics}) {
    my $name = $metric-&gt;name;
    $name =~ s/^ga\://;
    print "$name\t";
}

print "\n";

# Print tab separated values

for my $entry (@{$res-&gt;entries}) {
    for my $dimension (@{$entry-&gt;dimensions}) {
        my $value = $dimension-&gt;value;
        print "$value\t";
    }
    for my $metric (@{$entry-&gt;metrics}) {
        my $value = $metric-&gt;value;
        print "$value\t";
    }
    print "\n";
}

exit 1;

</code></pre></div>]]>
        
    </content>
</entry>

<entry>
    <title>Extracting Windows Zip Files - Archive::Zip</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/2011/08/extracting-windows-zip-files---archivezip.html" />
    <id>tag:www.billruppert.com,2011://4.68</id>

    <published>2011-08-23T15:06:37Z</published>
    <updated>2011-08-23T15:14:43Z</updated>

    <summary><![CDATA[ I need to download a zip file and extract the contents as part of a batch process, with some fine grain control over the name and location of the extracted file. &nbsp;Never messed with zip files using Perl before,...]]></summary>
    <author>
        <name>Bill Ruppert</name>
        <uri>http://www.billruppert.com</uri>
    </author>
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Snippet" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="zip" label="zip" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-us" xml:base="http://www.billruppert.com/">
        <![CDATA[ <div>I need to download a zip file and extract the contents as part of a batch process, with some fine grain control over the name and location of the extracted file. &nbsp;</div><div><br /></div><div>Never messed with zip files using Perl before, so here is the first step - a very simple example to extract the contents of a zip file to the current directory using the names in the zip file.</div><div><br /></div><div>There is an excellent FAQ and lots of good examples in the distribution.</div><div><br /></div><div><span class="Apple-style-span" style="font-family: monospace; white-space: pre; ">#!/usr/bin/perl</span></div><pre><code># extract_zip.pl - very simple zip extract example

use strict;
use warnings;
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );

my $zip_name = "example.zip";

my $zip = Archive::Zip-&gt;new($zip_name);
unless (defined $zip) {
	die "Unable to open $zip_name\n";
}

print "The zip file contains ", $zip-&gt;numberOfMembers(), " members:\n";

for my $member_name ($zip-&gt;memberNames()) {
	print "  Extracting $member_name\n";
	my $status = $zip-&gt;extractMemberWithoutPaths($member_name);
	die "\nExtracting $member_name from $zip_name failed\n" if $status != AZ_OK;
}

exit 1;
</code></pre><pre><code><br /></code></pre>]]>
        
    </content>
</entry>

<entry>
    <title>Cache::FileCache Example</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/2011/04/cachefilecache.html" />
    <id>tag:www.billruppert.com,2011://4.64</id>

    <published>2011-04-29T21:58:13Z</published>
    <updated>2011-05-05T12:26:18Z</updated>

    <summary>There is a spot in our real estate system that&apos;s always needed a cache to hold some data obtained from the internet. I finally got around to it using Cache::FileCache. Not the latest and greatest, but available on my increasingly...</summary>
    <author>
        <name>Bill Ruppert</name>
        <uri>http://www.billruppert.com</uri>
    </author>
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Snippet" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="cachefilecache" label="Cache::FileCache" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-us" xml:base="http://www.billruppert.com/">
        <![CDATA[There is a spot in our real estate system that's always needed a cache to hold some data obtained from the internet.  I finally got around to it using Cache::FileCache.  Not the latest and greatest, but available on my increasingly antiquated system.  It was hard to find a some decent example code, so here is some I wrote.

<pre><code>
#!/usr/bin/perl

# tCacheFile.pl - try out Cache::FileCache
# 04/29/2011  Bill Ruppert

use strict;
use warnings;
use Cache::FileCache;

# Setup cache
my $cache = new Cache::FileCache({ 
	namespace           =&gt; 'FruitCache',
	default_expires_in  =&gt; '100 days',
	cache_root          =&gt; 'C:/tools/cache/',
	auto_purge_interval =&gt; '1 day',
});

# Cache some items
$cache-&gt;set('Orange', 'A round citrus fruit');
$cache-&gt;set('Lemon',  'A yellow pointed sour citrus fruit');
$cache-&gt;set('Apple',  'A red roundish fruit good for pies');

# Get all items in cache
print "Get all items in cache:\n";
for ($cache-&gt;get_keys()) {
	my $data = $cache-&gt;get($_);
	printf "  %-10s: %s\n", $_, $data;
}

# Mix cache hits and misses
print "\nTry some hits and misses:\n";
for (qw( Lemon Kiwi Orange Melon Apple )) {
	my $data = $cache-&gt;get($_);
	$data = "Not cached!" unless defined $data;
	printf "  %-10s: %s\n", $_, $data;
}

exit 1;
</code></pre>]]>
        
    </content>
</entry>

<entry>
    <title>Comparing DNS Servers in Perl</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/2009/12/comparing-dns-servers-in-perl.html" />
    <id>tag:www.billruppert.com,2009://4.55</id>

    <published>2009-12-04T15:10:55Z</published>
    <updated>2009-12-04T15:26:27Z</updated>

    <summary><![CDATA[I've been reading about Google's new DNS service with great interest.&nbsp; I had to switch to OpenDNS some time ago when my ISP began redirecting 404's to a search page.&nbsp; This wreaked havoc on my link verification tools.While reading, I...]]></summary>
    <author>
        <name>Bill Ruppert</name>
        <uri>http://www.billruppert.com</uri>
    </author>
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Script" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.billruppert.com/">
        <![CDATA[I've been reading about Google's new DNS service with great interest.&nbsp; I had to switch to OpenDNS some time ago when my ISP began redirecting 404's to a search page.&nbsp; This wreaked havoc on my link verification tools.<br /><br />While reading, I came upon a shell script at <a href="http://www.manu-j.com/blog/opendns-alternative-google-dns-rocks/">http://www.manu-j.com/blog/opendns-alternative-google-dns-rocks/</a> that I wanted to try.&nbsp; Since I run WinXP, I translated it to Perl and spruced it up a bit.&nbsp; I installed the utility from <a href="http://members.shaw.ca/nicholas.fong/dig/">http://members.shaw.ca/nicholas.fong/dig/</a> and away we went...<br /> 
<pre><code>

# dnstimes.pl - test dns server times

use strict;
use warnings;

my @urls = qw(
	lifehacker.com
	facebook.com
	manu-j.com
	reddit.com
	tb4.fr
	bbc.co.uk
	cindyruppert.com
);

my %dns_servers = (
	Level_3	=&gt; '4.2.2.2',
	Google	=&gt; '8.8.8.8',
	OpenDNS	=&gt; '208.67.222.222',
);

for my $dns_firm (sort keys %dns_servers) {
	my $dns_ip = $dns_servers{$dns_firm};
	for my $url (@urls) {
		my $result = `dig \@$dns_ip $url`;
		my ($time) = $result =~ /Query time: (\d+)/s;
		print "$dns_firm\t$url\t$time\n";
	}
}

</code></pre>
<br /><br />]]>
        
    </content>
</entry>

<entry>
    <title>Removing HTML::FormFu elements from a form</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/2009/08/removing-htmlformfu-elements-from-a-form.html" />
    <id>tag:www.billruppert.com,2009://4.54</id>

    <published>2009-08-12T22:20:01Z</published>
    <updated>2009-08-12T22:30:00Z</updated>

    <summary>Figuring this out was somewhat painful, so I thought I would blog it.I want to use the same form yaml for several different actions (update, create, view) andI had a list of field names I wanted to remove that were...</summary>
    <author>
        <name>Bill Ruppert</name>
        <uri>http://www.billruppert.com</uri>
    </author>
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Snippet" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Web Development" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.billruppert.com/">
        <![CDATA[Figuring this out was somewhat painful, so I thought I would blog it.<br /><br />I want to use the same form yaml for several different actions (update, create, view) andI had a list of field names I wanted to remove that were not relevant for create.<br /><br />The remove_element method only works on the immediate children of the invoking object (as does get element), so $form-&gt;remove_element does not usually work.&nbsp; I found <a href="http://www.mail-archive.com/html-formfu@lists.scsys.co.uk/msg01559.html">a posting</a> on the HTML::FormFu list where Carl Franks showed the idiom $element-&gt;parent-&gt;remove_element($element);<br /><br />So my code became:<br /><br />
<code></code><pre># remove fields not needed for this action
for (qw(created_by created_time changed_by changed_time version)) {
	my $element = $form-&gt;get_all_element({name =&gt; $_});
	if ($element) {
		$element-&gt;parent-&gt;remove_element($element);
	}
}

<br />Works great!<br /></pre>
]]>
        
    </content>
</entry>

<entry>
    <title>Check Google toolbar pagerank against multiple hosts</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/2009/08/check-google-toolbar-pagerank-against-multiple-hosts.html" />
    <id>tag:www.billruppert.com,2009://4.53</id>

    <published>2009-08-07T19:18:07Z</published>
    <updated>2009-08-07T19:23:11Z</updated>

    <summary><![CDATA[One of my sites was coming up with a graybar, so I wanted to check it against other hosts, besides the default.&nbsp; I tried a couple of the websites that I normally do this with, and they weren't working.&nbsp; So,...]]></summary>
    <author>
        <name>Bill Ruppert</name>
        <uri>http://www.billruppert.com</uri>
    </author>
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Script" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.billruppert.com/">
        <![CDATA[One of my sites was coming up with a graybar, so I wanted to check it against other hosts, besides the default.&nbsp; I tried a couple of the websites that I normally do this with, and they weren't working.&nbsp; So, I wrote the following few lines.<br /><br /><pre><code>
use strict;
use warnings;
 
use WWW::Google::PageRank;

my @hosts = (
	"toolbarqueries.google.com",
	"209.85.227.147",
	"209.85.227.104",
);

for my $host (@hosts) {
	print "\n$host\n";
	my $pr = WWW::Google::PageRank-&gt;new(host =&gt; $host)
		or die $!;
	for my $domain (@ARGV) {
		$domain =~ s{http://}{};
		$domain =~ s{/$}{};
		my $pagerank = $pr-&gt;get("http://$domain/");
		print "    $pagerank  $domain\n";
	}
}
</code></pre>
]]>
        
    </content>
</entry>

<entry>
    <title>&quot;Everything&quot; at VoidTools.com</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/2009/06/everything-at-voidtoolscom.html" />
    <id>tag:www.billruppert.com,2009://4.41</id>

    <published>2009-06-05T14:44:29Z</published>
    <updated>2009-06-05T14:51:36Z</updated>

    <summary><![CDATA[I just used Everything to find all of the copies of Redemption.dll on my machine.&nbsp; As I did so, it I realized that I had to give it a shoutout and make a donation as well.&nbsp; This is really a...]]></summary>
    <author>
        <name>Bill Ruppert</name>
        <uri>http://www.billruppert.com</uri>
    </author>
    
        <category term="Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.billruppert.com/">
        <![CDATA[I just used Everything to find all of the copies of Redemption.dll on my machine.&nbsp; As I did so, it I realized that I had to give it a shoutout and make a donation as well.&nbsp; <br /><br />This is really a great tool.&nbsp; It requires NTFS, and uses it to instantly index and find all of the file names on your computer.&nbsp; And I do mean instantly.&nbsp; I'm shocked at how often I use it.<br /><br /><a href="http://www.voidtools.com/">http://www.voidtools.com</a><br /><br />Thanks David!<br />]]>
        
    </content>
</entry>

<entry>
    <title>Deleting Old Files</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/2009/05/deleting-old-files.html" />
    <id>tag:www.billruppert.com,2009://4.38</id>

    <published>2009-05-24T14:51:19Z</published>
    <updated>2009-05-24T20:04:44Z</updated>

    <summary><![CDATA[Here is a script that deletes old files.&nbsp; In the Unix environment this is an easy job for a one line script using find.&nbsp; This Perl version has the -test option, to allow you to see what will happen, and...]]></summary>
    <author>
        <name>Bill Ruppert</name>
        <uri>http://www.billruppert.com</uri>
    </author>
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Script" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.billruppert.com/">
        <![CDATA[Here is a script that deletes old files.&nbsp; In the Unix environment this is an easy job for a one line script using find.&nbsp; This Perl version has the -test option, to allow you to see what will happen, and prints some totals.<br /><pre><code><br />#!/usr/bin/perl

# delold.pl - delete old files

#-----------------------------------------------------------
# 05/24/2009  WR  Written
#-----------------------------------------------------------

use strict;
use warnings;
use Win32::Autoglob;
use Getopt::Long;

$| = 1;

sub print_usage;
sub abort_usage;

# option defaults
my $days_back    = 10;
my $test_flag    = 0;
my $verbose_flag = 0;
my $quiet_flag   = 0;

# get options
GetOptions (
    'days=i'  =&gt; \$days_back,
    'test'    =&gt; \$test_flag,
    'verbose' =&gt; \$verbose_flag,
    'quiet'   =&gt; \$quiet_flag,
    'usage'   =&gt; sub {print_usage; exit 1},
) or abort_usage "Invalid option";

my $time = time();

my $files_to_delete = 0;
my $files_total     = 0;
my $files_failed    = 0;

FILE:
for my $file (@ARGV) {

    # must exist, must be a plain old file
    next FILE if !-e $file;
    next FILE if !-f $file;

    $files_total++;

    # modified age in days
    my ($mtime) = (stat($file))[9];
    my $modified_age = ($time - $mtime) / (3600 * 24);

    # skip if too young
    next FILE if $modified_age &lt; $days_back;
    
    $files_to_delete++;

    if ($test_flag || $verbose_flag) {
        printf "Age: %-6.1f  File: %s\n",
            $modified_age,
            $file;
    }

    # skip if we are testing
    next FILE if $test_flag;

    # delete the file
    if (!unlink $file) {
        warn "Failed to delete file $file\n";
        $files_failed++;
    }

}

if ($test_flag) {
    print "\nTest Flag is set, no deletes done!\n";
}

my $files_remaining = $files_total - $files_to_delete + $files_failed;

if (!$quiet_flag || $test_flag) {
    print "\n";
    print "Total files:      $files_total\n";
    print "Files to delete:  $files_to_delete\n";
    print "Failed to delete: $files_failed\n";
    print "Files remaining:  $files_remaining\n";
}

exit 1;

sub abort_usage {
    print STDERR join("\n", @_), "\n" if @_;
    print_usage;
    exit 0;
}

sub print_usage {
    print STDERR &lt;&lt;END;
Usage: delold.pl [Options] files...
Options:
    --days n      - Set age of files to keep.
                    Files over "days" old will be deleted.
                    Default is 10 days.
    --test        - Print file names to be deleted with age,
                    but do not actually delete.
                    Default is false.
    --verbose     - Print file name and age while deleting.
                    Default is false.
    --quiet       - Suppress printing of totals after deleting.
                    Default is false.
    --usage       - print this message and exit
END
}

</code></pre>]]>
        
    </content>
</entry>

<entry>
    <title>Promoting Perl</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/2009/05/promoting-perl.html" />
    <id>tag:www.billruppert.com,2009://4.36</id>

    <published>2009-05-18T21:53:27Z</published>
    <updated>2009-05-18T21:54:43Z</updated>

    <summary><![CDATA[The Perl community is making an effort to improve visibility.&nbsp; I added "Perl programming" to the top of the blog in support of this effort....]]></summary>
    <author>
        <name>Bill Ruppert</name>
        <uri>http://www.billruppert.com</uri>
    </author>
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.billruppert.com/">
        <![CDATA[The Perl community is making an effort to improve visibility.&nbsp; I added "Perl programming" to the top of the blog in support of this effort. ]]>
        
    </content>
</entry>

<entry>
    <title>Load SQLite Tables from .csv files</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/2009/04/load-sqlite-tables-from-csv-files.html" />
    <id>tag:www.billruppert.com,2009://4.35</id>

    <published>2009-04-28T21:28:01Z</published>
    <updated>2009-04-28T21:38:52Z</updated>

    <summary><![CDATA[Here is a quick script I wrote to load SQLite tables from CSV files.&nbsp; I exported the files from Microsoft Access.&nbsp; The first row has to have correct column names.Text::xSV is the best CSV file handler I could find on...]]></summary>
    <author>
        <name>Bill Ruppert</name>
        <uri>http://www.billruppert.com</uri>
    </author>
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Snippet" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.billruppert.com/">
        <![CDATA[Here is a quick script I wrote to load SQLite tables from CSV files.&nbsp; I exported the files from Microsoft Access.&nbsp; The first row has to have correct column names.<br /><br />Text::xSV is the best CSV file handler I could find on CPAN.&nbsp; It correctly handles files with embedded newlines as well as very large files.&nbsp; SQL::Abstract makes it very easy to use straight DBI to speed up the load without going through an ORM.&nbsp; <br /><br />I prepare each row separately because I may have cases where there are trailing unused fields, and some Microsoft programs (Outlook comes to mind) do not attempt to output empty fields for them.&nbsp; If the speed difference is important, you may want to try to guarantee the exact number of fields in each row so you can prepare once.<br />

<pre><code>
#!/usr/bin/perl

# load_csv.pl - Load a db table from a csv file.
#               First row must be field names.
# 04/28/2009  W. Ruppert

use strict;
use warnings;
use Text::xSV;
use DBI;
use SQL::Abstract;

$| = 1;

sub usage {
    my ($msg) = @_;
    warn "$msg\n" if $msg;
    die "Usage: load_csv.pl db table csvfile\n";
}

# get parms
my $db        = shift || usage "No database name";
my $table     = shift || usage "No table name";
my $data_file = shift || usage "No csv data file";

usage "No such file: $db"        unless -e $db;
usage "No such file: $data_file" unless -e $data_file;

# setup csv file
my $csv = new Text::xSV;
$csv-&gt;open_file("$data_file");
$csv-&gt;read_header();

my $sql = SQL::Abstract-&gt;new;

# connect to db
my $dbh = DBI-&gt;connect("dbi:SQLite:$db", "","",
        { RaiseError =&gt; 1, PrintError =&gt; 0 }
) or die "can't connect\n";

$dbh-&gt;do('begin');

my $max_commit  = 1000;
my $inserted    = 0;

# process csv rows
while (my %fieldvals = $csv-&gt;fetchrow_hash) {

    # SQL::Abstract sets up the DBI variables
    my($stmt, @bind) = $sql-&gt;insert($table, \%fieldvals);

    # insert the row
    my $sth = $dbh-&gt;prepare($stmt);
    $inserted += $sth-&gt;execute(@bind);

    # progress bar
    print "*"            unless $inserted % 10;
    print " $inserted\n" unless $inserted % 500;

    # commit every once in a while
    unless ($inserted % $max_commit) {
        $dbh-&gt;do('commit');
        $dbh-&gt;do('begin');
    }
}

$dbh-&gt;do('commit');
$dbh-&gt;disconnect;

print "\nInserted $inserted records\n";
exit 1;
</code></pre>]]>
        
    </content>
</entry>

<entry>
    <title>Firefox FOUC fixed</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/2009/04/firefox-fouc-fixed.html" />
    <id>tag:www.billruppert.com,2009://4.34</id>

    <published>2009-04-27T15:25:20Z</published>
    <updated>2009-04-27T15:39:24Z</updated>

    <summary><![CDATA[Had a nasty FOUC (flash of unstyled content) on one of our websites.&nbsp; It was real bad in Firefox, didn't check it in IE.&nbsp; The page loads a fairly small amount of CSS (28k) in the head.&nbsp; No scripts though.&nbsp;...]]></summary>
    <author>
        <name>Bill Ruppert</name>
        <uri>http://www.billruppert.com</uri>
    </author>
    
        <category term="Web Development" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.billruppert.com/">
        <![CDATA[Had a nasty FOUC (flash of unstyled content) on one of our websites.&nbsp; It was real bad in Firefox, didn't check it in IE.&nbsp; <br /><br />The page loads a fairly small amount of CSS (28k) in the head.&nbsp; No scripts though.&nbsp; Our main site does not have this problem, and it has a small script in the head (to prevent external framing), so I added that but no difference.<br /><br />The main site also has a scipt at the top of the body to pre-load the "Cool DHTML Tooltip" from www.dynamicdrive.com.&nbsp; Adding that script fixed the FOUC:<br /><br />&lt;body&gt;<br />&lt;div id="dhtmltooltip"&gt;&lt;/div&gt;<br />&lt;script type="text/javascript" src="js/tooltip.js"&gt;&lt;/script&gt;<br /><br />Now there is a blank screen for a while, then the formatted page loads.&nbsp; I guess the script stops the rendering from starting too fast.&nbsp; I don't actually use the tooltip script on this site, but it is only 4k.<br />]]>
        
    </content>
</entry>

<entry>
    <title>Determine Image Size from URL</title>
    <link rel="alternate" type="text/html" href="http://www.billruppert.com/2009/04/new-blog.html" />
    <id>tag:www.billruppert.com,2009://4.31</id>

    <published>2009-04-17T16:47:15Z</published>
    <updated>2009-04-17T17:02:12Z</updated>

    <summary><![CDATA[Need to get the size of an image on the web without storing it.&nbsp; Done by pulling the image with LWP::Simple and giving the content buffer to Image::Size. #!/usr/bin/perl # Get dimensions of web image # 04/17/2009 WR use strict;...]]></summary>
    <author>
        <name>Bill Ruppert</name>
        <uri>http://www.billruppert.com</uri>
    </author>
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Snippet" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.billruppert.com/">
        <![CDATA[Need to get the size of an image on the web without storing it.&nbsp; Done by pulling the image with LWP::Simple and giving the content buffer to Image::Size.<br /><br /><br />
<pre><code>
#!/usr/bin/perl
# Get dimensions of web image
# 04/17/2009  WR

use strict;
use warnings;
use LWP::Simple;
use Image::Size;

my @urls = (
	"http://www.google.com/intl/en_ALL/images/logo.gif",
	"http://l.yimg.com/a/i/ww/beta/y3.gif",
	"http://www.example.com/nothing.gif",
	"http://graphics8.nytimes.com/images/misc/nytlogo379x64.gif",
);

URL:
for my $url (@urls) {
	my $image = get $url;
	unless (defined $image) {
		warn "Couldn't get $url!\n";
		next URL;
	}
	my ($width, $height) = imgsize(\$image);
	printf "%4d %4d   %s\n", $width, $height, $url;
}

exit 1;
</code></pre>]]>
        
    </content>
</entry>

</feed>

