a minimal hook to produce kml sitemaps if no locations specified then we try to build for every model in installed applications go through the given sources and return a 3tuple of the application label module name and field name of every geometryfield encountered in the sources if no sources are provided then all models this method is overridden so the appropriate geoformat attribute is placed on each url element a minimal hook to produce kml sitemaps if no locations specified then we try to build for every model in installed applications go through the given sources and return a 3 tuple of the application label module name and field name of every geometryfield encountered in the sources if no sources are provided then all models this method is overridden so the appropriate geo_format attribute is placed on each url element
from django.apps import apps
from django.contrib.gis.db.models import GeometryField
from django.contrib.sitemaps import Sitemap
from django.db import models
from django.urls import reverse


class KMLSitemap(Sitemap):
    

    geo_format = "kml"

    def __init__(self, locations=None):
        
        
        self.locations = self._build_kml_sources(locations)

    def _build_kml_sources(self, sources):
        
        kml_sources = []
        if sources is None:
            sources = apps.get_models()
        for source in sources:
            if isinstance(source, models.base.ModelBase):
                for field in source._meta.fields:
                    if isinstance(field, GeometryField):
                        kml_sources.append(
                            (
                                source._meta.app_label,
                                source._meta.model_name,
                                field.name,
                            )
                        )
            elif isinstance(source, (list, tuple)):
                if len(source) != 3:
                    raise ValueError(
                        "Must specify a 3-tuple of (app_label, module_name, "
                        "field_name)."
                    )
                kml_sources.append(source)
            else:
                raise TypeError("KML Sources must be a model or a 3-tuple.")
        return kml_sources

    def get_urls(self, page=1, site=None, protocol=None):
        
        urls = Sitemap.get_urls(self, page=page, site=site, protocol=protocol)
        for url in urls:
            url["geo_format"] = self.geo_format
        return urls

    def items(self):
        return self.locations

    def location(self, obj):
        return reverse(
            "django.contrib.gis.sitemaps.views.%s" % self.geo_format,
            kwargs={
                "label": obj[0],
                "model": obj[1],
                "field_name": obj[2],
            },
        )


class KMZSitemap(KMLSitemap):
    geo_format = "kmz"