Merge "Adds update workflow"
authorJack Morgan <jack.morgan@intel.com>
Tue, 9 Jan 2018 00:12:59 +0000 (00:12 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Tue, 9 Jan 2018 00:12:59 +0000 (00:12 +0000)
31 files changed:
.gitignore [new file with mode: 0644]
.gitreview [new file with mode: 0644]
dashboard/config.env.sample
dashboard/src/account/migrations/0002_userprofile_email_addr.py [new file with mode: 0644]
dashboard/src/account/models.py
dashboard/src/api/serializers.py
dashboard/src/api/urls.py
dashboard/src/api/views.py
dashboard/src/booking/admin.py
dashboard/src/booking/forms.py
dashboard/src/booking/migrations/0002_auto_20171213_1506.py [moved from dashboard/src/notification/migrations/0001_initial.py with 51% similarity]
dashboard/src/booking/models.py
dashboard/src/booking/views.py
dashboard/src/notification/admin.py [deleted file]
dashboard/src/notification/apps.py [deleted file]
dashboard/src/notification/models.py [deleted file]
dashboard/src/notification/signals.py [deleted file]
dashboard/src/notification/tasks.py [deleted file]
dashboard/src/notification/tests.py [deleted file]
dashboard/src/notifier/__init__.py [new file with mode: 0644]
dashboard/src/notifier/admin.py [moved from dashboard/src/notification/migrations/__init__.py with 82% similarity]
dashboard/src/notifier/apps.py [moved from dashboard/src/notification/__init__.py with 83% similarity]
dashboard/src/notifier/dispatchers.py [new file with mode: 0644]
dashboard/src/notifier/migrations/0001_initial.py [new file with mode: 0644]
dashboard/src/notifier/migrations/__init__.py [new file with mode: 0644]
dashboard/src/notifier/models.py [new file with mode: 0644]
dashboard/src/pharos_dashboard/settings.py
dashboard/src/templates/booking/booking_calendar.html
dashboard/src/templates/booking/booking_detail.html
dashboard/src/templates/booking/booking_table.html
dashboard/web/requirements.txt

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..1b73728
--- /dev/null
@@ -0,0 +1,66 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*.confc
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+eggs/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# PyInstaller
+#  Usually these files are written by a python script from a template 
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.cache
+nosetests.xml
+coverage.xml
+
+# Translations
+*.mo
+*.pot
+
+# Log files:
+*.log
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# SublimeText
+*.sublime-project
+*.sublime-workspace
+
+*~
+.*.sw?
+/docs_build/
+/docs_output/
+/releng/
+
+# macos preview
+.DS_Store
diff --git a/.gitreview b/.gitreview
new file mode 100644 (file)
index 0000000..9f94f15
--- /dev/null
@@ -0,0 +1,4 @@
+[gerrit]
+host=gerrit.opnfv.org
+port=29418
+project=pharos-tools.git
index b370fe2..edd2bf0 100644 (file)
@@ -25,3 +25,9 @@ RABBITMQ_PASSWORD=opnfvopnfv
 
 #Jenkins Build Server
 JENKINS_URL=https://build.opnfv.org/ci
+
+# Email Settings
+EMAIL_HOST=
+EMAIL_PORT=
+EMAIL_HOST_USER=
+EMAIL_HOST_PASSWORD=
diff --git a/dashboard/src/account/migrations/0002_userprofile_email_addr.py b/dashboard/src/account/migrations/0002_userprofile_email_addr.py
new file mode 100644 (file)
index 0000000..bfbed17
--- /dev/null
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10 on 2017-12-14 20:37
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('account', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='userprofile',
+            name='email_addr',
+            field=models.CharField(default='email@mail.com', max_length=300),
+        ),
+    ]
index bfc0bbe..47b012b 100644 (file)
@@ -20,7 +20,7 @@ class UserProfile(models.Model):
     timezone = models.CharField(max_length=100, blank=False, default='UTC')
     ssh_public_key = models.FileField(upload_to=upload_to, null=True, blank=True)
     pgp_public_key = models.FileField(upload_to=upload_to, null=True, blank=True)
-    email_addr = models.CharField(max_length=300, blank=false, default='email@mail.com')
+    email_addr = models.CharField(max_length=300, blank=False, default='email@mail.com')
     company = models.CharField(max_length=200, blank=False)
 
     oauth_token = models.CharField(max_length=1024, blank=False)
index 4478175..c371a92 100644 (file)
 
 from rest_framework import serializers
 
+from notifier.models import Notifier
 from booking.models import Booking
 from dashboard.models import Server, Resource, ResourceStatus
 
 class BookingSerializer(serializers.ModelSerializer):
     installer_name = serializers.CharField(source='installer.name')
     scenario_name = serializers.CharField(source='scenario.name')
+    opsys_name = serializers.CharField(source='opsys.name')
 
     class Meta:
         model = Booking
-        fields = ('id', 'resource_id', 'start', 'end', 'installer_name', 'scenario_name', 'purpose')
+        fields = ('id', 'resource_id', 'start', 'end', 'opsys_name', 'installer_name', 'scenario_name', 'purpose')
 
 
 class ServerSerializer(serializers.ModelSerializer):
@@ -37,3 +39,8 @@ class ResourceStatusSerializer(serializers.ModelSerializer):
     class Meta:
         model = ResourceStatus
         fields = ('id', 'resource', 'timestamp','type', 'title', 'content')
+
+class NotifierSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = Notifier
+        fields = ('id', 'title', 'content', 'user', 'sender', 'message_type', 'msg_sent')
index a4a4b2f..71cd3ef 100644 (file)
@@ -33,8 +33,9 @@ router.register(r'resources', ResourceViewSet)
 router.register(r'servers', ServerViewSet)
 router.register(r'bookings', BookingViewSet)
 router.register(r'resource_status', ResourceStatusViewSet)
+router.register(r'notifier', NotifierViewSet)
 
 urlpatterns = [
     url(r'^', include(router.urls)),
     url(r'^token$', GenerateTokenView.as_view(), name='generate_token'),
-]
\ No newline at end of file
+]
index 84fa1b5..c16d57d 100644 (file)
@@ -8,7 +8,7 @@
 ##############################################################################
 
 
-from django.contrib.auth.decorators import login_required
+from django.contrib.auth.decorators import login_required, user_passes_test
 from django.shortcuts import redirect
 from django.utils.decorators import method_decorator
 from django.views import View
@@ -41,6 +41,9 @@ class ResourceStatusViewSet(viewsets.ModelViewSet):
     queryset = ResourceStatus.objects.all()
     serializer_class = ResourceStatusSerializer
 
+class NotifierViewSet(viewsets.ModelViewSet):
+    queryset = Notifier.objects.none()
+    serializer_class = NotifierSerializer
 
 @method_decorator(login_required, name='dispatch')
 class GenerateTokenView(View):
index d883be1..51e1031 100644 (file)
@@ -13,5 +13,6 @@ from django.contrib import admin
 from booking.models import *
 
 admin.site.register(Booking)
+admin.site.register(Opsys)
 admin.site.register(Installer)
-admin.site.register(Scenario)
\ No newline at end of file
+admin.site.register(Scenario)
index 2dbfacb..1f09c05 100644 (file)
 
 import django.forms as forms
 
-from booking.models import Installer, Scenario
+from booking.models import Installer, Scenario, Opsys
 
 
 class BookingForm(forms.Form):
-    fields = ['start', 'end', 'purpose', 'installer', 'scenario']
+    fields = ['start', 'end', 'purpose', 'opsys', 'installer', 'scenario']
 
     start = forms.DateTimeField()
     end = forms.DateTimeField()
     purpose = forms.CharField(max_length=300)
+    opsys = forms.ModelChoiceField(queryset=Opsys.objects.all(), required=False)
     installer = forms.ModelChoiceField(queryset=Installer.objects.all(), required=False)
-    scenario = forms.ModelChoiceField(queryset=Scenario.objects.all(), required=False)
\ No newline at end of file
+    scenario = forms.ModelChoiceField(queryset=Scenario.objects.all(), required=False)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Generated by Django 1.10 on 2016-11-03 13:33
+# Generated by Django 1.10 on 2017-12-13 15:06
 from __future__ import unicode_literals
 
 from django.db import migrations, models
@@ -8,21 +8,21 @@ import django.db.models.deletion
 
 class Migration(migrations.Migration):
 
-    initial = True
-
     dependencies = [
         ('booking', '0001_initial'),
     ]
 
     operations = [
         migrations.CreateModel(
-            name='BookingNotification',
+            name='Opsys',
             fields=[
                 ('id', models.AutoField(primary_key=True, serialize=False)),
-                ('type', models.CharField(max_length=100)),
-                ('submit_time', models.DateTimeField()),
-                ('submitted', models.BooleanField(default=False)),
-                ('booking', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='booking.Booking')),
+                ('name', models.CharField(max_length=100)),
             ],
         ),
+        migrations.AddField(
+            model_name='booking',
+            name='opsys',
+            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='booking.Opsys'),
+        ),
     ]
index 0b3fa3b..0bf5961 100644 (file)
@@ -31,6 +31,12 @@ class Scenario(models.Model):
     def __str__(self):
         return self.name
 
+class Opsys(models.Model):
+    id = models.AutoField(primary_key=True)
+    name = models.CharField(max_length=100)
+
+    def __str__(self):
+        return self.name
 
 class Booking(models.Model):
     id = models.AutoField(primary_key=True)
@@ -41,6 +47,7 @@ class Booking(models.Model):
     jira_issue_id = models.IntegerField(null=True)
     jira_issue_status = models.CharField(max_length=50)
 
+    opsys = models.ForeignKey(Opsys, models.DO_NOTHING, null=True)
     installer = models.ForeignKey(Installer, models.DO_NOTHING, null=True)
     scenario = models.ForeignKey(Scenario, models.DO_NOTHING, null=True)
     purpose = models.CharField(max_length=300, blank=False)
index 6fdca0e..da2fe11 100644 (file)
@@ -70,6 +70,7 @@ class BookingFormView(FormView):
         booking = Booking(start=form.cleaned_data['start'],
                           end=form.cleaned_data['end'],
                           purpose=form.cleaned_data['purpose'],
+                          opsys=form.cleaned_data['opsys'],
                           installer=form.cleaned_data['installer'],
                           scenario=form.cleaned_data['scenario'],
                           resource=self.resource, user=user)
@@ -117,6 +118,6 @@ class ResourceBookingsJSON(View):
     def get(self, request, *args, **kwargs):
         resource = get_object_or_404(Resource, id=self.kwargs['resource_id'])
         bookings = resource.booking_set.get_queryset().values('id', 'start', 'end', 'purpose',
-                                                              'jira_issue_status',
+                                                              'jira_issue_status', 'opsys__name',
                                                               'installer__name', 'scenario__name')
         return JsonResponse({'bookings': list(bookings)})
diff --git a/dashboard/src/notification/admin.py b/dashboard/src/notification/admin.py
deleted file mode 100644 (file)
index bcaa1ab..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-from django.conf import settings
-from django.contrib import admin
-
-from notification.models import BookingNotification
-
-if settings.DEBUG:
-    admin.site.register(BookingNotification)
\ No newline at end of file
diff --git a/dashboard/src/notification/apps.py b/dashboard/src/notification/apps.py
deleted file mode 100644 (file)
index 2de22c4..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-from django.apps import AppConfig
-
-
-class NotificationConfig(AppConfig):
-    name = 'notification'
-
-    def ready(self):
-        import notification.signals #noqa
\ No newline at end of file
diff --git a/dashboard/src/notification/models.py b/dashboard/src/notification/models.py
deleted file mode 100644 (file)
index 89b3023..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-from django.db import models
-
-class BookingNotification(models.Model):
-    id = models.AutoField(primary_key=True)
-    type = models.CharField(max_length=100)
-    booking = models.ForeignKey('booking.Booking', on_delete=models.CASCADE)
-    submit_time = models.DateTimeField()
-    submitted = models.BooleanField(default=False)
-
-    def get_content(self):
-        return {
-            'resource_id': self.booking.resource.id,
-            'booking_id': self.booking.id,
-            'user': self.booking.user.username,
-            'user_id': self.booking.user.id,
-        }
-
-    def save(self, *args, **kwargs):
-        notifications = self.booking.bookingnotification_set.filter(type=self.type).exclude(
-            id=self.id)
-        #if notifications.count() > 0:
-        #    raise ValueError('Doubled Notification')
-        return super(BookingNotification, self).save(*args, **kwargs)
diff --git a/dashboard/src/notification/signals.py b/dashboard/src/notification/signals.py
deleted file mode 100644 (file)
index 936c25b..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-from django.db.models.signals import post_save
-from django.dispatch import receiver
-
-from booking.models import Booking
-from notification.models import BookingNotification
-
-
-@receiver(post_save, sender=Booking)
-def booking_notification_handler(sender, instance, **kwargs):
-    BookingNotification.objects.update_or_create(
-        booking=instance, type='booking_start', defaults={'submit_time': instance.start}
-    )
-    BookingNotification.objects.update_or_create(
-        booking=instance, type='booking_end', defaults={'submit_time': instance.end}
-    )
\ No newline at end of file
diff --git a/dashboard/src/notification/tasks.py b/dashboard/src/notification/tasks.py
deleted file mode 100644 (file)
index 7f73762..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-import os
-import sys
-from datetime import timedelta
-
-from celery import shared_task
-from django.conf import settings
-from django.utils import timezone
-
-from notification.models import BookingNotification
-
-# this adds the top level directory to the python path, this is needed so that we can access the
-# notification library
-sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
-
-from dashboard_notification.notification import Notification, Message
-
-
-@shared_task
-def send_booking_notifications():
-    with Notification(dashboard_url=settings.RABBITMQ_URL, user=settings.RABBITMQ_USER, password=settings.RABBITMQ_PASSWORD) as messaging:
-        now = timezone.now()
-        notifications = BookingNotification.objects.filter(submitted=False,
-                                                           submit_time__gt=now - timedelta(minutes=1),
-                                                           submit_time__lt=now + timedelta(minutes=5))
-        for notification in notifications:
-            message = Message(type=notification.type, topic=notification.booking.resource.name,
-                              content=notification.get_content())
-            messaging.send(message)
-            notification.submitted = True
-            notification.save()
-
-@shared_task
-def notification_debug():
-    with Notification(dashboard_url=settings.RABBITMQ_URL) as messaging:
-        notifications = BookingNotification.objects.all()
-        for notification in notifications:
-            message = Message(type=notification.type, topic=notification.booking.resource.name,
-                              content=notification.get_content())
-            messaging.send(message)
diff --git a/dashboard/src/notification/tests.py b/dashboard/src/notification/tests.py
deleted file mode 100644 (file)
index 9df9aa6..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-from datetime import timedelta
-from unittest import TestCase
-
-from django.contrib.auth.models import User
-from django.utils import timezone
-
-from booking.models import Booking
-from dashboard.models import Resource
-from jenkins.models import JenkinsSlave
-from notification.models import *
-
-
-class JenkinsModelTestCase(TestCase):
-    def setUp(self):
-        self.slave = JenkinsSlave.objects.create(name='test1', url='test')
-        self.res1 = Resource.objects.create(name='res1', slave=self.slave, description='x',
-                                            url='x')
-        self.user1 = User.objects.create(username='user1')
-
-        start = timezone.now()
-        end = start + timedelta(days=1)
-        self.booking = Booking.objects.create(start=start, end=end, purpose='test',
-                                              resource=self.res1, user=self.user1)
-
-    def test_booking_notification(self):
-        BookingNotification.objects.create(type='test', booking=self.booking,
-                                           submit_time=timezone.now())
-
-        self.assertRaises(ValueError, BookingNotification.objects.create, type='test',
-                          booking=self.booking,
-                          submit_time=timezone.now())
diff --git a/dashboard/src/notifier/__init__.py b/dashboard/src/notifier/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
similarity index 82%
rename from dashboard/src/notification/migrations/__init__.py
rename to dashboard/src/notifier/admin.py
index b5914ce..cfbe778 100644 (file)
@@ -7,4 +7,8 @@
 # http://www.apache.org/licenses/LICENSE-2.0
 ##############################################################################
 
+from django.contrib import admin
 
+from notifier.models import *
+
+admin.site.register(Notifier)
similarity index 83%
rename from dashboard/src/notification/__init__.py
rename to dashboard/src/notifier/apps.py
index 37dcbdd..da5d3b0 100644 (file)
@@ -7,5 +7,8 @@
 # http://www.apache.org/licenses/LICENSE-2.0
 ##############################################################################
 
+from django.apps import AppConfig
 
-default_app_config = 'notification.apps.NotificationConfig'
\ No newline at end of file
+
+class NotifierConfig(AppConfig):
+    name = 'notifier'
diff --git a/dashboard/src/notifier/dispatchers.py b/dashboard/src/notifier/dispatchers.py
new file mode 100644 (file)
index 0000000..64be2a5
--- /dev/null
@@ -0,0 +1,34 @@
+##############################################################################
+# Copyright (c) 2016 Max Breitenfeldt and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from django.db.models.signals import pre_save
+from django.dispatch import receiver
+from django.contrib import messages
+from django.core.mail import send_mail
+
+class DispatchHandler():
+
+    @receiver(pre_save, sender='notifier.Notifier')
+    def dispatch(sender, instance, *args, **kwargs):
+        try:
+            msg_type = getattr(DispatchHandler, instance.message_type)
+            msg_type(instance)
+        except AttributeError:
+            instance.msg_sent = 'no dispatcher by given name exists: sending by email'
+            email(instance)
+
+    def email(instance):
+        if instance.msg_sent != 'no dispatcher by given name exists: sending by email':
+            instance.msg_sent = 'by email'
+        send_mail(instance.title,instance.content + 
+            '\n\n This message pertains to the following resource: ' + 
+            instance.resource.name,instance.sender,[instance.user.email_addr], fail_silently=False)
+
+    def webnotification(instance):
+        instance.msg_sent='by web notification'
diff --git a/dashboard/src/notifier/migrations/0001_initial.py b/dashboard/src/notifier/migrations/0001_initial.py
new file mode 100644 (file)
index 0000000..78d2bad
--- /dev/null
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10 on 2017-12-14 21:41
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import fernet_fields.fields
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('account', '0002_userprofile_email_addr'),
+        ('dashboard', '0002_auto_20170505_0815'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Notifier',
+            fields=[
+                ('id', models.AutoField(primary_key=True, serialize=False)),
+                ('title', models.CharField(max_length=240)),
+                ('content', fernet_fields.fields.EncryptedTextField()),
+                ('sender', models.CharField(default='unknown', max_length=240)),
+                ('message_type', models.CharField(choices=[('email', 'Email'), ('webnotification', 'Web Notification')], default='email', max_length=240)),
+                ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='account.UserProfile')),
+            ],
+        ),
+    ]
diff --git a/dashboard/src/notifier/migrations/__init__.py b/dashboard/src/notifier/migrations/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/dashboard/src/notifier/models.py b/dashboard/src/notifier/models.py
new file mode 100644 (file)
index 0000000..9ebc6fc
--- /dev/null
@@ -0,0 +1,38 @@
+##############################################################################
+# Copyright (c) 2016 Max Breitenfeldt and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from django.db import models
+from jira import JIRA, JIRAError
+from dashboard.models import Resource
+from booking.models import Booking
+from django.contrib.auth.models import User
+from account.models import UserProfile
+from django.contrib import messages
+from django.db.models.signals import pre_save
+from fernet_fields import EncryptedTextField
+
+class Notifier(models.Model):
+    id = models.AutoField(primary_key=True)
+    title = models.CharField(max_length=240)
+    content = EncryptedTextField()
+    user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, null=True, blank=True)
+    sender = models.CharField(max_length=240, default='unknown')
+    message_type = models.CharField(max_length=240, default='email', choices=(
+        ('email','Email'), 
+        ('webnotification', 'Web Notification')))
+    msg_sent = ''
+
+    import notifier.dispatchers
+
+    def __str__(self):
+        return self.title
+
+    def getEmail(self):
+        return self.user.email_addr
+
index 83ad172..240f68e 100644 (file)
@@ -14,7 +14,7 @@ INSTALLED_APPS = [
     'booking',
     'account',
     'jenkins',
-    'notification',
+    'notifier',
     'django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.contenttypes',
@@ -188,3 +188,9 @@ CI_SLAVES_URL = os.environ['JENKINS_URL'] + '/label/ci-pod/api/json?tree=nodes[n
 ALL_JOBS_URL = os.environ['JENKINS_URL'] + '/api/json?tree=jobs[displayName,url,lastBuild[fullDisplayName,building,builtOn,timestamp,result]'
 GET_SLAVE_URL = os.environ['JENKINS_URL'] + '/computer/'
 
+# Notifier Settings
+EMAIL_HOST = os.environ['EMAIL_HOST']
+EMAIL_PORT = os.environ['EMAIL_PORT']
+EMAIL_HOST_USER = os.environ['EMAIL_HOST_USER']
+EMAIL_HOST_PASSWORD = os.environ['EMAIL_HOST_PASSWORD']
+EMAIL_USE_TLS=True
index 4644e85..16f0a4a 100644 (file)
@@ -45,6 +45,7 @@
                             <div class='input-group' id='endtimepicker'>
                                 {% bootstrap_field form.end addon_after='<span class="glyphicon glyphicon-calendar"></span>' %}
                             </div>
+                            {% bootstrap_field form.opsys %}
                             {% bootstrap_field form.purpose %}
                             {% bootstrap_field form.installer %}
                             {% bootstrap_field form.scenario %}
     <script src={% static "js/fullcalendar-options.js" %}></script>
     <script src={% static "js/datetimepicker-options.js" %}></script>
     <script src={% static "js/booking-calendar.js" %}></script>
-{% endblock extrajs %}
\ No newline at end of file
+{% endblock extrajs %}
index 4b016b2..cb937d3 100644 (file)
 <p>
     <b>Purpose: </b> {{ booking.purpose }}
 </p>
+<p>
+    <b>Operating System: </b> {{ booking.opsys }}
+</p>
 <p>
     <b>Installer: </b> {{ booking.installer }}
 </p>
 <p>
     <b>Scenario: </b> {{ booking.scenario }}
-</p>
\ No newline at end of file
+</p>
index 655b013..af2248c 100644 (file)
@@ -7,6 +7,7 @@
     <th>Purpose</th>
     <th>Start</th>
     <th>End</th>
+    <th>Operating System</th>
     <th>Installer</th>
     <th>Scenario</th>
 </tr>
@@ -26,6 +27,9 @@
         <td>
             {{ booking.end }}
         </td>
+        <td>
+            {{ booking.opsys }}
+        </td>
         <td>
             {{ booking.installer }}
         </td>
@@ -34,4 +38,4 @@
         </td>
     </tr>
 {% endfor %}
-</tbody>
\ No newline at end of file
+</tbody>
index f80f1c0..0d864d3 100644 (file)
@@ -15,3 +15,4 @@ pika==0.10.0
 psycopg2==2.6.2
 PyJWT==1.4.2
 requests==2.11.0
+django-fernet-fields==0.5