]>
Commit | Line | Data |
---|---|---|
1 | #!/usr/bin/env python | |
2 | ||
3 | # | |
4 | # THIS IS NO LONGER SUPPORTED | |
5 | # | |
6 | print """ | |
7 | This script no longer works after the geocaching.com website update see: | |
8 | http://blog.geocaching.com/2011/05/preview-of-geocaching-com-may-4th-website-release/ | |
9 | ||
10 | It is now recommended to use the geo-* tools instead: | |
11 | http://geo.rkkda.com/ | |
12 | """ | |
13 | import sys | |
14 | sys.exit(1) | |
15 | ||
16 | # | |
17 | # One day this script could be resurrected, as the geo-* tools are not perhaps the fastest... | |
18 | # | |
19 | ||
20 | # | |
21 | # gcget -- screen scrape Geocaching.com's annoying web interface | |
22 | # aka SHOW ME THE CACHE!!! | |
23 | # | |
24 | # Copyright 2007, Evan Battaglia | |
25 | # Distributed under the terms of the GPL v2. | |
26 | # | |
27 | # | |
28 | # requires module mechanize | |
29 | # | |
30 | ||
31 | # DEFAULT USERNAME AND PASSWORD: THESE ARE OVERWRITTEN BY COMMAND-LINE OPTIONS | |
32 | ||
33 | USER="username" | |
34 | PASS="password" | |
35 | ||
36 | # docs needed! | |
37 | # this has some extra args in: | |
38 | # gcget lat,lon maxnumgcs [maxdist] [threshold] | |
39 | # threshold -- if find more than this # of geocaches, don't get ANY, | |
40 | # instead give warning and quit | |
41 | ||
42 | import sys | |
43 | import getopt | |
44 | ||
45 | def help(): | |
46 | print """gcget v0.1 | |
47 | This program is free software, distributed under the terms of the GNU GPL v2. | |
48 | ||
49 | Usage: gcget [-u username] [-p password] lat,lon maxnumberofgcs [maxdistance] [threshold] | |
50 | Downloads up to maxnumberofgcs at a distance of up to maxdistance from lat,lon. | |
51 | If we number of geocaches within maxdistance is above threshold, don't download any | |
52 | geocaches, just give a warning and quit. | |
53 | ||
54 | If username and password are not given, will use default values hard-coded in script. | |
55 | ||
56 | Happy caching!!! | |
57 | """ | |
58 | ||
59 | # | |
60 | # PARSE OPTIONS: USERNAME AND PASSWORD | |
61 | # | |
62 | # | |
63 | # | |
64 | try: | |
65 | opts, args = getopt.gnu_getopt(sys.argv[1:], "u:p:d", ["help"]) | |
66 | except getopt.GetoptError: | |
67 | # print help information and exit: | |
68 | help() | |
69 | sys.exit(2) | |
70 | ||
71 | DEBUG = False | |
72 | ||
73 | for o, a in opts: | |
74 | if o == "-p": | |
75 | PASS = a | |
76 | if o == "-u": | |
77 | USER = a | |
78 | if o == "--help" or o == "-h": | |
79 | help() | |
80 | sys.exit() | |
81 | if o == "-d": | |
82 | DEBUG = True | |
83 | ||
84 | if len(args) < 2: | |
85 | help() | |
86 | sys.exit() | |
87 | ||
88 | ######################### | |
89 | #ll = args[0].split(",") | |
90 | #lat = ll[0] | |
91 | #lon = ll[1] | |
92 | #The following line replaced the previous 3 lines. | |
93 | lat, lon = args[0].split(",") | |
94 | ||
95 | if len(args) >= 3: | |
96 | maxdist = args[2] | |
97 | else: | |
98 | maxdist = "999" | |
99 | ||
100 | if len(args) >= 4: | |
101 | threshold = int(args[3]) | |
102 | else: | |
103 | threshold = 1000000; | |
104 | ||
105 | # rounds up to multiples of 20. 20 | |
106 | n = int((int(args[1])+19)/20) | |
107 | ||
108 | import re | |
109 | from mechanize import Browser | |
110 | import ClientForm | |
111 | ||
112 | # get magic number for "Next" button. | |
113 | # this is normally 16 (link hidden is $ctl16), unless there are less than 10 pages of results, | |
114 | # in which case it will be less (e.g. 09 for 3 pages of results) | |
115 | def getmagicnumber(b): | |
116 | for i in range(16,0,-1): | |
117 | if re.compile("pgrBottom.ctl%02d" % i).search(b.response().get_data()): | |
118 | return i | |
119 | return None | |
120 | ||
121 | b=Browser() | |
122 | b.open("http://geocaching.com/seek/") | |
123 | b.follow_link(text="Log in") | |
124 | b.select_form(nr=0) | |
125 | # The Username and Password fields on the Login form changed | |
126 | b["ctl00$ContentBody$myUsername"] = USER | |
127 | b["ctl00$ContentBody$myPassword"] = PASS | |
128 | b.submit() | |
129 | ||
130 | magicnumber = 0 # the ctl number of Next. get only once | |
131 | ||
132 | try: b.select_form("form4") | |
133 | except: pass | |
134 | try: | |
135 | b.select_form("form4") | |
136 | except: | |
137 | b.select_form("form4") | |
138 | print >> sys.stderr, "Invalid username/password" | |
139 | if DEBUG: | |
140 | f=open("gcget.badlogin.html","w") | |
141 | f.write(b.response().get_data()) | |
142 | f.close() | |
143 | print >> sys.stderr, "Dumping last HTML page recieved into gcget.badlogin.html" | |
144 | sys.exit() | |
145 | ||
146 | b["origin_lat"] = lat | |
147 | b["origin_long"] = lon | |
148 | b["dist"] = maxdist | |
149 | b.submit() | |
150 | ||
151 | thresholdre = re.compile("Total Records: <b>([0-9]*)</b>") | |
152 | m = thresholdre.search(b.response().get_data()) | |
153 | if m: | |
154 | if int(m.group(1)) > threshold: | |
155 | sys.stderr.write("THRESHOLD %d > %d\n" % (int(m.group(1)), threshold)) | |
156 | sys.exit(4) | |
157 | else: | |
158 | records = int(m.group(1)) | |
159 | sys.stderr.write("ok found %d, getting min(%d,%d) gcs\n" % (int(m.group(1)), int(records), int(args[1]))) | |
160 | else: | |
161 | print "can't find total records" | |
162 | sys.exit(0) | |
163 | ||
164 | pages = 0 | |
165 | # (records+19)/20 is the max pages | |
166 | for ii in range(min(n,(records+19)/20)): | |
167 | try: | |
168 | b.select_form(nr=0) | |
169 | b['CID'] = [i.name for i in b.find_control('CID').items] | |
170 | b.submit() | |
171 | except: | |
172 | break | |
173 | ||
174 | # only print one header, start of xml file | |
175 | lines = b.response().get_data().split("\n") | |
176 | if ii == 0: | |
177 | print "\n".join(lines[0:2]) | |
178 | ||
179 | # core | |
180 | print "\n".join(lines[2:-1]) | |
181 | ||
182 | print "</waypoint>" | |
183 | ||
184 | pages += 1 | |
185 | sys.stderr.write("i") | |
186 | sys.stderr.flush() | |
187 | ||
188 | b.back() | |
189 | ||
190 | if not magicnumber: | |
191 | magicnumber = getmagicnumber(b) | |
192 | if not magicnumber: | |
193 | # print "couldn't find magic number!" # why does this happen? | |
194 | break | |
195 | ||
196 | b.select_form(nr=0) | |
197 | [f for f in b.forms()][0].new_control("hidden", "ctl00$ContentBody$pgrBottom$ctl%02d" % magicnumber, {}) | |
198 | b.submit() | |
199 | ||
200 | sys.stderr.write("\n") | |
201 | ||
202 | if pages: | |
203 | print "</loc>" | |
204 | ||
205 | # f=open("delmeNOW","w") | |
206 | # f.write(b.response().get_data()) | |
207 | # f.close() | |
208 |