]>
Commit | Line | Data |
---|---|---|
28c82d8b EB |
1 | #!/usr/bin/env python |
2 | ||
3 | # | |
4 | # gcget -- screen scrape Geocaching.com's annoying web interface | |
5 | # aka SHOW ME THE CACHE!!! | |
6 | # | |
7 | # Copyright 2007, Evan Battaglia | |
8 | # Distributed under the terms of the GPS v2. | |
9 | # | |
05225ccd | 10 | # |
28c82d8b | 11 | # requires module mechanize |
05225ccd | 12 | # |
05225ccd | 13 | |
28c82d8b EB |
14 | USER="username" |
15 | PASS="password" | |
16 | ||
17 | # docs needed! | |
18 | # this has some extra args in: | |
19 | # gcget lat,lon maxnumgcs [maxdist] [threshold] | |
20 | # threshold -- if find more than this # of geocaches, don't get ANY, | |
21 | # instead give warning and quit | |
22 | ||
23 | import sys | |
24 | ll = sys.argv[1].split(",") | |
25 | lat = ll[0] | |
26 | lon = ll[1] | |
27 | ||
28 | if len(sys.argv) >= 4: | |
29 | maxdist = sys.argv[3] | |
30 | else: | |
31 | maxdist = "999" | |
32 | if len(sys.argv) >= 5: | |
33 | threshold = int(sys.argv[4]) | |
34 | else: | |
35 | threshold = 1000000; | |
36 | ||
37 | # rounds up to multiples of 20. 20 | |
38 | n = int((int(sys.argv[2])+19)/20) | |
39 | ||
40 | import re | |
41 | from mechanize import Browser | |
42 | import ClientForm | |
43 | ||
44 | def getmagicnumber(b): | |
45 | for i in range(16,0,-1): | |
46 | if re.compile("pgrBottom..ctl%d" % i).search(b.response().get_data()): | |
47 | return i | |
48 | return 0 | |
49 | ||
50 | b=Browser() | |
51 | b.open("http://geocaching.com/seek/") | |
52 | b.follow_link(text_regex="log in") | |
53 | b.select_form(nr=0) | |
54 | b["myUsername"] = USER | |
55 | b["myPassword"] = PASS | |
56 | b.submit() | |
57 | ||
58 | magicnumber = 0 # the ctl number of Next. get only once | |
59 | ||
60 | try: b.select_form("form4") | |
61 | except: pass | |
62 | b.select_form("form4") | |
63 | b["origin_lat"] = lat | |
64 | b["origin_long"] = lon | |
65 | b["dist"] = maxdist | |
66 | b.submit() | |
67 | ||
68 | thresholdre = re.compile("Total Records: <b>([0-9]*)</b>") | |
69 | m = thresholdre.search(b.response().get_data()) | |
70 | if m: | |
71 | if int(m.group(1)) > threshold: | |
72 | sys.stderr.write("THRESHOLD %d > %d\n" % (int(m.group(1)), threshold)) | |
73 | sys.exit(4) | |
74 | else: | |
75 | records = int(m.group(1)) | |
76 | sys.stderr.write("ok found %d, getting min(%d,%d) gcs\n" % (int(m.group(1)), int(records), int(sys.argv[2]))) | |
77 | else: | |
78 | print "can't find total records" | |
79 | sys.exit(0) | |
80 | ||
81 | pages = 0 | |
82 | # (records+19)/20 is the max pages | |
83 | for ii in range(min(n,(records+19)/20)): | |
84 | try: | |
85 | b.select_form(nr=0) | |
86 | b['CID'] = [i.name for i in b.find_control('CID').items] | |
87 | b.submit() | |
88 | except: | |
89 | break | |
90 | ||
91 | # only print one header, start of xml file | |
92 | lines = b.response().get_data().split("\n") | |
93 | if ii == 0: | |
94 | print "\n".join(lines[0:2]) | |
95 | ||
96 | # core | |
97 | print "\n".join(lines[2:-1]) | |
98 | ||
99 | print "</waypoint>" | |
100 | ||
101 | pages += 1 | |
102 | sys.stderr.write("i") | |
103 | sys.stderr.flush() | |
104 | ||
105 | b.back() | |
106 | ||
107 | if not magicnumber: | |
108 | magicnumber = getmagicnumber(b) | |
109 | ||
110 | b.select_form(nr=0) | |
111 | [f for f in b.forms()][0].new_control("hidden", "pgrBottom$_ctl%d" % magicnumber, {}) | |
112 | b.submit() | |
113 | ||
114 | sys.stderr.write("\n") | |
115 | ||
116 | if pages: | |
117 | print "</loc>" | |
118 | ||
119 | # f=open("delmeNOW","w") | |
120 | # f.write(b.response().get_data()) | |
121 | # f.close() |