def lastCacheDate(self): cur = geocacher.db().cursor() cur.execute("SELECT MAX(found_date) FROM Caches WHERE found = 1") return textToDateTime(cur.fetchone()[0]).date()
def load(self, filename, fileUpdates={}, gpxFilename=None): ''' Imports the given .gpx file into the database. Arguments filename: path to the file from which to import the cache information Keyword Arguments fileUpdates: Dictionary for adding updates to for reporting back to the user gpxFilename: filename to use in gpx source column if different from filename ''' mode = geocacher.config().importMode userName = geocacher.config().GCUserName userId = geocacher.config().GCUserID # Load GPX file if os.path.isfile(filename): gpxDoc = ElementTree.parse(filename).getroot() # Determine the file version schema = gpxDoc.attrib[ '{http://www.w3.org/2001/XMLSchema-instance}schemaLocation'] if schema.rfind('http://www.groundspeak.com/cache/1/0/1') >= 0: gpxVer = '1.0.1' elif schema.rfind('http://www.groundspeak.com/cache/1/0') >= 0: gpxVer = '1.0' else: gpxVer = '1.0' self.setNamespace(gpxVer) gpxDoc = ElementTree.parse(filename).getroot() NS = self.NS if gpxFilename == None: sourceFile = os.path.abspath(filename) else: sourceFile = gpxFilename + ":" + os.path.basename(filename) else: return (False, fileUpdates) # Get the date the GPX file was created try: gpxDate = textToDateTime('%s' % gpxDoc.find("gpx:time", NS).text) logging.debug('Date from File contents: %s' % dateTimeToText(gpxDate)) except: gpxDate = datetime.utcfromtimestamp(os.path.getmtime(filename)) logging.debug('Date from file timestamp: %s' % dateTimeToText(gpxDate)) # Create list for extra points extraWpts = [] # Find the waypoints and process them for wpt in gpxDoc.findall("gpx:wpt", NS): code = getTextFromPath(wpt, "gpx:name", NS) logging.debug(code) if code[:2] != "GC": extraWpts.append(wpt) continue lon = float(getAttribFromPath(wpt, ".", "lon", NS, '0.0')) lat = float(getAttribFromPath(wpt, ".", "lat", NS, '0.0')) id = int(getAttribFromPath(wpt, "gs:cache", "id", NS)) available = textToBool( getAttribFromPath(wpt, "gs:cache", "available", NS, 'True')) archived = textToBool( getAttribFromPath(wpt, "gs:cache", "archived", NS, 'False')) name = getTextFromPath(wpt, "gpx:urlname", NS) url = getTextFromPath(wpt, "gpx:url", NS) placed = textToDateTime(getTextFromPath(wpt, "gpx:time", NS)) placed_by = getTextFromPath(wpt, "gs:cache//gs:placed_by", NS) owner = getTextFromPath(wpt, "gs:cache//gs:owner", NS) owner_id = int( getAttribFromPath(wpt, "gs:cache//gs:owner", "id", NS)) cachetype = getTextFromPath(wpt, "gs:cache//gs:type", NS) container = getTextFromPath(wpt, "gs:cache//gs:container", NS, "Not Specified") difficulty = float( getTextFromPath(wpt, "gs:cache//gs:difficulty", NS, "1")) terrain = float( getTextFromPath(wpt, "gs:cache//gs:terrain", NS, "1")) state = getTextFromPath(wpt, "gs:cache//gs:state", NS) country = getTextFromPath(wpt, "gs:cache//gs:country", NS) short_desc = getTextFromPath(wpt, "gs:cache//gs:short_description", NS, "") short_desc_html = textToBool( getAttribFromPath(wpt, "gs:cache//gs:short_description", "html", NS, "False")) long_desc = getTextFromPath(wpt, "gs:cache//gs:long_description", NS, "") long_desc_html = textToBool( getAttribFromPath(wpt, "gs:cache//gs:long_description", "html", NS, "False")) hints = getTextFromPath(wpt, "gs:cache//gs:encoded_hints", NS, "") if code in fileUpdates.keys(): cacheUpdates = fileUpdates[code] else: cacheUpdates = {} cache = geocacher.db().getCacheByCode(code) if cache == None: cacheUpdates['change type'] = 'new' cacheUpdates['lat'] = [lat, ''] cacheUpdates['lon'] = [lon, ''] cacheUpdates['ci'] = [id, ''] cacheUpdates['available'] = [available, ''] cacheUpdates['archived'] = [archived, ''] cacheUpdates['name'] = [name, ''] cacheUpdates['url'] = [url, ''] cacheUpdates['placed_by'] = [placed_by, ''] cacheUpdates['owner'] = [owner, ''] cacheUpdates['owner_id'] = [owner_id, ''] cacheUpdates['type'] = [cachetype, ''] cacheUpdates['container'] = [container, ''] cacheUpdates['difficulty'] = [difficulty, ''] cacheUpdates['terrain'] = [terrain, ''] cacheUpdates['state'] = [state, ''] cacheUpdates['country'] = [country, ''] cacheUpdates['short_desc'] = [short_desc, ''] cacheUpdates['short_desc_html'] = [short_desc_html, ''] cacheUpdates['long_desc'] = [long_desc, ''] cacheUpdates['long_desc_html'] = [long_desc_html, ''] cacheUpdates['encoded_hints'] = [hints, ''] cacheUpdates['gpx_date'] = [gpxDate, ''] cache = geocacher.db().addCache( code, lat=lat, lon=lon, id=id, available=available, archived=archived, name=name, url=url, placed=placed, placed_by=placed_by, owner=owner, owner_id=owner_id, type=cachetype, container=container, difficulty=difficulty, terrain=terrain, state=state, country=country, short_desc=short_desc, short_desc_html=short_desc_html, long_desc=long_desc, long_desc_html=long_desc_html, encoded_hints=hints, gpx_date=gpxDate) elif 'change type' not in cacheUpdates.keys(): cacheUpdates['change type'] = 'update' if ((cache.gpx_date <= gpxDate and mode == "update") or mode == "replace"): if cache.lon != lon: cacheUpdates['lon'] = [lon, cache.lon] cache.lon = lon if cache.lat != lat: cacheUpdates['lat'] = [lat, cache.lat] cache.lat = lat if cache.id != id: cacheUpdates['available'] = [cache.available, available] cache.id = id if cache.archived != archived: cacheUpdates['archived'] = [archived, cache.archived] cache.archived = archived if cache.name != name: cacheUpdates['name'] = [name, cache.name] cache.name = name if cache.url != url: cacheUpdates['url'] = [url, cache.url] cache.url = url if cache.placed_by != placed_by: cacheUpdates['placed_by'] = [placed_by, cache.placed_by] cache.placed_by = placed_by if cache.owner != owner: cacheUpdates['owner'] = [owner, cache.owner] cache.owner = owner if cache.owner_id != owner_id: cacheUpdates['owner_id'] = [owner_id, cache.owner_id] cache.owner_id = owner_id if cache.type != cachetype: cacheUpdates['type'] = [owner_id, cache.owner_id] cache.type = cachetype if cache.container != container: cacheUpdates['container'] = [container, cache.container] cache.container = container if cache.difficulty != difficulty: cacheUpdates['difficulty'] = [difficulty, cache.difficulty] cache.difficulty = difficulty if cache.terrain != terrain: cacheUpdates['terrain'] = [terrain, cache.terrain] cache.terrain = terrain if cache.state != state: cacheUpdates['state'] = [state, cache.state] cache.state = state if cache.country != country: cacheUpdates['country'] = [country, cache.country] cache.country = country if cache.short_desc != short_desc: cacheUpdates['short_desc'] = [short_desc, cache.short_desc] cache.short_desc = short_desc if cache.short_desc_html != short_desc_html: cacheUpdates['short_desc_html'] = [ short_desc_html, cache.short_desc_html ] cache.short_desc_html = short_desc_html if cache.long_desc != long_desc: cacheUpdates['long_desc'] = [long_desc, cache.long_desc] cache.long_desc = long_desc if cache.long_desc_html != long_desc_html: cacheUpdates['long_desc_html'] = [ long_desc_html, cache.long_desc_html ] if cache.encoded_hints != hints: cacheUpdates['encoded_hints'] = [ hints, cache.encoded_hints ] cache.encoded_hints = hints if gpxVer == '1.0.1': attribsUpdates = {} wptAttribIds = [] for wptAttrib in wpt.findall( "gs:cache//gs:attributes//gs:attribute", NS): attribId = int(wptAttrib.attrib['id']) attribInc = textToBool(wptAttrib.attrib['inc']) attribDesc = wptAttrib.text wptAttribIds.append(attribId) attribUpdates = {} attrib = cache.getAttributeById(attribId) if attrib is None: logging.debug( 'Attribute %i not found in existing data, creating' % attribId) attribUpdates['inc'] = [attribInc, ''] attribUpdates['Description'] = [attribDesc, ''] attrib = cache.addAttribute( attribId, attribInc, attribDesc) else: if attribInc != attrib.inc: attribUpdates['inc'] = [attribInc, attrib.inc] attrib.inc = attribInc if attribDesc != attrib.description: attribUpdates['Description'] = [attribDesc, ''] attrib.description = attribDesc if len(attribUpdates) > 0: attrib.save() attribsUpdates[attribId] = attribUpdates # Go through the cache attribs and delete any that are not #listed in the wpt for cacheAttribId in cache.getAttributeIds(): if not (cacheAttribId in wptAttribIds): toDelete = cache.getAttributeById(cacheAttribId) attribsUpdates[cacheAttribId] = { _('Removed'): ['', ''] } toDelete.delete() if len(attribsUpdates) > 0: cacheUpdates['Attributes'] = attribsUpdates # Always update Logs and travel bugs foundUpdated = False logsUpdates = {} for wptLog in wpt.findall("gs:cache//gs:logs//gs:log", NS): logId = int(getAttribFromPath(wptLog, '.', "id", NS)) logDate = textToDateTime(getTextFromPath( wptLog, "gs:date", NS)) logType = getTextFromPath(wptLog, "gs:type", NS) logFinderId = int( getAttribFromPath(wptLog, "gs:finder", "id", NS)) logFinderName = getTextFromPath(wptLog, "gs:finder", NS) logEncoded = textToBool( getAttribFromPath(wptLog, "gs:text", "encoded", NS, "False")) logText = getTextFromPath(wptLog, "gs:text", NS) logUpdates = {} log = cache.getLogById(logId) if log == None: logging.debug( 'Log %i not forund in existing data, creating' % logId) logUpdates['id'] = [logId, ''] logUpdates['date'] = [logDate, ''] logUpdates['type'] = [logType, ''] logUpdates['finder_id'] = [logFinderId, ''] logUpdates['finder_name'] = [logFinderName, ''] logUpdates['encoded'] = [logEncoded, ''] logUpdates['text'] = [logText, ''] log = cache.addLog(logId, date=logDate, logType=logType, finder_id=logFinderId, finder_name=logFinderName, encoded=logEncoded, text=logText) else: logging.debug( 'Log %i found in existing data, checking data' % logId) if logDate != log.date: logUpdates['id'] = [logDate, log.date] log.date = logDate if logType != log.logType: logUpdates['type'] = [logType, log.logType] log.logType = logType if logFinderId != log.finder_id: logUpdates['finder_id'] = [logFinderId, log.finder_id] log.finder_id = logFinderId if logFinderName != log.finder_name: logUpdates['finder_name'] = [ logFinderName, log.finder_name ] log.finder_name = logFinderName if logEncoded != log.encoded: logUpdates['encoded'] = [logEncoded, log.encoded] log.encoded = logEncoded if logText != log.text: logUpdates['text'] = [logText, log.text] log.text = logText if len(logUpdates) > 0: log.save() logsUpdates[logId] = logUpdates # Update Own find details if this is the first log with changes # in it that is of the "Found it" type and the finderId or # finderName matches the users values if ((not foundUpdated) and (logFinderId == userId or logFinderName == userName)): logging.debug('User ID or Name match for log id %i' % logId) if logType in ['Found it', 'Attended']: logging.debug('Log type is found or attended') if not cache.found: cacheUpdates['found'] = [True, False] cache.found = True if cache.found_date != logDate: cacheUpdates['found_date'] = [ logDate, cache.found_date ] cache.found_date = logDate foundUpdated = True elif logType == "Didn't find it": logging.debug('Log type is DNF') if not cache.dnf: cacheUpdates['dnf'] = [True, False] cache.dnf = True if cache.dnf_date != logDate: cacheUpdates['dnf_date'] = [ logDate, cache.dnf_date ] cache.dnf_date = logDate foundUpdated = True if foundUpdated: if cache.own_log_id != logId: cacheUpdates['own_log_id'] = [ logId, cache.own_log_id ] cache.own_log_id = logId cache.refreshOwnLog() if len(logsUpdates) > 0: cacheUpdates['Logs'] = logsUpdates tbUpdates = {} wptTbRefs = [] cacheTbRefs = cache.getTravelBugRefs() for wptTb in wpt.findall('gs:cache//gs:travelbugs//gs:travelbug', NS): wptTbRef = wptTb.attrib['ref'] wptTbRefs.append(wptTbRef) wptTbId = wptTb.attrib['id'] wptTbName = getTextFromPath(wptTb, 'gs:name', NS) if not (wptTbRef in cacheTbRefs): tbUpdates[wptTbRef + ' ' + wptTbName] = [_('Added'), ''] cacheTb = cache.addTravelBug(wptTbRef, id=wptTbId, name=wptTbName) else: cacheTb = cache.getTravelBugByRef(wptTbRef) if cacheTb.name != wptTbName: tbUpdates[wptTbRef + ' ' + wptTbName] = [cacheTb.name, wptTbName] cacheTb.name = wptTbName cacheTb.save() # Go through the list of travel bugs in the cache and delete any # that are not listed in the wpt for cacheTbRef in cacheTbRefs: if not (cacheTbRef in wptTbRefs): toDelete = cache.getTravelBugByRef(cacheTbRef) tbUpdates[cacheTbRef + ' ' + toDelete.name] = [_('Removed'), ''] toDelete.delete() if len(tbUpdates) > 0: cacheUpdates['Travel Bugs'] = tbUpdates # Always update the gpx date and source file name even if no changes cache.gpx_date = gpxDate cache.source = sourceFile cache.save() if len(cacheUpdates) > 1: fileUpdates[code] = cacheUpdates for wpt in extraWpts: lon = float(getAttribFromPath(wpt, ".", "lon", NS, '0.0')) lat = float(getAttribFromPath(wpt, ".", "lat", NS, '0.0')) id = getTextFromPath(wpt, 'gpx:name', NS) time = textToDateTime(getTextFromPath(wpt, 'gpx:time', NS)) cmt = getTextFromPath(wpt, 'gpx:cmt', NS, '') name = getTextFromPath(wpt, 'gpx:desc', NS) url = getTextFromPath(wpt, 'gpx:url', NS) sym = getTextFromPath(wpt, 'gpx:sym', NS) cacheCode = 'GC' + id[2:] cache = geocacher.db().getCacheByCode(cacheCode) if cache is not None: if cacheCode in fileUpdates.keys(): cacheUpdates = fileUpdates[cacheCode] else: cacheUpdates = {} cacheUpdates['change type'] = _('update') addWaypoint = cache.getAddWaypointByCode(id) addWptUpdates = {} if 'Add Wpts' in cacheUpdates.keys(): if id in cacheUpdates['Add Wpts'].keys(): addWptUpdates = cacheUpdates['Add Wpts'][id] if addWaypoint is None: addWaypoint = cache.addAddWaypoint(id, lat=lat, lon=lon, name=name, url=url, time=time, cmt=cmt, sym=sym) addWptUpdates['id'] = [id, ''] addWptUpdates['lat'] = [lat, ''] addWptUpdates['lon'] = [lon, ''] addWptUpdates['name'] = [name, ''] addWptUpdates['url'] = [url, ''] addWptUpdates['time'] = [time, ''] addWptUpdates['cmt'] = [cmt, ''] addWptUpdates['sym'] = [sym, ''] else: if addWaypoint.lat != lat: addWptUpdates['lat'] = [lat, addWaypoint.lat] addWaypoint.lat = lat if addWaypoint.lon != lon: addWptUpdates['lon'] = [lon, addWaypoint.lon] addWaypoint.lon = lon if addWaypoint.name != name: addWptUpdates['name'] = [name, addWaypoint.name] addWaypoint.name = name if addWaypoint.url != url: addWptUpdates['url'] = [url, addWaypoint.url] addWaypoint.url = url if addWaypoint.time != time: addWptUpdates['time'] = [time, addWaypoint.time] addWaypoint.time = time if addWaypoint.cmt != cmt: addWptUpdates['cmt'] = [cmt, addWaypoint.cmt] addWaypoint.cmt = cmt if addWaypoint.sym != sym: addWptUpdates['sym'] = [sym, addWaypoint.sym] addWaypoint.sym = sym if len(addWptUpdates) > 0: cache.gpx_date = gpxDate cache.source = os.path.abspath(filename) if 'Add Wpts' in cacheUpdates.keys(): cacheUpdates['Add Wpts'][id] = addWptUpdates else: cacheUpdates['Add Wpts'] = {id: addWptUpdates} addWaypoint.save() cache.save() fileUpdates[cacheCode] = cacheUpdates if len(fileUpdates) > 0: geocacher.db().commit() return (True, fileUpdates)
def load(self,filename,fileUpdates={},gpxFilename = None): ''' Imports the given .gpx file into the database. Arguments filename: path to the file from which to import the cache information Keyword Arguments fileUpdates: Dictionary for adding updates to for reporting back to the user gpxFilename: filename to use in gpx source column if different from filename ''' mode = geocacher.config().importMode userName = geocacher.config().GCUserName userId = geocacher.config().GCUserID # Load GPX file if os.path.isfile(filename): gpxDoc = ElementTree.parse(filename).getroot() # Determine the file version schema = gpxDoc.attrib['{http://www.w3.org/2001/XMLSchema-instance}schemaLocation'] if schema.rfind('http://www.groundspeak.com/cache/1/0/1') >= 0: gpxVer = '1.0.1' elif schema.rfind('http://www.groundspeak.com/cache/1/0') >= 0: gpxVer = '1.0' else: gpxVer = '1.0' self.setNamespace(gpxVer) gpxDoc = ElementTree.parse(filename).getroot() NS = self.NS if gpxFilename == None: sourceFile = os.path.abspath(filename) else: sourceFile = gpxFilename + ":" + os.path.basename(filename) else: return (False, fileUpdates) # Get the date the GPX file was created try: gpxDate = textToDateTime('%s' % gpxDoc.find("gpx:time", NS).text) logging.debug('Date from File contents: %s' % dateTimeToText(gpxDate)) except: gpxDate = datetime.utcfromtimestamp(os.path.getmtime(filename)) logging.debug('Date from file timestamp: %s' % dateTimeToText(gpxDate)) # Create list for extra points extraWpts = [] # Find the waypoints and process them for wpt in gpxDoc.findall("gpx:wpt", NS): code = getTextFromPath(wpt,"gpx:name",NS) logging.debug(code) if code[:2] !="GC": extraWpts.append(wpt) continue lon = float(getAttribFromPath(wpt,".","lon",NS,'0.0')) lat = float(getAttribFromPath(wpt,".","lat",NS,'0.0')) id = int(getAttribFromPath(wpt,"gs:cache","id",NS)) available = textToBool(getAttribFromPath(wpt,"gs:cache","available",NS,'True')) archived = textToBool(getAttribFromPath(wpt,"gs:cache","archived",NS,'False')) name = getTextFromPath(wpt,"gpx:urlname",NS) url = getTextFromPath(wpt,"gpx:url",NS) placed = textToDateTime(getTextFromPath(wpt,"gpx:time",NS)) placed_by = getTextFromPath(wpt,"gs:cache//gs:placed_by",NS) owner = getTextFromPath(wpt,"gs:cache//gs:owner",NS) owner_id = int(getAttribFromPath(wpt,"gs:cache//gs:owner","id",NS)) cachetype = getTextFromPath(wpt,"gs:cache//gs:type",NS) container = getTextFromPath(wpt,"gs:cache//gs:container",NS,"Not Specified") difficulty = float(getTextFromPath(wpt,"gs:cache//gs:difficulty",NS,"1")) terrain = float(getTextFromPath(wpt,"gs:cache//gs:terrain",NS,"1")) state = getTextFromPath(wpt,"gs:cache//gs:state",NS) country = getTextFromPath(wpt,"gs:cache//gs:country",NS) short_desc = getTextFromPath(wpt,"gs:cache//gs:short_description",NS,"") short_desc_html = textToBool(getAttribFromPath(wpt,"gs:cache//gs:short_description","html",NS,"False")) long_desc = getTextFromPath(wpt,"gs:cache//gs:long_description",NS,"") long_desc_html = textToBool(getAttribFromPath(wpt,"gs:cache//gs:long_description","html",NS,"False")) hints = getTextFromPath(wpt,"gs:cache//gs:encoded_hints",NS,"") if code in fileUpdates.keys(): cacheUpdates = fileUpdates[code] else: cacheUpdates = {} cache = geocacher.db().getCacheByCode(code) if cache==None: cacheUpdates['change type'] = 'new' cacheUpdates['lat'] = [lat,''] cacheUpdates['lon'] = [lon,''] cacheUpdates['ci'] = [id,''] cacheUpdates['available'] = [available,''] cacheUpdates['archived'] = [archived,''] cacheUpdates['name'] = [name,''] cacheUpdates['url'] = [url,''] cacheUpdates['placed_by'] = [placed_by,''] cacheUpdates['owner'] = [owner,''] cacheUpdates['owner_id'] = [owner_id,''] cacheUpdates['type'] = [cachetype,''] cacheUpdates['container'] = [container,''] cacheUpdates['difficulty'] = [difficulty,''] cacheUpdates['terrain'] = [terrain,''] cacheUpdates['state'] = [state,''] cacheUpdates['country'] = [country,''] cacheUpdates['short_desc'] = [short_desc,''] cacheUpdates['short_desc_html'] = [short_desc_html,''] cacheUpdates['long_desc'] = [long_desc,''] cacheUpdates['long_desc_html'] = [long_desc_html,''] cacheUpdates['encoded_hints'] = [hints,''] cacheUpdates['gpx_date'] = [gpxDate,''] cache = geocacher.db().addCache(code,lat=lat,lon=lon,id=id, available=available,archived=archived, name=name,url=url, placed=placed,placed_by=placed_by, owner=owner,owner_id=owner_id, type=cachetype,container=container, difficulty=difficulty,terrain=terrain, state=state,country=country, short_desc=short_desc, short_desc_html=short_desc_html, long_desc=long_desc, long_desc_html=long_desc_html, encoded_hints=hints,gpx_date=gpxDate) elif 'change type' not in cacheUpdates.keys(): cacheUpdates['change type'] = 'update' if ((cache.gpx_date<=gpxDate and mode=="update") or mode=="replace"): if cache.lon != lon: cacheUpdates['lon'] = [lon,cache.lon] cache.lon = lon if cache.lat != lat: cacheUpdates['lat'] = [lat,cache.lat] cache.lat = lat if cache.id != id: cacheUpdates['available'] = [cache.available,available] cache.id = id if cache.archived != archived: cacheUpdates['archived'] = [archived,cache.archived] cache.archived = archived if cache.name != name: cacheUpdates['name'] = [name,cache.name] cache.name = name if cache.url != url: cacheUpdates['url'] = [url,cache.url] cache.url = url if cache.placed_by != placed_by: cacheUpdates['placed_by'] = [placed_by,cache.placed_by] cache.placed_by = placed_by if cache.owner != owner: cacheUpdates['owner'] = [owner,cache.owner] cache.owner = owner if cache.owner_id != owner_id: cacheUpdates['owner_id'] = [owner_id,cache.owner_id] cache.owner_id = owner_id if cache.type != cachetype: cacheUpdates['type'] = [owner_id,cache.owner_id] cache.type = cachetype if cache.container != container: cacheUpdates['container'] = [container,cache.container] cache.container = container if cache.difficulty != difficulty: cacheUpdates['difficulty'] = [difficulty,cache.difficulty] cache.difficulty = difficulty if cache.terrain != terrain: cacheUpdates['terrain'] = [terrain,cache.terrain] cache.terrain = terrain if cache.state != state: cacheUpdates['state'] = [state,cache.state] cache.state = state if cache.country != country: cacheUpdates['country'] = [country,cache.country] cache.country = country if cache.short_desc != short_desc: cacheUpdates['short_desc'] = [short_desc,cache.short_desc] cache.short_desc = short_desc if cache.short_desc_html != short_desc_html: cacheUpdates['short_desc_html'] = [short_desc_html, cache.short_desc_html] cache.short_desc_html = short_desc_html if cache.long_desc != long_desc: cacheUpdates['long_desc'] = [long_desc,cache.long_desc] cache.long_desc = long_desc if cache.long_desc_html != long_desc_html: cacheUpdates['long_desc_html'] = [long_desc_html, cache.long_desc_html] if cache.encoded_hints != hints: cacheUpdates['encoded_hints'] = [hints,cache.encoded_hints] cache.encoded_hints = hints if gpxVer == '1.0.1': attribsUpdates = {} wptAttribIds = [] for wptAttrib in wpt.findall("gs:cache//gs:attributes//gs:attribute", NS): attribId = int(wptAttrib.attrib['id']) attribInc = textToBool(wptAttrib.attrib['inc']) attribDesc = wptAttrib.text wptAttribIds.append(attribId) attribUpdates = {} attrib = cache.getAttributeById(attribId) if attrib is None: logging.debug('Attribute %i not found in existing data, creating' % attribId) attribUpdates['inc'] = [attribInc, ''] attribUpdates['Description'] = [attribDesc, ''] attrib = cache.addAttribute(attribId, attribInc, attribDesc) else: if attribInc != attrib.inc: attribUpdates['inc'] = [attribInc, attrib.inc] attrib.inc = attribInc if attribDesc != attrib.description: attribUpdates['Description'] = [attribDesc, ''] attrib.description = attribDesc if len(attribUpdates) > 0: attrib.save() attribsUpdates[attribId] = attribUpdates # Go through the cache attribs and delete any that are not #listed in the wpt for cacheAttribId in cache.getAttributeIds(): if not(cacheAttribId in wptAttribIds): toDelete = cache.getAttributeById(cacheAttribId) attribsUpdates[cacheAttribId] = {_('Removed'):['','']} toDelete.delete() if len(attribsUpdates) > 0: cacheUpdates['Attributes'] = attribsUpdates # Always update Logs and travel bugs foundUpdated=False logsUpdates = {} for wptLog in wpt.findall("gs:cache//gs:logs//gs:log", NS): logId = int(getAttribFromPath(wptLog, '.', "id",NS)) logDate = textToDateTime(getTextFromPath(wptLog, "gs:date",NS)) logType = getTextFromPath(wptLog, "gs:type",NS) logFinderId = int(getAttribFromPath(wptLog, "gs:finder", "id", NS)) logFinderName = getTextFromPath(wptLog, "gs:finder",NS) logEncoded = textToBool(getAttribFromPath(wptLog, "gs:text", "encoded", NS, "False")) logText = getTextFromPath(wptLog, "gs:text",NS) logUpdates = {} log = cache.getLogById(logId) if log==None: logging.debug('Log %i not forund in existing data, creating' % logId) logUpdates['id'] = [logId,''] logUpdates['date'] = [logDate,''] logUpdates['type'] = [logType,''] logUpdates['finder_id'] = [logFinderId,''] logUpdates['finder_name'] = [logFinderName,''] logUpdates['encoded'] = [logEncoded,''] logUpdates['text'] = [logText,''] log = cache.addLog(logId,date=logDate,logType=logType, finder_id=logFinderId,finder_name=logFinderName, encoded=logEncoded,text=logText) else: logging.debug('Log %i found in existing data, checking data' % logId) if logDate != log.date: logUpdates['id'] = [logDate,log.date] log.date = logDate if logType != log.logType: logUpdates['type'] = [logType,log.logType] log.logType = logType if logFinderId != log.finder_id: logUpdates['finder_id'] = [logFinderId,log.finder_id] log.finder_id = logFinderId if logFinderName != log.finder_name: logUpdates['finder_name'] = [logFinderName,log.finder_name] log.finder_name = logFinderName if logEncoded != log.encoded: logUpdates['encoded'] = [logEncoded,log.encoded] log.encoded = logEncoded if logText != log.text: logUpdates['text'] = [logText,log.text] log.text = logText if len(logUpdates) > 0: log.save() logsUpdates[logId] = logUpdates # Update Own find details if this is the first log with changes # in it that is of the "Found it" type and the finderId or # finderName matches the users values if ((not foundUpdated) and(logFinderId == userId or logFinderName == userName)): logging.debug('User ID or Name match for log id %i' % logId) if logType in ['Found it', 'Attended']: logging.debug('Log type is found or attended') if not cache.found: cacheUpdates['found'] = [True,False] cache.found = True if cache.found_date != logDate: cacheUpdates['found_date'] = [logDate,cache.found_date] cache.found_date = logDate foundUpdated = True elif logType == "Didn't find it": logging.debug('Log type is DNF') if not cache.dnf: cacheUpdates['dnf'] = [True,False] cache.dnf = True if cache.dnf_date != logDate: cacheUpdates['dnf_date'] = [logDate,cache.dnf_date] cache.dnf_date = logDate foundUpdated = True if foundUpdated: if cache.own_log_id != logId: cacheUpdates['own_log_id'] = [logId,cache.own_log_id] cache.own_log_id = logId cache.refreshOwnLog() if len(logsUpdates) > 0: cacheUpdates['Logs'] = logsUpdates tbUpdates = {} wptTbRefs = [] cacheTbRefs = cache.getTravelBugRefs() for wptTb in wpt.findall('gs:cache//gs:travelbugs//gs:travelbug', NS): wptTbRef = wptTb.attrib['ref'] wptTbRefs.append(wptTbRef) wptTbId = wptTb.attrib['id'] wptTbName = getTextFromPath(wptTb,'gs:name',NS) if not (wptTbRef in cacheTbRefs): tbUpdates[wptTbRef + ' ' +wptTbName] = [_('Added'),''] cacheTb = cache.addTravelBug(wptTbRef,id=wptTbId,name=wptTbName) else: cacheTb = cache.getTravelBugByRef(wptTbRef) if cacheTb.name != wptTbName: tbUpdates[wptTbRef + ' ' +wptTbName] = [cacheTb.name, wptTbName] cacheTb.name = wptTbName cacheTb.save() # Go through the list of travel bugs in the cache and delete any # that are not listed in the wpt for cacheTbRef in cacheTbRefs: if not(cacheTbRef in wptTbRefs): toDelete = cache.getTravelBugByRef(cacheTbRef) tbUpdates[cacheTbRef + ' ' +toDelete.name] = [_('Removed'),''] toDelete.delete() if len(tbUpdates) > 0: cacheUpdates['Travel Bugs'] = tbUpdates # Always update the gpx date and source file name even if no changes cache.gpx_date = gpxDate cache.source = sourceFile cache.save() if len(cacheUpdates) > 1: fileUpdates[code] = cacheUpdates for wpt in extraWpts: lon = float(getAttribFromPath(wpt,".","lon",NS,'0.0')) lat = float(getAttribFromPath(wpt,".","lat",NS,'0.0')) id = getTextFromPath(wpt,'gpx:name',NS) time = textToDateTime(getTextFromPath(wpt,'gpx:time',NS)) cmt = getTextFromPath(wpt,'gpx:cmt',NS,'') name = getTextFromPath(wpt,'gpx:desc',NS) url = getTextFromPath(wpt,'gpx:url',NS) sym = getTextFromPath(wpt,'gpx:sym',NS) cacheCode = 'GC'+id[2:] cache = geocacher.db().getCacheByCode(cacheCode) if cache is not None: if cacheCode in fileUpdates.keys(): cacheUpdates = fileUpdates[cacheCode] else: cacheUpdates = {} cacheUpdates['change type'] = _('update') addWaypoint = cache.getAddWaypointByCode(id) addWptUpdates = {} if 'Add Wpts' in cacheUpdates.keys(): if id in cacheUpdates['Add Wpts'].keys(): addWptUpdates =cacheUpdates['Add Wpts'][id] if addWaypoint is None: addWaypoint = cache.addAddWaypoint(id, lat=lat, lon=lon, name=name, url=url, time=time, cmt=cmt, sym=sym) addWptUpdates['id'] = [id,''] addWptUpdates['lat'] = [lat,''] addWptUpdates['lon'] = [lon,''] addWptUpdates['name'] = [name,''] addWptUpdates['url'] = [url,''] addWptUpdates['time'] = [time,''] addWptUpdates['cmt'] = [cmt,''] addWptUpdates['sym'] = [sym,''] else: if addWaypoint.lat != lat: addWptUpdates['lat'] = [lat,addWaypoint.lat] addWaypoint.lat = lat if addWaypoint.lon != lon: addWptUpdates['lon'] = [lon,addWaypoint.lon] addWaypoint.lon = lon if addWaypoint.name != name: addWptUpdates['name'] = [name,addWaypoint.name] addWaypoint.name = name if addWaypoint.url != url: addWptUpdates['url'] = [url,addWaypoint.url] addWaypoint.url = url if addWaypoint.time != time: addWptUpdates['time'] = [time,addWaypoint.time] addWaypoint.time = time if addWaypoint.cmt != cmt: addWptUpdates['cmt'] = [cmt,addWaypoint.cmt] addWaypoint.cmt = cmt if addWaypoint.sym != sym: addWptUpdates['sym'] = [sym,addWaypoint.sym] addWaypoint.sym = sym if len(addWptUpdates) > 0: cache.gpx_date = gpxDate cache.source = os.path.abspath(filename) if 'Add Wpts' in cacheUpdates.keys(): cacheUpdates['Add Wpts'][id] = addWptUpdates else: cacheUpdates['Add Wpts'] = {id: addWptUpdates} addWaypoint.save() cache.save() fileUpdates[cacheCode] = cacheUpdates if len(fileUpdates) > 0: geocacher.db().commit() return (True,fileUpdates)