|
67 | 67 | from ietf.ietfauth.htpasswd import update_htpasswd_file |
68 | 68 | from ietf.ietfauth.utils import role_required, has_role |
69 | 69 | from ietf.mailinglists.models import Subscribed, Whitelisted |
| 70 | +from ietf.name.models import ExtResourceName |
70 | 71 | from ietf.person.models import Person, Email, Alias, PersonalApiKey, PERSON_API_KEY_VALUES |
71 | 72 | from ietf.review.models import ReviewerSettings, ReviewWish, ReviewAssignment |
72 | 73 | from ietf.review.utils import unavailable_periods_to_list, get_default_filter_re |
73 | 74 | from ietf.doc.fields import SearchableDocumentField |
74 | 75 | from ietf.utils.decorators import person_required |
75 | 76 | from ietf.utils.mail import send_mail |
| 77 | +from ietf.utils.validators import validate_external_resource_value |
| 78 | + |
76 | 79 |
|
77 | 80 | def index(request): |
78 | 81 | return render(request, 'registration/index.html') |
@@ -286,6 +289,79 @@ def profile(request): |
286 | 289 | 'settings':settings, |
287 | 290 | }) |
288 | 291 |
|
| 292 | +@login_required |
| 293 | +@person_required |
| 294 | +def edit_person_externalresources(request): |
| 295 | + class PersonExtResourceForm(forms.Form): |
| 296 | + resources = forms.CharField(widget=forms.Textarea, label="Additional Resources", required=False, |
| 297 | + help_text=("Format: 'tag value (Optional description)'." |
| 298 | + " Separate multiple entries with newline. When the value is a URL, use https:// where possible.") ) |
| 299 | + |
| 300 | + def clean_resources(self): |
| 301 | + lines = [x.strip() for x in self.cleaned_data["resources"].splitlines() if x.strip()] |
| 302 | + errors = [] |
| 303 | + for l in lines: |
| 304 | + parts = l.split() |
| 305 | + if len(parts) == 1: |
| 306 | + errors.append("Too few fields: Expected at least tag and value: '%s'" % l) |
| 307 | + elif len(parts) >= 2: |
| 308 | + name_slug = parts[0] |
| 309 | + try: |
| 310 | + name = ExtResourceName.objects.get(slug=name_slug) |
| 311 | + except ObjectDoesNotExist: |
| 312 | + errors.append("Bad tag in '%s': Expected one of %s" % (l, ', '.join([ o.slug for o in ExtResourceName.objects.all() ]))) |
| 313 | + continue |
| 314 | + value = parts[1] |
| 315 | + try: |
| 316 | + validate_external_resource_value(name, value) |
| 317 | + except ValidationError as e: |
| 318 | + e.message += " : " + value |
| 319 | + errors.append(e) |
| 320 | + if errors: |
| 321 | + raise ValidationError(errors) |
| 322 | + return lines |
| 323 | + |
| 324 | + def format_resources(resources, fs="\n"): |
| 325 | + res = [] |
| 326 | + for r in resources: |
| 327 | + if r.display_name: |
| 328 | + res.append("%s %s (%s)" % (r.name.slug, r.value, r.display_name.strip('()'))) |
| 329 | + else: |
| 330 | + res.append("%s %s" % (r.name.slug, r.value)) |
| 331 | + # TODO: This is likely problematic if value has spaces. How then to delineate value and display_name? Perhaps in the short term move to comma or pipe separation. |
| 332 | + # Might be better to shift to a formset instead of parsing these lines. |
| 333 | + return fs.join(res) |
| 334 | + |
| 335 | + person = request.user.person |
| 336 | + |
| 337 | + old_resources = format_resources(person.personextresource_set.all()) |
| 338 | + |
| 339 | + if request.method == 'POST': |
| 340 | + form = PersonExtResourceForm(request.POST) |
| 341 | + if form.is_valid(): |
| 342 | + old_resources = sorted(old_resources.splitlines()) |
| 343 | + new_resources = sorted(form.cleaned_data['resources']) |
| 344 | + if old_resources != new_resources: |
| 345 | + person.personextresource_set.all().delete() |
| 346 | + for u in new_resources: |
| 347 | + parts = u.split(None, 2) |
| 348 | + name = parts[0] |
| 349 | + value = parts[1] |
| 350 | + display_name = ' '.join(parts[2:]).strip('()') |
| 351 | + person.personextresource_set.create(value=value, name_id=name, display_name=display_name) |
| 352 | + new_resources = format_resources(person.personextresource_set.all()) |
| 353 | + messages.success(request,"Person resources updated.") |
| 354 | + else: |
| 355 | + messages.info(request,"No change in Person resources.") |
| 356 | + return redirect('ietf.ietfauth.views.profile') |
| 357 | + else: |
| 358 | + form = PersonExtResourceForm(initial={'resources': old_resources, }) |
| 359 | + |
| 360 | + info = "Valid tags:<br><br> %s" % ', '.join([ o.slug for o in ExtResourceName.objects.all().order_by('slug') ]) |
| 361 | + # May need to explain the tags more - probably more reason to move to a formset. |
| 362 | + title = "Additional person resources" |
| 363 | + return render(request, 'ietfauth/edit_field.html',dict(person=person, form=form, title=title, info=info) ) |
| 364 | + |
289 | 365 | def confirm_new_email(request, auth): |
290 | 366 | try: |
291 | 367 | username, email = django.core.signing.loads(auth, salt="add_email", max_age=settings.DAYS_TO_EXPIRE_REGISTRATION_LINK * 24 * 60 * 60) |
|
0 commit comments