#!/usr/bin/perl # # gps2ipod # # Version 2.0 # # Synchronizes geocaches between Garmin GPS and text files in # the current working directory. It does the following: # # - Download all the waypoints from your GPS # - Extract all the Geocaches (waypoint ID with prefix GC) # - Get all the files in the current directory # - Extract all the Geocache .txt files (GC*.txt) # - Determine which .txt files no longer correspond to a # Geocache waypoint on the GPS, and delete them # - Determine which Geocaches have already been synced # to the current directory, and will remove them from the list # - Download (slowly) the Geocaching.com page for each cache # - Transform it into a useful text file # - Save the text file in the current directory # # To synchronize your iPod with your GPS, cd to your iPod's # "Notes" directory, then run this script. # # To avoid the wrath of the Geocaching.com site admins, this # script implements the following to control bandwidth: # # - a 10-second pause between each page request # - a 30-second pause between each 20 page requests # # This mimics the behavior of a user who used the search page # to get a list of geocaches to inspect. # # For questions, comments, and suggestions, contact: # # Matthew M. Swann # swannman@mac.com # ############################################################## # Declared at end of file sub SanitizeHTML; sub RemoveDuplicates; # The building blocks of the URL used to fetch the geocache data # for each waypoint $URLprefix = "http://www.geocaching.com/seek/cache_details.aspx?wp="; $URLsuffix = "&Submit6=Find&pf=y&decrypt=y"; # Counter for number of waypoints downloaded from Geocaching.com # so that we can pause after every 20 to lessen the load $counter = 0; # Download all waypoints from the GPS $waypoints = `gpsbabel -i garmin -f /dev/cu.USA19H821P1.1`; # Extract all the Geocache IDs into a list @IDs = $waypoints =~ /\s(GC.+)\//g; # Get all the files in the current directory opendir dir, "."; @files = readdir dir; closedir dir; # Make one long string out of all the filenames $fileblob = join "", @files; # Then make a new list out of only the Geocache .txt files # (There MUST be a better way to do this!) @files = $fileblob =~ /GC.+?\.txt/g; # Make a new list containing all the Geocaches that exist in the # current directory but not on the GPS, so we can remove them my @toRemove; outer2: foreach $file (@files) { # For each file in the dir, look at each Geocache on the GPS foreach $ID (@IDs) { # If there's a Geocache that matches the file if (($ID . ".txt") eq $file) { # Skip to the next file in the dir, this one is fine next outer2; } } # If we got here, then we didn't find an ID to match the current file push @toRemove, $file; } # If we found files to remove, take care of them if (scalar(@toRemove) > 0) { # Let the user know what we determined, and give him a few seconds to cancel print "Removing " . scalar(@toRemove) . " caches from the current directory" . "\n"; sleep 5; # Remove the files unlink @toRemove; print "Done\n\n"; } # Remove Geocaches I've already downloaded from the list of IDs outer: foreach $ID (@IDs) { # For each Geocache ID, look at each Geocache .txt file foreach $file (@files) { # If there's a file that matches the ID if (($ID . ".txt") eq $file) { # Remove the ID from the list $ID = undef; # Skip ahead to the next ID in the loop, since we found # a match (no need to look at the rest of the @files) next outer; } } } # For each waypoint in the list whose ID starts with GC, # capture the ID, build a URL, and get the HTML from that URL. foreach $ID (@IDs) { # Skip the IDs we deleted (which are now just null entries in the list) if ($ID eq "") { # Move along, nothing to see here next; } print $ID . "\n"; # Use the ID to create the URL for the Geocache's webpage my $URL = $URLprefix . $ID . $URLsuffix; # Use the URL to create the command to fetch the HTML for the webpage my $CMD = "curl -s \"" . $URL ."\""; # Execute the command and store the results in $HTML my $HTML = `$CMD`; # Update the number of times we've accessed a page $counter++; # Extract the CacheName $HTML =~ /CacheName\"\>(.+?)\; my $CacheName = $1; # Extract the CacheSize $HTML =~ /CacheOwner.+\>(Size:\s.+?)\; my $CacheSize = $1; # Extract the ShortDescription and sanitize it $HTML =~ /ShortDescription\"\>(.+?)\<\/span/s; my $ShortDesc = SanitizeHTML($1); # Extract the LongDescription and sanitize it $HTML =~ /LongDescription\"\>(.+?)\<\/span/s; my $LongDesc = SanitizeHTML($1); # Extract the Hints and sanitize them $HTML =~ /Hints\"\>(.+?)\<\/span/; my $Hints = SanitizeHTML($1); # Open a new file named after the Geocache ID $filename = ">" . $ID . ".txt"; open my $file, $filename or die "Can't creat logfile: $!"; # Write our data out to a file print $file "
and
become carriage returns
$raw =~ s/\
/\n/ig;
$raw =~ s/\
/\n/ig;
#