Code: Alles auswählen
import os
import re
import glob
import xml.etree.ElementTree as ElementTree
#PATH = r"C:\Users\Susanne\Dateien\Verschiedenes\Geocaching" # Testpfad
#PATH = r"D:\Verschiedenes\Python\Geocaching\gpx_test" # anderer Testpfad
PATH = r"F:\Garmin" # Pfad zu dem Gerät
CODIERUNG = "cp1252"
def xml_anschauen(xml_tree):
"""zeigt Tags, Attribute und Text eines xml-Baumes an (zum Herausfinden der Tags)"""
for x in xml_tree.iter():
if x.text:
t = x.text.encode("utf-8")
print x.tag, x.attrib, t
def zeichen_ersetzen(string):
""""ersetzt Zeichen, die Probleme bei der Darstellung machen
bisher: u2013 -> Bindestrich"""
return string.replace(u"\u2013", "-")
class Geocache(object):
def __init__(self, dateiname_path):
self._dateiname_path = dateiname_path
self._gccode = os.path.splitext(os.path.basename(dateiname_path))[0] # GC-Code
geocache_tree = ElementTree.parse(dateiname_path) # .gpx-Datei einlesen
#xml_anschauen(geocache_tree)
name = geocache_tree.find(".//{http://www.groundspeak.com/cache/1/0}name").text # Name auslesen
self._name = zeichen_ersetzen(name) # TODO: Warnung bei Zeichen ausgeben, die Probleme machen und nicht ersetzt werden
# TODO: weitere Eigenschaften auslesen und speichern
def get_gccode(self):
return self._gccode
def get_name(self):
return self._name
def get_dateiname_path(self):
return self._dateiname_path
def kurzinfo(self):
""" gibt eine einzeilige Kurzinfo zurueck"""
return u"{} : {}".format(self._gccode,self._name)
def langinfo(self):
"""gibt eine ausfuehrliche Info zurueck (im Moment noch nicht vorhanden)""" # TODO, wenn andere Eigenschaften da
return u"{} : {}".format(self._gccode,self._name)
def sortieren(cacheliste, kriterium_zahl, richtung):
"""sortiert die Cacheliste nach dem angegebenen Kriterium"""
kriterien = ["_gccode", "_name"] # Sortierkriterium festlegen
try:
kriterium = kriterien[int(kriterium_zahl)-1]
except IndexError:
return cacheliste # bei ungueltiger Eingabe (zu große Zahl) unsortierte Liste zurueckgeben
except ValueError:
return cacheliste # bei ungueltiger Eingabe (kein Int) unsortierte Liste zurueckgeben
rev = (richtung == "2") # Richtung festlegen
return sorted(cacheliste, key = lambda geocache: getattr(geocache, kriterium).lower(), reverse = rev)
def alle_anzeigen(caches):
"""zeigt die Kurzinfo zu allen Caches in der Liste "caches" an"""
print "\nWonach sollen die Geocaches sortiert werden?"
print "1: GC-Code"
print "2: Name"
eingabe_kriterium = raw_input(">> ")
print "In welche Richtung sollen die Caches sortiert werden?"
print "1: aufsteigend"
print "2: absteigend"
eingabe_richtung = raw_input(">> ")
caches = sortieren(caches, eingabe_kriterium, eingabe_richtung)
for c in caches:
print c.kurzinfo()
if len(caches) == 0:
print "keine Geocaches auf dem Geraet"
def einen_anzeigen(caches):
"""zeigt die ausfuehrliche Info zu einem bestimmten Cache an und fuehst ggf. weitere Aktionen damit durch (z.B. loeschen)"""
gc = raw_input("Gib den GC-Code ein: ")
cache = None
for c in caches:
if gc == c.get_gccode():
cache = c
break
if not cache:
print "dieser GC-Code existiert nicht"
else:
print cache.langinfo()
print "\nWas moechstest du als naechstes tun?"
print "1: diesen Cache loeschen"
print "2: zurueck"
eingabe = raw_input(">> ")
if eingabe == "1":
caches = loeschen([cache], caches, "suche", False, False)[0] # False nur Dummy fuer warning und found_exists
elif eingabe == "2":
pass
return caches # Rueckgabe notwendig, falls Cache geloescht wurde
def loeschen(del_liste, cacheliste, quelle, warning, found_exists):
"""loescht den oder die Caches in del_liste aus cacheliste
-> gibt cacheliste ohne geloeschte Caches zurueck sowie Information,
ob es nach dem Loeschen noch immer als gefunden markierte Caches auf dem Geraet gibt"""
if quelle == "found":
print "Achtung! Du solltest die Caches vor dem Loeschen auf geocaching.com loggen."
if warning == True:
print "Warnung! Bei Fortfahren werden auch Log-Informationen ueber Caches geloescht, die nicht gefunden wurden."
eingabe = raw_input("\nWillst du den / die ausgewaehlten Cache(s) wirklich loeschen? (y/n) ")
if eingabe == "y":
for d in del_liste:
os.remove(d.get_dateiname_path())
cacheliste = [c for c in cacheliste if c not in del_liste]
if quelle == "found":
found_exists = False
os.remove(os.path.join(PATH,"geocache_visits.txt"))
os.remove(os.path.join(PATH,"geocache_logs.xml"))
return [cacheliste, found_exists]
def suchen(caches):
"""durchsucht Liste "caches" nach bestimmter Eigenschaft -> suchergebnisse
ermoeglich weitere Aktionen mit den gefundenen Caches"""
suchergebnisse = []
print "\nWonach willst du suchen?"
print "1: Name"
# TODO: hier noch weitere Suchmoeglichkeiten
eingabe = raw_input(">> ")
if eingabe == "1": # Suche im Cachenamen
suchbegriff = raw_input("Suche nach... ").decode(CODIERUNG)
for c in caches:
if suchbegriff in c.get_name():
print c.kurzinfo()
suchergebnisse.append(c)
# TODO: andere Suchmoeglichkeiten
else:
return caches # Ende der Funktion bei ungueltiger Eingabe
if len(suchergebnisse) == 0:
print "keine Geocaches gefunden"
else: # Aktionen mit den Auswahl von Caches
caches = aktionen_cacheauswahl(suchergebnisse, caches, "suche", False, False) # False nur Dummy fuer warning und found_exists
return caches # Rueckgabe notwendig, falls Cache(s) geloescht wurden
def aktionen_cacheauswahl(auswahl, caches, quelle, warning, found_exists):
"""Untermenue für eine Auswahl an Caches (aus Suche oder den gefundenen Caches)"""
while True:
print "\nWas moechtest du als naechstes tun?"
if quelle == "suche":
print "1: Alle Suchergebnisse erneut anzeigen (bei evtl. Loeschen nicht aktualisiert)"
print "2: Alle Suchergebnisse loeschen"
print "3: Beschreibung fuer eines der Suchergebnisse anzeigen"
print "4: zurueck"
elif quelle == "found":
print "1: Alle gefundenen Caches erneut anzeigen (bei evtl. Loeschen nicht aktualisiert)"
print "2: Alle gefundenen Caches loeschen"
print "3: zurueck"
eingabe = raw_input(">> ")
if eingabe == "1":
for f in auswahl:
print f.kurzinfo()
elif eingabe == "2":
[caches, found_exists] = loeschen(auswahl, caches, quelle, warning, found_exists)
elif eingabe == "3" and quelle == "suche":
caches = einen_anzeigen(caches)
elif eingabe == "3" and quelle == "found":
return [caches, found_exists]
elif eingabe == "4" and quelle == "suche":
return caches
def gefundene_anzeigen(found_caches, caches, warning, found_exists):
for fc in found_caches:
print fc.kurzinfo()
[caches, found_exists] = aktionen_cacheauswahl(found_caches, caches, "found", warning, found_exists)
return [caches, found_exists] # Rueckgabe noetig, falls Caches geloescht wurden
def get_logged_and_found_caches(visits_file):
"""liest aus visits_file die geloggten und gefundenen Caches aus"""
logged_caches_raw = []
with open(visits_file) as visits:
for linenumber,line in enumerate(visits):
line_new = ""
for buchstabe in line:
if buchstabe.encode("hex") != "00":
line_new = line_new + buchstabe
if linenumber == 0 and line_new[0].encode("hex") == "ff" and line_new[1].encode("hex") == "fe":
line_new = line_new[2:] # skip UTF-16 byte order mark
logged_caches_raw.append(line_new)
logged_caches = []
for lcr in logged_caches_raw:
lcr = lcr.split(",")
lcr.remove(lcr[-1])
if len(lcr) > 0:
logged_caches.append(lcr)
found_caches = []
for lc in logged_caches:
if lc[-1] == "Found it":
try:
found_caches.append(Geocache(os.path.join(PATH,"GPX",lc[0]+".gpx")))
except IOError:
print "\nWARNUNG! Der Geocache {} befindet sich nicht auf dem Geraet. Er wird daher im Folgenden nicht mehr beruecksichtigt.".format(lc[0])
return [logged_caches, found_caches]
def main():
geocaches = [] # alle Caches aus GC*.gpx-Dateien in PATH\GPX auslesen und in Liste geocaches speichern
GPX_PATH = os.path.join(PATH, "GPX")
for datei in glob.glob(os.path.join(GPX_PATH,"GC*.gpx")):
geocaches.append(Geocache(datei))
found_exists = False # alle Caches aus Logdatei in logged_caches und alle gefundenen in found_caches speichern
warning = False
if os.path.isfile(os.path.join(PATH, "geocache_visits.txt")):
[logged_caches, found_caches] = get_logged_and_found_caches(os.path.join(PATH, "geocache_visits.txt"))
if len(found_caches) > 0:
found_exists = True
if len(found_caches) < len(logged_caches):
warning = True
while True: # Hauptmenue
print "\nWas moechtest du als naechstes tun?"
print "1: Alle auf dem Geraet gespeicherten Geocaches sortieren und anzeigen"
print "2: Beschreibung fuer einen bestimmten Cache anzeigen (GC-Code erforderlich)"
print "3: Geocaches durchsuchen"
if found_exists:
print "4: Alle gefundenen Caches anzeigen"
print "5: Programm verlassen"
else:
print "4: Programm verlassen"
eingabe = raw_input(">> ")
if eingabe == "1":
alle_anzeigen(geocaches)
elif eingabe == "2":
geocaches = einen_anzeigen(geocaches)
elif eingabe == "3":
geocaches = suchen(geocaches)
elif eingabe == "4" and found_exists:
[geocaches, found_exists] = gefundene_anzeigen(found_caches, geocaches, warning, found_exists)
elif eingabe == "4" and not found_exists:
break
elif eingabe == "5" and found_exists:
break
def test():
#Geocache("D:\Verschiedenes\Python\Geocaching\gpx_test\GC5FEV4.gpx") # einen Beispielcache erstellen
Geocache("C:\Users\Susanne\Dateien\Verschiedenes\Geocaching\gpx_test\GC5FEV4.gpx") # einen Beispielcache erstellen
if __name__ == "__main__":
main()
#test()