|
13 | 13 | # Django imports |
14 | 14 | from django import forms |
15 | 15 | from django.utils.html import mark_safe # type:ignore |
| 16 | +from django.core.exceptions import ValidationError, ObjectDoesNotExist |
16 | 17 |
|
17 | 18 | # IETF imports |
18 | 19 | from ietf.group.models import Group, GroupHistory, GroupStateName |
19 | | -from ietf.name.models import ReviewTypeName |
| 20 | +from ietf.name.models import ReviewTypeName, ExtResourceName |
20 | 21 | from ietf.person.fields import SearchableEmailsField, PersonEmailChoiceField |
21 | 22 | from ietf.person.models import Person |
22 | 23 | from ietf.review.models import ReviewerSettings, UnavailablePeriod, ReviewSecretarySettings |
|
26 | 27 | from ietf.utils.text import strip_suffix |
27 | 28 | #from ietf.utils.ordereddict import insert_after_in_ordered_dict |
28 | 29 | from ietf.utils.fields import DatepickerDateField, MultiEmailField |
| 30 | +from ietf.utils.validators import validate_external_resource_value |
29 | 31 |
|
30 | 32 | # --- Constants -------------------------------------------------------- |
31 | 33 |
|
@@ -82,6 +84,7 @@ class GroupForm(forms.Form): |
82 | 84 | list_subscribe = forms.CharField(max_length=255, required=False) |
83 | 85 | list_archive = forms.CharField(max_length=255, required=False) |
84 | 86 | urls = forms.CharField(widget=forms.Textarea, label="Additional URLs", help_text="Format: https://site/path (Optional description). Separate multiple entries with newline. Prefer HTTPS URLs where possible.", required=False) |
| 87 | + resources = forms.CharField(widget=forms.Textarea, label="Additional Resources", help_text="UPDATEME: Format: https://site/path (Optional description). Separate multiple entries with newline. Prefer HTTPS URLs where possible.", required=False) |
85 | 88 | closing_note = forms.CharField(widget=forms.Textarea, label="Closing note", required=False) |
86 | 89 |
|
87 | 90 | def __init__(self, *args, **kwargs): |
@@ -127,6 +130,12 @@ def __init__(self, *args, **kwargs): |
127 | 130 | for f in keys: |
128 | 131 | if f != field and not (f == 'closing_note' and field == 'state'): |
129 | 132 | del self.fields[f] |
| 133 | + if 'resources' in self.fields: |
| 134 | + info = "Format: 'tag value (Optional description)'. " \ |
| 135 | + + "Separate multiple entries with newline. When the value is a URL, use https:// where possible.<br>" \ |
| 136 | + + "Valid tags: %s" % ', '.join([ o.slug for o in ExtResourceName.objects.all().order_by('slug') ]) |
| 137 | + self.fields['resources'].help_text = mark_safe('<div>'+info+'</div>') |
| 138 | + |
130 | 139 |
|
131 | 140 | def clean_acronym(self): |
132 | 141 | # Changing the acronym of an already existing group will cause 404s all |
@@ -186,6 +195,30 @@ def clean_acronym(self): |
186 | 195 | def clean_urls(self): |
187 | 196 | return [x.strip() for x in self.cleaned_data["urls"].splitlines() if x.strip()] |
188 | 197 |
|
| 198 | + def clean_resources(self): |
| 199 | + lines = [x.strip() for x in self.cleaned_data["resources"].splitlines() if x.strip()] |
| 200 | + errors = [] |
| 201 | + for l in lines: |
| 202 | + parts = l.split() |
| 203 | + if len(parts) == 1: |
| 204 | + errors.append("Too few fields: Expected at least tag and value: '%s'" % l) |
| 205 | + elif len(parts) >= 2: |
| 206 | + name_slug = parts[0] |
| 207 | + try: |
| 208 | + name = ExtResourceName.objects.get(slug=name_slug) |
| 209 | + except ObjectDoesNotExist: |
| 210 | + errors.append("Bad tag in '%s': Expected one of %s" % (l, ', '.join([ o.slug for o in ExtResourceName.objects.all() ]))) |
| 211 | + continue |
| 212 | + value = parts[1] |
| 213 | + try: |
| 214 | + validate_external_resource_value(name, value) |
| 215 | + except ValidationError as e: |
| 216 | + e.message += " : " + value |
| 217 | + errors.append(e) |
| 218 | + if errors: |
| 219 | + raise ValidationError(errors) |
| 220 | + return lines |
| 221 | + |
189 | 222 | def clean_delegates(self): |
190 | 223 | if len(self.cleaned_data["delegates"]) > MAX_GROUP_DELEGATES: |
191 | 224 | raise forms.ValidationError("At most %s delegates can be appointed at the same time, please remove %s delegates." % ( |
|
0 commit comments