diff --git a/gracedb/alerts/fields.py b/gracedb/alerts/fields.py new file mode 100644 index 0000000000000000000000000000000000000000..4fd85a1175672ac5c6d5e01c19c8a856b67984dd --- /dev/null +++ b/gracedb/alerts/fields.py @@ -0,0 +1,7 @@ +from django.db import models + +from .validators import validate_phone + + +class PhoneNumberField(models.CharField): + validators = [validate_phone] diff --git a/gracedb/alerts/migrations/0001_initial.py b/gracedb/alerts/migrations/0001_initial.py index 0097f75d6412b0bb481455af2cbc5e5eec87d436..6d4736b5d84f85073fda233368d6e4cf4f746937 100644 --- a/gracedb/alerts/migrations/0001_initial.py +++ b/gracedb/alerts/migrations/0001_initial.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.18 on 2019-01-17 20:11 +# Generated by Django 1.11.18 on 2019-01-17 20:24 from __future__ import unicode_literals -import alerts.models +import alerts.fields from django.conf import settings from django.db import migrations, models import django.db.models.deletion @@ -24,7 +24,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('desc', models.CharField(max_length=20)), ('email', models.EmailField(blank=True, max_length=254)), - ('phone', alerts.models.PhoneNumberField(blank=True, max_length=255, validators=[alerts.models.validate_phone])), + ('phone', alerts.fields.PhoneNumberField(blank=True, max_length=255)), ('call_phone', models.BooleanField(default=False)), ('text_phone', models.BooleanField(default=False)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), diff --git a/gracedb/alerts/models.py b/gracedb/alerts/models.py index 6e29680e0b5629011d8c7acde906bd42de4ff2e2..ceb785e9bb49ae5b15ad58b32040791b2bbc5f1a 100644 --- a/gracedb/alerts/models.py +++ b/gracedb/alerts/models.py @@ -1,48 +1,22 @@ +from collections import defaultdict + +from django.contrib.auth import get_user_model from django.db import models from django.core.exceptions import ValidationError, NON_FIELD_ERRORS -from django.contrib.auth.models import User from events.models import Label, Pipeline +from .fields import PhoneNumberField -from collections import defaultdict -import phonenumbers -import logging -log = logging.getLogger(__name__) - -def validate_phone(value): - try: - phone = phonenumbers.parse(value, 'US') - except phonenumbers.NumberParseException: - raise ValidationError('Not a valid phone number: {0}'.format(value)) - if not phonenumbers.is_valid_number(phone): - raise ValidationError('Not a valid phone number: {0}'.format(value)) - return phonenumbers.format_number(phone, phonenumbers.PhoneNumberFormat.E164) - -class PhoneNumberField(models.CharField): - - def __init__(self, *args, **kwargs): - super(PhoneNumberField, self).__init__(*args, **kwargs) - - def get_prep_value(self, value): - if value: - return validate_phone(value) - else: - return '' -#class Notification(models.Model): -# user = models.ForeignKey(User, null=False) -# onLabel = models.ManyToManyField(Label, blank=True) -# onTypeCreate = models.CharField(max_length=20, choices=TYPES, blank=True) -# onTypeChange = models.CharField(max_length=20, choices=TYPES, blank=True) -# email = models.EmailField() +# Set up user model +UserModel = get_user_model() + class Contact(models.Model): - user = models.ForeignKey(User, null=False) - #new_user = models.ForeignKey(DjangoUser, null=True) + user = models.ForeignKey(UserModel, null=False) desc = models.CharField(max_length=20) email = models.EmailField(blank=True) - phone = PhoneNumberField(blank=True, max_length=255, - validators=[validate_phone]) + phone = PhoneNumberField(blank=True, max_length=255) # These fields specify whether alert should be a phone # call or text (or both). call_phone = models.BooleanField(default=False) @@ -86,12 +60,13 @@ class Contact(models.Model): print('\tPhone: {0} (call={1}, text={2})'.format(self.phone, self.call_phone, self.text_phone)) + class Trigger(models.Model): # TP 6 Jul 2017: TYPES and triggerType don't seem to be used anywhere... TYPES = ( ("create", "create"), ("change","change"), ("label","label") ) triggerType = models.CharField(max_length=20, choices=TYPES, blank=True) - user = models.ForeignKey(User, null=False) + user = models.ForeignKey(UserModel, null=False) labels = models.ManyToManyField(Label, blank=True) pipelines = models.ManyToManyField(Pipeline, blank=True) contacts = models.ManyToManyField(Contact, blank=False) @@ -120,4 +95,3 @@ class Trigger(models.Model): thresh, ", ".join([x.desc for x in self.contacts.all()]) ) - diff --git a/gracedb/alerts/validators.py b/gracedb/alerts/validators.py new file mode 100644 index 0000000000000000000000000000000000000000..36d17bbfed9c89612bd8ccecded038740a28bb08 --- /dev/null +++ b/gracedb/alerts/validators.py @@ -0,0 +1,17 @@ +import phonenumbers + + +def validate_phone(value): + # Try to parse phone number + try: + phone = phonenumbers.parse(value, 'US') + except phonenumbers.NumberParseException: + raise ValidationError('Not a valid phone number: {0}'.format(value)) + + # Validate phone number + if not phonenumbers.is_valid_number(phone): + raise ValidationError('Not a valid phone number: {0}'.format(value)) + + # Return phone number as a formatted string + return phonenumbers.format_number(phone, + phonenumbers.PhoneNumberFormat.E164)