@@ -148,6 +148,7 @@ INSTALLED_APPS = (
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
+ 'django.contrib.sitemaps',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
new file mode 100644
@@ -0,0 +1,36 @@
+# layerindex-web - sitemap definitions
+#
+# Licensed under the MIT license, see COPYING.MIT for details
+#
+# SPDX-License-Identifier: MIT
+
+from django.contrib.sitemaps import Sitemap
+from django.urls import reverse
+
+from layerindex.models import LayerItem
+
+BRANCH_VIEWS = ('layer_list', 'recipe_search', 'machine_search', 'distro_search', 'class_search')
+
+
+class StaticViewSitemap(Sitemap):
+ changefreq = 'daily'
+ priority = 0.5
+
+ def items(self):
+ return list(BRANCH_VIEWS) + ['about', 'stats']
+
+ def location(self, item):
+ if item in BRANCH_VIEWS:
+ return reverse(item, args=('master',))
+ return reverse(item)
+
+
+class LayerSitemap(Sitemap):
+ changefreq = 'weekly'
+ priority = 0.8
+
+ def items(self):
+ return LayerItem.objects.filter(status='P', comparison=False).order_by('name')
+
+ def lastmod(self, obj):
+ return obj.updated
@@ -148,6 +148,7 @@ INSTALLED_APPS = (
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
+ 'django.contrib.sitemaps',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
new file mode 100644
@@ -0,0 +1,38 @@
+# layerindex-web - tests for sitemap.xml
+#
+# Licensed under the MIT license, see COPYING.MIT for details
+#
+# SPDX-License-Identifier: MIT
+
+import pytest
+from django.test import TestCase
+
+from layerindex.models import LayerItem
+
+
+@pytest.mark.django_db
+class TestSitemap(TestCase):
+
+ def _layer(self, name, status='P', comparison=False):
+ return LayerItem.objects.create(
+ name=name,
+ status=status,
+ layer_type='A',
+ summary=name,
+ description=name,
+ vcs_url='git://example.com/%s.git' % name,
+ comparison=comparison,
+ )
+
+ def test_sitemap(self):
+ self._layer('meta-published')
+ self._layer('meta-new', status='N')
+ self._layer('meta-compare', comparison=True)
+
+ response = self.client.get('/sitemap.xml')
+ self.assertEqual(response.status_code, 200)
+ content = response.content.decode()
+ self.assertIn('/layerindex/branch/master/layer/meta-published/', content)
+ self.assertIn('/layerindex/about/', content)
+ self.assertNotIn('meta-new', content)
+ self.assertNotIn('meta-compare', content)
@@ -12,13 +12,22 @@ from django.views.generic import RedirectView, TemplateView
from layerindex.auth_views import CaptchaRegistrationView, CaptchaPasswordResetView, delete_account_view, \
PasswordResetSecurityQuestions
from django.contrib import admin
+from django.contrib.sitemaps.views import sitemap
+from layerindex.sitemaps import StaticViewSitemap, LayerSitemap
admin.autodiscover()
from django.conf import settings
+sitemaps = {
+ 'static': StaticViewSitemap,
+ 'layers': LayerSitemap,
+}
+
urlpatterns = [
re_path(r'^layerindex/', include('layerindex.urls')),
re_path(r'^admin/', admin.site.urls),
+ re_path(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
+ name='django.contrib.sitemaps.views.sitemap'),
re_path(r'^accounts/password_reset/$',
CaptchaPasswordResetView.as_view(
email_template_name='registration/password_reset_email.txt',