4 # DO NOT EDIT! This file is generated from geo-nearest.sh
8 # geo-nearest: Fetch list of nearest geocaches.
10 # Requires: curl; gpsbabel; bash or ksh;
11 # mysql (if using the gpsdrive.sql output option)
13 # Donated to the public domain by Rick Richardson <rickr@mn.rr.com>
15 # Use at your own risk. Not suitable for any purpose. Not legal tender.
17 # $Id: geo-nearest.sh,v 1.42 2011/04/06 19:10:38 rick Exp $
25 `basename $PROGNAME` - Fetch a list of nearest geocaches
28 `basename $PROGNAME` [options]
30 `basename $PROGNAME` [options] latitude longitude
32 `basename $PROGNAME` [options] zipcode
34 `basename $PROGNAME` [options] u=<username>
36 `basename $PROGNAME` [options] pq=<pocket-query>
38 `basename $PROGNAME` [options] tx=<bookmark-id>
40 `basename $PROGNAME` [options] -b bookmark
41 `basename $PROGNAME` [options] guid=<bookmark-id>
44 Fetch a list of nearest geocaches.
47 A premium member (\$30/yr) OR a basic member (free) login at:
48 http://www.geocaching.com
49 Visit a cache page and click the "Download to EasyGPS" link at least
50 once so you can read and agree to the license terms. Otherwise, you
51 will not get any waypoint data.
53 curl http://curl.haxx.se/
54 gpsbabel http://gpsbabel.sourceforge.net/
61 A basic member will get caches very slow (20 cache pages per minute)
62 because we have to get the actual cache pages. They will be stored in:
63 ~/.geo/caches/GCXXXX.html.
64 Of course, after running this command, geo-html2gpx could be run.
67 Nearest 20 caches, display shortnames:
71 Search nearest 500 caches for virtual caches not yet found:
73 geo-nearest -n500 -Ivirtual -Xifound
75 Add nearest 50 caches to a GpsDrive SQL database
77 geo-nearest -n50 -f -s -S
79 Purge the existing SQL database of all geocaches, and fetch
82 geo-nearest -S -P -s -n200
84 640x480 map of nearest caches using map source 2:
86 geo-nearest -omap,"-a2 -W640 -H480"
90 geo-nearest -n200 -Xifound -udyl1231 -pPW | awk '{print \$1}' >1.foo
91 geo-nearest -n200 -Xifound -urickrich -pPW |awk '{print \$1}' >2.foo
92 geo-gid -otabsep \$(comm -12 1.foo 2.foo) >both
96 geo-nearest u=team-deadhead
100 # nearby caches of this (puzzle) type, that I haven't found
101 geo-nearest -n500 -f -otabsep tx=40861821-1835-4e11-b666-8d41064d03fe |
102 geo-mystery >> Caches/rick.ts
104 Fetch a bookmark list:
108 geo-nearest guid=baae5bf9-4315-4874-b7fb-ac84c9585641
112 geo-nearest pq=08be103b-ffd1-4e27-992f-616e144e24df
119 geo-newest, geo-found, geo-placed, geo-keyword, geo-code, geo-map,
127 ##############################################################################
128 # begin #include "geo-common"
129 ##############################################################################
131 # I doubt this stuff will work in other than english
135 # Common global constants
137 UA="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)"
138 WEBHOME="http://geo.rkkda.com/"
141 # Common global variables
148 # Report an error and exit
151 echo "`basename $PROGNAME`: $1" >&2
156 if [ $DEBUG -ge $1 ]; then
157 echo "`basename $PROGNAME`: $2" >&2
162 if [ $VERBOSE -ge $1 ]; then
168 if [ $DEBUG -ge $DBGCMD_LVL ]; then
176 # procedure to remove cruft files
179 if [ $DEBUG = 0 -a "$CRUFT" != "" ]; then
182 [ -f $i ] && rm -f $i
187 trap remove_cruft EXIT
190 # Convert DegDec, MinDec, or DMS lat/lon to DegDec
193 # Handle NSEW prefixes
194 arg1=`echo "$1" | sed -e 's/^[nNeE]//' -e 's/^[wW]/-/' -e 's/^[sS]/-/'`
195 # If negative, print the sign then take the absolute value
197 -*) echo -n "-"; arg1=`echo "$arg1" | sed 's/^-//'`;;
199 # Now handle the 3 different formats
203 *.*.*) echo "$arg1" \
204 | sed -e 's/,//' -e 's#\([^.]*\)\.#\1 #' -e 's#$# 6k 60/+p#' \
208 echo "$arg1" | sed 's/^lat=//'
211 echo "$arg1" | sed 's/^lon=//'
217 2) echo "6k $arg1 $2 60/+p" | dc;;
218 3) echo "6k $arg1 $2 60/ $3 3600/++p" | dc;;
223 # Convert DegDec to MinDec
227 'BEGIN{ i=int(v); f=(v-i)*60; if(f<0)f=-f; printf "%d.%06.3f\n", i, f}'
231 # Read RC file, if there is one
234 if [ -f $HOME/.georc ]; then
236 # Allow LAT/LON in rc file to be in any of the formats that we grok
237 if [ "" != "$LAT" ]; then
240 if [ "" != "$LON" ]; then
244 cat <<-EOF > $HOME/.georc
246 # These are the default values for the geo-* series of programs
247 # Please edit this file as needed. Setting values for
248 # USERNAME, PASSWORD, LAT/LON, and STATE are required.
251 #################################
252 # Login and paid membership status for www.geocaching.com...
257 #################################
258 # Your HOME lat/lon and state...
263 #################################
264 # Default map scale, font, and source...
269 #################################
270 # Login for terraserver.com...
271 #TSCOM_EMAIL=xxx@yyy.com
274 #################################
280 error "First time user: please review and edit $HOME/.georc"
284 if [ `uname` = 'Darwin' ]; then
288 PATH=$PATH:/usr/local/bin:/opt/local/bin
297 # Get the value from a name= value= pair in a file
300 # <input type="hidden" name="__EVENTTARGET" value=""
303 eval $what=`$sed -n "s/^.*\"$what\" *value=\"\([^\"]*\)\".*/\1/p" < $where`
309 # incomplete, just does what we need it to do
312 echo "$1" | sed -e 's/\+/%2B/g' -e 's/\&/%26/g' #-e 's/\//%2F/'
322 split("1 2 3 4 5 6 7 8 9 A B C D E F", hextab, " ")
324 for (i = 1; i <= 255; ++i) ord[ sprintf ("%c", i) "" ] = i + 0
328 for (i = 1; i <= length($0); ++i ) {
329 c = substr ($0, i, 1)
331 if (val >= 97 && val <= 122) #0x61-0x7A
333 else if (val >= 65 && val <= 90) #0x41-0x5A
335 else if (val >= 48 && val <= 57) #0x30-0x39
337 else if (val >= 45 && val <= 46) #0x2D-0x2E
340 encoded = encoded "+"
341 else if (val < 128) {
344 encoded = encoded "%" hextab[hi] hextab[lo]
350 encoded = encoded "%" hextab[hi] hextab[lo]
354 encoded = encoded "%" hextab[hi] hextab[lo]
363 # return true if current arguments appear to be a lat/lon
366 if [ "$#" -lt 2 ]; then
370 lat=*) ;; # cut/paste from GPX file
371 [NS]) return 0;; # cut/paste from gc.com
379 [EWew][0-9]*) return 0;;
380 [-][0-9]*) return 0;;
387 # split lines between two strings
393 split_lines_between() {
398 ##############################################################################
399 # end #include "geo-common"
400 ##############################################################################
401 ##############################################################################
402 # begin #include "geo-common-gc"
404 # $Id: geo-common-gc,v 1.242 2011/05/21 17:38:57 rick Exp $
405 ##############################################################################
408 # Common global constants
410 UA="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)"
411 UA="Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/XX (KHTML, like Gecko) Version/ZZ Safari/YY"
412 GEO="http://www.geocaching.com"
413 GEOS="https://www.geocaching.com"
416 # Global variables that can be overridden on command line or rc file
426 CYGWIN*) CURL_OPTS=-k;;
433 COOKIE_FILE=$HOME/.geocookies
445 GEOSLEEP=${GEOSLEEP:-8}
448 # Common options handling
453 -b bookmark Use list "bookmark" [none]
454 -c Remove cookie file when done
455 -f Do not report any found or unavailable caches
456 -m Do not report any members-only caches
457 -F Report caches found by the login 'username' as unfound
458 -n num Return "num" caches [$NUM]
459 -s Output short names for the caches (gpsbabel option)
460 -I term Include only caches with 'term' [$INCLUDE]
461 -X term Exclude caches with 'term' [$EXCLUDE]
462 terms: "" (exclude none), unfound, ifound, soc, unavail,
463 regular, multi, virtual, webcam, event, hybrid, cito
464 -r radius Display only caches with radius (e.g. -r 25M)
465 -M mystery Use file 'mystery' for unknown/mystery/puzzle
466 caches [$GEOMYSTERY]. Awk Format:
469 GC2CBVB n44.45.123 w93.00.321 Final
470 GC2CC1Z 44.123456 -93.564123 Cache
472 -u username Username for http://www.geocaching.com
473 -p password Password for http://www.geocaching.com
474 -o format Output format, -o? for possibilities [$OUTFMT]
475 plus "gpsdrive.sql" for direct insertion into MySQL DB
476 plus "map[,geo-map-opts]" to display a geo-map.
477 -O filename Output file, if not stdout
478 -S Alias for -o gpsdrive.sql
479 -d For -S, just delete selected records
480 -P For -S, purge all records of type -t $SQLTAG*
481 -t type For -ogpsdrive.sql, the waypoint type [$SQLTAG]
482 -H htmldir Also fetch the printable HTML pages (slowly)
483 -L logdir Also fetch the plain text log entries (slowly)
484 For -H or -L, the limit is 1500 updated caches/day.
485 -! "lpr -Plp" Print HTML pages
486 -D lvl Debug level [$DEBUG]
487 -U Retrieve latest version of this script
490 Defaults can also be set with variables in file \$HOME/.georc:
492 PASSWORD=password; USERNAME=username; SOC=0|1;
493 LAT=latitude; LON=logitude; GEOMYSTERY=/dev/null;
494 NUM=num; OUTFMT=format; BABELFLAGS=-s;
495 SQLUSER=gast; SQLPASS=gast; SQLDB=geoinfo;
501 # Defaults for options that cannot be overriden in the RC file
512 while getopts "!:H:L:I:X:b:cdfFmM:n:o:O:p:Pr:sSt:u:D:Uh?-" opt
515 "!") CMDPIPE="$OPTARG";;
516 b) BOOKMARK="$OPTARG";;
519 f) FOUND=0; EXCLUDE="$EXCLUDE|-ifound";;
521 M) GEOMYSTERY="$OPTARG";;
523 if [ "$INCLUDE" = "*" ]; then
528 INCLUDE="$INCLUDE-$OPTARG"
531 if [ "" = "$OPTARG" ]; then
532 EXCLUDE=-ExClUdEnOtHiNg
534 EXCLUDE="$EXCLUDE|-$OPTARG"
542 *) error "Not a number: '$NUM'";;
544 if [ "$NUM" -lt 1 -o "$NUM" -gt 999999 ]; then
545 error "NUM is not between 1 and 999999 ($NUM)"
549 RADIUS_NUM=`awk -v "N=$RADIUS" 'BEGIN{printf "%d\n", N}'`
551 *km*|*KM*) RADIUS_UNITS=km;;
555 s) BABELFLAGS="$BABELFLAGS -s"; GEONUKE=",nuke_placer";;
556 S) OUTFMT="gpsdrive.sql";;
557 t) SQLTAG="$OPTARG";;
558 u) USERNAME="$OPTARG";;
559 p) PASSWORD="$OPTARG";;
560 o) OUTFMT="$OPTARG";;
561 O) OUTFILE="$OPTARG";;
562 H) HTMLDIR="$OPTARG";;
563 L) LOGDIR="$OPTARG";;
565 U) echo "Getting latest version of this script..."
566 curl $CURL_OPTS -o$UPDATE_FILE "$UPDATE_URL"
567 chmod +x "$UPDATE_FILE"
568 echo "Latest version is in $UPDATE_FILE"
575 shiftamt=`expr $OPTIND - 1`
579 0) EXCLUDE="$EXCLUDE|-soc";;
584 OUTFMT=tiger,newmarker=grnpin,iconismarker
588 MAPOPTS=`echo "$OUTFMT" | sed -n 's/map,\(.*\)$/\1/p'`
589 OUTFMT=tiger,newmarker=grnpin,iconismarker
604 LOGUSERNAME="$USERNAME"
613 get_value __EVENTTARGET $file
614 get_value __EVENTARGUMENT $file
615 get_value __VIEWSTATEFIELDCOUNT $file
616 get_value __VIEWSTATE $file; __VIEWSTATE=`urlencode "$__VIEWSTATE"`
617 get_value __EVENTVALIDATION $file;
618 __EVENTVALIDATION=`urlencode "$__EVENTVALIDATION"`
620 viewstate="$viewstate -d __VIEWSTATE=$__VIEWSTATE"
621 if [ "$__VIEWSTATEFIELDCOUNT" != "" ]; then
622 get_value __VIEWSTATE1 $file; __VIEWSTATE1=`urlencode "$__VIEWSTATE1"`
623 get_value __VIEWSTATE2 $file; __VIEWSTATE2=`urlencode "$__VIEWSTATE2"`
624 get_value __VIEWSTATE3 $file; __VIEWSTATE3=`urlencode "$__VIEWSTATE3"`
625 get_value __VIEWSTATE4 $file; __VIEWSTATE4=`urlencode "$__VIEWSTATE4"`
626 get_value __VIEWSTATE5 $file; __VIEWSTATE5=`urlencode "$__VIEWSTATE5"`
627 get_value __VIEWSTATE6 $file; __VIEWSTATE6=`urlencode "$__VIEWSTATE6"`
628 get_value __VIEWSTATE7 $file; __VIEWSTATE7=`urlencode "$__VIEWSTATE7"`
629 get_value __VIEWSTATE8 $file; __VIEWSTATE8=`urlencode "$__VIEWSTATE8"`
630 get_value __VIEWSTATE9 $file; __VIEWSTATE9=`urlencode "$__VIEWSTATE9"`
631 get_value __VIEWSTATE10 $file; __VIEWSTATE10=`urlencode "$__VIEWSTATE10"`
633 viewstate="$viewstate -d __VIEWSTATEFIELDCOUNT=$__VIEWSTATEFIELDCOUNT"
634 viewstate="$viewstate -d __VIEWSTATE1=$__VIEWSTATE1"
635 viewstate="$viewstate -d __VIEWSTATE2=$__VIEWSTATE2"
636 viewstate="$viewstate -d __VIEWSTATE3=$__VIEWSTATE3"
637 viewstate="$viewstate -d __VIEWSTATE4=$__VIEWSTATE4"
638 viewstate="$viewstate -d __VIEWSTATE5=$__VIEWSTATE5"
639 viewstate="$viewstate -d __VIEWSTATE6=$__VIEWSTATE6"
640 viewstate="$viewstate -d __VIEWSTATE7=$__VIEWSTATE7"
641 viewstate="$viewstate -d __VIEWSTATE8=$__VIEWSTATE8"
642 if [ "$__VIEWSTATE9" != "" ]; then
643 # __VIEWSTATEFIELDCOUNT == 9, but VIEWSTATE9 is null on geo-myfinds!
644 viewstate="$viewstate -d __VIEWSTATE9=$__VIEWSTATE9"
645 viewstate="$viewstate -d __VIEWSTATE10=$__VIEWSTATE10"
651 # login to geocaching.com
653 # Outputs: $__VIEWSTATE
656 _username=`urlencode "$1"`
657 _password=`urlencode "$2"`
659 [ "$_username" != dummy ] || error "You need a www.geocaching.com username"
660 [ "$_password" != dummy ] || error "You need a www.geocaching.com password"
663 # Get the login page so we can get a valid viewstate
665 LOGINPAGE=${TMP}-login.html
666 CRUFT="$CRUFT $LOGINPAGE"
668 URL="$GEOS/login/default.aspx"
669 debug 1 "curl $CURL_OPTS $URL"
670 curl $CURL_OPTS -s -A "$UA" -c$COOKIE_FILE \
673 [ -s $LOGINPAGE ] || error "Unable to connect to gc.com"
674 get_value __VIEWSTATE $LOGINPAGE
675 __VIEWSTATE=`urlencode "$__VIEWSTATE"`
676 get_value __EVENTVALIDATION $LOGINPAGE
677 __EVENTVALIDATION=`urlencode "$__EVENTVALIDATION"`
684 URL="$GEOS/login/default.aspx"
687 dbgcmd curl $CURL_OPTS -s -A "$UA" -b$COOKIE_FILE -c$COOKIE_FILE \
688 -d __VIEWSTATE="$__VIEWSTATE" \
689 -d __EVENTVALIDATION="$__EVENTVALIDATION" \
691 -dctl00%24SiteContent%24tbUsername="$_username" \
692 -dctl00%24SiteContent%24tbPassword="$_password" \
693 -dctl00%24SiteContent%24btnSignIn=Login \
694 -L "$URL" > $LOGINPAGE
695 if grep -q "ErrorText" $LOGINPAGE; then
696 error "Login username/password does not match."
701 # procedure to nag about agreeing to EasyGps download license
705 You have not agreed to the waypoint download license at $GEO
707 Click one of the waypoint license agreement links at $GEO,
708 read and agree to the license terms, then try this program again.
713 # getcids infile cidfile xtrafile archfile number
715 # Wade thru the HTML and produce lists of found, notfound and new CIDs
723 -v "USERFOUND=$USERFOUND" \
724 -v "VARTIME=$VARTIME" \
730 function debug(lvl, text) {
732 print text > "/dev/stderr"
734 function hex2dec(x, val) {
735 for (val = 0; length(x); x = substr(x, 2))
736 val = 16*val + index("0123456789ABCDEF", substr(x, 1, 1)) - 1
739 # Convert GC0000 to 58913
740 function wp2id(wp, val) {
743 print "wp2id: " wp " ..." > "/dev/stderr"
744 if (length(wp) <= 4 && wp < "G000")
748 print "wp2id hex: " val " ..." > "/dev/stderr"
751 set = "0123456789ABCDEFGHJKMNPQRTVWXYZ"
753 for (pos = 1; pos <= length(wp); ++pos)
756 val += index(set, substr(wp, pos, 1)) - 1;
760 print "wp2id id: " val " ..." > "/dev/stderr"
763 function id2wp(id, val) {
768 gid = sprintf("GC%04X", id)
771 GcOffset = 16 * 31 * 31 * 31 - 65536
772 GcSet = "0123456789ABCDEFGHJKMNPQRTVWXYZ"
774 for (i = 1; i <= 4; ++i)
776 gid = substr(GcSet, id%31 + 1, 1) gid
779 tmp = substr(GcSet, id%31 + 1, 1)
791 print "id = ", id, "wp = ", gid > "/dev/stderr"
794 function hash2sdt(text,
795 value, mod, sizePre, diff, terrainPre, difficultyPre) {
797 ratingKey = "hbM9fjmrxy7z42LFD58BkKgPGdHscvCqNnw3ptO6lJ"
800 if (length(text) > 6)
801 text = substr(text, length(text) - 6 + 1)
802 # add missing leading zero
803 while (length(text) < 6)
806 for (i = 0; i < 6; i ++) {
807 value += (index(ratingKey, substr(text, i+1, 1)) - 1) \
810 # debug(5, "sdk value: " value)
812 mod = (value - 131586) % 16777216
814 sizePre = int(mod / (42 ^ 3));
815 if (sizePre == 0) diff = 0
816 else if (sizePre == 1) diff = 131072
817 else if (sizePre == 3) diff = 262144
818 else if (sizePre == 5) diff = 393217
819 else if (sizePre == 7) diff = 524288
820 else if (sizePre == 8) diff = 655360
821 else if (sizePre == 12) diff = 917504
824 terrainPre = int((mod - diff) / 252)
825 difficultyPre = int(((mod - diff) % 42) - (terrainPre * 4))
828 if (sizePre == 0) size = "not chosen"
829 else if (sizePre == 1) size = "Micro"
830 else if (sizePre == 3) size = "Regular"
831 else if (sizePre == 5) size = "Large"
832 else if (sizePre == 7) size = "Virtual"
833 else if (sizePre == 8) size = "Unknown"
834 else if (sizePre == 12) size = "Small"
838 if (terrainPre == 0) terrain = 1.0
839 else if (terrainPre == 1) terrain = 1.5
840 else if (terrainPre == 2) terrain = 2.0
841 else if (terrainPre == 3) terrain = 2.5
842 else if (terrainPre == 4) terrain = 3.0
843 else if (terrainPre == 5) terrain = 3.5
844 else if (terrainPre == 6) terrain = 4.0
845 else if (terrainPre == 7) terrain = 4.5
849 if (difficultyPre == 0) difficulty = 1.0
850 else if (difficultyPre == 1) difficulty = 1.5
851 else if (difficultyPre == 2) difficulty = 2.0
852 else if (difficultyPre == 3) difficulty = 2.5
853 else if (difficultyPre == 4) difficulty = 3.0
854 else if (difficultyPre == 5) difficulty = 3.5
855 else if (difficultyPre == 6) difficulty = 4.0
856 else if (difficultyPre == 7) difficulty = 4.5
857 else difficulty = 5.0
859 function begin_new_entry() {
860 # Beginning of a new entry, reset variables to defaults
874 container = "unknown"
875 sendgps = 0 # Non-subscription members
877 #gctype = "Traditional cache"
883 print "Begin " NUM " ..." > "/dev/stderr"
885 function parse_dates(text, cmd, val) {
886 sub("[*]$", "", text)
887 debug(5, "parse_dates: text=" text)
890 cmd = sprintf("%s -d \"%s\" +%%s", DATE, "12am today")
891 cmd | getline val; close(cmd)
893 else if (text ~ /Yesterday/)
895 cmd = sprintf("%s -d \"%s\" +%%s", DATE, "12am yesterday")
896 cmd | getline val; close(cmd)
898 else if (text ~ /ago/)
900 cmd = sprintf("%s -d \"12am %s\" +%%s", DATE, text)
901 cmd | getline val; close(cmd)
903 else if (text ~ /[0-9][^<]*[0-9]/ )
905 cmd = sprintf("%s -d \"12am %s\" +%%s", DATE, text)
906 cmd | getline val; close(cmd)
910 debug(5, "parse_dates: val=" val)
914 q = sprintf("%c", 39)
916 gctype = "Traditional cache"
919 # Test: geo-nearest -s (18)
920 # Test: geo-newest -s (20)
921 # Test: geo-nearest -b multi (8)
923 # For geo-nearest AND geo-nearest -b
924 /class=".* Data BorderTop"/ {
926 debug(3, "Data BorderTop")
932 inrecord && tdcnt >= 1 && tdcnt <= 10 {
934 print "tdcnt " tdcnt ", text: " $0 > "/dev/stderr"
936 /<a href="\/seek\/cache_details.aspx?[^>]*>/ {
939 # remove strikeout class
940 sub("<span class[^>]*>", "", name)
941 sub("</span>", "", name)
942 sub(".*<span>", "", name)
943 sub("</span>.*", "", name)
945 sub(".*<a href=.../seek/cache_details.aspx?[^>]*>", "", name)
946 sub("</a>*.", "", name)
947 sub("</[^>]*>", "", name)
948 sub("</[^>]*>", "", name)
949 sub("<[^>]*>", "", name)
950 sub("<[^>]*>", "", name)
957 /Premium Member Only Cache/ {
960 tdcnt == (8-0) && /[0-9][0-9]*.[0-9][0-9]*/ {
964 sub(/ *<.*/, "", date)
965 sub(/\015/, "", date)
966 debug(5, "date: " date)
967 cmd = sprintf("%s -d \"12am %s\" +%%s", DATE, date)
968 cmd | getline placedt; close(cmd)
969 debug(5, "placedt: " placedt)
972 # Yesterday<strong>*</strong><br />
973 # <span class="Success">
978 # Yesterday<strong>*</strong><br />
979 # <span class="Success">
982 tdcnt == (9-0) && /[a-zA-Z0-9*>]<br .>/ {
983 # catch dates DD MMM YY, N days ago, Today, Yesterday
986 sub(".*<td>", "", date)
988 lastfoundt = parse_dates(date)
990 debug(5, "lastfoundt: " lastfoundt)
992 tdcnt == (9-0) && /[a-zA-Z0-9*>]<.span>/ {
995 sub(".*Success.>", "", date)
997 ifoundt = parse_dates(date)
998 debug(5, "ifoundt: " ifoundt)
1001 # i.e. <font color="red">
1002 avail = 0; archived = 1
1004 /<\/strike><\/font/ {
1005 # i.e. <font color="red">
1006 avail = 0; archived = 1
1011 /class=".*Strike">/ {
1014 /class=".*Warning Strike.*">/ {
1015 avail = 0; archived = 1
1017 tdcnt == 5 && /^ *GC/ {
1019 sub("^ *", "", gcid)
1020 sub("\015", "", gcid)
1021 debug(5, "GCID: <" gcid ">")
1024 /left" nowrap>[0-9].*[0-9][0-9]<.td>/ {
1026 j = match($0, "<.td>")
1027 date = substr($0, i+1, j-i-1)
1029 cmd = sprintf("%s -d \"%s\" +%%s", DATE, date)
1030 cmd | getline placedt; close(cmd)
1032 /left" nowrap>[0-9].*[0-9][0-9].<IMG/ {
1033 # gc.com calls this "new"
1035 j = match($0, " <IMG ")
1036 date = substr($0, i+1, j-i-1)
1038 cmd = sprintf("%s -d \"%s\" +%%s", DATE, date)
1039 cmd | getline placedt; close(cmd)
1041 /alt=.Your Geocache/ {
1043 # A mistake in the HTML! should be alt="my cache"
1049 /alt="Earthcache"/ {
1051 gctype = "Earthcache"
1053 /alt="Event Cache"/ {
1055 gctype = "Event cache"
1057 /alt="Cache In Trash Out Event"/ {
1059 gctype = "Cache In Trash Out Event"
1061 /alt="Traditional Cache"/ {
1063 gctype = "Traditional cache"
1065 /alt="Letterbox Hybrid"/ {
1067 gctype = "Letterbox Hybrid"
1069 /alt="Multi-cache"/ {
1071 gctype = "Multi-Cache"
1073 /alt="Unknown Cache"/ {
1075 gctype = "Unknown Cache"
1077 /alt="Virtual Cache"/ {
1079 gctype = "Virtual cache"
1081 /alt="Webcam Cache"/ {
1083 gctype = "Webcam Cache"
1085 /alt="Wherigo Cache"/ {
1087 gctype = "Wherigo Cache"
1089 /alt="Mega-Event Cache"/ {
1091 gctype = "Mega-Event Cache"
1094 i = match($0, "value=.")
1095 cid = substr($0, i+7, 99) + 0
1098 i = match($0, "value=.")
1099 bid = substr($0, i+7, 99) + 0
1101 #/ImgGen.seek.CacheInfo.ashx?v=/ {
1104 debug(5, "sdt text: " text)
1105 sub(".*?v=", "", text)
1106 sub(". .*", "", text)
1107 debug(5, "sdt text: " text)
1109 debug(5, "size: " size " difficulty: " difficulty " terrain: " terrain)
1112 /Unapproved cache/ && inrecord {
1113 avail = 0; archived = 1
1115 /class=.Checkbox NoBolding./ {
1116 sendgps = 1 # Subscription members
1118 /<\/[tT][rR]>/ && inrecord {
1119 # RER mod 11/22/10: if (0 && ..
1120 if (0 && sendgps == 0)
1125 strtype = "Geocache"
1127 if (soc) strtype = strtype "-soc"
1128 if (unfound) strtype = strtype "-unfound"
1129 else if (ifound) strtype = strtype "-ifound"
1130 if (!avail) strtype = strtype "-unavail"
1131 if (archived) strtype = strtype "-archived"
1133 strtype = strtype "-" type
1135 # gpsbabel only allows one time in the DB, figure out what
1136 # time to use for this, but always carry all three times
1138 if (iplaced) ifoundt = placedt
1140 if (VARTIME == "placed") vartime = placedt
1141 else if (VARTIME == "ifound") vartime = ifoundt
1142 else if (foundt > 0) vartime = foundt
1143 else vartime = placedt
1145 # date -d 1970-01-01 1237093200 sec +%Y%m%d
1147 cmd = sprintf("%s -d \"1970-01-01 %d sec\" +%%Y%%m%%d",
1149 cmd | getline lastfound; close(cmd)
1151 # avail=1 is the choice right now (8/19/05)
1152 # archived=0 is the choice right now (11/14/06)
1153 if (!archived && (SOC || !soc))
1156 printf("-dBID=%d\n", bid) > CIDFILE
1158 } else if (cid != 0) {
1159 printf("-dCID=%d\n", cid) > CIDFILE
1161 # GCID type vartime ifound soc iplaced tPLACED tFOUND tIFOUND
1163 #difficulty, terrain, container,
1164 printf "%s\t%s\t%d\t%s\t%s\t%s\t%d\t%d\t%d\t" \
1166 gcid, strtype, vartime,
1167 ifound, soc, iplaced, placedt, foundt, ifoundt,
1168 gctype, "hint", lastfound >> XTRAFILE
1175 print "Archived ", gcid, " " name > "/dev/stderr"
1177 name = "error-no-name!"
1178 # Use "merge" file output, NOT XTRAFILE!
1179 printf "%s\t%s\t0.0\t0.0\t%s%s%s\t%s\t%d\t" \
1180 "%s\t%s\t%s\t%d\t%d\t%d\t%.1f\t%.1f\t%s\t%s\t%s\t%s\n",
1182 "http://www.geocaching.com/seek/cache_details.aspx",
1184 difficulty, terrain, container,
1186 ifound, soc, iplaced, placedt, foundt, ifoundt,
1187 gctype, "hint", lastfound >> ARCHFILE
1196 # A temporary style we can use for merging the loc data with
1197 # the scraped html data. This is a dual purpose hack. We
1198 # use it as an output format to convert the .loc data to a
1199 # record-per-line format. We use it as an input format to
1200 # read up the merged data.
1202 make_scrape_style() {
1206 RECORD_DELIMITER NEWLINE
1208 IFIELD SHORTNAME, "", "%s"
1209 IFIELD DESCRIPTION, "", "%s"
1210 IFIELD LAT_DECIMAL, "", "%08.5f"
1211 IFIELD LON_DECIMAL, "", "%08.5f"
1212 IFIELD URL, "", "%s"
1213 IFIELD GEOCACHE_DIFF, "", "%3.1f" #difficulty
1214 IFIELD GEOCACHE_TERR, "", "%3.1f" #terrain
1215 IFIELD GEOCACHE_CONTAINER,"", "%s" #container (not set)
1216 IFIELD ICON_DESCR, "", "%s" #strtype (Geocache-*)
1217 IFIELD TIMET_TIME, "", "%ld" #variable time
1218 IFIELD IGNORE, "", "%s" #ifound
1219 IFIELD IGNORE, "", "%s" #soc
1220 IFIELD IGNORE, "", "%s" #iplaced
1221 IFIELD IGNORE, "", "%s" #placed time
1222 IFIELD IGNORE, "", "%s" #found time
1223 IFIELD IGNORE, "", "%s" #ifound time
1224 IFIELD GEOCACHE_TYPE, "", "%s" #gc.com type
1225 IFIELD GEOCACHE_HINT, "", "%s" #gc.com hint
1226 IFIELD GEOCACHE_LAST_FOUND, "","%s" #gc.com last found
1227 OFIELD SHORTNAME, "", "%s"
1228 OFIELD DESCRIPTION, "", "%s"
1229 OFIELD LAT_DECIMAL, "", "%08.5f"
1230 OFIELD LON_DECIMAL, "", "%08.5f"
1231 OFIELD URL, "", "%s"
1232 OFIELD GEOCACHE_DIFF, "", "%3.1f" #difficulty
1233 OFIELD GEOCACHE_TERR, "", "%3.1f" #terrain
1234 OFIELD GEOCACHE_CONTAINER,"", "%s" #container (not set)
1236 # OFIELD ICON_DESCR, "", "%s"
1240 # csv2csv puzzle-file
1243 if [ ! -e "$1" ]; then
1244 error "Don't have a -M '$1' file"
1247 awk -v GEOMYSTERY=$1 '
1248 function latlon ( val ) {
1249 if (val ~ ".[.]..*[.].*")
1251 if (val ~ "[-wWsS]")
1253 val = substr(val, 2)
1256 else if (val ~ "[nNeE]")
1258 val = substr(val, 2)
1264 sub("[^.]*[.]", "", val)
1265 dd += (val+0.0) / 60.0
1266 return neg ? -dd : dd
1271 while (getline <GEOMYSTERY > 0)
1293 deglat = latlon( lat[$1] )
1294 deglon = latlon( lon[$1] )
1295 # GC# Desc lat lon URL diff terr size
1296 for (i = 1; i <= 2; ++i)
1298 printf "%.6f\t%.6f\t", deglat, deglon
1299 for (i = 5; i < NF; ++i)
1310 # Query the gc website
1313 if [ $USERFOUND = 0 ]; then
1316 if [ $FOUND = 0 ]; then
1317 SEARCH="$SEARCH&f=1"
1320 if [ $DEBUG -gt 0 ]; then
1334 MERGEFILE=$TMP.merge
1339 CRUFT="$CRUFT $HTMLPAGE"
1340 CRUFT="$CRUFT $CIDFILE"
1341 CRUFT="$CRUFT $LOCFILE"
1342 CRUFT="$CRUFT $LOCTMPFILE"
1343 CRUFT="$CRUFT $XTRAFILE"
1344 CRUFT="$CRUFT $CSVFILE"
1345 CRUFT="$CRUFT $CSVFILE2"
1346 CRUFT="$CRUFT $JOINFILE"
1347 CRUFT="$CRUFT $MERGEFILE"
1348 CRUFT="$CRUFT $ARCHFILE"
1349 CRUFT="$CRUFT $OUTWAY"
1350 CRUFT="$CRUFT $STYLE"
1351 if [ $NOCOOKIES = 1 ]; then
1352 CRUFT="$CRUFT $COOKIE_FILE"
1358 gc_login "$USERNAME" "$PASSWORD"
1363 if [ "$BOOKMARK" != "" ]; then
1364 URL="$GEO/bookmarks"
1365 debug 1 "$start: curl $URL #bookmark"
1367 curl $CURL_OPTS -L -s -b $COOKIE_FILE -A "$UA" "$URL" \
1368 | grep -y ">$BOOKMARK<" \
1369 | sed -e 's@^.*href=.http://www.geocaching.com/@@' -e 's/.>.*$//'
1373 *) error "No bookmark with the name '$BOOKMARK'.";;
1378 # We might combine one or more pages into a single XML, so cobble
1379 # up a header with the ?xml and loc tags.
1381 cat <<-EOF > $LOCFILE
1382 <?xml version="1.0" encoding="UTF-8"?>
1383 <loc version="1.0" src="EasyGPS">
1387 # Loop, getting at least "NUM" locations
1390 if [ $DEBUG -gt 0 ]; then
1391 filter2="tee $TMP.bulk"
1400 while ((start <= NUM)); do
1404 # Fetch the page of closest caches and scrape the cache ID's
1411 URL="$GEO/seek/nearest.aspx"
1415 debug 1 "$start: curl $URL #list"
1416 if ((start > 0)); then
1417 # "postback"... grab the "next" button
1420 __EVENTTARGET="ListInfo\$pgrBMItems\$_ctl8"
1423 TGT=$(sed -n "s/^.*__doPostBack('.*pgrTop\$\(.*\)','.*/\1/p" \
1425 if [ "$TGT" = "" ]; then
1426 error "TGT is blank!"
1428 __EVENTTARGET="ctl00%24ContentBody%24pgrTop%24$TGT"
1431 curl $CURL_OPTS -L -s -b $COOKIE_FILE -A "$UA" \
1432 -d __EVENTTARGET="$__EVENTTARGET" \
1435 | sed -e "s/'/'/g" -e "s/\r//" > $HTMLPAGE
1437 curl $CURL_OPTS -L -s -b $COOKIE_FILE -A "$UA" \
1439 | sed -e "s/'/'/g" -e "s/\r//" > $HTMLPAGE
1440 if [ "$DEBUG" -ge 1 ]; then
1441 grep "Total Records:.*Top.*" $HTMLPAGE |
1442 sed -e "s/<.b>.*//" -e "s/^.*span>//" -e "s/<b>//" 1>&2
1445 rc=$?; if [ $rc != 0 ]; then
1446 error "curl: fetch $URL"
1448 if grep -s -q "We encountered an error when requesting that page!" \
1450 error "searching error (1) on $start"
1452 if grep -s -q "has resulted in an error" \
1454 error "searching error (2) on $start"
1456 if grep -s -q "By State" $HTMLPAGE; then
1457 error "searching gave up on $start"
1459 if grep -s -q ">Advanced Search<" $HTMLPAGE; then
1460 error "need a country AND a state!"
1464 # Grab a few important values from the page
1466 gc_getviewstate $HTMLPAGE
1469 # Grab the CIDs into two categories: found and notfound
1472 getcids $HTMLPAGE $CIDFILE $XTRAFILE $ARCHFILE $((NUM-start))
1475 # Fetch the waypoints, rip out the ?xml and loc tags, and
1476 # append to the $LOCFILE file.
1478 if [ -s "$CIDFILE" ]; then
1485 URL="$GEO/seek/nearest.aspx"
1489 debug 2 "$start: curl $URL #loc"
1490 curl $CURL_OPTS -s -b $COOKIE_FILE -A "$UA" \
1493 -d "Download=Download+Waypoints" \
1494 -d "ListInfo:btnDownload=Download+to+.Loc" \
1497 | sed -e 's/^<?xml [^>]*>//' \
1498 -e 's/>[gG]eocache</>Geocache</g' \
1499 -e 's/<loc [^>]*>//' \
1502 rc=$?; if [ $rc != 0 ]; then
1503 error "curl: fetch the waypoints"
1505 if grep -s -q "you are not logged in" $LOCTMPFILE; then
1506 error "you are not logged in on $start"
1508 if grep -s -q "has resulted in an error" $LOCTMPFILE; then
1509 error "searching error (3) on $start"
1511 if grep -s -q "Geocaching > Search for Geocaches" $LOCTMPFILE; then
1512 error "searching error (4) on $start"
1514 if grep -s -q "recaptcha_challenge_field" $LOCTMPFILE; then
1516 # Basic members: do it the SLOW way
1518 if [ "$GEODIR" != "" -a ! -d "$GEODIR" ]; then
1519 mkdir "$GEODIR" || error "Couldn't mkdir $GEODIR"
1521 if [ "$GEODIR/caches" != "" -a ! -d "$GEODIR/caches" ]; then
1522 mkdir "$GEODIR/caches" \
1523 || error "Couldn't mkdir $GEODIR/caches"
1526 if [ $subscriber = 1 ]; then
1527 debug 0 "Basic Member: pay the \$30/yr fee for Premium Member!"
1528 debug 0 "Basic Member: doing it the REAL SLOW way!!!"
1529 timestamp="$GEODIR/caches/.timestamp"
1530 $touch -d "1 day ago" $timestamp
1538 grep "^ *GC.*" $HTMLPAGE \
1540 | while read gcid; do
1542 # Get the cache page
1544 cachepage="$GEODIR/caches/$gcid.html"
1545 if [ ! -s $cachepage -o $timestamp -nt $cachepage ]; then
1546 # cache page doesn't exist or out of date
1548 urlpage="http://www.geocaching.com"
1549 urlpage="$urlpage/seek/cache_details.aspx"
1550 urlpage="$urlpage?log=y&wp=$gcid"
1551 debug 0 "$bstart: curl $urlpage #cache fetch $gcid.html"
1552 curl $CURL_OPTS -L -s -b $COOKIE_FILE -A "$UA" \
1553 $urlpage > $cachepage
1557 # Cobble up the .loc file entry
1559 name=` grep -A1 "<head><title>" $cachepage \
1560 | tail -1 | tr -d "\r" \
1561 | sed -e 's/[ ]*GC[^ ]* //' -e 's/ (.*by/ by/' `
1562 diff=` grep ctl00_ContentBody_uxLegendScale $cachepage \
1563 | sed -e 's/.*alt="//' -e 's/ .*//' `
1564 terr=` grep ctl00_ContentBody_Localize6 $cachepage \
1565 | sed -e 's/.*alt="//' -e 's/ .*//' `
1566 size=` grep "alt=.Size:" $cachepage \
1567 | sed -e 's/.*alt="Size: //' -e 's/" .*//' `
1580 echo "<name id=\"$gcid\"><![CDATA[$name]]></name>"
1581 grep "lnkConversions" $cachepage \
1582 | sed -e 's/.*lat=/<coord lat="/' \
1583 -e 's/&lon=/" lon="/' -e 's@&.*@"/>@'
1584 echo "<type>Geocache</type>"
1585 echo -n "<link text=\"Cache Details\">"
1586 urlpage="http://www.geocaching.com"
1587 urlpage="$urlpage/seek/cache_details.aspx"
1588 urlpage="$urlpage?wp=$gcid"
1591 echo "<difficulty>$diff</difficulty>"
1592 echo "<terrain>$terr</terrain>"
1593 echo "<container>$cont</container>"
1596 debug 3 "bstart: $bstart"
1597 if [ $bstart == $NUM ]; then
1604 cat $LOCTMPFILE >> $LOCFILE
1609 # Check to see if the user hasn't agreed to license terms
1611 if grep -s -q "lblAgreementText" $LOCFILE; then
1619 # If the Next button is disabled, break this loop
1620 # grep "Records: <b>[1-9].*disabled.><b>Next<" $HTMLPAGE
1621 if grep -s -q "Records: <b>[1-9].*disabled.><b>Next " $HTMLPAGE; then
1622 # echo "$start: dis"
1628 # Finish off the .loc file
1630 echo "</loc>" >> $LOCFILE
1633 # Convert the .loc data to .csv format and join it with
1634 # the extra data scraped from the HTML page. Filter out
1635 # the data according to the -I and -X options.
1637 # http://www.geocaching.com/seek/cache_details.aspx?wp=GCG2H4
1638 # http://www.geocaching.com/seek/cache_details.aspx?log=y&wp=GCG2H4
1639 # http://www.geocaching.com/seek/cache_details.aspx?ID=92117&log=y
1641 # The joined .csv format looks like this:
1642 # GCH636 Jidana 3 by rickrich 44.94520 -93.47540 \
1643 # http://www.geocaching.com/seek/cache_details.aspx?log=y&wp=GCH636 \
1644 # Geocache-ifound-regular 1070285077 1 0 1 \
1645 # 1067925600 1070285077 0
1647 make_scrape_style > $STYLE
1649 dbgcmd gpsbabel -i geo$GEONUKE -f $LOCFILE \
1650 -o xcsv,style=$STYLE -F $CSVFILE2
1651 if [ $? != 0 ]; then
1652 cp $LOCFILE /tmp/geo.err
1653 error "gpsbabel returned error code [1]"
1656 # Convert CSV into CSV with puzzles...
1657 csv2csv $GEOMYSTERY < $CSVFILE2 > $CSVFILE
1659 join -t ' ' $CSVFILE $XTRAFILE > $JOINFILE
1660 if [ $? != 0 ]; then
1661 cp $CSVFILE /tmp/geo.err.csv
1662 cp $XTRAFILE /tmp/geo.err.xtra
1663 error "joined file error: see join /tmp/geo.err.{csv,xtra}"
1665 egrep -- "$INCLUDE" < $JOINFILE \
1666 | egrep -v -- "$EXCLUDE" \
1667 | sed -e 's/wp=/log=y\&&/' > $MERGEFILE
1669 if [ $FOUND = 1 ]; then
1671 | egrep -- "$INCLUDE" | egrep -v -- "$EXCLUDE" \
1672 | sed -e 's/wp=/log=y\&&/' >> $MERGEFILE
1675 if [ $DEBUG -ge 2 ]; then
1676 # First two of these should be the same number of lines!
1679 wc -l $MERGEFILE >&2
1683 # Convert to the desired format
1686 if [ "$RADIUS" != "" ]; then
1687 BABELFILT="-x radius,distance=$RADIUS,lat=$LAT,lon=$LON"
1690 if [ $SQL = 1 ]; then
1694 if [ "$OUTFILE" != "" ]; then
1698 if [ $PURGE = 1 ]; then
1699 gpsdrive_purge | gpsdrive_mysql
1703 dbgcmd gpsbabel $BABELFLAGS \
1704 -i xcsv,style=$STYLE -f $MERGEFILE \
1705 $BABELFILT -o "$OUTFMT" -F $OUTWAY
1706 if [ $? != 0 ]; then
1707 error "gpsbabel returned error code [2]"
1709 gpsdrive_add <$OUTWAY $SQLTAG | gpsdrive_mysql
1710 elif [ $MAP = 1 ]; then
1711 dbgcmd gpsbabel $BABELFLAGS \
1712 -i xcsv,style=$STYLE -f $MERGEFILE \
1713 $BABELFILT -o "$OUTFMT" -F $OUTWAY
1714 if [ $? != 0 ]; then
1715 error "gpsbabel returned error code [3]"
1717 if [ "$OUTFILE" = "" ]; then
1718 dbgcmd geo-map -s0 $MAPOPTS -t$OUTWAY
1720 dbgcmd geo-map -s0 $MAPOPTS -t$OUTWAY -o"$OUTFILE"
1724 # output to stdout or to a file
1726 if [ "$OUTFILE" = "" ]; then
1727 OUTTMP="$TMP.way"; CRUFT="$CRUFT $OUTTMP"
1728 dbgcmd gpsbabel $BABELFLAGS \
1729 -i xcsv,style=$STYLE -f $MERGEFILE \
1730 $BABELFILT -o "$OUTFMT" -F $OUTTMP
1731 if [ $? != 0 ]; then
1732 error "gpsbabel returned error code [4]"
1736 dbgcmd gpsbabel $BABELFLAGS \
1737 -i xcsv,style=$STYLE -f $MERGEFILE \
1738 $BABELFILT -o "$OUTFMT" -F $OUTFILE
1739 if [ $? != 0 ]; then
1740 error "gpsbabel returned error code [5]"
1746 # Optionally, print the HTML pages
1748 if [ "$CMDPIPE" != "" ]; then
1751 while read id desc lat lon url diff terr container strtype \
1752 vartime ifound soc iplaced placedt foundt ifoundt extra; do
1753 url="$url&decrypt=y"
1756 CRUFT="$CRUFT $HTMLPAGE2"
1757 debug 1 "curl $url" >&2
1758 dbgcmd curl $CURL_OPTS -s -A "$UA" -b $COOKIE_FILE "$url" > $HTMLPAGE2
1759 htmldoc --quiet -t ps --nup 2 --fontsize 14 --webpage $HTMLPAGE2 \
1760 | psselect -q -p1-1 | eval $CMDPIPE
1767 # Optionally, fetch printable HTML pages
1769 if [ "$HTMLDIR" != "" -o "$LOGDIR" != "" ]; then
1770 if [ "$HTMLDIR" != "" -a ! -d "$HTMLDIR" ]; then
1771 mkdir "$HTMLDIR" || error "Couldn't mkdir $HTMLDIR"
1773 if [ "$LOGDIR" != "" -a ! -d "$LOGDIR" ]; then
1774 mkdir "$LOGDIR" || error "Couldn't mkdir $LOGDIR"
1778 CRUFT="$CRUFT $HTMLPAGE2"
1780 CRUFT="$CRUFT $TIMESTAMP"
1784 if [ $DEBUG -ge 3 ]; then
1789 while read id desc lat lon url diff terr container strtype \
1790 vartime ifound soc iplaced placedt foundt ifoundt extra; do
1792 # Don't fetch page if we already have a current version
1794 if [ $placedt -gt $foundt ]; then
1799 $touch -d "1/1/70 $filetime seconds last second" $TIMESTAMP
1800 if [ "$filetime" -gt 0 -a "$HTMLDIR/$id.html" -nt $TIMESTAMP ]; then
1805 if [ "$subscriber" == 0 -a "$HTMLDIR" != "" ]; then
1806 debug 2 "cp $GEODIR/caches/$id.html $HTMLDIR/$id.html"
1807 cp "$GEODIR/caches/$id.html" "$HTMLDIR/$id.html"
1808 # debug 2 "f: $filetime"
1809 if [ "$filetime" -gt 0 ]; then
1810 $touch -d "1/1/70 $filetime seconds" "$HTMLDIR/$id.html"
1815 # Limit to 1000 caches/day
1816 ((fetchcnt=fetchcnt+1))
1817 if [ $fetchcnt -gt $fetchmax ]; then
1818 error "Fetch count exceeded $fetchmax. Try tomorrow!"
1821 # Be kind to the server. Do not remove this sleep
1824 echo "<BASE HREF=http://www.geocaching.com/seek/>" > $HTMLPAGE
1825 debug 1 "curl $url" >&2
1826 dbgcmd curl $CURL_OPTS -s -A "$UA" -b $COOKIE_FILE "$url" |
1827 tr -d "\001\007\010\013\017\020\031" >> $HTMLPAGE
1828 if [ $? != 0 ]; then
1829 error "Couldn't fetch $id cache page"
1832 size=$(ls -l $HTMLPAGE | awk '{print $5}')
1833 if [ $size -lt 1000 ]; then
1834 debug 0 "Could not retrieve web page for cache $id"
1838 if [ "$HTMLDIR" != "" ]; then
1839 cp $HTMLPAGE "$HTMLDIR/$id.html" ||
1840 error "Couldn't copy $id cache page"
1841 if [ "$filetime" -gt 0 ]; then
1842 $touch -d "1/1/70 $filetime seconds" "$HTMLDIR/$id.html"
1846 if [ "$LOGDIR" != "" ]; then
1847 sed -e '1,/Cache find counts/d' -e 's/<STRONG><IMG SRC=/\
1849 egrep ">$LOGUSERNAME<|strong> \($LOGUSERNAME\) \(" > $HTMLPAGE2
1850 lynx -dump $HTMLPAGE2 > $LOGDIR/$id.log
1851 if [ "$filetime" -gt 0 ]; then
1852 $touch -d "1/1/70 $filetime seconds" "$LOGDIR/$id.log"
1858 if [ "$LOGDIR" != "" ]; then
1859 # This is a hack, and might be innaccurate
1860 echo -n "Finds:" >&2
1861 MONTHS=" January | February | March | April | May | June "
1862 MONTHS="$MONTHS| July | August | September | October "
1863 MONTHS="$MONTHS| November | December "
1864 egrep "$MONTHS" $LOGDIR/*.log |
1865 egrep "icon_smile|icon_happy|icon_camera" | wc -l >&2
1871 ##############################################################################
1872 # end #include "geo-common-gc"
1873 ##############################################################################
1874 ##############################################################################
1875 # begin #include "geo-common-gpsdrive"
1876 ##############################################################################
1879 # default MySQL global options...
1884 SQLITEDB=$HOME/.gpsdrive/waypoints.db
1888 # procedures for updating gpsdrive database via MySQL
1890 # Global Vars: $SQLDB, $SQLTAG $OUTFILE
1892 gpsdrive_create_210() {
1893 echo "CREATE TABLE poi ("
1894 echo "poi_id INTEGER PRIMARY KEY,"
1895 echo "name VARCHAR(80) NOT NULL default 'not specified',"
1896 echo "poi_type VARCHAR(160) NOT NULL default 'unknown',"
1897 echo "lat DOUBLE NOT NULL default '0',"
1898 echo "lon DOUBLE NOT NULL default '0',"
1899 echo "alt DOUBLE default '0',"
1900 echo "comment VARCHAR(255) default NULL,"
1901 echo "last_modified DATETIME NOT NULL default '0000-00-00',"
1902 echo "source_id INTEGER NOT NULL default '1',"
1903 echo "private CHAR(1) default NULL);"
1904 echo "CREATE TABLE poi_extra ("
1905 echo "poi_id INTEGER NOT NULL default '0',"
1906 echo "field_name VARCHAR(160) NOT NULL default '0',"
1907 echo "entry VARCHAR(8192) default NULL);"
1911 case "$GPSDRIVE_VER" in
1913 delcmd="delete from waypoints"
1915 echo "$delcmd where type like '$SQLTAG%';"
1918 if [ ! -s $SQLITEDB ]; then
1921 delcmd="delete from poi"
1922 echo "$delcmd where poi_type like '$SQLTAG%';"
1927 gpsdrive_add_209() {
1928 delcmd="delete from waypoints"
1929 addcmd="replace into waypoints (name,lat,lon,type)"
1932 while read name lat lon type extra
1934 name=`echo "$name" | tr -d "'"`
1935 # Primary key is autoincrementing id number, so delete
1936 # the old record (if any) by name and type
1937 if [ $PURGE = 0 ]; then
1938 echo "$delcmd where name='$name' and type like '$SQLTAG%';"
1941 if [ $DELETE = 0 ]; then
1942 # Add the new record
1943 if [ "$sqltag" = "Geocache" ]; then
1948 echo "$addcmd values ('$name','$lat','$lon','$tag');"
1954 if [ ! -s $SQLITEDB ]; then
1957 delcmd="delete from poi"
1958 addcmd="replace into poi (poi_id,name,poi_type,lat,lon,alt,comment,last_modified)"
1960 sqltag=`echo "$sqltag" | tr A-Z a-z`
1963 #while read name lat lon type extra
1965 egrep -v 'Geocache Found|-ifound' | tr ' ' '|' | tr -d "'" |
1966 while read index shortname description notes url urltext icon lat lon \
1967 lat32 lon32 latdecdir londecdir latdirdec londirdec latdir londir \
1968 altfeet altmeters excel timet diff terr container type \
1969 pathmiles pathkm placer yyyymmmdd hint lastfound extra
1971 if [ "$placer" = "$USERNAME" ]; then
1974 if [ "$placer" = "dyl1231" ]; then
1977 name=`echo "$description" | tr -d "'"`
1978 # Primary key is autoincrementing id number, so delete
1979 # the old record (if any) by name and type
1980 if [ $PURGE = 0 ]; then
1981 echo "$delcmd where name='$name' and poi_type like '%$sqltag%';"
1985 if [ $DELETE = 0 ]; then
1986 # Add the new record
1987 if [ "$sqltag" = "geocache" ]; then
1993 "Earthcache") poi_type="geocache.geocache_earth";;
1994 "Event Cache") poi_type="geocache.geocache_event";;
1995 "Mega-Event Cache") poi_type="geocache.geocache_event";;
1996 "Cache In Trash Out Event") poi_type="geocache.geocache_event";;
1997 "found") poi_type="geocache.geocache_found";;
1998 "Multi-cache") poi_type="geocache.geocache_multi";;
1999 "Unknown Cache") poi_type="geocache.geocache_mystery";;
2000 "night") poi_type="geocache.geocache_night";;
2001 "Traditional Cache") poi_type="geocache.geocache_traditional";;
2002 "Virtual Cache") poi_type="geocache.geocache_virtual";;
2003 "Webcam Cache") poi_type="geocache.geocache_webcam";;
2004 *) poi_type="geocache";;
2006 echo -n "$addcmd values ($poi_id,'$name','$poi_type',"
2007 echo -n "'$lat','$lon',"
2008 echo -n "'0.0'," #alt
2009 echo -n "'$type $container $diff/$terr. Last Found: $lastfound. $hint',"
2017 case "$GPSDRIVE_VER" in
2018 ""|"2.09") gpsdrive_add_209 "$1";;
2019 "2.10") gpsdrive_add_210 "$1";;
2024 if [ "$OUTFILE" != "" ]; then
2026 elif [ $DEBUG -gt 0 ]; then
2029 mysql -u$SQLUSER -p$SQLPASS
2033 gpsdrive_sqlite3() {
2034 if [ "$OUTFILE" != "" ]; then
2036 elif [ $DEBUG -gt 0 ]; then
2039 sqlite3 $HOME/.gpsdrive/waypoints.db
2044 # Extended list of gpsbabel output formats
2046 gpsbabel_formats() {
2047 gpsbabel -? | sed -e '1,/File Types/d' -e '/Supported data filters/,$d'
2048 echo " gpsdrive.sql " \
2049 "GpsDrive direct MySQL database insertion"
2050 echo " map[,geo-map-opts] " \
2051 "Display map of waypoints using geo-map"
2054 ##############################################################################
2055 # end #include "geo-common-gpsdrive"
2056 ##############################################################################
2059 # Set default options, can be overriden on command line or in rc file
2061 UPDATE_URL=$WEBHOME/geo-nearest
2062 UPDATE_FILE=geo-nearest.new
2067 # Process the options
2078 # Cut and paste from geocaching.com cache page
2079 # N 44° 58.630 W 093° 09.310
2080 LAT=`echo "$1$2.$3" | tr -d '\260\302' `
2082 LON=`echo "$4$5.$6" | tr -d '\260\302' `
2084 SEARCH="?origin_lat=$LAT&origin_long=$LON"
2089 SEARCH="?origin_lat=$LAT&origin_long=$LON"
2093 iraq|Iraq) SEARCH="?country_id=97" ;;
2103 SEARCH="?$1&lat=$LAT&lng=$LON"
2106 SEARCH="bookmarks/view.aspx?$1"
2113 error "'$1' isn't something I understand how to search for"
2118 SEARCH="?origin_lat=$LAT&origin_long=$LON"