<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Patrick Hartman</title>
	<atom:link href="http://www.patrickhartman.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.patrickhartman.com</link>
	<description>web development, photoshop scripting and other thoughts</description>
	<lastBuildDate>Thu, 18 Feb 2010 06:57:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Installing mod_perl from ActivePerl PPM</title>
		<link>http://www.patrickhartman.com/2010/02/18/installing-mod_perl-from-activeperl-ppm/</link>
		<comments>http://www.patrickhartman.com/2010/02/18/installing-mod_perl-from-activeperl-ppm/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 06:57:13 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.patrickhartman.com/?p=40</guid>
		<description><![CDATA[Today I installed mod_perl for the first time and ran into a few roadblocks. Nothing terribly hard to figure out, but it took some searching to get everything I needed. I thought I would share a very short tutorial on how to get it up and running quickly and hopefully prevent someone else from having [...]]]></description>
			<content:encoded><![CDATA[<p>Today I installed mod_perl for the first time and ran into a few roadblocks. Nothing terribly hard to figure out, but it took some searching to get everything I needed. I thought I would share a very short tutorial on how to get it up and running quickly and hopefully prevent someone else from having to do the same detective work.</p>
<p>This is what I had to do with ActivePerl 5.10.1.1007 and Apache 2.2.11:</p>
<ol>
<li>Install mod_perl from the ActivePerl PPM. It is not available on the ActiveState repository (by default you only have that one), so you will need to add the <a href="http://cpan.uwinnipeg.ca/PPMPackages/10xx/package.xml">University of Winnipeg 5.10 repository</a>.</li>
<li>If you used the command line PPM to install mod_perl, it prompted you to install the Apache module you need to accompany the Perl module. If you install it using the Windows PPM, it won&#8217;t prompt you and just skip that. You have to download <a href="http://cpan.uwinnipeg.ca/PPMPackages/10xx/x86/mod_perl.so">mod_perl.so</a> and place it in your /apache/modules/ directory.</li>
<li>Last think you will have to do is configure Apache&#8217;s httpd.conf file. The article <a href="http://perl.apache.org/docs/2.0/os/win32/config.html">Configuring mod_perl 2.0 for Win32</a> gives very good instructions for doing so. This will guide you through adding the LoadModule line and configuring what directories you want to have files be handled by Perl.
</ol>
<p>Once you complete the above, just restart Apache and you are good to go!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.patrickhartman.com/2010/02/18/installing-mod_perl-from-activeperl-ppm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL connection string for multiple servers in PHP</title>
		<link>http://www.patrickhartman.com/2009/10/03/mysql-connection-string-for-multiple-servers/</link>
		<comments>http://www.patrickhartman.com/2009/10/03/mysql-connection-string-for-multiple-servers/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 10:56:59 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.patrickhartman.com/?p=33</guid>
		<description><![CDATA[This is something that I started doing recently that I have found really helpful. Whenever I have a MySQL include file for a web development project, I set it up so it will work on both my local dev server and the live website. I accomplish this by checking to see where the file is [...]]]></description>
			<content:encoded><![CDATA[<p>This is something that I started doing recently that I have found really helpful. Whenever I have a MySQL include file for a web development project, I set it up so it will work on both my local dev server and the live website. I accomplish this by checking to see where the file is being loaded from &#8211; if it is being loaded from the web server, you just connect to localhost; if it is being loaded somewhere else, it will use the domain name to access the database server.</p>
<pre class="brush: php">
// define your settings
$domain = "example.com";
$user = "dblogin";
$pass = "dbpassword";
$schema = "dbname";

// check to see where this is being loaded from
if ($_SERVER['HTTP_HOST'] == "$domain" || $_SERVER['HTTP_HOST'] == "www.$domain") {
	// if loaded off website, connect to localhost
	$link = mysqli_connect("localhost", $user, $pass, $schema) or die(mysqli_error());
} else {
	// otherwise you will need to access it remotely
	$link = mysqli_connect($domain, $user, $pass, $schema) or die(mysqli_error());
}

// check your connection
if (mysqli_connect_errno()) {
	printf("Connect failed: %s\n", mysqli_connect_error());
	exit();
}
</pre>
<p>This works great because you have have the exact same files on both servers, when you deploy changes to the site you don&#8217;t need to worry about removing your development server info.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.patrickhartman.com/2009/10/03/mysql-connection-string-for-multiple-servers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Check if time falls between a range in PHP</title>
		<link>http://www.patrickhartman.com/2009/08/29/check-if-time-falls-between-a-range-in-php/</link>
		<comments>http://www.patrickhartman.com/2009/08/29/check-if-time-falls-between-a-range-in-php/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 16:31:00 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.patrickhartman.com/?p=27</guid>
		<description><![CDATA[I was digging through some old stuff today and found this PHP function I wrote awhile back. You pass a time to the function along with a start time and end time, and it will determine if the time falls between that range. I figured I would post it on here in case anyone has [...]]]></description>
			<content:encoded><![CDATA[<p>I was digging through some old stuff today and found this PHP function I wrote awhile back. You pass a time to the function along with a start time and end time, and it will determine if the time falls between that range. I figured I would post it on here in case anyone has a need for it.</p>
<pre class="brush: php;">
function CheckTime($currentTime, $startTime, $endTime){
	// written 11/26/2006 by Patrick H. (patrickh@gmail.com)
	//
	// the time passed must meet all the below criteria to return 1 (true):
	//
	// - current hour needs to be equal or greater than start hour
	// - current hour needs to be equal or less than end hour
	// - current minute needs to be equal or greater than start minute (if current hour is ok)
	// - current minute needs to be equal or less than end minute (if current hour is ok)
	//
	// if any of those checks does not pass, it will return 0 (false)

	global $cHour;
	global $cMin;
	global $sHour;
	global $sMin;
	global $eHour;
	global $eMin;

	// break up current time
	$now = explode(":",$currentTime);
	$cHour = intval($now[0]);	// current time - hour
	$cMin = intval($now[1]);	// current time - minute

	// break up start time
	$start = explode(":",$startTime);
	$sHour = intval($start[0]);	// start of range - hour
	$sMin = intval($start[1]);	// start of range - minute

	// brek up end time
	$end = explode(":",$endTime);
	$eHour = intval($end[0]);	// end of range - hour
	$eMin = intval($end[1]);	// end of range - minute

	// this is the variable used to track the result of the checks
	$pass = true;

	if($sHour < $eHour){
		// the range is on the same day

		// compare to the start hour
		if($cHour < $sHour){
			$pass = false;
		};

		// compare to the end hour
		if($cHour > $eHour){
			$pass = false;
		};

		// compare to the start min
		if($cHour == $sHour){
			if($cMin < $sMin){
				$pass = false;
			};
		};

		// compare to the end min
		if($cHour == $eHour){
			if($cMin > $eMin){
				$pass = false;
			};
		};

	} else {
		// the range is overnight, so the logic is a little different

		if( ($cHour < $sHour) &#038;&#038; ($cHour > $eHour) ){
			$pass = false;
		};

		// compare to the start min
		if($cHour == $sHour){
			if($cMin < $sMin){
				$pass = false;
			};
		};

		// compare to the end min
		if($cHour == $eHour){
			if($cMin > $eMin){
				$pass = false;
			};
		};

	};

	// done with check, return the result
	if($pass == false){
		return 0;	// failed
	} else {
		return 1;	// passed
	};

};

// test it out
// make sure you use military time
// usage: current time, range start time, range end time

echo CheckTime("06:30","15:20","06:45");	// this should return 1
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.patrickhartman.com/2009/08/29/check-if-time-falls-between-a-range-in-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Perl for Google Analytics API</title>
		<link>http://www.patrickhartman.com/2009/08/10/using-perl-for-google-analytics-api/</link>
		<comments>http://www.patrickhartman.com/2009/08/10/using-perl-for-google-analytics-api/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 01:47:46 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[google analytics]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.patrickhartman.com/?p=13</guid>
		<description><![CDATA[We use Google Analytics at work, and it has always been painful to create any kind of automated reports using that data. To date I have had to setup scheduled .csv reports to myself, parse them and import the into a database. It was definitely a pain to setup and maintain, so I was thrilled [...]]]></description>
			<content:encoded><![CDATA[<p>We use Google Analytics at work, and it has always been painful to create any kind of automated reports using that data. To date I have had to setup scheduled .csv reports to myself, parse them and import the into a database. It was definitely a pain to setup and maintain, so I was thrilled to see Google finally released a <a href="http://code.google.com/apis/analytics/docs/">API for Google Analytics</a>. I decided to put this together to help give people a starting point for using their Google Analytics information in their Perl programs.</p>
<p>The first thing you will need to do is request a token from Google. This is what you will use to authenticate yourself on all data feed requests for your session. </p>
<pre class="brush: perl;">
#!/usr/bin/perl -w
use strict;
use LWP::UserAgent;
use XML::Simple;

# this sub will return the token you need to authenticate api requests
# you need to pass your ga login and password to it
sub gaGetToken {
    # arguments passed to this function
    my $user = $_[0];
    my $pass = $_[1];

    # create user agent object
    my $ua = LWP::UserAgent->new;
    $ua->agent("MyApp/0.1 ");

    # Create a request
    my $req = HTTP::Request->new(POST => 'https://www.google.com/accounts/ClientLogin');
    $req->content_type('application/x-www-form-urlencoded');
    $req->content("accountType=GOOGLE&#038;Email=$user&#038;Passwd=$pass&#038;service=analytics&#038;source=companyName-applicationName-versionID");

    # Pass request to the user agent and get a response back
    my $res = $ua->request($req);

    # declare variable
    my $token;

    # Check the outcome of the response
    if ($res->is_success) {
        # look at the result
        if ($res->content =~ m/(?<=Auth=).*/im) {
            # store token so it can be used in subsequent requests
            $token = $&#038;;
        }
    }
    else {
        # return the error if there was a problem
        return "error: ". $res->status_line;
        die;
    }

    # return the token
    return $token;
}

# authenticate with the API to receive token
my $token = &#038;gaGetToken('username','password');
</pre>
<p>This will give you the token you need to make other requests. Now you have the token, you can request a data feed of the analytics account information that is tied to your Google account. The way I chose to handle this is the parse the feed and return an array of account names and account numbers.</p>
<pre class="brush: perl; first-line: 48;">
# this sub will return an array of all your ga accounts
# you need to pass your token to it
sub gaAccounts {
    # the token you passed to this sub
    my $token = $_[0];

    # create user agent object
    my $ua = LWP::UserAgent->new;
    $ua->agent("MyApp/0.1 ");

    # add authorization to headers
    my @headers = (Authorization => "GoogleLogin Auth=$token");

    # request the accounts feed
    my $res = $ua->get("https://www.google.com/analytics/feeds/accounts/default", @headers);

    # define accounts array
    my @accounts;

    # if the request was successful...
    if ($res->is_success) {
        # declare variables
        my ($content, $e);

        # this is the xml it returns
        $content = $res->content;

        # create a xml object for the response
        my $xml = new XML::Simple(KeyAttr=>[]);
        my $tree = $xml->XMLin($content);

        # iterate through each entry
        my $x = 0;
        foreach $e (@{$tree->{entry}})
        {
            # add the account to the array
            $accounts[$x][0] = $e->{title}->{content};
            $accounts[$x][1] = $e->{'dxp:tableId'};
            $x++
        }
    } else {
        # return the error if there was a problem
        return "error: ". $res->status_line;
        die;
    }

    # return the array of accounts
    return @accounts;
}

# get array of all sites in your account
my @sites = &#038;gaAccounts($token);

# list all the sites in the array
foreach(@sites) {
    print $_->[0] ." => ". $_->[1] ."\n";
}

# going forward, we will use the first account number
my $website = $sites[0][1];
</pre>
<p>Now you have a token and account number, you have everything you need to make data feed requests for the Google Analytics information for that account. Here is a example of getting visits by day:</p>
<pre class="brush: perl; first-line: 108;">
# this sub will return the xml from a datafeed request
# you need to pass your token to it
sub gaDataFeed {
    # arguments passed to this function
    my $url = $_[0];
    my $token = $_[1];    

    # create user agent object
    my $ua = LWP::UserAgent->new;
    $ua->agent("MyApp/0.1 ");

    # add authorization to headers
    my @headers = (Authorization => "GoogleLogin Auth=$token");

    # request page
    my $res = $ua->get($url, @headers);

    my $content;

    # if the request was successful...
    if ($res->is_success) {
        # this is the xml response
        $content = $res->content;
    } else {
        # return the error if there was a problem
        return "error: ". $res->status_line;
        die;
    }

    # return the xml
    return $content;
}

# to test, lets request visit by day
my $pageviews = &#038;gaDataFeed("https://www.google.com/analytics/feeds/data?ids=$website&#038;dimensions=ga%3Adate&#038;metrics=ga%3Avisits&#038;start-date=2009-07-27&#038;end-date=2009-08-10&#038;max-results=365", $token);

# create a xml object for the response
my $xml = new XML::Simple(KeyAttr=>[]);
my $tree = $xml->XMLin($pageviews);

# iterate through each entry in the xml
foreach my $e (@{$tree->{entry}})
{
    # date value
    print $e->{'dxp:dimension'}->{value};
    print " : ";
    # visitors value
    print $e->{'dxp:metric'}->{value};
    print "\n";
}
</pre>
<p>That is the basics, you can use the above to access just about anything in your Google Analytics account. There is a good <a href="http://code.google.com/apis/analytics/docs/gdata/gdataExplorer.html">query explorer</a> that you can use to generate and test data feed request URI&#8217;s. I hope this helps you get started with Google Analytics and Perl.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.patrickhartman.com/2009/08/10/using-perl-for-google-analytics-api/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Streaming HD movies to PS3</title>
		<link>http://www.patrickhartman.com/2009/08/08/streaming-hd-movies-to-ps3/</link>
		<comments>http://www.patrickhartman.com/2009/08/08/streaming-hd-movies-to-ps3/#comments</comments>
		<pubDate>Sat, 08 Aug 2009 18:08:50 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[hd]]></category>
		<category><![CDATA[ps3]]></category>
		<category><![CDATA[tversity]]></category>

		<guid isPermaLink="false">http://www.patrickhartman.com/?p=7</guid>
		<description><![CDATA[I recently found out that I could stream HD video files to my PS3. If you have a file that is .m2ts, you can add it to your Tversity library and the PS3 will recognize it and play with no problems. However, often when you download a x264 movie it comes in  the format [...]]]></description>
			<content:encoded><![CDATA[<p>I recently found out that I could stream HD video files to my PS3. If you have a file that is .m2ts, you can add it to your Tversity library and the PS3 will recognize it and play with no problems. However, often when you download a x264 movie it comes in  the format .mkv which the PS3 does not support. Luckily there is a quick way to convert .mkv to .m2ts on PC:</p>
<ol>
<li><a href="http://www.videohelp.com/tools/tsMuxeR">Download tsMuxer</a> made by SmartWare (freeware)</li>
<li>add your .mkv file to the <strong>Input Files</strong> area</li>
<li>choose M2TS muxing in the <strong>Output area</strong></li>
<li>under <strong>General track options</strong>, set Change level to 4.0 if it defaults to a level higher then that</li>
<li>click the <strong>Start muxing</strong> button and it will create you a new .m2ts file that you can stream to your PS3</li>
</ol>
<p>The program is surprisingly fast, it usually takes me 1-2 minutes to convert a 5GB video file.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.patrickhartman.com/2009/08/08/streaming-hd-movies-to-ps3/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Tversity streaming to PS3 fix</title>
		<link>http://www.patrickhartman.com/2009/08/02/tversity-streaming-to-ps3-fix/</link>
		<comments>http://www.patrickhartman.com/2009/08/02/tversity-streaming-to-ps3-fix/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 10:14:55 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[64-bit]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[ps3]]></category>
		<category><![CDATA[tversity]]></category>

		<guid isPermaLink="false">http://www.patrickhartman.com/?p=3</guid>
		<description><![CDATA[Despite Tversity streaming flawlessly to my PS3 from Windows XP x86, I have never been able to get it working quite right from Windows XP x64. Every time I have tried to set it up, it would always have some degree of choppiness and not allow me to fast forward more than a few seconds [...]]]></description>
			<content:encoded><![CDATA[<p>Despite Tversity streaming flawlessly to my PS3 from Windows XP x86, I have never been able to get it working quite right from Windows XP x64. Every time I have tried to set it up, it would always have some degree of choppiness and not allow me to fast forward more than a few seconds before it would hang. When looking through the <a href="http://forums.tversity.com/viewtopic.php?f=2&amp;t=11993&amp;p=64081&amp;hilit=1496#p64081">Tversity forums</a> tonight I finally stumbled on a solution that has appeared to fix things entirely.</p>
<p>The key seems to be changing the MTU value on the PS3 from automatic to 1496 (<a href="http://manuals.playstation.net/document/en/ps3/current/settings/connectadvance.html">instructions</a>). That&#8217;s it, all I did was change that on my PS3 and use the default Tversity settings and everything streams with no stuttering at all.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.patrickhartman.com/2009/08/02/tversity-streaming-to-ps3-fix/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
