]> git.menne-pb.de Git - pinpoint.git/commitdiff
Prepared a rewrite, to tidy up the code.
authorJörn Menne <jmenne@fedora.de>
Tue, 4 Feb 2025 21:00:24 +0000 (22:00 +0100)
committerJörn Menne <jmenne@fedora.de>
Tue, 4 Feb 2025 21:00:24 +0000 (22:00 +0100)
Furthermore comments and documentation will be incorporated from the
beginning.

62 files changed:
README.md
doc/Makefile [new file with mode: 0644]
doc/conf.py [new file with mode: 0644]
doc/georeport/models.rst [new file with mode: 0644]
doc/index.rst [new file with mode: 0644]
doc/make.bat [new file with mode: 0644]
docker-compose.yaml [new file with mode: 0644]
georeport/__init__.py
georeport/admin.py
georeport/forms.py [deleted file]
georeport/migrations/0001_initial.py [deleted file]
georeport/migrations/0002_report_state.py [deleted file]
georeport/migrations/0003_category_alter_report_description_report_category.py [deleted file]
georeport/migrations/0004_report_email_report_published.py [deleted file]
georeport/migrations/0005_category_parent.py [deleted file]
georeport/migrations/0006_alter_category_options_group.py [deleted file]
georeport/migrations/0007_delete_group.py [deleted file]
georeport/migrations/0008_category_group.py [deleted file]
georeport/models.py
georeport/static/georeport/create_Report.js [deleted file]
georeport/static/georeport/details.js [deleted file]
georeport/static/georeport/mapsetup.js [deleted file]
georeport/static/georeport/recurse_selection.js [deleted file]
georeport/static/georeport/style.css [deleted file]
georeport/templates/georeport/base.html [deleted file]
georeport/templates/georeport/category.html [deleted file]
georeport/templates/georeport/create.html [deleted file]
georeport/templates/georeport/detail.html [deleted file]
georeport/templates/georeport/index.html [deleted file]
georeport/urls.py
georeport/views.py
manage.py
pinpoint_report/__init__.py [moved from pinpoint/__init__.py with 100% similarity]
pinpoint_report/asgi.py [moved from pinpoint/asgi.py with 71% similarity]
pinpoint_report/settings.py [moved from pinpoint/settings.py with 82% similarity]
pinpoint_report/urls.py [moved from pinpoint/urls.py with 69% similarity]
pinpoint_report/wsgi.py [moved from pinpoint/wsgi.py with 71% similarity]
polls/__init__.py [deleted file]
polls/admin.py [deleted file]
polls/apps.py [deleted file]
polls/migrations/0001_initial.py [deleted file]
polls/migrations/__init__.py [deleted file]
polls/models.py [deleted file]
polls/templates/polls/detail.html [deleted file]
polls/templates/polls/index.html [deleted file]
polls/templates/polls/results.html [deleted file]
polls/tests.py [deleted file]
polls/urls.py [deleted file]
polls/views.py [deleted file]
requirements.txt
snippets/__init__.py [deleted file]
snippets/admin.py [deleted file]
snippets/apps.py [deleted file]
snippets/migrations/0001_initial.py [deleted file]
snippets/migrations/0002_alter_snippet_owner.py [deleted file]
snippets/migrations/__init__.py [deleted file]
snippets/models.py [deleted file]
snippets/permissions.py [deleted file]
snippets/serializers.py [deleted file]
snippets/tests.py [deleted file]
snippets/urls.py [deleted file]
snippets/views.py [deleted file]

index e67b81754926dc15669bc119cfc5cd5b70aa2d41..a6c769b3cddefa498a866a2b3d50dff95f56e8cc 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,17 +1,5 @@
-# Pinpoint
+# Pinpoint-Report
 
-Simple project, in  which it is possible to make a report to a specific location
-
-planned upcoming Features:
-
-- [ ] Hierarchical Categories
-  - [ ] Recursive Categories
-- [ ] User Management
-  - User can be grouped
-  - Groups have change access to categories
-    - maybe groups enable creation of subcategories
-- [ ] Sending Mails
-- [ ] Open311 Compliance
-- [ ] Tests
-
-- [ ] Publishing and depublishing of reports
+Pinpoint-Report is a web-app, which allows to create reports for locations.
+This is done by clicking on a map to specify the location and afterwards
+fill some fields to provide information.
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644 (file)
index 0000000..d4bb2cb
--- /dev/null
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS    ?=
+SPHINXBUILD   ?= sphinx-build
+SOURCEDIR     = .
+BUILDDIR      = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+       @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+       @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/doc/conf.py b/doc/conf.py
new file mode 100644 (file)
index 0000000..9056080
--- /dev/null
@@ -0,0 +1,40 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# For the full list of built-in configuration values, see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Project information -----------------------------------------------------
+# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
+import os
+import sys
+import django
+
+sys.path.insert(0, os.path.abspath(".."))
+os.environ["DJANGO_SETTINGS_MODULE"] = "pinpoint_report.settings"
+django.setup()
+
+project = "Pinpoint-Report"
+copyright = "2025, Jörn Menne"
+author = "Jörn Menne"
+release = "0.1"
+
+# -- General configuration ---------------------------------------------------
+# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
+
+extensions = [
+    "sphinx.ext.autodoc",
+    "sphinx.ext.duration",
+    "sphinx.ext.napoleon",
+    "sphinxcontrib.plantuml",
+    "sphinx.ext.mathjax",
+]
+
+templates_path = ["_templates"]
+exclude_patterns = []
+
+
+# -- Options for HTML output -------------------------------------------------
+# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
+
+html_theme = "alabaster"
+html_static_path = ["_static"]
diff --git a/doc/georeport/models.rst b/doc/georeport/models.rst
new file mode 100644 (file)
index 0000000..3d7d447
--- /dev/null
@@ -0,0 +1,6 @@
+Models
+======
+
+Here are the models used in Pinpoint-Report
+
+
diff --git a/doc/index.rst b/doc/index.rst
new file mode 100644 (file)
index 0000000..92425bb
--- /dev/null
@@ -0,0 +1,18 @@
+.. Pinpoint-Report documentation master file, created by
+   sphinx-quickstart on Tue Feb  4 12:52:16 2025.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Pinpoint-Report documentation
+=============================
+
+Add your content using ``reStructuredText`` syntax. See the
+`reStructuredText <https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html>`_
+documentation for details.
+
+
+.. toctree::
+    :maxdepth: 2
+    :caption: Contents:
+
+    georeport/models
diff --git a/doc/make.bat b/doc/make.bat
new file mode 100644 (file)
index 0000000..32bb245
--- /dev/null
@@ -0,0 +1,35 @@
+@ECHO OFF\r
+\r
+pushd %~dp0\r
+\r
+REM Command file for Sphinx documentation\r
+\r
+if "%SPHINXBUILD%" == "" (\r
+       set SPHINXBUILD=sphinx-build\r
+)\r
+set SOURCEDIR=.\r
+set BUILDDIR=_build\r
+\r
+%SPHINXBUILD% >NUL 2>NUL\r
+if errorlevel 9009 (\r
+       echo.\r
+       echo.The 'sphinx-build' command was not found. Make sure you have Sphinx\r
+       echo.installed, then set the SPHINXBUILD environment variable to point\r
+       echo.to the full path of the 'sphinx-build' executable. Alternatively you\r
+       echo.may add the Sphinx directory to PATH.\r
+       echo.\r
+       echo.If you don't have Sphinx installed, grab it from\r
+       echo.https://www.sphinx-doc.org/\r
+       exit /b 1\r
+)\r
+\r
+if "%1" == "" goto help\r
+\r
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\r
+goto end\r
+\r
+:help\r
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\r
+\r
+:end\r
+popd\r
diff --git a/docker-compose.yaml b/docker-compose.yaml
new file mode 100644 (file)
index 0000000..d0a6db0
--- /dev/null
@@ -0,0 +1,12 @@
+version: "3"
+
+services:
+  minio:
+    image: bitnami/minio
+    ports:
+      - 9000:9000
+      - 9001:9001
+    environment:
+      - MINIO_ROOT_USER=minio
+      - MINIO_ROOT_PASSWORD=minio123
+    restart: unless-stopped
index 4e80bd4b2a3ec7d4efbd73cfed1cb14bb677a436..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,3 +0,0 @@
-# Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
-# GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
-__version__ = "0.1.0"
index 2447a2d1c4fc3cb003dc4d2888aaa294e681389f..8c38f3f3dad51e4585f3984282c2a4bec5349c1e 100644 (file)
@@ -1,70 +1,3 @@
-# Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
-# GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
-
-
-from django.contrib import admin, messages
-from django.urls import base
-from django.utils.translation import ngettext
+from django.contrib import admin
 
 # Register your models here.
-
-from .models import Category, Report
-
-
-@admin.register(Report)
-class ReportAdmin(admin.ModelAdmin):
-    exclude = None
-    readonly_fields = ["creation_time", "last_change"]
-    actions = ["make_public"]
-    list_display = ["title", "category__name", "state", "published"]
-
-    list_filter = ["state"]
-
-    @admin.action(description="Publish selected reports.")
-    def make_public(self, request, queryset):
-        updated = queryset.update(published=True)
-        self.message_user(
-            request,
-            ngettext(
-                "%d report was published",
-                "%d reports were published",
-                updated,
-            )
-            % updated,
-            messages.SUCCESS,
-        )
-
-
-class CategoryInline(admin.TabularInline):
-    model = Category
-    extra = 0
-    can_delete = False
-
-    def has_change_permission(self, request, obj=None):
-        return False
-
-
-@admin.register(Category)
-class CategoryAdmin(admin.ModelAdmin):
-    exlude = None
-    inlines = [CategoryInline]
-
-    def has_change_permission(self, request, obj=None):
-        basepermission = super().has_change_permission(request, obj)
-        if obj:
-            allowed = obj.group.all()
-        else:
-            allowed = []
-
-        if basepermission and (request.user in allowed):
-            return True
-        return False
-
-
-class GeoreportAdminSite(admin.AdminSite):
-    site_header = "My cool admin site"
-
-
-admin_site = GeoreportAdminSite(name="coolAdmin")
-admin_site.register(Report, ReportAdmin)
-admin_site.register(Category, CategoryAdmin)
diff --git a/georeport/forms.py b/georeport/forms.py
deleted file mode 100644 (file)
index 958099b..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
-# GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
-
-
-from django.forms import ModelForm
-
-from .models import Report
-
-
-class ReportForm(ModelForm):
-    class Meta:
-        model = Report
-        fields = ["title", "description", "latitude", "longitude", "email", "category"]
diff --git a/georeport/migrations/0001_initial.py b/georeport/migrations/0001_initial.py
deleted file mode 100644 (file)
index 1fd09d0..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-# Generated by Django 5.1.3 on 2024-11-30 14:05
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    initial = True
-
-    dependencies = [
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='Report',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('title', models.CharField(max_length=80)),
-                ('creation_time', models.DateTimeField(auto_now_add=True)),
-                ('last_change', models.DateTimeField(auto_now=True)),
-                ('description', models.CharField(max_length=255, null=True)),
-                ('latitude', models.DecimalField(decimal_places=6, max_digits=8)),
-                ('longitude', models.DecimalField(decimal_places=6, max_digits=9)),
-            ],
-        ),
-    ]
diff --git a/georeport/migrations/0002_report_state.py b/georeport/migrations/0002_report_state.py
deleted file mode 100644 (file)
index 506b77b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 5.1.3 on 2024-12-02 09:15
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('georeport', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='report',
-            name='state',
-            field=models.IntegerField(choices=[(0, 'New'), (1, 'Finished')], default=0),
-        ),
-    ]
diff --git a/georeport/migrations/0003_category_alter_report_description_report_category.py b/georeport/migrations/0003_category_alter_report_description_report_category.py
deleted file mode 100644 (file)
index 8f292da..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-# Generated by Django 5.1.4 on 2024-12-21 13:30
-
-import django.db.models.deletion
-import georeport.models
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('georeport', '0002_report_state'),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='Category',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('name', models.CharField(max_length=100)),
-            ],
-        ),
-        migrations.AlterField(
-            model_name='report',
-            name='description',
-            field=models.CharField(blank=True, max_length=255, null=True),
-        ),
-        migrations.AddField(
-            model_name='report',
-            name='category',
-            field=models.ForeignKey(default=georeport.models.get_default_related, on_delete=django.db.models.deletion.RESTRICT, to='georeport.category'),
-        ),
-    ]
diff --git a/georeport/migrations/0004_report_email_report_published.py b/georeport/migrations/0004_report_email_report_published.py
deleted file mode 100644 (file)
index 4a422ee..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 5.1.4 on 2025-01-06 09:56
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-    dependencies = [
-        ("georeport", "0003_category_alter_report_description_report_category"),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name="report",
-            name="email",
-            field=models.EmailField(default="mail@pinpoint.de", max_length=254),
-            preserve_default=False,
-        ),
-        migrations.AddField(
-            model_name="report",
-            name="published",
-            field=models.BooleanField(default=True),
-        ),
-    ]
diff --git a/georeport/migrations/0005_category_parent.py b/georeport/migrations/0005_category_parent.py
deleted file mode 100644 (file)
index 95fdee8..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-# Generated by Django 5.1.4 on 2025-01-06 10:04
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('georeport', '0004_report_email_report_published'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='category',
-            name='parent',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='georeport.category'),
-        ),
-    ]
diff --git a/georeport/migrations/0006_alter_category_options_group.py b/georeport/migrations/0006_alter_category_options_group.py
deleted file mode 100644 (file)
index c56fb9b..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-# Generated by Django 5.1.4 on 2025-01-13 10:58
-
-import django.contrib.auth.models
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('auth', '0012_alter_user_first_name_max_length'),
-        ('georeport', '0005_category_parent'),
-    ]
-
-    operations = [
-        migrations.AlterModelOptions(
-            name='category',
-            options={'verbose_name_plural': 'Categories'},
-        ),
-        migrations.CreateModel(
-            name='Group',
-            fields=[
-                ('group_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='auth.group')),
-                ('categories', models.ManyToManyField(related_name='auth_groups', to='georeport.category')),
-            ],
-            bases=('auth.group',),
-            managers=[
-                ('objects', django.contrib.auth.models.GroupManager()),
-            ],
-        ),
-    ]
diff --git a/georeport/migrations/0007_delete_group.py b/georeport/migrations/0007_delete_group.py
deleted file mode 100644 (file)
index 89e8e14..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-# Generated by Django 5.1.4 on 2025-01-15 09:09
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('georeport', '0006_alter_category_options_group'),
-    ]
-
-    operations = [
-        migrations.DeleteModel(
-            name='Group',
-        ),
-    ]
diff --git a/georeport/migrations/0008_category_group.py b/georeport/migrations/0008_category_group.py
deleted file mode 100644 (file)
index 679705b..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# Generated by Django 5.1.4 on 2025-01-20 12:04
-
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('georeport', '0007_delete_group'),
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='category',
-            name='group',
-            field=models.ManyToManyField(related_name='owner', to=settings.AUTH_USER_MODEL),
-        ),
-    ]
index c347749b09a3afd3535993f07fe6b3961fd73543..71a836239075aa6e6e4ecb700e9c42c95c022d91 100644 (file)
@@ -1,62 +1,3 @@
-# Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
-# GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
-
-
-from asyncio import wait
 from django.db import models
-from django.contrib.auth.models import Group, User, Permission
 
 # Create your models here.
-
-
-class Category(models.Model):
-    name = models.CharField(max_length=100)
-    parent = models.ForeignKey(
-        "self",
-        on_delete=models.CASCADE,
-        related_name="children",
-        null=True,
-        blank=True,
-    )
-
-    group = models.ManyToManyField(User, related_name="owner")
-
-    class Meta:
-        verbose_name_plural = "Categories"
-
-    def __str__(self):
-        return self.name
-
-
-def get_default_related():
-    def get_default_related():
-        return Category.objects.first().id
-
-
-class Report(models.Model):
-    class State(models.IntegerChoices):
-        NEW = 0
-        FINISHED = 1
-
-    title = models.CharField(max_length=80)
-    creation_time = models.DateTimeField(auto_now_add=True)
-    # TODO last change shall be set to creation_time at creation_time
-    last_change = models.DateTimeField(auto_now=True)
-    description = models.CharField(max_length=255, null=True, blank=True)
-
-    latitude = models.DecimalField(max_digits=8, decimal_places=6)
-    longitude = models.DecimalField(max_digits=9, decimal_places=6)
-
-    state = models.IntegerField(choices=State, default=0)
-    category = models.ForeignKey(
-        Category, on_delete=models.RESTRICT, default=get_default_related
-    )
-
-    published = models.BooleanField(default=True)
-
-    email = models.EmailField()
-
-    # TODO add status
-    #
-    def __str__(self):
-        return self.title
diff --git a/georeport/static/georeport/create_Report.js b/georeport/static/georeport/create_Report.js
deleted file mode 100644 (file)
index 195c3f0..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* 
- * Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
- * GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
-*/
-var lat_input = document.getElementById("latitude");
-var lng_input = document.getElementById("longitude");
-let marker = L.marker();
-
-/* 
- * set to 6 decimals points to get a precision of around 10cm 
- * according to https://en.wikipedia.org/wiki/Decimal_degrees
-*/
-const precision = 6
-
-
-lat_input.addEventListener("change", () => {
-  marker.setLatLng([lat_input.value, lng_input.value])
-  i.addTo(map);
-
-});
-lng_input.addEventListener("change", () => {
-  marker.setLatLng([lat_input.value, lng_input.value])
-    .addTo(map);
-
-});
-
-function onMapClick(e) {
-  marker.setLatLng(e.latlng)
-    .addTo(map);
-
-  lat_input.value = e.latlng.lat.toFixed(precision);
-  lng_input.value = e.latlng.lng.toFixed(precision);
-}
-
-map.on("click", onMapClick);
-
diff --git a/georeport/static/georeport/details.js b/georeport/static/georeport/details.js
deleted file mode 100644 (file)
index a5d091d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/* 
- * Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
- * GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
-*/
-var marker = L.marker();
-
-var lat = document.getElementById("p-lat").dataset.lat;
-var lng = document.getElementById("p-lng").dataset.lng;
-
-marker.setLatLng([lat, lng])
-    .addTo(map);
diff --git a/georeport/static/georeport/mapsetup.js b/georeport/static/georeport/mapsetup.js
deleted file mode 100644 (file)
index e364add..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/* 
- * Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
- * GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
-*/
-var map = L.map("map").setView([51.7173, 8.753557], 15);
-L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
-    maxZoom: 19,
-    attribution: "&copy; <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap</a>"
-}).addTo(map);
diff --git a/georeport/static/georeport/recurse_selection.js b/georeport/static/georeport/recurse_selection.js
deleted file mode 100644 (file)
index dba6c99..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/* 
- * Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
- * GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
-*/
-var level = 0
-function getsubcats(element) {
-    const id = element.id;;
-    var level = 0;
-
-    if (id == "category")
-        level = 0;
-    else
-        level = id
-
-    console.log(level);
-    const rootselect = document.getElementById(id);
-
-    let = url = `category/${rootselect.value}/children`;
-
-    const form = document.getElementById("form");
-    const submit = document.getElementById("submit");
-    console.log(url);
-    fetch(url)
-        .then(response => {
-            if (!response.ok) {
-                throw new Error(`HTTP Error: Status: ${response.status}`);
-            }
-            return response.json();
-        })
-        .then(data => {
-            console.log(data);
-            level++;
-
-            let subcats = data["subcategories"];
-            if (subcats.length == 0) {
-                let oldselect = document.getElementById(level);
-                rootselect.name = "category";
-                if (oldselect) {
-                    form.removeChild(oldselect);
-                    oldselect.remove();
-                    form.removeChild(submit);
-                    form.appendChild(submit);
-                }
-                return
-            }
-
-            let select = document.getElementById(level);
-            if (select != null)
-                select.remove();
-            select = document.createElement("select");
-            select.id = level;
-            select.name = select.id;
-            select.value = "";
-            select.innerHTML = "Choose a subcategory";
-            select.onchange = function () {
-                getsubcats(this);
-            }
-            select.name = "category";
-            rootselect.name = "root";
-
-            var option = document.createElement("option");
-            option.value = "";
-            option.innerHTML = "Subcategory";
-            option.disabled = true;
-            option.selected = true;
-            select.appendChild(option);
-
-
-            console.log(subcats);
-            for (var cat of subcats) {
-                option = document.createElement("option");
-                option.value = cat.id;
-                option.innerText = cat.name;
-                select.appendChild(option);
-            }
-
-            form.removeChild(submit);
-            form.appendChild(select);
-            form.appendChild(submit);
-
-            console.log(level);
-        });
-
-}
-
-// TODO: Better IDs for new selections 
-// TODO: Labels for selection*/
-// TODO: Tidy up 
-
diff --git a/georeport/static/georeport/style.css b/georeport/static/georeport/style.css
deleted file mode 100644 (file)
index 2e73e20..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#map {
-    width:  50%;
-    border: 3px solid;
-    margin: auto;
-    border-radius: 25px;
-}
diff --git a/georeport/templates/georeport/base.html b/georeport/templates/georeport/base.html
deleted file mode 100644 (file)
index fff44d9..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-<!--
-Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
-GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
--->
-<!DOCTYPE html>
-{% load static %}
-<html>
-    <head>
-        <title>{% block title %}Georeport{% endblock %}</title>
-        <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
-            integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
-            crossorigin=""/>
-
-        <!-- Make sure you put this AFTER Leaflet's CSS -->
-        <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
-            integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
-            crossorigin="">
-        </script>
-
-        <style>
-            #map { height: 500px;}
-        </style>
-        <link rel="stylesheet" href="{% static 'georeport/style.css' %}"
-
-    </head>
-
-    <body>
-
-        <div id="map"></div>
-        <script src="{% static 'georeport/mapsetup.js' %}"></script>
-        {% block body %}
-        {% endblock %}
-    </body>
-</html>
diff --git a/georeport/templates/georeport/category.html b/georeport/templates/georeport/category.html
deleted file mode 100644 (file)
index ec526ce..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<!--
-Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
-GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
--->
-{% extends "georeport/base.html" %}
-{% load static %}
-{% block title %}Detail {{ category.id }} {% endblock %}
-{% block body %}
-    <h1>Categoriy {{ category.id }}</h1>
-    <p>Name: {{ category.name }}</p>
-    {% if category.parent %}
-    <p>Supercategory:<a href={{category.parent.id }}>{{category.parent}}</a></p>
-    {%endif%}
-    {% if category.children.exists %}
-    <h3>Subcategories:</h3>
-    <ul>
-        {% for child in category.children.all %}
-            <li><a href={{ child.id }}>{{child.name}} </a></li>
-        {% endfor %}
-    </ul>
-    {% endif %}
-    <a href="{% url 'index' %}">Back</a>
-{% endblock %}
diff --git a/georeport/templates/georeport/create.html b/georeport/templates/georeport/create.html
deleted file mode 100644 (file)
index a28a6b8..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-<!--
-Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
-GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
--->
-{% extends "georeport/base.html" %}
-{% load static %}
-{% block title %}New report {% endblock %}
-{% block body %} 
-<!--
-<form method="post">
-    {% csrf_token %}
-    {{ reportForm }}
-    <input type="submit"/>
-</form>-->
-<script src="{% static 'georeport/recurse_selection.js' %}"></script>
-<form method="post" id="form">
-    {% csrf_token %}
-    <label for="title">Title:</label>
-    <input type="text" id="title" name="title" required> </br>
-    <label for="description">Description:</label>
-    <input type="text" id="description" name="description"> </br>
-    <label for="latitude">Latitude:</label>
-    <input type="number" id="latitude" name="latitude" step=0.000001 required > </br>
-    <label for="longitude">Longitude:</label>
-    <input type="number" id="longitude" name="longitude" step=0.000001 required > </br>
-    <label for="email">Email:</label>
-    <input type="email" id="email" name="email"i required > </br>
-    <label for="category">Category</label>
-    <select id="category" name="category" onchange="getsubcats(this)" required>
-        <option value="" disabled selected>Choose a category.</option>
-        {% for cat in categories %}
-            {% if cat.parent is none %}
-                <option value="{{cat.id}}">{{cat.name}}</option>
-            {% endif %}
-        {% endfor %}
-    </select></br>
-    <input type="submit" id="submit">
-</form>
-<script src="{% static 'georeport/create_Report.js' %}"></script>
-
-<!-- TODO better URLS -->
-<a href="/georeport">Cancel</a>
-{% endblock %}
-
diff --git a/georeport/templates/georeport/detail.html b/georeport/templates/georeport/detail.html
deleted file mode 100644 (file)
index 8284d2c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<!--
-Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
-GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
--->
-{% extends "georeport/base.html" %}
-{% load static %}
-{% block title %}Detail {{ report.id }} {% endblock %} 
-{% block body %} 
-    <h1>Report {{ report.id }}</h1>
-    <p>Title: {{ report.title }}</p>
-    <p>Erstellt am : {{ report.creation_time }}</p>
-    <p>Geändert: {{ report.last_changed  }}</p>
-    <p id="p-lat" data-lat="{{ report.latitude }}">Latitude: {{ report.latitude }}</p>
-    <p id="p-lng" data-lng="{{ report.longitude }}">Longitude: {{ report.longitude }}</p>
-    <p>Status: {{ report.get_state_display }} </p>
-    <p>Kategorie: {{ report.category }} </p>
-    <a href="{% url 'index' %}">Back</a>
-    <script src="{% static 'georeport/details.js' %}"></script>
-{% endblock %} 
diff --git a/georeport/templates/georeport/index.html b/georeport/templates/georeport/index.html
deleted file mode 100644 (file)
index 00745a2..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-<!--
-Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
-GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
--->
-{% extends "georeport/base.html" %}
-{% load static %}
-{% block title %}Index{% endblock %}
-
-{% block body %}
-<h1>Reports </h1>
-<a href="create">New Report</a>
-<ul>
-    <!-- List with published reports -->
-    {% for report in report_list %}
-        {% if report.published %}
-            <li><a href="{{ report.id }}">{{ report.title }}</a></li>
-            <script>
-                let marker{{report.id}} = L.marker([{{report.latitude}},{{report.longitude}}]);
-                marker{{report.id}}.addTo(map);
-            </script>
-        {% endif %}
-    {% endfor %}
-</ul>
-
-<h2>Categories</h2>
-<ul>
-    {% for category in category_list %}
-        <li><a href="category/{{ category.id }}">{{ category.name }}</a></li>
-    {% endfor %}
-</ul>
-
-{% endblock %}
index 06b40fffa1b749f1632b342f3e965f272d6cd811..ab074cbda2791283ae0345b3430cde1e05f66274 100644 (file)
@@ -1,16 +1,19 @@
-# Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
-# GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
-
-
+from . import views
 from django.urls import path
+# TODO: Adjust to open311
+#  /services: -> List with Categories  <- GET
+#  /sercvice/{id} -> single Category <- GET
+#  /requests -> Create a new Request <- POST
+#  /requests -> Get all Requests <- GET
+#  /requests/{id} -> Get a specific Request <- GET
 
-from . import views
 
 urlpatterns = [
     path("", views.index, name="index"),
-    path("<int:id>", views.details, name="detail"),
-    path("create", views.create, name="create"),
-    path("category/<int:id>", views.category_details, name="category"),
-    # TODO
-    path("category/<int:id>/children", views.get_subcategories, name="subcategories"),
+    #  path("<int:id>", views.details, name="detail"),
+    #  path("create", views.create, name="create"),
+    #  path("category/<int:id>", views.category_details, name="category"),
+    #  # TODO
+    #  path("category/<int:id>/children", views.get_subcategories, name="subcategories"),
+    #  path("<str:b64nonce>/<str:b64ct>", views.finish_link, name="finish"),
 ]
index 31138107120566f95a2dace6d79892c3e818e9ff..4da908d3e534d849461352bdb3542cae57cb516f 100644 (file)
@@ -1,78 +1,16 @@
-# Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
-# GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
-
-
-from django.http import HttpResponseForbidden, JsonResponse
-from django.shortcuts import get_object_or_404, redirect, render
-
-from .forms import ReportForm
-import json
-
 # Create your views here.
-from .models import Category, Report
-import pdb
-
-
-def index(request):
-    reports = Report.objects.all()
-    categories = Category.objects.all()
-    return render(
-        request,
-        "georeport/index.html",
-        context={"report_list": reports, "category_list": categories},
-    )
-
 
-def details(request, id):
-    report = get_object_or_404(Report, pk=id)
-    if report.published:
-        return render(request, "georeport/detail.html", context={"report": report})
-    else:
-        return HttpResponseForbidden("The report is not published")
+# TODO: Index-Views
+# TODO: Category-List
+# TODO: Report-List
+# TODO: Create-Report
+# TODO: DetailView
+# TODO: Category-Detail
+# TODO: Supcategories
 
 
-def category_details(request, id):
-    category = get_object_or_404(Category, pk=id)
-    user = request.user
+from django.http import HttpResponse
 
-    allowed = category.group.all()
 
-    if user in allowed or user.is_superuser:
-        return render(
-            request, "georeport/category.html", context={"category": category}
-        )
-    else:
-        return HttpResponseForbidden("Not allowed")
-
-
-def create(request):
-    if request.method == "POST":
-        post = request.POST
-        report = {}
-        report["title"] = post["title"]
-        report["longitude"] = post["longitude"]
-        report["latitude"] = post["latitude"]
-        report["category"] = post["category"]
-        report["email"] = post["email"]
-
-        reportForm = ReportForm(report)
-        # reportForm = ReportForm(request.POST)
-
-        # TODO Inputvalidation
-        reportForm.save()
-        return redirect("index")
-    else:
-        reportForm = ReportForm()
-
-    return render(
-        request,
-        "georeport/create.html",
-        context={"reportForm": reportForm, "categories": Category.objects.all()},
-    )
-
-
-def get_subcategories(request, id):
-    subcats = Category.objects.filter(parent__id=id)
-    data = [{"id": cat.id, "name": cat.name} for cat in subcats]
-    data = {"subcategories": data}
-    return JsonResponse(data)
+def index(request):
+    return HttpResponse(b"Pinpoint-Report")
index 52c4ff2befdf96e893c2a720cf6783fb34c1b35a..2476f132db6de1f5501152aab20607d94a2d8681 100755 (executable)
--- a/manage.py
+++ b/manage.py
@@ -6,7 +6,7 @@ import sys
 
 def main():
     """Run administrative tasks."""
-    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pinpoint.settings')
+    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pinpoint_report.settings')
     try:
         from django.core.management import execute_from_command_line
     except ImportError as exc:
similarity index 71%
rename from pinpoint/asgi.py
rename to pinpoint_report/asgi.py
index 2b72c59c6212204d58a49527b2f9f7a7ade2c858..94abb2f11d26abc29429e4903f3cc7c19e532718 100644 (file)
@@ -1,5 +1,5 @@
 """
-ASGI config for pinpoint project.
+ASGI config for pinpoint_report project.
 
 It exposes the ASGI callable as a module-level variable named ``application``.
 
@@ -11,6 +11,6 @@ import os
 
 from django.core.asgi import get_asgi_application
 
-os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pinpoint.settings')
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pinpoint_report.settings')
 
 application = get_asgi_application()
similarity index 82%
rename from pinpoint/settings.py
rename to pinpoint_report/settings.py
index 84380f0806d49c88550b3ad90c3e518261eacaa3..2b35eaf729c5999a1d9563020000c91f68edfa99 100644 (file)
@@ -1,7 +1,7 @@
 """
-Django settings for pinpoint project.
+Django settings for pinpoint_report project.
 
-Generated by 'django-admin startproject' using Django 5.1.3.
+Generated by 'django-admin startproject' using Django 5.1.5.
 
 For more information on this file, see
 https://docs.djangoproject.com/en/5.1/topics/settings/
@@ -10,6 +10,7 @@ For the full list of settings and their values, see
 https://docs.djangoproject.com/en/5.1/ref/settings/
 """
 
+import sys
 from pathlib import Path
 
 # Build paths inside the project like this: BASE_DIR / 'subdir'.
@@ -20,28 +21,24 @@ BASE_DIR = Path(__file__).resolve().parent.parent
 # See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
 
 # SECURITY WARNING: keep the secret key used in production secret!
-SECRET_KEY = "django-insecure-&7#5doz#@q$^jtjn!^*fmta$=eaqjd@8mtf(1=^=lt8*xen(+g"
+SECRET_KEY = "django-insecure-^f3zw!cfp(mkh()na5(i-#s3472ue*n7@m34crljq82e66#_0m"
 
 # SECURITY WARNING: don't run with debug turned on in production!
 DEBUG = True
 
-ALLOWED_HOSTS = []
+ALLOWED_HOSTS = [".localhost", "127.0.0.1", "[::1]"]
 
 
 # Application definition
 
 INSTALLED_APPS = [
     "georeport.apps.GeoreportConfig",
-    "polls.apps.PollsConfig",
     "django.contrib.admin",
     "django.contrib.auth",
     "django.contrib.contenttypes",
     "django.contrib.sessions",
     "django.contrib.messages",
     "django.contrib.staticfiles",
-    "rest_framework",
-    "snippets",
-    "debug_toolbar",
 ]
 
 MIDDLEWARE = [
@@ -52,15 +49,14 @@ MIDDLEWARE = [
     "django.contrib.auth.middleware.AuthenticationMiddleware",
     "django.contrib.messages.middleware.MessageMiddleware",
     "django.middleware.clickjacking.XFrameOptionsMiddleware",
-    "debug_toolbar.middleware.DebugToolbarMiddleware",
 ]
 
-ROOT_URLCONF = "pinpoint.urls"
+ROOT_URLCONF = "pinpoint_report.urls"
 
 TEMPLATES = [
     {
         "BACKEND": "django.template.backends.django.DjangoTemplates",
-        "DIRS": [BASE_DIR / "templates"],
+        "DIRS": [],
         "APP_DIRS": True,
         "OPTIONS": {
             "context_processors": [
@@ -73,7 +69,7 @@ TEMPLATES = [
     },
 ]
 
-WSGI_APPLICATION = "pinpoint.wsgi.application"
+WSGI_APPLICATION = "pinpoint_report.wsgi.application"
 
 
 # Database
@@ -128,10 +124,14 @@ STATIC_URL = "static/"
 
 DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
 
-INTERNAL_IPS = [
-    "127.0.0.1",
-]
-REST_FRAMEWORK = {
-    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
-    "PAGE_SIZE": 10,
-}
+TESTING = "test" in sys.argv
+
+if not TESTING:
+    INSTALLED_APPS = [
+        *INSTALLED_APPS,
+        "debug_toolbar",
+    ]
+    MIDDLEWARE = [
+        "debug_toolbar.middleware.DebugToolbarMiddleware",
+        *MIDDLEWARE,
+    ]
similarity index 69%
rename from pinpoint/urls.py
rename to pinpoint_report/urls.py
index 0e04e01d3116ed160543ef8ae4c96a75a36b60c6..201171c1f8f6f79a3014e3a0c99d5933fe9afcc6 100644 (file)
@@ -1,5 +1,5 @@
 """
-URL configuration for pinpoint project.
+URL configuration for pinpoint_report project.
 
 The `urlpatterns` list routes URLs to views. For more information please see:
     https://docs.djangoproject.com/en/5.1/topics/http/urls/
@@ -16,15 +16,13 @@ Including another URLconf
 """
 
 from django.contrib import admin
-from django.urls import path, include
+from django.urls import path
+from django.conf import settings
 from debug_toolbar.toolbar import debug_toolbar_urls
 
-from georeport.admin import admin_site
-
 urlpatterns = [
     path("admin/", admin.site.urls),
-    path("myadmin/", admin_site.urls),
-    path("snippets/", include("snippets.urls")),
-    path("georeport/", include("georeport.urls")),
-    path("polls/", include("polls.urls")),
-] + debug_toolbar_urls()
+]
+
+if settings.TESTING:
+    urlpatterns = [*urlpatterns] + debug_toolbar_urls()
similarity index 71%
rename from pinpoint/wsgi.py
rename to pinpoint_report/wsgi.py
index 77a0b83d9879ea3a84827ad098a5682aa8488e59..803a00dfe673d3a82d1f17777399e6af3e58e118 100644 (file)
@@ -1,5 +1,5 @@
 """
-WSGI config for pinpoint project.
+WSGI config for pinpoint_report project.
 
 It exposes the WSGI callable as a module-level variable named ``application``.
 
@@ -11,6 +11,6 @@ import os
 
 from django.core.wsgi import get_wsgi_application
 
-os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pinpoint.settings')
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pinpoint_report.settings')
 
 application = get_wsgi_application()
diff --git a/polls/__init__.py b/polls/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/polls/admin.py b/polls/admin.py
deleted file mode 100644 (file)
index a847220..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from django.contrib import admin
-
-# Register your models here.
-
-from .models import *
-
-
-class ChoiceInLine(admin.TabularInline):
-    model = Choice
-    extra = 0
-
-
-@admin.register(Question)
-class QuestionAdmin(admin.ModelAdmin):
-    fieldsets = [
-        (None, {"fields": ["question_text"]}),
-        ("Date Information", {"fields": ["pub_date"]}),
-    ]
-    inlines = [ChoiceInLine]
-
-    list_display = ["question_text", "pub_date", "was_published_recently"]
-    search_fields = ["question_text"]
-
-
-admin.site.register(Choice)
diff --git a/polls/apps.py b/polls/apps.py
deleted file mode 100644 (file)
index 5a5f94c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-from django.apps import AppConfig
-
-
-class PollsConfig(AppConfig):
-    default_auto_field = 'django.db.models.BigAutoField'
-    name = 'polls'
diff --git a/polls/migrations/0001_initial.py b/polls/migrations/0001_initial.py
deleted file mode 100644 (file)
index 8512a5b..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-# Generated by Django 5.1.4 on 2025-01-16 18:35
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    initial = True
-
-    dependencies = [
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='Question',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('question_text', models.CharField(max_length=100)),
-                ('pub_date', models.DateTimeField(verbose_name='date published')),
-            ],
-        ),
-        migrations.CreateModel(
-            name='Choice',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('choice_text', models.CharField(max_length=200)),
-                ('votes', models.IntegerField(default=0)),
-                ('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='polls.question')),
-            ],
-        ),
-    ]
diff --git a/polls/migrations/__init__.py b/polls/migrations/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/polls/models.py b/polls/models.py
deleted file mode 100644 (file)
index cbcef16..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from django.db import models
-import datetime
-from django.utils import timezone
-from django.contrib import admin
-
-
-class Question(models.Model):
-    question_text = models.CharField(max_length=100)
-    pub_date = models.DateTimeField("date published")
-
-    @admin.display(boolean=True, ordering="pub_date", description="Published recently?")
-    def was_published_recently(self):
-        now = timezone.now()
-        return now - datetime.timedelta(days=1) <= self.pub_date <= now
-
-    def __str__(self):  # type: ignore
-        return self.question_text
-
-
-class Choice(models.Model):
-    question = models.ForeignKey(Question, on_delete=models.CASCADE)
-    choice_text = models.CharField(max_length=200)
-    votes = models.IntegerField(default=0)  # type:ignore
-
-    def __str__(self):  # type: ignore
-        return self.choice_text
diff --git a/polls/templates/polls/detail.html b/polls/templates/polls/detail.html
deleted file mode 100644 (file)
index 8d92d7c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<html>
-    <head>
-        <title>Detail</title>
-    </head>
-    <body>
-        <form action="{% url 'polls:vote' question.id %}" method="post">
-        {% csrf_token %}
-        <fieldset>
-            <legend><h1>{{ question.question_text }}</h1></legend>
-            {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
-            {% for choice in question.choice_set.all %}
-                <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
-                <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
-            {% endfor %}
-        </fieldset>
-        <input type="submit" value="Vote">
-        </form>  
-    </body>
-</html>
diff --git a/polls/templates/polls/index.html b/polls/templates/polls/index.html
deleted file mode 100644 (file)
index d7c0dc1..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<html>
-    <head>
-        <title>Index</title>
-    </head>
-    <body>
-        {% if latest_question_list %}
-            <ul>
-                {% for question in latest_question_list %}
-            <li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text}}</a></li>
-                {% endfor %}
-            </ul>
-        {% else %}
-            <p>No polls</p>
-        {% endif %}
-
-    </body>
-</html>
diff --git a/polls/templates/polls/results.html b/polls/templates/polls/results.html
deleted file mode 100644 (file)
index 1837ca8..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-<html>
-    <head>
-        <title>Results</title>
-    </head>
-    <body>
-        <h1>{{question.question_text}}</h1>
-
-        <ul>
-            {% for choice in question.choice_set.all %}
-                <li>{{choice.choice_text}} -- {{choice.votes }} vote {{choice.votes|pluralize}}</li>
-            {% endfor %}
-        </ul>
-        <a href="{% url 'polls:detail' question.id %}">Vote again?</a>
-    </body>
-</html>
diff --git a/polls/tests.py b/polls/tests.py
deleted file mode 100644 (file)
index 62b987b..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-from django.urls import reverse
-from django.test import TestCase
-
-import datetime
-from django.utils import timezone
-
-from .models import Question
-
-
-class QuestionModelTests(TestCase):
-    def test_was_published_recently_with_future_question(self):
-        time = timezone.now() + datetime.timedelta(days=30)
-        future_question = Question(pub_date=time)
-        self.assertIs(future_question.was_published_recently(), False)
-
-    def test_was_published_recently_with_old_question(self):
-        """
-        was_published_recently() returns False for questions whose pub_date
-        is older than 1 day.
-        """
-        time = timezone.now() - datetime.timedelta(days=1, seconds=1)
-        old_question = Question(pub_date=time)
-        self.assertIs(old_question.was_published_recently(), False)
-
-    def test_was_published_recently_with_recent_question(self):
-        """
-        was_published_recently() returns True for questions whose pub_date
-        is within the last day.
-        """
-        time = timezone.now() - datetime.timedelta(hours=23, minutes=59, seconds=59)
-        recent_question = Question(pub_date=time)
-        self.assertIs(recent_question.was_published_recently(), True)
-
-
-def create_question(question_text, days):
-    """
-    Create a question with the given `question_text` and published the
-    given number of `days` offset to now (negative for questions published
-    in the past, positive for questions that have yet to be published).
-    """
-    time = timezone.now() + datetime.timedelta(days=days)
-    return Question.objects.create(question_text=question_text, pub_date=time)
-
-
-class QuestionIndexViewTests(TestCase):
-    def test_no_questoin(self):
-        response = self.client.get(reverse("polls:index"))
-        self.assertEqual(response.status_code, 200)
-        self.assertContains(response, "No polls")
-        self.assertQuerySetEqual(response.context["latest_question_list"], [])
-
-    def test_past_question(self):
-        """
-        Questions with a pub_date in the past are displayed on the
-        index page.
-        """
-        question = create_question(question_text="Past question.", days=-30)
-        response = self.client.get(reverse("polls:index"))
-        self.assertQuerySetEqual(
-            response.context["latest_question_list"],
-            [question],
-        )
-
-    def test_future_question(self):
-        """
-        Questions with a pub_date in the future aren't displayed on
-        the index page.
-        """
-        create_question(question_text="Future question.", days=30)
-        response = self.client.get(reverse("polls:index"))
-        self.assertContains(response, "No polls")
-        self.assertQuerySetEqual(response.context["latest_question_list"], [])
-
-    def test_future_question_and_past_question(self):
-        """
-        Even if both past and future questions exist, only past questions
-        are displayed.
-        """
-        question = create_question(question_text="Past question.", days=-30)
-        create_question(question_text="Future question.", days=30)
-        response = self.client.get(reverse("polls:index"))
-        self.assertQuerySetEqual(
-            response.context["latest_question_list"],
-            [question],
-        )
-
-    def test_two_past_questions(self):
-        """
-        The questions index page may display multiple questions.
-        """
-        question1 = create_question(question_text="Past question 1.", days=-30)
-        question2 = create_question(question_text="Past question 2.", days=-5)
-        response = self.client.get(reverse("polls:index"))
-        self.assertQuerySetEqual(
-            response.context["latest_question_list"],
-            [question2, question1],
-        )
-
-
-class QuestionDetailViewTests(TestCase):
-    def test_future_question(self):
-        """
-        The detail view of a question with a pub_date in the future
-        returns a 404 not found.
-        """
-        future_question = create_question(question_text="Future question.", days=5)
-        url = reverse("polls:detail", args=(future_question.id,))
-        response = self.client.get(url)
-        self.assertEqual(response.status_code, 404)
-
-    def test_past_question(self):
-        """
-        The detail view of a question with a pub_date in the past
-        displays the question's text.
-        """
-        past_question = create_question(question_text="Past Question.", days=-5)
-        url = reverse("polls:detail", args=(past_question.id,))
-        response = self.client.get(url)
-        self.assertContains(response, past_question.question_text)
diff --git a/polls/urls.py b/polls/urls.py
deleted file mode 100644 (file)
index ce53e6f..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-from django.urls import path
-
-from . import views
-
-app_name = "polls"
-urlpatterns = [
-    # ex: /polls/
-    path("", views.IndexView.as_view(), name="index"),
-    # ex: /polls/5/
-    path("<int:pk>/", views.DetailView.as_view(), name="detail"),
-    # ex: /polls/5/results/
-    path("<int:pk>/results/", views.ResultsView.as_view(), name="results"),
-    # ex: /polls/5/vote/
-    path("<int:question_id>/vote/", views.vote, name="vote"),
-]
diff --git a/polls/views.py b/polls/views.py
deleted file mode 100644 (file)
index 4687658..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-from django.shortcuts import get_object_or_404, render
-
-from django.http import HttpResponse, HttpResponseRedirect
-from django.urls import reverse
-
-from polls.models import Question, Choice
-from django.db.models import F
-from django.views import generic
-
-from django.utils import timezone
-
-
-class IndexView(generic.ListView):
-    template_name = "polls/index.html"
-    context_object_name = "latest_question_list"
-
-    def get_queryset(self):
-        return Question.objects.filter(pub_date__lte=timezone.now()).order_by(
-            "-pub_date"
-        )[:5]
-
-
-class DetailView(generic.DetailView):
-    model = Question
-    template_name = "polls/detail.html"
-
-    def get_queryset(self):
-        return Question.objects.filter(pub_date__lte=timezone.now())
-
-
-class ResultsView(generic.DetailView):
-    model = Question
-    template_name = "polls/results.html"
-
-
-def vote(request, question_id):
-    question = get_object_or_404(Question, pk=question_id)
-    try:
-        selected_choice = question.choice_set.get(pk=request.POST["choice"])
-    except (KeyError, Choice.DoesNotExist):
-        # Redisplay the question voting form.
-        return render(
-            request,
-            "polls/detail.html",
-            {
-                "question": question,
-                "error_message": "You didn't select a choice.",
-            },
-        )
-    else:
-        selected_choice.votes = F("votes") + 1
-        selected_choice.save()
-        # Always return an HttpResponseRedirect after successfully dealing
-        # with POST data. This prevents data from being posted twice if a
-        # user hits the Back button.
-        return HttpResponseRedirect(reverse("polls:results", args=(question.id,)))
index 3b8d0ff3121f9fda3248c5497c6423fbc6648811..e35bad924ba7b2b2c0f225f444f7394c4443ad24 100644 (file)
@@ -1,2 +1,3 @@
+# Django
 django 
 django-debug-toolbar
diff --git a/snippets/__init__.py b/snippets/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/snippets/admin.py b/snippets/admin.py
deleted file mode 100644 (file)
index 8c38f3f..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.contrib import admin
-
-# Register your models here.
diff --git a/snippets/apps.py b/snippets/apps.py
deleted file mode 100644 (file)
index 33dd0be..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-from django.apps import AppConfig
-
-
-class SnippetsConfig(AppConfig):
-    default_auto_field = 'django.db.models.BigAutoField'
-    name = 'snippets'
diff --git a/snippets/migrations/0001_initial.py b/snippets/migrations/0001_initial.py
deleted file mode 100644 (file)
index 212f776..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-# Generated by Django 5.1.4 on 2025-01-15 09:36
-
-import django.db.models.deletion
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    initial = True
-
-    dependencies = [
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='Snippet',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('created', models.DateTimeField(auto_now_add=True)),
-                ('title', models.CharField(blank=True, default='', max_length=100)),
-                ('code', models.TextField()),
-                ('linenos', models.BooleanField(default=False)),
-                ('language', models.CharField(choices=[('abap', 'ABAP'), ('abnf', 'ABNF'), ('actionscript', 'ActionScript'), ('actionscript3', 'ActionScript 3'), ('ada', 'Ada'), ('adl', 'ADL'), ('agda', 'Agda'), ('aheui', 'Aheui'), ('alloy', 'Alloy'), ('ambienttalk', 'AmbientTalk'), ('amdgpu', 'AMDGPU'), ('ampl', 'Ampl'), ('androidbp', 'Soong'), ('ansys', 'ANSYS parametric design language'), ('antlr', 'ANTLR'), ('antlr-actionscript', 'ANTLR With ActionScript Target'), ('antlr-cpp', 'ANTLR With CPP Target'), ('antlr-csharp', 'ANTLR With C# Target'), ('antlr-java', 'ANTLR With Java Target'), ('antlr-objc', 'ANTLR With ObjectiveC Target'), ('antlr-perl', 'ANTLR With Perl Target'), ('antlr-python', 'ANTLR With Python Target'), ('antlr-ruby', 'ANTLR With Ruby Target'), ('apacheconf', 'ApacheConf'), ('apl', 'APL'), ('applescript', 'AppleScript'), ('arduino', 'Arduino'), ('arrow', 'Arrow'), ('arturo', 'Arturo'), ('asc', 'ASCII armored'), ('asn1', 'ASN.1'), ('aspectj', 'AspectJ'), ('aspx-cs', 'aspx-cs'), ('aspx-vb', 'aspx-vb'), ('asymptote', 'Asymptote'), ('augeas', 'Augeas'), ('autohotkey', 'autohotkey'), ('autoit', 'AutoIt'), ('awk', 'Awk'), ('bare', 'BARE'), ('basemake', 'Base Makefile'), ('bash', 'Bash'), ('batch', 'Batchfile'), ('bbcbasic', 'BBC Basic'), ('bbcode', 'BBCode'), ('bc', 'BC'), ('bdd', 'Bdd'), ('befunge', 'Befunge'), ('berry', 'Berry'), ('bibtex', 'BibTeX'), ('blitzbasic', 'BlitzBasic'), ('blitzmax', 'BlitzMax'), ('blueprint', 'Blueprint'), ('bnf', 'BNF'), ('boa', 'Boa'), ('boo', 'Boo'), ('boogie', 'Boogie'), ('bqn', 'BQN'), ('brainfuck', 'Brainfuck'), ('bst', 'BST'), ('bugs', 'BUGS'), ('c', 'C'), ('c-objdump', 'c-objdump'), ('ca65', 'ca65 assembler'), ('cadl', 'cADL'), ('camkes', 'CAmkES'), ('capdl', 'CapDL'), ('capnp', "Cap'n Proto"), ('carbon', 'Carbon'), ('cbmbas', 'CBM BASIC V2'), ('cddl', 'CDDL'), ('ceylon', 'Ceylon'), ('cfc', 'Coldfusion CFC'), ('cfengine3', 'CFEngine3'), ('cfm', 'Coldfusion HTML'), ('cfs', 'cfstatement'), ('chaiscript', 'ChaiScript'), ('chapel', 'Chapel'), ('charmci', 'Charmci'), ('cheetah', 'Cheetah'), ('cirru', 'Cirru'), ('clay', 'Clay'), ('clean', 'Clean'), ('clojure', 'Clojure'), ('clojurescript', 'ClojureScript'), ('cmake', 'CMake'), ('cobol', 'COBOL'), ('cobolfree', 'COBOLFree'), ('codeql', 'CodeQL'), ('coffeescript', 'CoffeeScript'), ('comal', 'COMAL-80'), ('common-lisp', 'Common Lisp'), ('componentpascal', 'Component Pascal'), ('console', 'Bash Session'), ('coq', 'Coq'), ('cplint', 'cplint'), ('cpp', 'C++'), ('cpp-objdump', 'cpp-objdump'), ('cpsa', 'CPSA'), ('cr', 'Crystal'), ('crmsh', 'Crmsh'), ('croc', 'Croc'), ('cryptol', 'Cryptol'), ('csharp', 'C#'), ('csound', 'Csound Orchestra'), ('csound-document', 'Csound Document'), ('csound-score', 'Csound Score'), ('css', 'CSS'), ('css+django', 'CSS+Django/Jinja'), ('css+genshitext', 'CSS+Genshi Text'), ('css+lasso', 'CSS+Lasso'), ('css+mako', 'CSS+Mako'), ('css+mozpreproc', 'CSS+mozpreproc'), ('css+myghty', 'CSS+Myghty'), ('css+php', 'CSS+PHP'), ('css+ruby', 'CSS+Ruby'), ('css+smarty', 'CSS+Smarty'), ('css+ul4', 'CSS+UL4'), ('cuda', 'CUDA'), ('cypher', 'Cypher'), ('cython', 'Cython'), ('d', 'D'), ('d-objdump', 'd-objdump'), ('dart', 'Dart'), ('dasm16', 'DASM16'), ('dax', 'Dax'), ('debcontrol', 'Debian Control file'), ('debian.sources', 'Debian Sources file'), ('debsources', 'Debian Sourcelist'), ('delphi', 'Delphi'), ('desktop', 'Desktop file'), ('devicetree', 'Devicetree'), ('dg', 'dg'), ('diff', 'Diff'), ('django', 'Django/Jinja'), ('docker', 'Docker'), ('doscon', 'MSDOS Session'), ('dpatch', 'Darcs Patch'), ('dtd', 'DTD'), ('duel', 'Duel'), ('dylan', 'Dylan'), ('dylan-console', 'Dylan session'), ('dylan-lid', 'DylanLID'), ('earl-grey', 'Earl Grey'), ('easytrieve', 'Easytrieve'), ('ebnf', 'EBNF'), ('ec', 'eC'), ('ecl', 'ECL'), ('eiffel', 'Eiffel'), ('elixir', 'Elixir'), ('elm', 'Elm'), ('elpi', 'Elpi'), ('emacs-lisp', 'EmacsLisp'), ('email', 'E-mail'), ('erb', 'ERB'), ('erl', 'Erlang erl session'), ('erlang', 'Erlang'), ('evoque', 'Evoque'), ('execline', 'execline'), ('extempore', 'xtlang'), ('ezhil', 'Ezhil'), ('factor', 'Factor'), ('fan', 'Fantom'), ('fancy', 'Fancy'), ('felix', 'Felix'), ('fennel', 'Fennel'), ('fift', 'Fift'), ('fish', 'Fish'), ('flatline', 'Flatline'), ('floscript', 'FloScript'), ('forth', 'Forth'), ('fortran', 'Fortran'), ('fortranfixed', 'FortranFixed'), ('foxpro', 'FoxPro'), ('freefem', 'Freefem'), ('fsharp', 'F#'), ('fstar', 'FStar'), ('func', 'FunC'), ('futhark', 'Futhark'), ('gap', 'GAP'), ('gap-console', 'GAP session'), ('gas', 'GAS'), ('gcode', 'g-code'), ('gdscript', 'GDScript'), ('genshi', 'Genshi'), ('genshitext', 'Genshi Text'), ('gherkin', 'Gherkin'), ('gleam', 'Gleam'), ('glsl', 'GLSL'), ('gnuplot', 'Gnuplot'), ('go', 'Go'), ('golo', 'Golo'), ('gooddata-cl', 'GoodData-CL'), ('googlesql', 'GoogleSQL'), ('gosu', 'Gosu'), ('graphql', 'GraphQL'), ('graphviz', 'Graphviz'), ('groff', 'Groff'), ('groovy', 'Groovy'), ('gsql', 'GSQL'), ('gst', 'Gosu Template'), ('haml', 'Haml'), ('handlebars', 'Handlebars'), ('hare', 'Hare'), ('haskell', 'Haskell'), ('haxe', 'Haxe'), ('haxeml', 'Hxml'), ('hexdump', 'Hexdump'), ('hlsl', 'HLSL'), ('hsail', 'HSAIL'), ('hspec', 'Hspec'), ('html', 'HTML'), ('html+cheetah', 'HTML+Cheetah'), ('html+django', 'HTML+Django/Jinja'), ('html+evoque', 'HTML+Evoque'), ('html+genshi', 'HTML+Genshi'), ('html+handlebars', 'HTML+Handlebars'), ('html+lasso', 'HTML+Lasso'), ('html+mako', 'HTML+Mako'), ('html+myghty', 'HTML+Myghty'), ('html+ng2', 'HTML + Angular2'), ('html+php', 'HTML+PHP'), ('html+smarty', 'HTML+Smarty'), ('html+twig', 'HTML+Twig'), ('html+ul4', 'HTML+UL4'), ('html+velocity', 'HTML+Velocity'), ('http', 'HTTP'), ('hybris', 'Hybris'), ('hylang', 'Hy'), ('i6t', 'Inform 6 template'), ('icon', 'Icon'), ('idl', 'IDL'), ('idris', 'Idris'), ('iex', 'Elixir iex session'), ('igor', 'Igor'), ('inform6', 'Inform 6'), ('inform7', 'Inform 7'), ('ini', 'INI'), ('io', 'Io'), ('ioke', 'Ioke'), ('irc', 'IRC logs'), ('isabelle', 'Isabelle'), ('j', 'J'), ('jags', 'JAGS'), ('janet', 'Janet'), ('jasmin', 'Jasmin'), ('java', 'Java'), ('javascript', 'JavaScript'), ('javascript+cheetah', 'JavaScript+Cheetah'), ('javascript+django', 'JavaScript+Django/Jinja'), ('javascript+lasso', 'JavaScript+Lasso'), ('javascript+mako', 'JavaScript+Mako'), ('javascript+mozpreproc', 'Javascript+mozpreproc'), ('javascript+myghty', 'JavaScript+Myghty'), ('javascript+php', 'JavaScript+PHP'), ('javascript+ruby', 'JavaScript+Ruby'), ('javascript+smarty', 'JavaScript+Smarty'), ('jcl', 'JCL'), ('jlcon', 'Julia console'), ('jmespath', 'JMESPath'), ('js+genshitext', 'JavaScript+Genshi Text'), ('js+ul4', 'Javascript+UL4'), ('jsgf', 'JSGF'), ('jslt', 'JSLT'), ('json', 'JSON'), ('json5', 'JSON5'), ('jsonld', 'JSON-LD'), ('jsonnet', 'Jsonnet'), ('jsp', 'Java Server Page'), ('jsx', 'JSX'), ('julia', 'Julia'), ('juttle', 'Juttle'), ('k', 'K'), ('kal', 'Kal'), ('kconfig', 'Kconfig'), ('kmsg', 'Kernel log'), ('koka', 'Koka'), ('kotlin', 'Kotlin'), ('kql', 'Kusto'), ('kuin', 'Kuin'), ('lasso', 'Lasso'), ('ldapconf', 'LDAP configuration file'), ('ldif', 'LDIF'), ('lean', 'Lean'), ('lean4', 'Lean4'), ('less', 'LessCss'), ('lighttpd', 'Lighttpd configuration file'), ('lilypond', 'LilyPond'), ('limbo', 'Limbo'), ('liquid', 'liquid'), ('literate-agda', 'Literate Agda'), ('literate-cryptol', 'Literate Cryptol'), ('literate-haskell', 'Literate Haskell'), ('literate-idris', 'Literate Idris'), ('livescript', 'LiveScript'), ('llvm', 'LLVM'), ('llvm-mir', 'LLVM-MIR'), ('llvm-mir-body', 'LLVM-MIR Body'), ('logos', 'Logos'), ('logtalk', 'Logtalk'), ('lsl', 'LSL'), ('lua', 'Lua'), ('luau', 'Luau'), ('macaulay2', 'Macaulay2'), ('make', 'Makefile'), ('mako', 'Mako'), ('maple', 'Maple'), ('maql', 'MAQL'), ('markdown', 'Markdown'), ('mask', 'Mask'), ('mason', 'Mason'), ('mathematica', 'Mathematica'), ('matlab', 'Matlab'), ('matlabsession', 'Matlab session'), ('maxima', 'Maxima'), ('mcfunction', 'MCFunction'), ('mcschema', 'MCSchema'), ('meson', 'Meson'), ('mime', 'MIME'), ('minid', 'MiniD'), ('miniscript', 'MiniScript'), ('mips', 'MIPS'), ('modelica', 'Modelica'), ('modula2', 'Modula-2'), ('mojo', 'Mojo'), ('monkey', 'Monkey'), ('monte', 'Monte'), ('moocode', 'MOOCode'), ('moonscript', 'MoonScript'), ('mosel', 'Mosel'), ('mozhashpreproc', 'mozhashpreproc'), ('mozpercentpreproc', 'mozpercentpreproc'), ('mql', 'MQL'), ('mscgen', 'Mscgen'), ('mupad', 'MuPAD'), ('mxml', 'MXML'), ('myghty', 'Myghty'), ('mysql', 'MySQL'), ('nasm', 'NASM'), ('ncl', 'NCL'), ('nemerle', 'Nemerle'), ('nesc', 'nesC'), ('nestedtext', 'NestedText'), ('newlisp', 'NewLisp'), ('newspeak', 'Newspeak'), ('ng2', 'Angular2'), ('nginx', 'Nginx configuration file'), ('nimrod', 'Nimrod'), ('nit', 'Nit'), ('nixos', 'Nix'), ('nodejsrepl', 'Node.js REPL console session'), ('notmuch', 'Notmuch'), ('nsis', 'NSIS'), ('numba_ir', 'Numba_IR'), ('numpy', 'NumPy'), ('nusmv', 'NuSMV'), ('objdump', 'objdump'), ('objdump-nasm', 'objdump-nasm'), ('objective-c', 'Objective-C'), ('objective-c++', 'Objective-C++'), ('objective-j', 'Objective-J'), ('ocaml', 'OCaml'), ('octave', 'Octave'), ('odin', 'ODIN'), ('omg-idl', 'OMG Interface Definition Language'), ('ooc', 'Ooc'), ('opa', 'Opa'), ('openedge', 'OpenEdge ABL'), ('openscad', 'OpenSCAD'), ('org', 'Org Mode'), ('output', 'Text output'), ('pacmanconf', 'PacmanConf'), ('pan', 'Pan'), ('parasail', 'ParaSail'), ('pawn', 'Pawn'), ('pddl', 'PDDL'), ('peg', 'PEG'), ('perl', 'Perl'), ('perl6', 'Perl6'), ('phix', 'Phix'), ('php', 'PHP'), ('pig', 'Pig'), ('pike', 'Pike'), ('pkgconfig', 'PkgConfig'), ('plpgsql', 'PL/pgSQL'), ('pointless', 'Pointless'), ('pony', 'Pony'), ('portugol', 'Portugol'), ('postgres-explain', 'PostgreSQL EXPLAIN dialect'), ('postgresql', 'PostgreSQL SQL dialect'), ('postscript', 'PostScript'), ('pot', 'Gettext Catalog'), ('pov', 'POVRay'), ('powershell', 'PowerShell'), ('praat', 'Praat'), ('procfile', 'Procfile'), ('prolog', 'Prolog'), ('promela', 'Promela'), ('promql', 'PromQL'), ('properties', 'Properties'), ('protobuf', 'Protocol Buffer'), ('prql', 'PRQL'), ('psql', 'PostgreSQL console (psql)'), ('psysh', 'PsySH console session for PHP'), ('ptx', 'PTX'), ('pug', 'Pug'), ('puppet', 'Puppet'), ('pwsh-session', 'PowerShell Session'), ('py+ul4', 'Python+UL4'), ('py2tb', 'Python 2.x Traceback'), ('pycon', 'Python console session'), ('pypylog', 'PyPy Log'), ('pytb', 'Python Traceback'), ('python', 'Python'), ('python2', 'Python 2.x'), ('q', 'Q'), ('qbasic', 'QBasic'), ('qlik', 'Qlik'), ('qml', 'QML'), ('qvto', 'QVTO'), ('racket', 'Racket'), ('ragel', 'Ragel'), ('ragel-c', 'Ragel in C Host'), ('ragel-cpp', 'Ragel in CPP Host'), ('ragel-d', 'Ragel in D Host'), ('ragel-em', 'Embedded Ragel'), ('ragel-java', 'Ragel in Java Host'), ('ragel-objc', 'Ragel in Objective C Host'), ('ragel-ruby', 'Ragel in Ruby Host'), ('rbcon', 'Ruby irb session'), ('rconsole', 'RConsole'), ('rd', 'Rd'), ('reasonml', 'ReasonML'), ('rebol', 'REBOL'), ('red', 'Red'), ('redcode', 'Redcode'), ('registry', 'reg'), ('rego', 'Rego'), ('resourcebundle', 'ResourceBundle'), ('restructuredtext', 'reStructuredText'), ('rexx', 'Rexx'), ('rhtml', 'RHTML'), ('ride', 'Ride'), ('rita', 'Rita'), ('rng-compact', 'Relax-NG Compact'), ('roboconf-graph', 'Roboconf Graph'), ('roboconf-instances', 'Roboconf Instances'), ('robotframework', 'RobotFramework'), ('rql', 'RQL'), ('rsl', 'RSL'), ('ruby', 'Ruby'), ('rust', 'Rust'), ('sarl', 'SARL'), ('sas', 'SAS'), ('sass', 'Sass'), ('savi', 'Savi'), ('scala', 'Scala'), ('scaml', 'Scaml'), ('scdoc', 'scdoc'), ('scheme', 'Scheme'), ('scilab', 'Scilab'), ('scss', 'SCSS'), ('sed', 'Sed'), ('sgf', 'SmartGameFormat'), ('shen', 'Shen'), ('shexc', 'ShExC'), ('sieve', 'Sieve'), ('silver', 'Silver'), ('singularity', 'Singularity'), ('slash', 'Slash'), ('slim', 'Slim'), ('slurm', 'Slurm'), ('smali', 'Smali'), ('smalltalk', 'Smalltalk'), ('smarty', 'Smarty'), ('smithy', 'Smithy'), ('sml', 'Standard ML'), ('snbt', 'SNBT'), ('snobol', 'Snobol'), ('snowball', 'Snowball'), ('solidity', 'Solidity'), ('sophia', 'Sophia'), ('sp', 'SourcePawn'), ('sparql', 'SPARQL'), ('spec', 'RPMSpec'), ('spice', 'Spice'), ('splus', 'S'), ('sql', 'SQL'), ('sql+jinja', 'SQL+Jinja'), ('sqlite3', 'sqlite3con'), ('squidconf', 'SquidConf'), ('srcinfo', 'Srcinfo'), ('ssp', 'Scalate Server Page'), ('stan', 'Stan'), ('stata', 'Stata'), ('supercollider', 'SuperCollider'), ('swift', 'Swift'), ('swig', 'SWIG'), ('systemd', 'Systemd'), ('systemverilog', 'systemverilog'), ('tablegen', 'TableGen'), ('tact', 'Tact'), ('tads3', 'TADS 3'), ('tal', 'Tal'), ('tap', 'TAP'), ('tasm', 'TASM'), ('tcl', 'Tcl'), ('tcsh', 'Tcsh'), ('tcshcon', 'Tcsh Session'), ('tea', 'Tea'), ('teal', 'teal'), ('teratermmacro', 'Tera Term macro'), ('termcap', 'Termcap'), ('terminfo', 'Terminfo'), ('terraform', 'Terraform'), ('tex', 'TeX'), ('text', 'Text only'), ('thrift', 'Thrift'), ('ti', 'ThingsDB'), ('tid', 'tiddler'), ('tlb', 'Tl-b'), ('tls', 'TLS Presentation Language'), ('tnt', 'Typographic Number Theory'), ('todotxt', 'Todotxt'), ('toml', 'TOML'), ('trac-wiki', 'MoinMoin/Trac Wiki markup'), ('trafficscript', 'TrafficScript'), ('treetop', 'Treetop'), ('tsql', 'Transact-SQL'), ('tsx', 'TSX'), ('turtle', 'Turtle'), ('twig', 'Twig'), ('typescript', 'TypeScript'), ('typoscript', 'TypoScript'), ('typoscriptcssdata', 'TypoScriptCssData'), ('typoscripthtmldata', 'TypoScriptHtmlData'), ('typst', 'Typst'), ('ucode', 'ucode'), ('ul4', 'UL4'), ('unicon', 'Unicon'), ('unixconfig', 'Unix/Linux config files'), ('urbiscript', 'UrbiScript'), ('urlencoded', 'urlencoded'), ('usd', 'USD'), ('vala', 'Vala'), ('vb.net', 'VB.net'), ('vbscript', 'VBScript'), ('vcl', 'VCL'), ('vclsnippets', 'VCLSnippets'), ('vctreestatus', 'VCTreeStatus'), ('velocity', 'Velocity'), ('verifpal', 'Verifpal'), ('verilog', 'verilog'), ('vgl', 'VGL'), ('vhdl', 'vhdl'), ('vim', 'VimL'), ('visualprolog', 'Visual Prolog'), ('visualprologgrammar', 'Visual Prolog Grammar'), ('vue', 'Vue'), ('vyper', 'Vyper'), ('wast', 'WebAssembly'), ('wdiff', 'WDiff'), ('webidl', 'Web IDL'), ('wgsl', 'WebGPU Shading Language'), ('whiley', 'Whiley'), ('wikitext', 'Wikitext'), ('wowtoc', 'World of Warcraft TOC'), ('wren', 'Wren'), ('x10', 'X10'), ('xml', 'XML'), ('xml+cheetah', 'XML+Cheetah'), ('xml+django', 'XML+Django/Jinja'), ('xml+evoque', 'XML+Evoque'), ('xml+lasso', 'XML+Lasso'), ('xml+mako', 'XML+Mako'), ('xml+myghty', 'XML+Myghty'), ('xml+php', 'XML+PHP'), ('xml+ruby', 'XML+Ruby'), ('xml+smarty', 'XML+Smarty'), ('xml+ul4', 'XML+UL4'), ('xml+velocity', 'XML+Velocity'), ('xorg.conf', 'Xorg'), ('xpp', 'X++'), ('xquery', 'XQuery'), ('xslt', 'XSLT'), ('xtend', 'Xtend'), ('xul+mozpreproc', 'XUL+mozpreproc'), ('yaml', 'YAML'), ('yaml+jinja', 'YAML+Jinja'), ('yang', 'YANG'), ('yara', 'YARA'), ('zeek', 'Zeek'), ('zephir', 'Zephir'), ('zig', 'Zig'), ('zone', 'Zone')], default='python', max_length=100)),
-                ('style', models.CharField(choices=[('abap', 'abap'), ('algol', 'algol'), ('algol_nu', 'algol_nu'), ('arduino', 'arduino'), ('autumn', 'autumn'), ('borland', 'borland'), ('bw', 'bw'), ('coffee', 'coffee'), ('colorful', 'colorful'), ('default', 'default'), ('dracula', 'dracula'), ('emacs', 'emacs'), ('friendly', 'friendly'), ('friendly_grayscale', 'friendly_grayscale'), ('fruity', 'fruity'), ('github-dark', 'github-dark'), ('gruvbox-dark', 'gruvbox-dark'), ('gruvbox-light', 'gruvbox-light'), ('igor', 'igor'), ('inkpot', 'inkpot'), ('lightbulb', 'lightbulb'), ('lilypond', 'lilypond'), ('lovelace', 'lovelace'), ('manni', 'manni'), ('material', 'material'), ('monokai', 'monokai'), ('murphy', 'murphy'), ('native', 'native'), ('nord', 'nord'), ('nord-darker', 'nord-darker'), ('one-dark', 'one-dark'), ('paraiso-dark', 'paraiso-dark'), ('paraiso-light', 'paraiso-light'), ('pastie', 'pastie'), ('perldoc', 'perldoc'), ('rainbow_dash', 'rainbow_dash'), ('rrt', 'rrt'), ('sas', 'sas'), ('solarized-dark', 'solarized-dark'), ('solarized-light', 'solarized-light'), ('staroffice', 'staroffice'), ('stata-dark', 'stata-dark'), ('stata-light', 'stata-light'), ('tango', 'tango'), ('trac', 'trac'), ('vim', 'vim'), ('vs', 'vs'), ('xcode', 'xcode'), ('zenburn', 'zenburn')], default='friendly', max_length=100)),
-                ('highlighted', models.TextField()),
-                ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='owner', to=settings.AUTH_USER_MODEL)),
-            ],
-            options={
-                'ordering': ['created'],
-            },
-        ),
-    ]
diff --git a/snippets/migrations/0002_alter_snippet_owner.py b/snippets/migrations/0002_alter_snippet_owner.py
deleted file mode 100644 (file)
index e5ce189..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# Generated by Django 5.1.4 on 2025-01-16 18:35
-
-import django.db.models.deletion
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('snippets', '0001_initial'),
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='snippet',
-            name='owner',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='snippets', to=settings.AUTH_USER_MODEL),
-        ),
-    ]
diff --git a/snippets/migrations/__init__.py b/snippets/migrations/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/snippets/models.py b/snippets/models.py
deleted file mode 100644 (file)
index 96fbcde..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-from django.db import models
-
-from pygments.formatters import HtmlFormatter
-from pygments.lexers import get_all_lexers
-from pygments.styles import get_all_styles
-
-from pygments.lexers import get_lexer_by_name
-from pygments.formatters.html import HtmlFormatter
-from pygments import highlight
-
-
-LEXERS = [item for item in get_all_lexers() if item[1]]
-LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
-STYLE_CHOICES = sorted([(item, item) for item in get_all_styles()])
-
-
-class Snippet(models.Model):
-    created = models.DateTimeField(auto_now_add=True)
-    title = models.CharField(max_length=100, blank=True, default="")
-    code = models.TextField()
-    linenos = models.BooleanField(default=False)  # type: ignore
-    language = models.CharField(
-        choices=LANGUAGE_CHOICES, default="python", max_length=100
-    )
-    style = models.CharField(choices=STYLE_CHOICES, default="friendly", max_length=100)
-
-    owner = models.ForeignKey(
-        "auth.User", related_name="snippets", on_delete=models.CASCADE
-    )
-    highlighted = models.TextField()
-
-    def save(self, *args, **kwargs):
-        """
-        Use the `pygments` library to create a highlighted HTML
-        representation of the code snippet.
-        """
-        lexer = get_lexer_by_name(self.language)
-        linenos = "table" if self.linenos else False
-        options = {"title": self.title} if self.title else {}
-        formatter = HtmlFormatter(
-            style=self.style, linenos=linenos, full=True, **options
-        )
-        self.highlighted = highlight(self.code, lexer, formatter)
-        super().save(*args, **kwargs)
-
-    class Meta:
-        ordering = ["created"]
diff --git a/snippets/permissions.py b/snippets/permissions.py
deleted file mode 100644 (file)
index 1b9e8fe..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-from rest_framework import permissions
-
-
-class IsOwnerOrReadOnly(permissions.BasePermission):
-    """
-    Custom permission to only allow owner of an object to edit it.
-    """
-
-    def has_object_permission(self, request, view, obj):
-        # Read permission are allowed to any request
-        # so we'll always allow GET, HEAD, or OPTIONS requests
-        if request.method in permissions.SAFE_METHODS:
-            return True
-
-        # Write permissions are only allowed to the owner of the snippet
-        return obj.owner == request.user
diff --git a/snippets/serializers.py b/snippets/serializers.py
deleted file mode 100644 (file)
index 4b6eafc..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-from django.contrib.auth.models import User
-from .models import Snippet
-from rest_framework import serializers
-
-
-class SnippetSerializer(serializers.HyperlinkedModelSerializer):
-    owner = serializers.ReadOnlyField(source="owner.username")
-    hightlight = serializers.HyperlinkedIdentityField(
-        view_name="snippet-highlight", format="html"
-    )
-
-    class Meta:
-        model = Snippet
-        fields = [
-            "url",
-            "id",
-            "hightlight",
-            "owner",
-            "title",
-            "code",
-            "linenos",
-            "language",
-            "style",
-        ]
-
-
-class UserSerializer(serializers.HyperlinkedModelSerializer):
-    snippets = serializers.HyperlinkedRelatedField(
-        many=True,
-        view_name="snippet-detail",
-        read_only=True,
-    )
-
-    class Meta:
-        model = User
-        fields = ["url", "id", "username", "snippets"]
diff --git a/snippets/tests.py b/snippets/tests.py
deleted file mode 100644 (file)
index 7ce503c..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.test import TestCase
-
-# Create your tests here.
diff --git a/snippets/urls.py b/snippets/urls.py
deleted file mode 100644 (file)
index be8e133..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-from functools import partial
-from django.urls import path, include
-from rest_framework import renderers
-from rest_framework.decorators import renderer_classes
-from . import views
-from rest_framework.urlpatterns import format_suffix_patterns
-
-from .views import SnippetViewSet, UserViewSet
-
-from rest_framework.routers import DefaultRouter
-
-router = DefaultRouter()
-
-router.register(r"", SnippetViewSet, basename="snippet")
-router.register(r"users", UserViewSet, basename="user")
-
-urlpatterns = [path("", include(router.urls))]
diff --git a/snippets/views.py b/snippets/views.py
deleted file mode 100644 (file)
index b6f4a54..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-from django.contrib.auth.models import User
-from rest_framework import permissions, renderers, viewsets
-from rest_framework.decorators import api_view, action
-from rest_framework.reverse import reverse
-from rest_framework.views import Response
-
-from snippets.permissions import IsOwnerOrReadOnly
-
-from .serializers import SnippetSerializer, UserSerializer
-from snippets import serializers
-from .models import Snippet
-
-
-@api_view(["GET"])
-def api_root(request, format=None):
-    return Response(
-        {
-            "users": reverse("user-list", request=request, format=format),
-            "snippets": reverse("snippet-list", request=request, format=format),
-        }
-    )
-
-
-class SnippetViewSet(viewsets.ModelViewSet):
-    queryset = Snippet.objects.all()  # type: ignore
-    serializer_class = SnippetSerializer
-    permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
-
-    @action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])
-    def highlight(self, request, *args, **kwargs):
-        snippet = self.get_object()
-        return Response(snippet.highlighted)
-
-    def perform_create(self, serializer):
-        serializer.save(owner=self.request.user)
-
-
-class UserViewSet(viewsets.ReadOnlyModelViewSet):
-    queryset = User.objects.all()  # type:ignore
-    serializer_class = UserSerializer