Skip to content

Commit 1155aa8

Browse files
authored
Merge branch 'main' into pv-2023-11-react-maps
2 parents f2c7a29 + ba79db4 commit 1155aa8

File tree

18 files changed

+167
-71
lines changed

18 files changed

+167
-71
lines changed

.github/workflows/django.yml

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ jobs:
2222
--health-timeout 5s
2323
--health-retries 5
2424
steps:
25-
- uses: actions/checkout@v3
25+
- uses: actions/checkout@v4
2626
- name: Set up Python ${{ matrix.python-version }}
27-
uses: actions/setup-python@v4
27+
uses: actions/setup-python@v5
2828
with:
2929
python-version: '3.8'
3030
- name: Setup Node
31-
uses: actions/setup-node@v3
31+
uses: actions/setup-node@v4
3232
with:
3333
node-version: '18.x'
3434
- name: Setup Postgres
@@ -39,7 +39,7 @@ jobs:
3939
psql -c 'create database django;' -U postgres
4040
psql -c 'create database django_test;' -U postgres
4141
- name: Cache node modules
42-
uses: actions/cache@v3
42+
uses: actions/cache@v4
4343
env:
4444
cache-name: cache-node-modules
4545
with:
@@ -50,7 +50,7 @@ jobs:
5050
${{ runner.os }}-build-
5151
${{ runner.os }}-
5252
- name: Cache pip packages
53-
uses: actions/cache@v3
53+
uses: actions/cache@v4
5454
env:
5555
cache-name: cache-pip-packages
5656
with:
@@ -83,8 +83,3 @@ jobs:
8383
- name: Run Frontend Tests
8484
run: |
8585
npm test
86-
- name: Frontend Coverage
87-
uses: artiomtr/[email protected]
88-
with:
89-
github-token: ${{ secrets.GITHUB_TOKEN }}
90-
if: github.event_name == 'pull_request'

.husky/pre-commit

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
1-
#!/bin/sh
2-
. "$(dirname "$0")/_/husky.sh"
3-
41
make lint-quick

adhocracy4/dashboard/mixins.py

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import warnings
12
from copy import deepcopy
3+
from pathlib import Path
24

35
from django.apps import apps
46
from django.conf import settings
57
from django.contrib import messages
68
from django.core.exceptions import PermissionDenied
9+
from django.core.files.base import ContentFile
710
from django.shortcuts import get_object_or_404
811
from django.shortcuts import redirect
912
from django.urls import NoReverseMatch
@@ -107,29 +110,61 @@ def get_context_data(self, **kwargs):
107110

108111

109112
class DashboardComponentFormSignalMixin(edit.FormMixin):
113+
"""Mixin which sends a project_component_updated or module_component_updated signal
114+
when creating, updating or deleting an object via the HTTP POST method
115+
(e.g. from the dashboard).
116+
"""
117+
110118
def form_valid(self, form):
119+
# The call to super.form_valid() may delete self.project or self.module,
120+
# to be able to still reference them below we need to store them in separate
121+
# variables before they are deleted.
122+
project = self.project
123+
module = self.module
124+
111125
response = super().form_valid(form)
112126

113127
component = self.component
114128
if component.identifier in components.projects:
115129
signals.project_component_updated.send(
116130
sender=component.__class__,
117-
project=self.project,
131+
project=project,
118132
component=component,
119133
user=self.request.user,
120134
)
121135
else:
122136
signals.module_component_updated.send(
123137
sender=component.__class__,
124-
module=self.module,
138+
module=module,
125139
component=component,
126140
user=self.request.user,
127141
)
128142
return response
129143

130144

131145
class DashboardComponentDeleteSignalMixin(edit.DeletionMixin):
146+
"""Deprecated, use DashboardComponentFormSignalMixin for POST requests instead.
147+
This mixin will be removed in the next version.
148+
"""
149+
150+
def __init__(self):
151+
warnings.warn(
152+
"dashboard.mixins.DashboardComponentDeleteSignalMixin is deprecated, "
153+
"use dashboard.mixins.DashboardComponentFormSignalMixin for forms / POST "
154+
"requests. This mixin will be removed in the next version.",
155+
DeprecationWarning,
156+
)
157+
158+
super().__init__()
159+
132160
def delete(self, request, *args, **kwargs):
161+
warnings.warn(
162+
"dashboard.mixins.DashboardComponentDeleteSignalMixin.delete()"
163+
"is deprecated, use dashboard.mixins.DashboardComponentFormSignalMixin "
164+
"for forms / POST requests. This mixin will be removed in the next "
165+
"version.",
166+
DeprecationWarning,
167+
)
133168
# Project and module have to be stored before delete is called as
134169
# they may rely on the still existing db object.
135170
project = self.project
@@ -167,16 +202,31 @@ def post(self, request, *args, **kwargs):
167202

168203
project_clone = deepcopy(project)
169204
project_clone.pk = None
170-
if project_clone.tile_image:
171-
project_clone.tile_image.save(
172-
project.tile_image.name, project.tile_image, False
173-
)
174-
if project_clone.image:
175-
project_clone.image.save(project.image.name, project.image, False)
176205
project_clone.created = timezone.now()
177206
project_clone.is_draft = True
178207
project_clone.is_archived = False
208+
209+
if project.tile_image:
210+
# django's image.name contains the file storage location defined in 'upload_to'
211+
tile_file_name = Path(
212+
project.tile_image.name
213+
).name # retreives only the filename
214+
tile_copy = ContentFile(
215+
project.tile_image.read()
216+
) # retreives the image bytes
217+
project_clone.tile_image.save(tile_file_name, tile_copy, False)
218+
219+
if project.image:
220+
# django's image.name contains the file storage location defined in 'upload_to'
221+
image_file_name = Path(project.image.name).name
222+
image_copy = ContentFile(project.image.read())
223+
project_clone.image.save(image_file_name, image_copy, False)
224+
179225
project_clone.save()
226+
if project.topics:
227+
for topic in project.topics.all():
228+
project_clone.topics.add(topic)
229+
180230
signals.project_created.send(
181231
sender=None, project=project_clone, user=self.request.user
182232
)

adhocracy4/forms/fields.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def __init__(
1212
):
1313
label = kwargs.get("label", None)
1414
time_label = ""
15-
if type(label) == tuple:
15+
if isinstance(label, tuple):
1616
date_label, time_label = label
1717
kwargs["label"] = date_label
1818
elif label:

adhocracy4/phases/contents.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
class PhaseContent:
2-
32
features = {}
43

54
@property
@@ -17,7 +16,7 @@ class PhaseContents:
1716
_registry = {}
1817

1918
def __getitem__(self, identifier):
20-
if type(identifier) != str:
19+
if not isinstance(identifier, str):
2120
raise TypeError("Phase identifier must be str")
2221
return self._registry[identifier]
2322

adhocracy4/polls/exports.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ class PollCommentExportView(
2020
export_mixins.CommentExportWithRepliesToMixin,
2121
export_views.BaseItemExportView,
2222
):
23-
2423
model = Comment
2524

2625
fields = ["id", "comment", "created"]
@@ -47,7 +46,6 @@ def raise_exception(self):
4746

4847

4948
class PollExportView(PermissionRequiredMixin, export_views.BaseItemExportView):
50-
5149
permission_required = "a4polls.change_poll"
5250

5351
def get_permission_object(self):
@@ -112,7 +110,7 @@ def get_field_data(self, item, field):
112110

113111
else:
114112
field_object, is_text_field = field
115-
if type(field_object) == poll_models.Choice:
113+
if isinstance(field_object, poll_models.Choice):
116114
votes_qs = poll_models.Vote.objects.filter(
117115
choice=field_object, creator=user
118116
)

adhocracy4/projects/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def get_module_cluster_index(self, module):
177177
for idx, val in enumerate(self.participation_dates):
178178
if "modules" in val and module in val["modules"]:
179179
return idx
180-
if self.project.get_current_participation_date():
180+
if hasattr(self, "project") and self.project.get_current_participation_date():
181181
return self.project.get_current_participation_date()
182182
return 0
183183

changelog/1521.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## Fixed
2+
3+
- delete logic moved to form_valid method after django upgrade in dashboard component mixin

changelog/1527.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Fixed
2+
3+
- duplicated image path when a project gets duplicated in the dashboard

changelog/1528.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Added
2+
3+
- retreival of image name to save as new image instance when project is duplicated

0 commit comments

Comments
 (0)