diff --git a/get_bookmarks.py b/get_bookmarks.py index dd3c875..05fcb7f 100644 --- a/get_bookmarks.py +++ b/get_bookmarks.py @@ -6,18 +6,6 @@ import os from bs4 import BeautifulSoup from dotenv import load_dotenv from datetime import datetime -from xml.sax.saxutils import escape as _xml_escape - -def xml_escape(text): - """ - Escape text for use inside XML element text nodes. - - Important: At least '&', '<', '>' must be escaped to keep GPX well-formed. - We also escape quotes defensively. - """ - if text is None: - return '' - return _xml_escape(str(text), entities={'"': '"', "'": '''}) def create_gpx(places, folder_name, output_file='places.gpx'): """Create a GPX file from the collected places.""" @@ -41,12 +29,12 @@ def create_gpx(places, folder_name, output_file='places.gpx'): waypoints.append(waypoint_template.format( lat=place['coordinates']['lat'], lon=place['coordinates']['lng'], - name=xml_escape(place['name']), - desc=xml_escape(place['description'] or '') + name=place['name'], + desc=place['description'] or '' )) gpx_content = gpx_template.format( - folder_name=xml_escape(folder_name), + folder_name=folder_name, timestamp=datetime.utcnow().isoformat(), waypoints='\n'.join(waypoints) ) @@ -295,4 +283,4 @@ def main(): print("\nFailed to get bookmarks.") if __name__ == "__main__": - main() + main() \ No newline at end of file diff --git a/gpx_to_osmand_favorites.py b/gpx_to_osmand_favorites.py deleted file mode 100755 index 51a7a1f..0000000 --- a/gpx_to_osmand_favorites.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import xml.etree.ElementTree as ET -from datetime import datetime, timezone - -GPX_NS = "http://www.topografix.com/GPX/1/1" -OSMAND_NS = "https://osmand.net" - -ET.register_namespace("", GPX_NS) -ET.register_namespace("osmand", OSMAND_NS) - -def iso_now_z(): - return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z") - -def localname(tag): - return tag.split("}", 1)[-1] if "}" in tag else tag - -def find_child_by_localname(parent, wanted): - for ch in list(parent): - if localname(ch.tag) == wanted: - return ch - return None - -def get_metadata_name_anyns(root): - md = find_child_by_localname(root, "metadata") - if md is None: - return None - nm = find_child_by_localname(md, "name") - if nm is None: - return None - txt = (nm.text or "").strip() - return txt or None - -def guess_group(in_path, root, prefix): - base = get_metadata_name_anyns(root) - if not base: - base = os.path.splitext(os.path.basename(in_path))[0] - if prefix: - return f"{prefix.rstrip('/')}/{base}" - return base - -def main(): - if len(sys.argv) not in (3, 4): - print( - "Usage: gpx_to_osmand_favorites_autogroup_fixed.py input.gpx output.gpx [prefix]\n" - "Example: gpx_to_osmand_favorites_autogroup_fixed.py 4x4.gpx 4x4_osmand.gpx Norwegen", - file=sys.stderr - ) - sys.exit(2) - - in_path = sys.argv[1] - out_path = sys.argv[2] - prefix = sys.argv[3] if len(sys.argv) == 4 else "" - - tree = ET.parse(in_path) - root = tree.getroot() - - group = guess_group(in_path, root, prefix) - - in_wpts = [el for el in root.iter() if localname(el.tag) == "wpt"] - if not in_wpts: - raise SystemExit(f"No elements found in {in_path}") - - out_root = ET.Element(f"{{{GPX_NS}}}gpx", { - "version": "1.1", - "creator": "gpx_to_osmand_favorites_autogroup_fixed.py", - }) - - md = ET.SubElement(out_root, f"{{{GPX_NS}}}metadata") - ET.SubElement(md, f"{{{GPX_NS}}}name").text = f"OsmAnd favorites: {group}" - ET.SubElement(md, f"{{{GPX_NS}}}time").text = iso_now_z() - - written = 0 - for w in in_wpts: - lat = w.attrib.get("lat") - lon = w.attrib.get("lon") - if lat is None or lon is None: - continue - - out_wpt = ET.SubElement(out_root, f"{{{GPX_NS}}}wpt", {"lat": str(lat), "lon": str(lon)}) - - # Copy common fields if present - for ch in list(w): - ln = localname(ch.tag) - if ln in ("name", "cmt", "desc", "ele", "time") and ch.text not in (None, ""): - ET.SubElement(out_wpt, f"{{{GPX_NS}}}{ln}").text = ch.text - - # Ensure we have a name - if find_child_by_localname(out_wpt, "name") is None: - ET.SubElement(out_wpt, f"{{{GPX_NS}}}name").text = f"Favorite {written+1}" - - # OsmAnd favorites group (key field) - ET.SubElement(out_wpt, f"{{{GPX_NS}}}type").text = group - - # Optional OsmAnd hint (safe if ignored) - ext = ET.SubElement(out_wpt, f"{{{GPX_NS}}}extensions") - ET.SubElement(ext, f"{{{OSMAND_NS}}}category").text = group - - written += 1 - - ET.ElementTree(out_root).write(out_path, encoding="UTF-8", xml_declaration=True) - print(f"Wrote {written} waypoint(s) to {out_path} with OsmAnd favorites group '{group}'") - -if __name__ == "__main__": - main() \ No newline at end of file