Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work for Marple energy flexibility pilot #78

Merged
merged 31 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c39da86
remove create team option from search results page
struan Aug 14, 2024
5725553
formatting fixes to appease linting
struan Aug 14, 2024
1d281cd
add Challenge model
struan Aug 14, 2024
a2804f5
add challenge field to Team model
struan Aug 14, 2024
b416a61
add Challenge model to admin
struan Aug 14, 2024
7eeceb7
if a team has an challange then use that on team page
struan Aug 14, 2024
5576730
if there are challenges in the db use those for progress
struan Aug 14, 2024
589238e
add has_rich_description field to Challenge
struan Aug 14, 2024
9d0b29b
update default challenge template to use rich descriptions
struan Aug 14, 2024
33029c5
handle missing challenge template
struan Aug 14, 2024
daa1ded
make challenge admin list page a bit more useable
struan Aug 14, 2024
f83c870
add is_public and short_desc fields to Challenge model
struan Aug 14, 2024
d3c4795
use team challenges from database on public page if available
struan Aug 14, 2024
85ab14d
make ability to create teams a config option
struan Aug 14, 2024
3d2ec17
Replace boringavatars image API with Django template tag
zarino Sep 20, 2024
99b86ae
Improve help_text for Challenge model fields
zarino Sep 20, 2024
c052932
Teams can now have an optional "boundary"
zarino Sep 26, 2024
09398d7
Display team boundary (and user postcode location) on Team page
zarino Sep 26, 2024
daf670d
Allow user to check whether they are in a team’s area
zarino Sep 26, 2024
3f6405b
Zoom Team page map to fit both user and boundary
zarino Sep 26, 2024
b113844
Allow user to clear postcode stored in session
zarino Sep 26, 2024
e9e9914
Working social share button on team page
zarino Oct 2, 2024
6d4ff89
Improve wording on Join Team page
zarino Oct 2, 2024
beed6b7
Remove non-functional elements from search results page
zarino Oct 2, 2024
3663d12
Update homepage and About page, remove Alpha banner
zarino Oct 3, 2024
8f9c2ee
Self-serve account deletion, and updated Privacy Policy
zarino Oct 4, 2024
f461cf6
Make Team page modals available to both public and private
zarino Oct 4, 2024
6d24717
Couple of small styling fixes on logged-in Team page
zarino Oct 4, 2024
c8a28ef
Make team progress appear on public team page
zarino Oct 4, 2024
ded40aa
Remove version key from docker-compose.yml
zarino Oct 4, 2024
83dfc48
Teams can now have a custom description / HTML content
zarino Oct 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: '3.9'

services:
db:
image: postgis/postgis:13-3.3
Expand Down
26 changes: 25 additions & 1 deletion neighbourhood/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.gis.admin import OSMGeoAdmin
from django.core.exceptions import ValidationError
from django.forms import ModelForm
from django.urls import reverse
from django.utils.html import format_html, mark_safe

from .models import Team, Token, User
from .forms import GeoJsonUploadFormMixin
from .models import Challenge, Team, Token, User


@admin.register(Token)
Expand All @@ -21,8 +23,15 @@ class TeamMembershipInline(admin.TabularInline):
readonly_fields = ["created"]


class TeamAdminForm(GeoJsonUploadFormMixin, ModelForm):
class Meta:
model = Team
fields = "__all__" # This includes all fields from the model


@admin.register(Team)
class TeamAdmin(OSMGeoAdmin):
form = TeamAdminForm
list_display = (
"name",
"base_pc",
Expand All @@ -37,6 +46,13 @@ class TeamAdmin(OSMGeoAdmin):
TeamMembershipInline,
]

def save_model(self, request, obj, form, change):
if form.cleaned_data.get("geojson_file"):
obj.boundary = form.cleaned_data[
"geojson_file"
] # Set the geometry from the uploaded GeoJSON
super().save_model(request, obj, form, change)

@admin.display(description="Members")
def members_count(self, obj):
return obj.members.count()
Expand All @@ -46,6 +62,14 @@ def confirmed_members_count(self, obj):
return obj.confirmed_members.count()


@admin.register(Challenge)
class ChallengeAdmin(admin.ModelAdmin):
list_display = ("name", "description", "order", "is_active", "is_public")
list_editable = ("order", "is_active", "is_public")
list_filter = ["is_active", "is_public", "has_rich_description"]
ordering = ["order"]


class UserCreationForm(forms.ModelForm):
password1 = forms.CharField(label="Password", widget=forms.PasswordInput)
password2 = forms.CharField(
Expand Down
85 changes: 85 additions & 0 deletions neighbourhood/fixtures/marple.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"type": "Feature",
"properties": {
"name": "ENWL Marple tender area",
"centroid_postcode": "SK6 6LS",
"centroid_x": -2.066591374100896,
"centroid_y": 53.39961996874385
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-2.039118812158511, 53.39607300484717],
[-2.042842814812317, 53.39448694473424],
[-2.043153963148892, 53.39435496974106],
[-2.043761038598267, 53.39377300743112],
[-2.046757946071736, 53.39383891960464],
[-2.050842111782887, 53.39393000347705],
[-2.053311848440355, 53.39593310140093],
[-2.055799188015477, 53.396391994215016],
[-2.05680004484894, 53.396876003684966],
[-2.059123055858409, 53.39622095299339],
[-2.06229915905537, 53.39467500577833],
[-2.06335976411161, 53.39466401864138],
[-2.06440097127707, 53.394654021332414],
[-2.06570214184269, 53.393256036753165],
[-2.06547001267402, 53.39309194361166],
[-2.065492081719879, 53.390727038474076],
[-2.066833809553655, 53.39054993624833],
[-2.067586976880684, 53.39045090599354],
[-2.069305992228256, 53.391776000859906],
[-2.070963038905869, 53.39158698299477],
[-2.073016963213321, 53.391353026010236],
[-2.073820787541126, 53.392889935164014],
[-2.075369794717434, 53.39307098259181],
[-2.079744806544592, 53.393582007788005],
[-2.081626840001368, 53.39261104497916],
[-2.0820009295697, 53.39267101126091],
[-2.087773068832873, 53.39360395350738],
[-2.089930786303418, 53.393384100691996],
[-2.094063936043281, 53.396428031762014],
[-2.090812026940374, 53.400239010298925],
[-2.089640188121193, 53.40084096323959],
[-2.087241984207192, 53.404106938829216],
[-2.085080126112944, 53.40456503197877],
[-2.081552854913455, 53.404136050089164],
[-2.081104876333191, 53.40418804034439],
[-2.074833068962502, 53.404920041956295],
[-2.073134766096288, 53.406598990510524],
[-2.072818081077206, 53.406658059721565],
[-2.071054134738526, 53.4074920948995],
[-2.070827776288178, 53.40760009242962],
[-2.065489212442922, 53.40818300218019],
[-2.062966068471988, 53.408459054660995],
[-2.061752148194655, 53.40878903149416],
[-2.059870870972401, 53.40760296621254],
[-2.057656939619407, 53.40694897515642],
[-2.055820926222149, 53.40640604434848],
[-2.05557695740054, 53.406185939233396],
[-2.055993040137756, 53.40483494469654],
[-2.051116151063674, 53.402714945318706],
[-2.050852048840518, 53.40260000516593],
[-2.050575130365015, 53.401573989968206],
[-2.047693948274075, 53.39978106586205],
[-2.047631188850132, 53.399741900936355],
[-2.046798794412879, 53.39978798364892],
[-2.046278006232489, 53.39968302162833],
[-2.043686098226991, 53.399851999828556],
[-2.042906039561796, 53.39990199109662],
[-2.039514844632444, 53.396473044408225],
[-2.039118812158511, 53.39607300484717]
],
[
[-2.065494183111713, 53.39823698499189],
[-2.066366779330699, 53.399119986912446],
[-2.067535096349404, 53.399247955598184],
[-2.071064009447584, 53.39963600337904],
[-2.072254815444114, 53.39705197360281],
[-2.068512065186642, 53.39682497953908],
[-2.066200109513213, 53.396685887375654],
[-2.065494183111713, 53.39823698499189]
]
]
}
}
23 changes: 23 additions & 0 deletions neighbourhood/fixtures/memberships.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@
"email_confirmed": true
}
},
{
"model": "neighbourhood.user",
"pk": 4,
"fields": {
"email": "[email protected]",
"full_name": "Scottish Parliament Admin",
"is_active": true,
"email_confirmed": true
}
},
{
"model": "neighbourhood.membership",
"pk": 1,
Expand Down Expand Up @@ -65,5 +75,18 @@
"last_updated": "2023-01-01T14:23:00Z",
"date_joined": "2023-01-01"
}
},
{
"model": "neighbourhood.membership",
"pk": 4,
"fields": {
"team_id": 1,
"user_id": 4,
"confirmed": true,
"is_admin": true,
"created": "2023-01-01T14:23:00Z",
"last_updated": "2023-01-01T14:23:00Z",
"date_joined": "2023-01-01"
}
}
]
54 changes: 54 additions & 0 deletions neighbourhood/fixtures/teams.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
[
{
"model": "neighbourhood.challenge",
"pk": 1,
"fields": {
"name": "Recruit first team member",
"description": "Recruit your first team member",
"template": "neighbourhood/challenges/_default.html",
"created": "2023-06-22T14:23:00Z",
"last_updated": "2023-06-22T14:23:00Z",
"is_active": true,
"order": 1
}
},
{
"model": "neighbourhood.challenge",
"pk": 2,
"fields": {
"name": "Recruit second team member",
"description": "<p>Recruit your <b>second</b> team member</p>",
"has_rich_description": true,
"template": "neighbourhood/challenges/_default.html",
"created": "2023-06-22T14:23:00Z",
"last_updated": "2023-06-22T14:23:00Z",
"is_active": true,
"order": 2
}
},
{
"model": "neighbourhood.team",
"pk": 1,
Expand All @@ -24,6 +51,7 @@
"areas": [ 1 ],
"created": "2023-06-22T14:23:00Z",
"last_updated": "2023-06-22T14:23:00Z",
"challenge_id": 1,
"confirmed": true
}
},
Expand Down Expand Up @@ -55,6 +83,20 @@
"confirmed": false
}
},
{
"model": "neighbourhood.team",
"pk": 5,
"fields": {
"name": "southwark 1",
"base_pc": "se17 3he",
"centroid": "SRID=4326;POINT (-0.096961 51.484853)",
"slug": "southwark 1",
"areas": [ 2 ],
"created": "2023-06-22T14:23:00Z",
"last_updated": "2023-06-22T14:23:00Z",
"confirmed": true
}
},
{
"model": "neighbourhood.area",
"pk": 1,
Expand All @@ -66,5 +108,17 @@
"last_updated": "2023-06-22T14:23:00Z",
"mapit_id": 2651
}
},
{
"model": "neighbourhood.area",
"pk": 2,
"fields": {
"code": "E09000028",
"name": "Southwark Borough Council",
"area_type": "LBO",
"created": "2023-06-22T14:23:00Z",
"last_updated": "2023-06-22T14:23:00Z",
"mapit_id": 2491
}
}
]
26 changes: 26 additions & 0 deletions neighbourhood/forms.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import json

from django.contrib.gis.geos import GEOSGeometry
from django.contrib.sites.shortcuts import get_current_site
from django.core.exceptions import ValidationError
from django.core.mail import EmailMessage
from django.forms import (
BaseModelFormSet,
CharField,
EmailField,
FileField,
Form,
ModelForm,
modelformset_factory,
Expand Down Expand Up @@ -171,3 +175,25 @@ def clean(self):
raise ValidationError(data["error"])

self.postcode_data = data


class GeoJsonUploadFormMixin(ModelForm):
geojson_file = FileField(required=False, label="Upload GeoJSON")

def clean_geojson_file(self):
file = self.cleaned_data.get("geojson_file")
if file:
try:
geojson_data = json.load(file)
if geojson_data["type"] == "FeatureCollection":
feature = geojson_data["features"][0]
elif geojson_data["type"] == "Feature":
feature = geojson_data
else:
raise ValidationError(
"GeoJSON file must contain a single Feature or FeatureCollection."
)
return GEOSGeometry(json.dumps(feature["geometry"]))
except (KeyError, TypeError, json.JSONDecodeError):
raise ValidationError("Invalid GeoJSON file format.")
return None
Loading
Loading