#!/usr/bin/env python
#GetCache - a tool to gather and process geocache descriptions
#Copyright (C) 2008 Hein Ragas
#
#This program is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public License
#as published by the Free Software Foundation; either version 2
#of the License, or (at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# CHANGELOG:
# 1.1 : Initial public release
# 1.2 : Added capabilities of showing a certain number of logs in the HTML
# 1.3 : Added capabilities of mirroring images in descriptions
# 1.4 : Multi-language
# 1.5 : Ported to use lxml
"""GetCache v1.5
Downloads and combines geocache-descriptions of geocaching.com.
Exports the descriptions to HTML and waypoint information to KML and GPX
formats. Offers the possibility to upload the waypoints directly to a
Garmin USB-GPS receiver.
The geo-* tools (http://geo.rkkda.com/) and GPSBabel (http://www.gpsbabel.org)
have to be installed and available in the path.
Usage:
gecache [options] [waypoint] ([waypoint]...)
Options:
-?, --help Shows this help
-g, --gpx (1 or 0) Produces a GPX-file when set to 1
-k, --kml (1 or 0) Produces a KML-file when set to 1
-h, --html (1 or 0) Produces a HTML-file when set to 1
-s, --sendtogps (1 or 0) Sends the waypoints to a Garmin USB-GPS
Receiver. Implies '-g 1'.
-r, --redownload Do not cache the geocache information from
gc.com
-n, --name File-name to be used for the output files
-d, --desc Descriptions of the list
-z, --zip Creates a ZIP-file of all output files
-l, --logs ('a' or a number) Shows logs in the HTML. '-l a' shows all logs,
'-l 0' shows no logs, otherwise it will show
the given number of logs. Implies '-h 1'.
-m, --mirror (1 or 0) Makes a local copy of images used in the
HTML, so that the geocache descriptions can
also be read offline. Implies '-h 1'.
If no name or description is given, the GUI will appear. Options that
are not set will be read from the configuration file (~/.getcacherc). After
a run through the GUI, the settings will be written back to the configuration
file.
Examples:
getcache
getcache -g 1 -s 1 GCxxxx GCyyyy
For more help, see http://www.logrus.nl/getcache .
"""
FALSE = 0
TRUE = 1
import sys
import gobject
import pygtk
pygtk.require('2.0')
import gtk
import datetime
import math
import os
import re
import ConfigParser
from lxml import etree
import lxml.html
from user import home
import getopt
from sgmllib import SGMLParser
import htmlentitydefs
class BaseHTMLProcessor(SGMLParser):
def reset(self):
# extend (called by SGMLParser.__init__)
self.pieces = []
SGMLParser.reset(self)
def unknown_starttag(self, tag, attrs):
# called for each start tag
# attrs is a list of (attr, value) tuples
# e.g. for
, tag="pre", attrs=[("class", "screen")]
# Ideally we would like to reconstruct original tag and attributes, but
# we may end up quoting attribute values that weren't quoted in the source
# document, or we may change the type of quotes around the attribute value
# (single to double quotes).
# Note that improperly embedded non-HTML code (like client-side Javascript)
# may be parsed incorrectly by the ancestor, causing runtime script errors.
# All non-HTML code must be enclosed in HTML comment tags ()
# to ensure that it will pass through this parser unaltered (in handle_comment).
strattrs = "".join([' %s="%s"' % (key, value) for key, value in attrs])
self.pieces.append("<%(tag)s%(strattrs)s>" % locals())
def unknown_endtag(self, tag):
# called for each end tag, e.g. for , tag will be "pre"
# Reconstruct the original end tag.
self.pieces.append("%(tag)s>" % locals())
def handle_charref(self, ref):
# called for each character reference, e.g. for " ", ref will be "160"
# Reconstruct the original character reference.
self.pieces.append("%(ref)s;" % locals())
def handle_entityref(self, ref):
# called for each entity reference, e.g. for "©", ref will be "copy"
# Reconstruct the original entity reference.
self.pieces.append("&%(ref)s" % locals())
# standard HTML entities are closed with a semicolon; other entities are not
if htmlentitydefs.entitydefs.has_key(ref):
self.pieces.append(";")
def handle_data(self, text):
# called for each block of plain text, i.e. outside of any tag and
# not containing any character or entity references
# Store the original text verbatim.
self.pieces.append(text)
def handle_comment(self, text):
# called for each HTML comment, e.g.
# Reconstruct the original comment.
# It is especially important that the source document enclose client-side
# code (like Javascript) within comments so it can pass through this
# processor undisturbed; see comments in unknown_starttag for details.
self.pieces.append("" % locals())
def handle_pi(self, text):
# called for each processing instruction, e.g.
# Reconstruct original processing instruction.
self.pieces.append("%(text)s>" % locals())
def handle_decl(self, text):
# called for the DOCTYPE, if present, e.g.
#
# Reconstruct original DOCTYPE
self.pieces.append("" % locals())
def output(self):
"""Return processed HTML as a single string"""
return "".join(self.pieces)
class ImageMirror(BaseHTMLProcessor):
name = ''
def setName(self, name):
self.name = name
def reset(self):
self.imageList = []
BaseHTMLProcessor.reset(self)
def retrieveImages(self, conf):
for img in self.imageList:
imageParts = img.split(".")
newImageName = str(self.imageList.index(img))+'.'+imageParts[len(imageParts)-1]
os.popen('curl "' + img + '" -o ' + newImageName)
def start_img(self, attrs):
newAttr = []
for attr, val in attrs:
if attr.lower() == 'src':
if not(val in self.imageList):
self.imageList.append(val)
imageParts = val.split(".")
newVal = self.name+'/'+str(self.imageList.index(val))+'.'+imageParts[len(imageParts)-1]
newAttr.append((attr, newVal))
else:
newAttr.append((attr, val))
self.unknown_starttag('img', newAttr)
def getText(node):
return lxml.html.tostring(node)
def getAllText(xpathExpr,node):
text = ""
nodes = node.xpath(xpathExpr)
for node in nodes:
text += node.text
return text
def convertD2DM(degs):
mydegrees = int(float(degs))
remaining = float(degs) - float(mydegrees * 1.0)
myminutes = remaining * 60.0
myminutes = round(myminutes * 1000.0, 0) / 1000.0
return str(mydegrees) + " " + str(myminutes)
def getCoordinate(waypoint):
lat = waypoint.get('lat')
lon = waypoint.get('lon')
if lat < 0:
latDir = "S"
lat = abs(lat)
else:
latDir = "N"
if lon < 0:
lonDir = "W"
lon = abs(lon)
else:
lonDir = "E"
lat = latDir + " " + convertD2DM(lat)
lon = lonDir + " " + convertD2DM(lon)
return lat + " " + lon
def printCache(doc):
cacheOutput = ''
waypoints = doc.xpath('//wpt')
for wpt in waypoints:
# Determine whether this is a cache or an additional waypoint
cacheType = "0"
if wpt.xpath('sym')[0].text == "Geocache" or wpt.xpath('sym')[0].text == "Geocache Found":
# Determine the type of cache
cacheType = wpt.xpath('type')[0].text
if cacheType == "Geocache|Traditional Cache":
cacheType = "2"
if cacheType == "Geocache|Multi-cache":
cacheType = "3"
if cacheType == "Geocache|Unknown Cache":
cacheType = "8"
if cacheType == "Geocache|Virtual Cache":
cacheType = "4"
cacheOutput += '
'
cacheOutput += ''+getAllText('name',wpt)+''
cacheOutput += ' - '+getAllText('urlname',wpt)
cacheOutput += ' - ' + getCoordinate(wpt)
cacheOutput += ' - Size: ' + getAllText('cache/container',wpt)
cacheOutput += ' Difficulty: ' + getAllText('cache/difficulty',wpt)
cacheOutput += ' Terrain: ' + getAllText('cache/terrain',wpt) + '
'
descNode = wpt.xpath('cache/long_description')
for desc in descNode:
if desc.get('html') == 'False':
descText = getText(desc)
pat = re.compile('\n')
cacheOutput += pat.sub('
', descText)
else:
cacheOutput += getText(desc)
cacheOutput += '
Additional Hint: ' + getAllText('cache/encoded_hints',wpt) + ''
pat = re.compile('<')
cacheOutput = pat.sub('<', cacheOutput)
pat = re.compile('>')
cacheOutput = pat.sub('>', cacheOutput)
pat = re.compile('&')
cacheOutput = pat.sub('&', cacheOutput)
return cacheOutput
def printCacheLogs(doc, conf):
cacheOutput = ''
logCounter = 0
logs = doc.xpath('//log')
for log in logs:
if conf.showLogs == 'a' or int(conf.showLogs) > logCounter:
cacheOutput += '
'
cacheOutput += getAllText('finder', log) + " " + getAllText('type', log).lower()
cacheOutput += ' on ' + getAllText('date',log)[:10] + '
'
cacheOutput += getAllText('text',log)
logCounter += 1
pat = re.compile('\n')
cacheOutput = pat.sub('
', cacheOutput)
return cacheOutput
# Function to do the actual work
def createDescs(name, desc, cacheList, conf):
gcCodes = ''
mergeList = ''
os.chdir(conf.gpxDir)
for f in cacheList:
mergeList += ' -i gpx -f '+f+'.gpx'
if conf.redownload == 1 or (not (os.path.isfile(f+'.gpx'))):
gcCodes += f + ' '
if gcCodes != '':
if conf.gcUser != '':
gcCodes = "-u '" + conf.gcUser + "' -p '" + conf.gcPasswd + "' " + gcCodes
print "geo-gpx "+gcCodes
os.popen('geo-gpx '+gcCodes)
if conf.doHTML == 1:
totalHtml = ''
for f in cacheList:
os.popen("sed 's/groundspeak://g' "+f+".gpx > "+f+"-t.gpx")
os.popen("sed 's//g' "+f+"-t.gpx > "+f+"-ns.gpx")
os.remove(f+'-t.gpx')
doc = etree.parse(f+'-ns.gpx')
totalHtml += printCache(doc)
if conf.showLogs != 0:
totalHtml += printCacheLogs(doc, conf)
totalHtml += '
'
if conf.mirrorImgs == 1:
myMirror = ImageMirror()
myMirror.setName(name)
myMirror.feed(totalHtml)
totalHtml = myMirror.output()
if not (os.path.exists(conf.gpxDir+'/'+name)):
os.makedirs(conf.gpxDir+'/'+name)
os.chdir(conf.gpxDir+'/'+name)
myMirror.retrieveImages(conf)
os.chdir(conf.gpxDir)
# Open the output
myhtml = open(conf.gpxDir+'/'+name+'.html', 'w')
myhtml.write('')
myhtml.write(totalHtml)
myhtml.write('')
myhtml.close()
for f in cacheList:
os.remove(f+'-ns.gpx')
if conf.doGPX == 1:
os.popen("gpsbabel" + mergeList + " -o gpx -x track,merge -F tussen.gpx")
os.popen("sed 's/Various geocachers<\/author>/g' tussen.gpx > '"+conf.gpxDir+"/"+ name + ".gpx'")
os.remove('tussen.gpx')
if conf.sendImmediately == 1:
os.popen("gpsbabel -r -t -w -i gpx -f '"+conf.gpxDir+"/"+name+".gpx' -o garmin -F USB:")
if conf.doKML == 1:
os.popen("gpsbabel" + mergeList + " -o kml -x track,merge -F tussen.kml")
os.popen("sed 's/ tussen2.kml")
os.popen("sed 's/GPS device/"+desc+"/g' tussen2.kml > '"+conf.gpxDir+"/"+name+".kml'")
os.remove('tussen.kml')
os.remove('tussen2.kml')
if conf.zip == 1:
os.chdir(conf.gpxDir)
zipList = []
if conf.doHTML == 1:
zipList.append(name+'.html')
if conf.doGPX == 1:
zipList.append(name+'.gpx')
if conf.doKML == 1:
zipList.append(name+'.kml')
if conf.mirrorImgs == 1:
zipList.append(name+'/*.*')
if len(zipList) > 0:
os.popen("zip -m " + name+".zip " + " ".join(zipList))
if conf.mirrorImgs == 1:
os.rmdir(conf.gpxDir+'/'+name)
class AppLanguage:
def __init__(self):
self.alreadyPresent = 'Already in the list!'
self.nameFirst = 'Give a name first!'
self.descFirst = 'Give a description first!'
self.nothingToDo = 'Nothing to do'
self.processFinished = 'Finished'
self.collectionName = 'Name'
self.description = 'Description'
self.cachesForDate = 'Geocaches for '
self.output = 'Output'
self.sendToGPS = 'Send to GPSr'
self.redownload = 'Re-download'
self.includeImages = 'Incl. images'
self.showLogs = 'Show logs'
self.allLogs = 'All logs'
self.numberOfLogs = 'Number:'
self.addCache = 'Add cache:'
def readLanguage(self, language):
if os.path.isfile(home+'/.getcache.'+language+'.lng'):
config = ConfigParser.ConfigParser()
config.read(home+'/.getcache.'+language+'.lng')
self.alreadyPresent = config.get('language','AlreadyPresent')
self.nameFirst = config.get('language','NameFirst')
self.descFirst = config.get('language','descFirst')
self.nothingToDo = config.get('language','NothingToDo')
self.processFinished = config.get('language','ProcessFinished')
self.collectionName = config.get('language','CollectionName')
self.description = config.get('language','Description')
self.cachesForDate = config.get('language','CachesForDate')
self.output = config.get('language','Output')
self.sendToGPS = config.get('language','SendToGPS')
self.redownload = config.get('language','Redownload')
self.includeImages = config.get('language','IncludeImages')
self.showLogs = config.get('language','ShowLogs')
self.allLogs = config.get('language','AllLogs')
self.numberOfLogs = config.get('language','NumberOfLogs')
self.addCache = config.get('language','AddCache')
class AppConfig:
def __init__(self):
self.doGPX = 1
self.doHTML = 1
self.doKML = 1
self.gpxDir = '.'
self.sendImmediately = 0
self.redownload = 0
self.zip = 0
self.gcUser = ''
self.gcPasswd = ''
self.showLogs = '0'
self.mirrorImgs = 0
self.language = 'english'
self.lang = AppLanguage()
self.sourceGPX = None
self.doEverything = 0
def readConfig(self):
if os.path.isfile(home+'/.getcacherc'):
config = ConfigParser.ConfigParser()
config.read(home+'/.getcacherc')
self.doGPX = int(config.get('main','gpx'))
self.doHTML = int(config.get('main','html'))
self.doKML = int(config.get('main','kml'))
self.gpxDir = config.get('main','gpxdir')
self.sendImmediately = config.get('main','sendtogps')
try:
self.showLogs = config.get('main','showlogs')
self.mirrorImgs = int(config.get('main','mirrorimgs'))
self.language = config.get('main','language')
self.gcUser = config.get('main','gcuser')
self.gcPasswd = config.get('main','gcpwd')
except ConfigParser.NoOptionError:
pass
self.writeConfig()
self.lang.readLanguage(self.language)
def writeConfig(self):
config = ConfigParser.ConfigParser()
config.add_section('main')
config.set('main','gpx',str(self.doGPX))
config.set('main','html',str(self.doHTML))
config.set('main','kml',str(self.doKML))
config.set('main','gpxdir',self.gpxDir)
config.set('main','sendtogps',self.sendImmediately)
config.set('main','showlogs',self.showLogs)
config.set('main','mirrorimgs',self.mirrorImgs)
config.set('main','language',self.language)
config.set('main','gcuser',self.gcUser)
config.set('main','gcpwd',self.gcPasswd)
f = open(home+'/.getcacherc','w')
config.write(f)
f.close()
class GetCache:
def digits_check_input(self, widget, event, data=None):
key = gtk.gdk.keyval_name (event.keyval)
ONLYDIGITS="([0-9.,]|BackSpace|Left|Right|F1|period|Tab|Up|Down)"
if not re.match (ONLYDIGITS, key):
return True
def callback(self, widget, data):
self.iter = self.lstore.get_iter_first()
found = FALSE
while self.iter != None:
if self.lstore.get_value(self.iter,0) == self.waypoint.get_text():
found = TRUE
self.iter = self.lstore.iter_next(self.iter)
if found == TRUE:
self.mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, self.conf.lang.alreadyPresent)
self.mbox.run()
self.mbox.destroy()
else:
self.iter = self.lstore.append()
self.lstore.set(self.iter, 0, self.waypoint.get_text())
# Callback for the start
def execute(self, widget, data):
if self.namebox.get_text() == '':
self.mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, self.conf.lang.nameFirst)
self.run()
self.mbox.destroy()
self.namebox.grab_focus()
else:
if self.descbox.get_text() == '':
self.mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, self.conf.lang.descFirst)
self.mbox.run()
self.mbox.destroy()
self.descbox.grab_focus()
else:
self.cacheList = []
self.iter = self.lstore.get_iter_first()
while self.iter != None:
self.cacheList.append(self.lstore.get_value(self.iter,0))
self.iter = self.lstore.iter_next(self.iter)
if len(self.cacheList) == 0:
self.mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, self.conf.lang.nothingToDo)
self.mbox.run()
self.mbox.destroy()
else:
if self.checkGPX.get_active():
self.conf.doGPX = 1
else:
self.conf.doGPX = 0
if self.checkHTML.get_active():
self.conf.doHTML = 1
else:
self.conf.doHTML = 0
if self.checkKML.get_active():
self.conf.doKML = 1
else:
self.conf.doKML = 0
if self.checkSendToGPS.get_active():
self.conf.sendImmediately = 1
else:
self.conf.sendImmediately = 0
if self.checkRedownload.get_active():
self.conf.redownload = 1
if self.checkLogs.get_active():
if self.checkAllLogs.get_active():
self.conf.showLogs = 'a'
else:
self.conf.showLogs = self.numLogEntry.get_text()
else:
self.conf.showLogs = '0'
if self.checkMirror.get_active():
self.conf.mirrorImgs = 1
else:
self.conf.mirrorImgs = 0
self.conf.writeConfig()
createDescs(self.namebox.get_text(), self.descbox.get_text(), self.cacheList, self.conf)
self.mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, self.conf.lang.processFinished)
self.mbox.run()
self.mbox.destroy()
gtk.main_quit()
# another callback
def delete_event(self, widget, event, data=None):
gtk.main_quit()
return False
def toGPSClicked(self, widget, data=None):
if self.checkSendToGPS.get_active():
self.checkGPX.set_active(True)
def toGPXClicked(self, widget, data=None):
if not(self.checkGPX.get_active()):
self.checkSendToGPS.set_active(False)
def checkLogsClicked(self, widget, data=None):
if self.checkLogs.get_active():
self.checkHTML.set_active(True)
self.checkAllLogs.set_sensitive(True)
self.checkNumber.set_sensitive(True)
self.numLogEntry.set_sensitive(self.checkNumber.get_active())
else:
self.checkAllLogs.set_sensitive(False)
self.checkNumber.set_sensitive(False)
self.numLogEntry.set_sensitive(False)
def checkHTMLClicked(self, widget, data=None):
if not(self.checkHTML.get_active()):
self.checkLogs.set_active(False)
self.checkAllLogs.set_sensitive(False)
self.checkNumber.set_sensitive(False)
self.numLogEntry.set_sensitive(False)
self.checkMirror.set_active(False)
def checkMirrorClicked(self, widget, data=None):
if self.checkMirror.get_active():
self.checkHTML.set_active(True)
def logChoiceClicked(self, widget, data=None):
self.numLogEntry.set_sensitive(self.checkNumber.get_active())
def __init__(self, conf):
self.conf = conf
# Create a new window
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_title("Get Cache")
self.window.connect("delete_event", self.delete_event)
self.window.set_border_width(10)
# The Table that holds all the stuff
self.box2 = gtk.Table(10, 1, True)
self.window.add(self.box2)
# Label and textbox for setting the name
self.box1 = gtk.HBox(False, 0)
self.box2.attach(self.box1, 0, 1, 0, 1)
self.label = gtk.Label(self.conf.lang.collectionName)
self.box1.pack_start(self.label, True, True, 0)
self.namebox = gtk.Entry(15)
self.namebox.set_text(str(datetime.date.today()))
self.box1.pack_start(self.namebox, True, True, 0)
self.label.show()
self.namebox.show()
self.box1.show()
# Label and textbox for setting the description
self.box1 = gtk.HBox(False, 0)
self.box2.attach(self.box1, 0, 1, 1, 2)
self.label = gtk.Label(self.conf.lang.description)
self.box1.pack_start(self.label, True, True, 0)
self.descbox = gtk.Entry(40)
self.descbox.set_text(self.conf.lang.cachesForDate + str(datetime.date.today()))
self.box1.pack_start(self.descbox, True, True, 0)
self.label.show()
self.descbox.show()
self.box1.show()
# Output formats
self.box1 = gtk.HBox(False, 0)
self.box2.attach(self.box1, 0, 1, 2, 3)
self.label = gtk.Label(self.conf.lang.output)
self.box1.pack_start(self.label, True, True, 0)
self.checkGPX = gtk.CheckButton("GPX")
self.checkGPX.set_active(conf.doGPX == 1)
self.checkGPX.connect("toggled", self.toGPXClicked, "")
self.box1.pack_end(self.checkGPX, True, True, 0)
self.checkHTML = gtk.CheckButton("HTML")
self.checkHTML.set_active(conf.doHTML == 1)
self.checkHTML.connect("toggled", self.checkHTMLClicked, "")
self.box1.pack_end(self.checkHTML, True, True, 0)
self.checkKML = gtk.CheckButton("KML")
self.checkKML.set_active(conf.doKML == 1)
self.box1.pack_end(self.checkKML, True, True, 0)
self.checkKML.show()
self.checkHTML.show()
self.checkGPX.show()
self.label.show()
self.box1.show()
# Option to send to GPS & re-download GPX-files
self.box1 = gtk.HBox(False, 0)
self.box2.attach(self.box1, 0, 1, 3, 4)
self.checkSendToGPS = gtk.CheckButton(self.conf.lang.sendToGPS)
self.checkSendToGPS.set_active(conf.sendImmediately == 1)
self.checkSendToGPS.connect("toggled", self.toGPSClicked, "")
self.box1.pack_end(self.checkSendToGPS, True, True, 0)
self.checkRedownload = gtk.CheckButton(self.conf.lang.redownload)
self.checkRedownload.set_active(False)
self.box1.pack_start(self.checkRedownload, True, True, 0)
self.checkMirror = gtk.CheckButton(self.conf.lang.includeImages)
self.checkMirror.set_active(conf.mirrorImgs == 1)
self.checkMirror.connect("toggled", self.checkMirrorClicked, "")
self.box1.pack_end(self.checkMirror, True, True, 0)
self.checkMirror.show()
self.checkRedownload.show()
self.checkSendToGPS.show()
self.box1.show()
# Option to download logs
self.box1 = gtk.HBox(False, 0)
self.box2.attach(self.box1, 0, 1, 4, 5)
self.checkLogs = gtk.CheckButton(self.conf.lang.showLogs)
self.checkLogs.set_active(conf.showLogs != '0')
self.checkLogs.connect("toggled", self.checkLogsClicked,"")
self.box1.pack_start(self.checkLogs, True, True, 0)
self.checkAllLogs = gtk.RadioButton(None, self.conf.lang.allLogs)
self.checkAllLogs.connect("toggled", self.logChoiceClicked, "")
self.box1.pack_start(self.checkAllLogs, True, True, 0)
self.checkNumber = gtk.RadioButton(self.checkAllLogs, self.conf.lang.numberOfLogs)
self.checkNumber.connect("toggled", self.logChoiceClicked, "")
self.box1.pack_start(self.checkNumber, True, True, 0)
self.numLogEntry = gtk.Entry(3)
self.numLogEntry.connect("key_press_event",self.digits_check_input,"")
self.box1.pack_start(self.numLogEntry, True, True, 0)
if self.conf.showLogs == '0':
self.checkAllLogs.set_sensitive(False)
self.checkNumber.set_sensitive(False)
self.numLogEntry.set_sensitive(False)
else:
if self.conf.showLogs == 'a':
self.checkAllLogs.set_active(True)
self.numLogEntry.set_sensitive(False)
else:
self.checkNumber.set_active(True)
self.numLogEntry.set_text(self.conf.showLogs)
self.numLogEntry.show()
self.checkNumber.show()
self.checkAllLogs.show()
self.label.show()
self.checkLogs.show()
self.box1.show()
# Textbox and button to add waypoints to the list
self.box1 = gtk.HBox(False, 0)
self.box2.attach(self.box1, 0, 1, 5, 6)
self.label = gtk.Label(self.conf.lang.addCache)
self.box1.pack_start(self.label, True, True, 0)
self.waypoint = gtk.Entry(8)
self.waypoint.set_text("GC")
self.box1.pack_start(self.waypoint, True, True, 0)
self.button2 = gtk.Button(None, gtk.STOCK_ADD)
self.button2.connect("clicked", self.callback, None)
self.box1.pack_start(self.button2, True, True, 0)
self.label.show()
self.waypoint.show()
self.button2.show()
self.box1.show()
# Scrolling window to contain the list
self.sw = gtk.ScrolledWindow()
self.sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
self.sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
self.box2.attach(self.sw, 0, 1, 6, 10)
self.sw.show()
# List store
self.lstore = gtk.ListStore(gobject.TYPE_STRING)
# Tree view
self.treeview = gtk.TreeView(self.lstore)
self.column = gtk.TreeViewColumn('Waypoint', gtk.CellRendererText(), text=0)
self.treeview.append_column(self.column)
self.sw.add(self.treeview)
self.treeview.show()
# Button to start the whole process
self.button2 = gtk.Button(None, gtk.STOCK_EXECUTE)
self.button2.connect("clicked", self.execute, None)
self.box2.attach(self.button2, 0, 1, 10, 11)
self.button2.show()
# Make everything visible
self.box2.show()
self.window.show()
self.waypoint.select_region(2,2)
self.waypoint.grab_focus()
def usage():
print __doc__
def main():
gtk.main()
if __name__ == "__main__":
conf = AppConfig()
conf.readConfig()
listName = ''
listDesc = ''
try:
opts, args = getopt.getopt(sys.argv[1:],"z?g:k:h:s:rn:d:l:m:epq:",["gpx=","kml=","html=","sendtogps=","redownload","name=","desc=","help","zip","logs=","mirror=","everything","pocketquery="])
except getopt.GetoptError:
usage()
sys.exit(2)
for opt, arg in opts:
if opt in ("-?", "--help"):
usage()
sys.exit(2)
if opt in ("-g", "--gpx"):
conf.doGPX = int(arg)
if opt in ("-k", "--kml"):
conf.doKML = int(arg)
if opt in ("-h", "--html"):
conf.doHTML = int(arg)
if opt in ("-s", "--sendtogps"):
conf.sendImmediately = int(arg)
if opt in ("-r", "--redownload"):
conf.redownload = 1
if opt in ("-n", "--name"):
listName = arg
if opt in ("-d", "--desc"):
listDesc = arg
if opt in ("-z", "--zip"):
conf.zip = 1
if opt in ("-l", "--logs"):
conf.showLogs = arg
if opt in ("-m", "--mirror"):
conf.mirrorImgs = int(arg)
if opt in ("-e", "--everything"):
conf.doEverything = 1
if opt in ("-pq", "--pocketquery"):
conf.sourceGPX = arg
if conf.sendImmediately == 1:
conf.doGPX = 1
if conf.showLogs != '0' or conf.mirrorImgs == 1:
conf.doHTML = 1
if listName != '' and listDesc != '':
cacheList = args
createDescs(listName, listDesc, cacheList, conf)
print "Process finished."
else:
getcache = GetCache(conf)
main()