Skip to content

Commit 1bb2408

Browse files
author
[Arusey]
committed
CON-72-story(notifications): admin receives notification when device is not seen in a while
- setup queue manager for when notifications are sent - implement notifications when device is not seen in a while [Delivers CON-72]
1 parent c23c551 commit 1bb2408

File tree

9 files changed

+111
-12
lines changed

9 files changed

+111
-12
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from flask_socketio import send, emit
2+
from admin_notifications.models import AdminNotification
3+
from manage import socketio
4+
import celery
5+
6+
7+
@celery.task(name="create-notification")
8+
def create_notification(title, message, location_id):
9+
notification = AdminNotification(
10+
title=title,
11+
message=message,
12+
location_id=location_id,
13+
status="unread"
14+
)
15+
notification.save()
16+
new_notification = {"title": title, "message": message}
17+
return socketio.emit('notification', {'notification': new_notification}, broadcast=True)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from datetime import datetime
2+
from api.devices.models import Devices as DevicesModel
3+
from utilities.utility import update_entity_fields
4+
import celery
5+
6+
7+
@celery.task(name='check-device-last-seen')
8+
def notify_when_device_is_offline(**kwargs):
9+
query = DevicesModel.query
10+
online_devices = query.filter(DevicesModel.activity == "online").all()
11+
for device in online_devices:
12+
device_last_seen = device.last_seen
13+
current_time = datetime.now()
14+
duration_offline = current_time - device_last_seen
15+
16+
if duration_offline.days > 1:
17+
update_entity_fields(device, activity="offline")
18+
device.save()
19+
return online_devices
20+
21+
22+
def notify(**kwargs):
23+
query = DevicesModel.query
24+
offline_device = query.filter(DevicesModel.activity == "offline").first()
25+
if offline_device:
26+
pass
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from datetime import timedelta
2+
beat_schedule = {
3+
'run-check-device-last-seen-hourly': {
4+
'task': 'check-device-last-seen',
5+
'schedule': timedelta(seconds=5)
6+
}
7+
}

admin_notifications/models.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
from sqlalchemy import (Column, String, Enum, Integer, ForeignKey)
2-
from sqlalchemy.schema import Sequence
3-
from utilities.validations import validate_empty_fields
42
from helpers.database import Base
53
from utilities.utility import Utility, StatusType
64

@@ -17,6 +15,4 @@ class AdminNotification(Base, Utility):
1715
location_id = Column(
1816
Integer,
1917
ForeignKey('locations.id', ondelete="CASCADE"),
20-
nullable=True
21-
)
22-
18+
nullable=True)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""add activity column to devices table
2+
3+
Revision ID: 1b53553ddacf
4+
Revises: c65718cd4ed8
5+
Create Date: 2019-06-22 12:59:24.591339
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
from sqlalchemy.dialects import postgresql
11+
12+
13+
# revision identifiers, used by Alembic.
14+
revision = '1b53553ddacf'
15+
down_revision = 'c65718cd4ed8'
16+
branch_labels = None
17+
depends_on = None
18+
19+
20+
def upgrade():
21+
# ### commands auto generated by Alembic - please adjust! ###
22+
activitytype = postgresql.ENUM('online', 'offline', name='activitytype')
23+
activitytype.create(op.get_bind())
24+
op.add_column('devices', sa.Column('activity', sa.Enum(
25+
'online', 'offline', name='activitytype'), nullable=True))
26+
27+
# ### end Alembic commands ###
28+
29+
30+
def downgrade():
31+
# ### commands auto generated by Alembic - please adjust! ###
32+
op.drop_column('devices', 'activity')
33+
op.execute("DROP TYPE activitytype;")
34+
# ### end Alembic commands ###

api/devices/models.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
1-
from sqlalchemy import (Column, String, Integer, DateTime, ForeignKey)
1+
from sqlalchemy import (Column, String, Integer, DateTime, ForeignKey, Enum)
22
from sqlalchemy.schema import Sequence
33
from sqlalchemy.orm import relationship
44

55
from helpers.database import Base
66
from utilities.validations import validate_empty_fields
7-
from utilities.utility import Utility
7+
from utilities.utility import Utility, ActivityType
88

99

1010
class Devices(Base, Utility):
1111
__tablename__ = 'devices'
12-
id = Column(Integer, Sequence('devices_id_seq', start=1, increment=1), primary_key=True) # noqa
12+
id = Column(Integer, Sequence('devices_id_seq', start=1, increment=1), primary_key=True) # noqa
1313
name = Column(String, nullable=False)
1414
device_type = Column(String, nullable=False)
1515
date_added = Column(DateTime, nullable=False)
1616
last_seen = Column(DateTime, nullable=False)
1717
location = Column(String, nullable=False)
1818
room_id = Column(Integer, ForeignKey('rooms.id', ondelete="CASCADE"))
1919
room = relationship('Room')
20+
activity = Column(Enum(ActivityType), default="active")
2021

2122
def __init__(self, **kwargs):
2223
validate_empty_fields(**kwargs)

cworker.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
import os
2-
32
from celery import Celery
43
from app import create_app
5-
4+
from admin_notifications.helpers.queue_manager import beat_schedule
65

76
app = create_app(os.getenv('APP_SETTINGS') or 'default')
87
app.app_context().push()
98

109

10+
app.config.update(
11+
CELERY_BROKER_URL='redis://localhost:6379',
12+
CELERY_RESULT_BACKEND='redis://localhost:6379',
13+
CELERY_ACCEPT_CONTENT=['pickle'],
14+
CELERYBEAT_SCHEDULE=beat_schedule
15+
)
16+
17+
1118
def make_celery(app):
12-
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
19+
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'], include=['admin_notifications.helpers.device_last_seen', 'admin_notifications.helpers.create_notification'], # noqa 501
20+
backend=app.config['CELERY_BROKER_URL'])
21+
1322
celery.conf.update(app.config)
23+
celery.conf.enable_utc = False
1424
TaskBase = celery.Task
1525

1626
class ContextTask(TaskBase):
@@ -24,3 +34,5 @@ def __call__(self, *args, **kwargs):
2434

2535

2636
celery = make_celery(app)
37+
celery_scheduler = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
38+
celery_scheduler.conf.update(app.config)

helpers/email/email_setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def __init__(
3030
html=self.template,
3131
sender=self.sender)
3232

33-
@celery.task
33+
@celery.task(name='asynchronous-email-notifications')
3434
def send_async_email(msg_dict):
3535
mail = Mail()
3636
msg = Message()

utilities/utility.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ class QuestionType(enum.Enum):
8989
missingitem = "missing_items"
9090

9191

92+
9293
class StatusType(enum.Enum):
9394
read = "read"
9495
unread = "unread"
96+
97+
98+
class ActivityType(enum.Enum):
99+
online = "online"
100+
offline = "offline"

0 commit comments

Comments
 (0)