test notification

This commit is contained in:
hay-kot 2021-05-08 12:15:34 -08:00
commit c4d1a9ff9a
10 changed files with 117 additions and 59 deletions

View file

@ -0,0 +1 @@
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 245 240"><style>.st0{fill:#7289DA;}</style><path class="st0" d="M104.4 103.9c-5.7 0-10.2 5-10.2 11.1s4.6 11.1 10.2 11.1c5.7 0 10.2-5 10.2-11.1.1-6.1-4.5-11.1-10.2-11.1zM140.9 103.9c-5.7 0-10.2 5-10.2 11.1s4.6 11.1 10.2 11.1c5.7 0 10.2-5 10.2-11.1s-4.5-11.1-10.2-11.1z"/><path class="st0" d="M189.5 20h-134C44.2 20 35 29.2 35 40.6v135.2c0 11.4 9.2 20.6 20.5 20.6h113.4l-5.3-18.5 12.8 11.9 12.1 11.2 21.5 19V40.6c0-11.4-9.2-20.6-20.5-20.6zm-38.6 130.6s-3.6-4.3-6.6-8.1c13.1-3.7 18.1-11.9 18.1-11.9-4.1 2.7-8 4.6-11.5 5.9-5 2.1-9.8 3.5-14.5 4.3-9.6 1.8-18.4 1.3-25.9-.1-5.7-1.1-10.6-2.7-14.7-4.3-2.3-.9-4.8-2-7.3-3.4-.3-.2-.6-.3-.9-.5-.2-.1-.3-.2-.4-.3-1.8-1-2.8-1.7-2.8-1.7s4.8 8 17.5 11.8c-3 3.8-6.7 8.3-6.7 8.3-22.1-.7-30.5-15.2-30.5-15.2 0-32.2 14.4-58.3 14.4-58.3 14.4-10.8 28.1-10.5 28.1-10.5l1 1.2c-18 5.2-26.3 13.1-26.3 13.1s2.2-1.2 5.9-2.9c10.7-4.7 19.2-6 22.7-6.3.6-.1 1.1-.2 1.7-.2 6.1-.8 13-1 20.2-.2 9.5 1.1 19.7 3.9 30.1 9.6 0 0-7.9-7.5-24.9-12.7l1.4-1.6s13.7-.3 28.1 10.5c0 0 14.4 26.1 14.4 58.3 0 0-8.5 14.5-30.6 15.2z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<svg width="602px" height="602px" viewBox="57 57 602 602" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g id="layer1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="translate(58.964119, 58.887520)" opacity="0.91">
<ellipse style="fill: rgb(36, 157, 241); fill-rule: evenodd; stroke: rgb(255, 255, 255); stroke-width: 0;" transform="matrix(-0.674571, 0.73821, -0.73821, -0.674571, 556.833239, 241.613465)" cx="216.308" cy="152.076" rx="296.855" ry="296.855"/>
<path d="M 280.949 172.514 L 355.429 162.714 L 282.909 326.374 L 282.909 326.374 C 295.649 325.394 308.142 321.067 320.389 313.394 L 320.389 313.394 L 320.389 313.394 C 332.642 305.714 343.916 296.077 354.209 284.484 L 354.209 284.484 L 354.209 284.484 C 364.496 272.884 373.396 259.981 380.909 245.774 L 380.909 245.774 L 380.909 245.774 C 388.422 231.561 393.812 217.594 397.079 203.874 L 397.079 203.874 L 397.079 203.874 C 399.039 195.381 399.939 187.214 399.779 179.374 L 399.779 179.374 L 399.779 179.374 C 399.612 171.534 397.569 164.674 393.649 158.794 L 393.649 158.794 L 393.649 158.794 C 389.729 152.914 383.766 148.177 375.759 144.584 L 375.759 144.584 L 375.759 144.584 C 367.759 140.991 356.899 139.194 343.179 139.194 L 343.179 139.194 L 343.179 139.194 C 327.172 139.194 311.409 141.807 295.889 147.034 L 295.889 147.034 L 295.889 147.034 C 280.376 152.261 266.002 159.857 252.769 169.824 L 252.769 169.824 L 252.769 169.824 C 239.542 179.784 228.029 192.197 218.229 207.064 L 218.229 207.064 L 218.229 207.064 C 208.429 221.924 201.406 238.827 197.159 257.774 L 197.159 257.774 L 197.159 257.774 C 195.526 263.981 194.546 268.961 194.219 272.714 L 194.219 272.714 L 194.219 272.714 C 193.892 276.474 193.812 279.577 193.979 282.024 L 193.979 282.024 L 193.979 282.024 C 194.139 284.477 194.462 286.357 194.949 287.664 L 194.949 287.664 L 194.949 287.664 C 195.442 288.971 195.852 290.277 196.179 291.584 L 196.179 291.584 L 196.179 291.584 C 179.519 291.584 167.349 288.234 159.669 281.534 L 159.669 281.534 L 159.669 281.534 C 151.996 274.841 150.119 263.164 154.039 246.504 L 154.039 246.504 L 154.039 246.504 C 157.959 229.191 166.862 212.694 180.749 197.014 L 180.749 197.014 L 180.749 197.014 C 194.629 181.334 211.122 167.531 230.229 155.604 L 230.229 155.604 L 230.229 155.604 C 249.342 143.684 270.249 134.214 292.949 127.194 L 292.949 127.194 L 292.949 127.194 C 315.656 120.167 337.789 116.654 359.349 116.654 L 359.349 116.654 L 359.349 116.654 C 378.296 116.654 394.219 119.347 407.119 124.734 L 407.119 124.734 L 407.119 124.734 C 420.026 130.127 430.072 137.234 437.259 146.054 L 437.259 146.054 L 437.259 146.054 C 444.446 154.874 448.936 165.164 450.729 176.924 L 450.729 176.924 L 450.729 176.924 C 452.529 188.684 451.959 200.934 449.019 213.674 L 449.019 213.674 L 449.019 213.674 C 445.426 229.027 438.646 244.464 428.679 259.984 L 428.679 259.984 L 428.679 259.984 C 418.719 275.497 406.226 289.544 391.199 302.124 L 391.199 302.124 L 391.199 302.124 C 376.172 314.697 358.939 324.904 339.499 332.744 L 339.499 332.744 L 339.499 332.744 C 320.066 340.584 299.406 344.504 277.519 344.504 L 277.519 344.504 L 275.069 344.504 L 212.839 484.154 L 142.279 484.154 L 280.949 172.514 Z" transform="matrix(1, 0, 0, 1, 0, 0)" style="fill: rgb(255, 255, 255); fill-rule: nonzero; white-space: pre;"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -14,6 +14,7 @@ const aboutURLs = {
event: id => `${prefix}/events/${id}`,
allNotifications: `${prefix}/events/notifications`,
testNotifications: `${prefix}/events/notifications/test`,
notification: id => `${prefix}/events/notifications/${id}`,
};
@ -45,6 +46,14 @@ export const aboutAPI = {
const response = await apiReq.delete(aboutURLs.notification(id));
return response.data;
},
async testNotificationByID(id) {
const response = await apiReq.post(aboutURLs.testNotifications, { id: id });
return response.data;
},
async testNotificationByURL(url) {
const response = await apiReq.post(aboutURLs.testNotifications, { test_url: url });
return response.data;
},
// async getAppInfo() {
// const response = await apiReq.get(aboutURLs.version);
// return response.data;

View file

@ -14,9 +14,9 @@
</template>
<v-card-text class="mt-2">
We use the <a href="https://github.com/caronc/apprise/wiki" target="_blanks"> Apprise </a> library to
generate notifications. They offer many options for services to use. Refer to their wiki for a comprehensive
guide on how to create the URL for your service. If available, selecting the type of your notification can
include extra features Here are some common choices.
generate notifications. They offer many options for services to use for notifications. Refer to their wiki
for a comprehensive guide on how to create the URL for your service. If available, selecting the type of
your notification can include extra features Here are some common choices.
<div class="d-flex justify-space-around mt-1">
<a href="https://github.com/caronc/apprise/wiki/Notify_gotify" target="_blanks"> Gotify </a>
@ -33,6 +33,10 @@
</v-select>
<v-text-field label="Name" v-model="newNotification.name"> </v-text-field>
<v-text-field label="Notification URL" v-model="newNotification.notificationUrl"> </v-text-field>
<v-btn class="d-flex ml-auto" small color="info" @click="testByURL(newNotification.notificationUrl)">
<v-icon left> mdi-test-tube</v-icon>
Test
</v-btn>
<v-subheader class="pa-0 mb-0">
Select the events you would like to recieve notifications for on this URL
</v-subheader>
@ -55,31 +59,31 @@
<template v-slot:default>
<thead>
<tr>
<th class="text-left">
<th class="text-center">
Type
</th>
<th class="text-left">
<th class="text-center">
Name
</th>
<th class="text-left">
<th class="text-center">
General
</th>
<th class="text-left">
<th class="text-center">
Recipe
</th>
<th class="text-left">
<th class="text-center">
Backup
</th>
<th class="text-left">
<th class="text-center">
Scheduled
</th>
<th class="text-left">
<th class="text-center">
Migration
</th>
<th class="text-left">
<th class="text-center">
Group
</th>
<th class="text-left">
<th class="text-center">
User
</th>
</tr>
@ -87,7 +91,7 @@
<tbody>
<tr v-for="(item, index) in notifications" :key="index">
<td>
<v-avatar size="35" class="ma-1" color="primary">
<v-avatar size="35" class="ma-1" :color="getIcon(item.type).icon ? 'primary' : undefined">
<v-icon dark v-if="getIcon(item.type).icon"> {{ getIcon(item.type).icon }}</v-icon>
<v-img v-else :src="getIcon(item.type).image"> </v-img>
</v-avatar>
@ -96,30 +100,35 @@
<td>
{{ item.name }}
</td>
<td>
<td class="text-center">
<v-icon color="success"> {{ item.general ? "mdi-check" : "" }} </v-icon>
</td>
<td>
<td class="text-center">
<v-icon color="success"> {{ item.recipe ? "mdi-check" : "" }} </v-icon>
</td>
<td>
<td class="text-center">
<v-icon color="success"> {{ item.backup ? "mdi-check" : "" }} </v-icon>
</td>
<td>
<td class="text-center">
<v-icon color="success"> {{ item.scheduled ? "mdi-check" : "" }} </v-icon>
</td>
<td>
<td class="text-center">
<v-icon color="success"> {{ item.migration ? "mdi-check" : "" }} </v-icon>
</td>
<td>
<td class="text-center">
<v-icon color="success"> {{ item.group ? "mdi-check" : "" }} </v-icon>
</td>
<td>
<td class="text-center">
<v-icon color="success"> {{ item.user ? "mdi-check" : "" }} </v-icon>
</td>
<td>
<v-btn small icon color="error" @click="deleteNotification(item.id)">
<v-btn class="mx-1" small color="error" @click="deleteNotification(item.id)">
<v-icon> mdi-delete </v-icon>
Delete
</v-btn>
<v-btn small color="info" @click="testByID(item.id)">
<v-icon left> mdi-test-tube</v-icon>
Test
</v-btn>
</td>
</tr>
@ -162,12 +171,20 @@ export default {
},
{
text: "Discord",
icon: "mdi-discord",
image: "./static/discord.svg",
},
{
text: "Gotify",
image: "./static/gotify.png",
},
{
text: "Home Assistant",
image: "./static/home-assistant.png",
},
{
text: "Pushover",
image: "./static/pushover.svg",
},
],
};
},
@ -190,6 +207,12 @@ export default {
await api.about.deleteNotification(id);
this.getAllNotifications();
},
async testByID(id) {
await api.about.testNotificationByID(id);
},
async testByURL(url) {
await api.about.testNotificationByURL(url);
},
},
};
</script>

View file

@ -1,14 +1,20 @@
from fastapi import APIRouter, Depends
from http.client import HTTPException
from fastapi import APIRouter, Depends, status
from mealie.core.root_logger import get_logger
from mealie.db.database import db
from mealie.db.db_setup import generate_session
from mealie.routes.deps import get_current_user
from mealie.schema.event_notifications import EventNotificationIn, EventNotificationOut
from mealie.schema.events import EventsOut
from mealie.schema.events import Event, EventCategory, EventsOut, TestEvent
from mealie.schema.user import UserInDB
from mealie.services.events import post_notifications
from sqlalchemy.orm.session import Session
router = APIRouter(prefix="/events", tags=["App Events"])
logger = get_logger()
@router.get("", response_model=EventsOut)
async def get_events(session: Session = Depends(generate_session), current_user: UserInDB = Depends(get_current_user)):
@ -41,10 +47,35 @@ async def create_event_notification(
current_user: UserInDB = Depends(get_current_user),
):
""" Create event_notification in the Database """
return db.event_notifications.create(session, event_data)
@router.post("/notifications/test")
async def test_notification(
test_data: TestEvent,
session: Session = Depends(generate_session),
current_user: UserInDB = Depends(get_current_user),
):
""" Create event_notification in the Database """
if test_data.id:
print("TEST ID")
event_obj: EventNotificationIn = db.event_notifications.get(session, test_data.id)
test_data.test_url = event_obj.notification_url
test_event = Event(
title="Test Notification",
text="This is a test message from the Mealie API server",
category=EventCategory.general.value,
)
try:
post_notifications(test_event, [test_data.test_url])
except Exception as e:
logger.error(e)
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR)
@router.get("/notifications", response_model=list[EventNotificationOut])
async def get_all_event_notification(
session: Session = Depends(generate_session), current_user: UserInDB = Depends(get_current_user)

View file

@ -30,3 +30,8 @@ class Event(CamelModel):
class EventsOut(CamelModel):
total: int
events: list[Event]
class TestEvent(CamelModel):
id: Optional[int]
test_url: Optional[str]

View file

@ -1,32 +0,0 @@
import apprise
from mealie.schema.event_notifications import EventNotificationIn
from mealie.schema.events import Event
def post_notifications(event: Event, notification_dests=list[EventNotificationIn]):
# Create an Apprise instance
# discord = Discord(
# webhook_id="840358511842295829",
# webhook_token="EtcH6ACFM-qpHRkPw1TUTc_r8AiVMlKYhGEzlANvXj7SlGGFZt18dkYy96ayZHZ8HaI9",
# )
# Create our asset object
asset = apprise.AppriseAsset(async_mode=False)
# Create our object
apobj = apprise.Apprise(asset=asset)
# Add all of the notification services by their server url.
# A sample email notification:
for dest in notification_dests:
dest: EventNotificationIn
apobj.add(dest.notification_url)
# A sample pushbullet notification
# Then notify these services any time you desire. The below would
# notify all of the services loaded into our Apprise object.
apobj.notify(
body=event.text,
title=event.title,
)

View file

@ -1,17 +1,31 @@
import apprise
from mealie.db.database import db
from mealie.db.db_setup import create_session
from mealie.schema.events import Event, EventCategory
from mealie.services.event_notifications import post_notifications
from sqlalchemy.orm.session import Session
def post_notifications(event: Event, notification_urls=list[str]):
asset = apprise.AppriseAsset(async_mode=False)
apobj = apprise.Apprise(asset=asset)
for dest in notification_urls:
apobj.add(dest)
apobj.notify(
body=event.text,
title=event.title,
)
def save_event(title, text, category, session: Session):
event = Event(title=title, text=text, category=category)
session = session or create_session()
db.events.create(session, event.dict())
notification_objects = db.event_notifications.get(session=session, match_value=True, match_key=category, limit=9999)
post_notifications(event, notification_objects)
notification_urls = [x.notification_url for x in notification_objects]
post_notifications(event, notification_urls)
def create_general_event(title, text, session=None):