diff --git a/app/authentication/views.py b/app/authentication/views.py index 70c0d4a..244f181 100644 --- a/app/authentication/views.py +++ b/app/authentication/views.py @@ -79,6 +79,7 @@ def register_continue(request): user_password = request.POST.get('password1') gotify_user_info = gotify.api.create_user(user.username, user_password) gotify_app_info = gotify.api.create_application(user.username, user_password) + gotify.api.upload_application_picture(user.username, user_password, gotify_app_info['id']) gotify_user = gotify.models.GotifyUser( user=user, id=gotify_user_info['id'] diff --git a/app/gotify/api.py b/app/gotify/api.py index 766e9fa..b5a82e3 100644 --- a/app/gotify/api.py +++ b/app/gotify/api.py @@ -56,3 +56,20 @@ def create_application(username: str, password: str) -> dict: response.raise_for_status() return response.json() + + +def upload_application_picture(username: str, password: str, app_id: int): + with open('/app/static/medwings/images/logo/medwings-logo.png', 'rb') as image_file: + response = requests.post( + url=f"http://{settings.GOTIFY_CONFIG['HOST']}/application/{app_id}/image", + auth=HTTPBasicAuth( + username, + password, + ), + files={ + 'file': image_file + } + ) + + if response is not None: + response.raise_for_status() diff --git a/app/gotify/management/__init__.py b/app/gotify/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/gotify/management/commands/__init__.py b/app/gotify/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/gotify/management/commands/notify_all.py b/app/gotify/management/commands/notify_all.py new file mode 100644 index 0000000..d57e810 --- /dev/null +++ b/app/gotify/management/commands/notify_all.py @@ -0,0 +1,24 @@ +from django.urls import reverse +from django.core.management.base import BaseCommand + +from gotify import models + + +class Command(BaseCommand): + help = 'Notifies all users to take a vitals measurement now.' + + def handle(self, *args, **kwargs): + applications = models.GotifyApplication.objects.all() + + for application in applications: + message_text = f"Hello {application.user.user.first_name}. Please take your next vitals measurement now." + message_title = "Medwings Measurement Prompt" + url = reverse('mews-init') + + message = models.GotifyMessage( + message=message_text, + title=message_title, + url=url + ) + + application.send_message(message) diff --git a/app/gotify/models.py b/app/gotify/models.py index 523b844..0f43d5e 100644 --- a/app/gotify/models.py +++ b/app/gotify/models.py @@ -1,6 +1,10 @@ -from django.db import models +from enum import Enum +import json +from django.db import models from django.contrib.auth.models import User +from django.conf import settings +import requests class GotifyUser(models.Model): @@ -8,7 +12,68 @@ class GotifyUser(models.Model): id = models.PositiveIntegerField(verbose_name="Gotify User ID") +class GotifyMessageType(Enum): + plain = "text/plain" + markdown = "text/markdown" + + +class GotifyMessage(): + type: GotifyMessageType + message: str + title: str | None + priority: int + url: str | None + + def __init__(self, message: str, title: str | None = None, priority: int = 5, url: str | None = None, type: str = 'text/plain'): + self.message = message + self.title = title + if not 0 <= priority <= 10: + raise ValueError(f"Priority must be 0 to 10.") + self.priority = priority + self.url = url + self.type = GotifyMessageType(type) + + def as_dict(self) -> dict: + obj = { + "message": self.message, + "priority": self.priority, + "extras": { + "client::display": { + "contentType": self.type.value + } + } + } + + if self.title: + obj["title"] = self.title + + if self.url: + obj["extras"]["client::notification"] = { + "click": { + "url": self.url + } + } + + return obj + + class GotifyApplication(models.Model): user = models.OneToOneField(GotifyUser, on_delete=models.CASCADE, primary_key=True) id = models.PositiveIntegerField(verbose_name="Gotify Application ID") token = models.CharField(max_length=256, verbose_name="Gotify Application Token") + + def send_message(self, message: GotifyMessage): + endpoint_url = f"http://{settings.GOTIFY_CONFIG['HOST']}/message" + headers = { + "Authorization": f"Bearer {self.token}", + "Content-Type": "application/json" + } + + response = requests.post( + url=endpoint_url, + headers=headers, + data=json.dumps(message.as_dict()) + ) + + if response is not None: + response.raise_for_status() diff --git a/app/medwings/templates/medwings/index.html b/app/medwings/templates/medwings/index.html index 4865289..4afd42c 100644 --- a/app/medwings/templates/medwings/index.html +++ b/app/medwings/templates/medwings/index.html @@ -8,7 +8,6 @@
We understand that after receiving medical care, you may still have concerns about your health, particularly if you're at risk of sudden health changes. diff --git a/app/medwings/templates/medwings/mews-init.html b/app/medwings/templates/medwings/mews-init.html index 932c853..4e1e583 100644 --- a/app/medwings/templates/medwings/mews-init.html +++ b/app/medwings/templates/medwings/mews-init.html @@ -8,6 +8,14 @@ {% block content %}
Before you begin, please have your Withings devices ready for taking measurements.
+