Posts Tagged ‘Google’

iPhone

Wednesday, October 21st, 2009

I purchased an iPhone last June. I had been waiting for my Verizon Wireless contract to end for nearly six months and the iPhone 3GS had recently been released. It was as if the planets were aligning.

At the time, I had iPhone envy.  Quite a few people I knew had an iPhone and they always had this neat toy wherever they went.  Now that I've been using one for four months or so, I suppose I'm now a brainwashed Steve Jobs follower bent on supporting Apple's plan to take over the world.

Well maybe I'm not that bad, but it is what I consider to be one of my best purchases.  Since I've been taking the bus to work this semester, it has been quite useful for keeping me entertained on my ride.  I do wish DART had an app for the bus schedules though.  Instead they have these huge PDFs that are frankly a pain in the butt.  But, I'm getting a little off track.  This post isn't about DART (although I do appreciate the service they run).

I have found some nifty apps.  I'm sure some folks have ten times as many apps as I do.  I don't go app hunting that often and I try to stick to the free ones when I can.  In no particular order, some of my favorite (or most used apps) include..

  • MyWeather
  • Prowl & iNag (love/hate relationship of getting server alerts)
  • iDisk
  • Facebook
  • NPR News
  • Pandora
  • FlightControl
  • Unblock Me (free)

Some of the built-in apps are pretty nifty too.  Seeing the traffic on the Google Maps app is awesome.  Syncing the Calendar app to my Google Calendar is great.

Speaking of syncing, that has been one of the best things I've done since getting the iPhone.  All of my contacts are synced on the phone to MobileMe.  I then sync my MobileMe contacts to my Google (gmail/gvoice) contacts automatically with the Address Book application on my iMac.  Having everything in sync is a wonderful thing.  I do have to be careful though.  I'm relying on two cloud type services and you never know when one could do something stupid.  Making backups is always important.

Anyhow, enough Apple worshiping for one evening.  If anyone has any awesome apps to check out, feel free to leave a comment.

Using Linode DNS Manager for Google Apps

Monday, December 8th, 2008

I've hosted a few websites for other people and have used Google Apps to handle mail and calendar needs. This way I'm just using my Linode to only host the webpages. After manually creating the Google Apps DNS records a few times, I decided it'd be best to write a script using Linode's API to automate the process.

Since I haven't written a Perl script from scratch in awhile, I thought it would be good to use that. Michael Greb, who works at Linode, published a Perl module on CPAN called "WebService::Linode". Mike also posted some really helpful information regarding the installation of Perl modules under Ubuntu Linux. Instead of downloading, compiling, and installing the module the old fashioned manual way, you can use dh-make-perl. The dh-make-perl program will do all of that for you and create a Debian package file to install. This way if the CPAN module is ever upgraded or becomes part of the distro, it'll be handled automatically. I used the following commands to install the module (I also had to do the same thing for JSON because my installed version was too old).

$ dh-make-perl --cpan JSON --build
$ dh-make-perl --cpan WebService::Linode --build
$ sudo dpkg -i libjson-perl_2.12-1_all.deb libwebservice-linode-perl_0.02-1_all.deb

On the first run it will prompt for the Linode API key and store it in ~/.linode-api. Subsequent runs will simply read the key from that file. Below is an example of how it's usage.

$ googleapps-dns.pl -h
Usage:
    googleapps-dns.pl [ -d domainname ] [ -m ] [ -c ] [ -f ] [ -v ] [ -h ]

Options:
            -d domainname
                    Specify the domain name for adding the records.  This field is
                    required.
            -c      Add Google Chat's Jabber and XMPP records to route external
                    chat program to Google's services.
            -g      Add CNAMES that point calendar.domainname, docs.domainname,
                    mail.domainname, sites.domainname, and start.domainname to
                    ghs.google.com.
            -m      Add MX and SPF records for routing mail to Google Apps.
            -f      Force deletion of any conflicting records.
            -v      Enable verbose debugging messages.
            -h      Display help and options.

$ googleapps-dns.pl -d example.com -g -m -c
Would you like to delete any conflicting dns records? [Y/n] y
Please enter your Linode API Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
$

I hope this is helpful for other people managing sites hosted on Google Apps. The code is below.

#!/usr/bin/perl
#
# googleapps-dns.pl
#
# Script to populate the Linode's DNS Manager for Google Apps.
#
# Copyright (c) 2008 Patrick Hennessy 
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#

use strict;
use warnings;

use Getopt::Long;
use Pod::Usage;
use WebService::Linode::DNS;

# File to store apikey.  If undefined or blank, use ~/.linode-apikey.
#
my $apiKeyFile = '';

# Default resource record templates.
#
my %mailTemplate = ( resourceid => 0,  name => '', type => 'MX' );
my %xmppTemplate = ( resourceid => 0, name => '_xmpp-server', protocol => '_tcp', type => 'SRV', weight => 0, port => 5269 );
my %jabberTemplate = ( resourceid => 0, name => '_jabber', protocol => '_tcp', type => 'SRV', weight => 0, port => 5269 );
my %ghsTemplate = ( resourceid => 0, type => 'CNAME', target => 'ghs.google.com' );

# Google Apps DNS Records
#
my @googleMailRR = (
        { %mailTemplate, target => 'aspmx.l.google.com', priority => 10 },
        { %mailTemplate, target => 'alt1.aspmx.l.google.com', priority => 20 },
        { %mailTemplate, target => 'alt2.aspmx.l.google.com', priority => 20 },
        { %mailTemplate, target => 'aspmx2.googlemail.com', priority => 30 },
        { %mailTemplate, target => 'aspmx3.googlemail.com', priority => 30 },
        { %mailTemplate, target => 'aspmx4.googlemail.com', priority => 30 },
        { %mailTemplate, target => 'aspmx5.googlemail.com', priority => 30 },
        { %mailTemplate, type => 'TXT', target => 'v=spf1 a mx include:aspmx.googlemail.com -all' },
);

my @googleXMPPJabberRR = (
        { %xmppTemplate, target => 'xmpp-server.l.google.com', priority => 5 },
        { %xmppTemplate, target => 'xmpp-server1.l.google.com', priority => 20 },
        { %xmppTemplate, target => 'xmpp-server2.l.google.com', priority => 20 },
        { %xmppTemplate, target => 'xmpp-server3.l.google.com', priority => 20 },
        { %xmppTemplate, target => 'xmpp-server4.l.google.com', priority => 20 },
        { %jabberTemplate, target => 'xmpp-server.l.google.com', priority => 5 },
        { %jabberTemplate, target => 'xmpp-server1.l.google.com', priority => 20 },
        { %jabberTemplate, target => 'xmpp-server2.l.google.com', priority => 20 },
        { %jabberTemplate, target => 'xmpp-server3.l.google.com', priority => 20 },
        { %jabberTemplate, target => 'xmpp-server4.l.google.com', priority => 20 },
);

my @googleGHSRR = (
        { %ghsTemplate, name => 'calendar' },
        { %ghsTemplate, name => 'docs' },
        { %ghsTemplate, name => 'mail' },
        { %ghsTemplate, name => 'sites' },
        { %ghsTemplate, name => 'start' },
);

# =============================================================================
# Do not change anything below this line.
# =============================================================================
#
die "This script needs to be run interactively." if (! -t STDIN);

# Handle options.
#
my ($chat, $debug, $domainName, $force, $ghs, $help, $mail);
my $result = GetOptions(
        'd=s'           => $domainName,
        'c'             => $chat,
        'f'             => $force,
        'g'             => $ghs,
        'm'             => $mail,
        'v'             => $debug,
        'help|h|?'      => $help
);

# Usage
#
pod2usage(1) if $help;
pod2usage(1) if ! $domainName;
pod2usage(1) if (! $chat) && (! $ghs) && (! $mail);

# Prompt to see if we should delete conflicting records or just add the new Google records.
#
if (! defined($force)) {
        $force = parseresp(prompt("Would you like to delete any conflicting dns records? [Y/n] "));
}

# Get API key and create api object.
#
my $apiKey = getApiKey($apiKeyFile);
my $api = new WebService::Linode::DNS( apikey => $apiKey );

# Get domain object.
#
my $domain = $api->domainGet( domain => $domainName ) ||
        die "ERROR: Domain not found, please create the initial records first.n";

# XMPP+Jabber Records
#
processRRs($api, $domain, @googleXMPPJabberRR, $force) if $chat;

# Mail Records
#
processRRs($api, $domain, @googleMailRR, $force) if $mail;

# GHS Records
#
processRRs($api, $domain, @googleGHSRR, $force) if $ghs;
# Save the domain.
#
$api->domainSave(%$domain) || die "Couldn't save $domainNamen";

# All done.
#
exit(0);

# Subroutines
#
sub processRRs {
        my $api = shift;
        my $domain = shift;
        my $resourceRecords = shift;
        my $force = shift;

        # Remove any existing records.
        #
        if ($force) {
                for my $nRecord (@$resourceRecords) {
                        for my $eRecord (domainGetRRs($api, $domain->{domainid}, $nRecord->{type})) {
                                if (($eRecord->{type} =~ m/mx/i) && ($eRecord->{name} eq "")) {
                                        deleteRR($api, $eRecord);
                                } elsif (($eRecord->{type} =~ m/txt/i) && ($eRecord->{target} =~ m/v=spf/i)) {
                                        deleteRR($api, $eRecord);
                                } elsif (($eRecord->{type} =~ m/srv/i) && ($eRecord->{name} =~ m/_xmpp-server/i)) {
                                        deleteRR($api, $eRecord);
                                } elsif (($eRecord->{type} =~ m/srv/i) && ($eRecord->{name} =~ m/_jabber/i)) {
                                        deleteRR($api, $eRecord);
                                } elsif (($eRecord->{type} =~ m/cname/i) && ($eRecord->{target} =~ m/ghs.google.com/i)) {
                                        deleteRR($api, $eRecord);
                                }
                        }
                }
        }

        # Create new records.
        #
        for my $record (@$resourceRecords) {
                debug("SAVING RR: TYPE=$record->{type} NAME=$record->{name} TARGET=$record->{target}");
                my $rr = $api->domainResourceSave( 'domainid' => $domain->{domainid}, %$record ) ||
                        die "Could not save TYPE=$record->{type} NAME=$record->{name} TARGET=$record->{target}n";
        }
}

sub deleteRR {
        my $api = shift;
        my $record = shift;

        debug("DELETING RR: TYPE=$record->{type} NAME=$record->{name} TARGET=$record->{target}");
        my $result = $api->domainResourceDelete( resourceid => $record->{resourceid} ) ||
                warn "WARNING: Could not delete TYPE=$record->{type} NAME=$record->{name} TARGET=$record->{target}n";

        return $result;
}

sub domainGetRRs {
        my $api = shift;
        my $domainId = shift;
        my $domainRRType = shift;
        my @domainRRs = ();

        my $rrs = $api->domainResourceList( domainid => $domainId ) ||
                die "ERROR: Could not retrieve domain resource list.n";
        for my $rr (@$rrs) {
                push(@domainRRs, $rr) if ($rr->{type} =~ m/^$domainRRType$/i);
        }

        return @domainRRs;
}

sub getApiKey {
        my $apiKeyFile = shift;
        my $apiKey;

        if (!length($apiKeyFile)) {
                $apiKeyFile = (getpwnam(getlogin()))[7] . '/.linode-apikey';
        }

        if (-f $apiKeyFile) {
                chomp ($apiKey = `cat $apiKeyFile`);
        } else {
                $apiKey = prompt("Please enter your Linode API Key: ");
                system "echo '$apiKey' > $apiKeyFile";
        }

        return $apiKey;
}

sub parseresp {
        my $response = shift;
        my $val = 0;

        chomp($response);
        $val = 1 if ($response =~ m/^y/i );
        $val = 1 if ($response eq "");

        return $val;
}

sub prompt {
        my $promptstring = shift;

        print $promptstring;
        chomp (my $retstring = );

        return $retstring;
}

sub debug {
        my $msg = shift;

        print STDERR $msg, "n" if $debug;
}

__END__

=head1 NAME

googleapps-dns.pl - Create Google Apps DNS Records in Linode DNS Manager

=head1 SYNOPSIS

googleapps-dns.pl [ -d domainname ] [ -m ] [ -c ] [ -f ] [ -v ] [ -h ] 

=head1 OPTIONS

        -d domainname
                Specify the domain name for adding the records.  This field is 
                required.
        -c      Add Google Chat's Jabber and XMPP records to route external
                chat program to Google's services.
        -g      Add CNAMES that point calendar.domainname, docs.domainname, 
                mail.domainname, sites.domainname, and start.domainname to
                ghs.google.com.
        -m      Add MX and SPF records for routing mail to Google Apps.
        -f      Force deletion of any conflicting records.
        -v      Enable verbose debugging messages.
        -h      Display help and options.

=head1 DESCRIPTION

B provides a wizard to populate DNS records in the Linode 
DNS manager for Google Apps.  It requires that the domain already exist.  It 
would create the standard DNS entries which can be pruned manually later.

=cut

Googly Goodness

Thursday, November 20th, 2008

I've been impressed with Google recently.  I've started using Google Reader again.  I used it for awhile when it first came out, but I think some RSS feeds were glitchy or it could have been Google Reader in general.  Maybe I just got distracted by some other shiny object and stopped paying attention to it. But, it seems good now and you can share items with friends from your Gmail contact list. So, I'm starting to "share" items now that perk my interest.

This week Google added themes for Gmail.  It took awhile for them to show up for my account, but they're finally here!  So far, I like the shiny and silver lining theme.

The last thing is somewhat unrelated, but awesome nonetheless.  Well, technically Google owns Youtube.  For your viewing pleasure, here's Bike Hero..

http://www.youtube.com/watch?v=NlMYWuGUZlM


css.php