2024-04-16 16:07:48 -03:00
|
|
|
import datetime
|
|
|
|
|
|
|
|
from router_manager.models import Router
|
|
|
|
from .models import MessageChannel, Notification, MessageSettings, Message
|
|
|
|
from backup_data.models import RouterBackup
|
|
|
|
import requests
|
|
|
|
from django.utils import timezone
|
|
|
|
|
|
|
|
|
2024-04-17 14:17:37 -03:00
|
|
|
def concatenate_notifications(notification_type: str):
|
|
|
|
concatenate_count = 0
|
|
|
|
message_settings, _ = MessageSettings.objects.get_or_create(name='message_settings')
|
|
|
|
message_channel_list = MessageChannel.objects.filter(enabled=True)
|
|
|
|
if notification_type == 'status_online':
|
|
|
|
notification_text = 'Router status change: Online\n'
|
|
|
|
notification_list = Notification.objects.filter(notification_type='status_online')
|
|
|
|
message_channel_list = message_channel_list.filter(status_change_online=True)
|
|
|
|
elif notification_type == 'status_offline':
|
|
|
|
notification_text = 'Router status change: Offline\n'
|
|
|
|
notification_list = Notification.objects.filter(notification_type='status_offline')
|
|
|
|
message_channel_list = message_channel_list.filter(status_change_offline=True)
|
|
|
|
elif notification_type == 'backup_fail':
|
|
|
|
notification_text = 'Backup failed report\n'
|
|
|
|
notification_list = Notification.objects.filter(notification_type='backup_fail')
|
|
|
|
message_channel_list = message_channel_list.filter(backup_fail=True)
|
|
|
|
else:
|
|
|
|
return 0
|
|
|
|
|
|
|
|
notification_list = notification_list.order_by('created')
|
|
|
|
for notification in notification_list:
|
|
|
|
notification_text_temp = notification_text
|
|
|
|
if notification.router_backup:
|
|
|
|
notification_text_temp += f'\n- Backup: {notification.router_backup.id} for router {notification.router_backup.router.name} '
|
|
|
|
elif notification.router:
|
|
|
|
notification_text_temp += f'\n- Router {notification.router.name} ({notification.router.address})'
|
|
|
|
if len(notification_text_temp) < message_settings.max_length:
|
|
|
|
notification_text = notification_text_temp
|
|
|
|
notification.delete()
|
|
|
|
concatenate_count += 1
|
|
|
|
else:
|
|
|
|
break
|
|
|
|
|
|
|
|
for message_channel in message_channel_list:
|
|
|
|
Message.objects.create(
|
|
|
|
channel=message_channel,
|
|
|
|
subject=notification_text.split('\n')[0],
|
|
|
|
message=notification_text
|
|
|
|
)
|
|
|
|
return concatenate_count
|
|
|
|
|
|
|
|
|
|
|
|
def generate_backup_report(data):
|
|
|
|
message_settings, _ = MessageSettings.objects.get_or_create(name='message_settings')
|
|
|
|
yesterday = timezone.now() - datetime.timedelta(days=1)
|
|
|
|
failed_backup_list = RouterBackup.objects.filter(error=True, updated__gt=yesterday)
|
|
|
|
success_backup_list = RouterBackup.objects.filter(success=True, updated__gt=yesterday)
|
|
|
|
pending_backup_list = RouterBackup.objects.filter(success=False, error=False, updated__gt=yesterday)
|
|
|
|
if data['report_time_exception']:
|
|
|
|
message_text = 'Warning: Error calculating report time, please check your timezone settings.\n\n'
|
|
|
|
else:
|
|
|
|
message_text = ''
|
|
|
|
message_text = 'Routerfleet Daily backup report:\n'
|
|
|
|
message_text += f'Backups completed: {success_backup_list.count()}\n'
|
|
|
|
message_text += f'Backups failed: {failed_backup_list.count()}\n'
|
|
|
|
message_text += f'Backups pending: {pending_backup_list.count()}\n'
|
|
|
|
|
|
|
|
if failed_backup_list.count() > 0:
|
|
|
|
message_text += '\n=========\n Failed backups:\n'
|
|
|
|
message_text_temp = message_text
|
|
|
|
truncate_text = 'There are more failed backups, please check the web interface for the full list\n\n'
|
|
|
|
for backup in failed_backup_list:
|
|
|
|
message_text_temp += f'- Backup {backup.id} for router {backup.router.name} ({backup.router.address})\n'
|
|
|
|
if len(message_text_temp + truncate_text) < message_settings.max_length:
|
|
|
|
message_text = message_text_temp
|
|
|
|
else:
|
|
|
|
message_text += truncate_text
|
|
|
|
break
|
|
|
|
for message_channel in MessageChannel.objects.filter(enabled=True, daily_backup_report=True):
|
|
|
|
Message.objects.create(
|
|
|
|
channel=message_channel,
|
|
|
|
subject='Daily backup report',
|
|
|
|
message=message_text
|
|
|
|
)
|
2024-04-18 09:10:38 -03:00
|
|
|
message_settings.last_daily_backup_report = timezone.now()
|
|
|
|
message_settings.save()
|
2024-04-17 14:17:37 -03:00
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def generate_status_report(data):
|
|
|
|
message_settings, _ = MessageSettings.objects.get_or_create(name='message_settings')
|
|
|
|
router_list = Router.objects.filter(enabled=True, monitoring=True)
|
|
|
|
offline_count = router_list.filter(routerstatus__status_online=False).count()
|
|
|
|
if data['report_time_exception']:
|
|
|
|
message_text = 'Warning: Error calculating report time, please check your timezone settings.\n\n'
|
|
|
|
else:
|
|
|
|
message_text = ''
|
|
|
|
message_text += 'Routerfleet Daily status report:\n'
|
|
|
|
message_text += f'Monitored routers: {router_list.count()}\n'
|
|
|
|
message_text += f'Online: {router_list.filter(routerstatus__status_online=True).count()}\n'
|
|
|
|
message_text += f'Offline: {offline_count}\n'
|
|
|
|
|
|
|
|
if offline_count > 0:
|
|
|
|
message_text += '\n=========\n Offline routers:\n'
|
|
|
|
message_text_temp = message_text
|
|
|
|
truncate_text = 'There are more offline routers, please check the web interface for the full list\n\n'
|
|
|
|
for router in router_list.filter(routerstatus__status_online=False):
|
|
|
|
message_text_temp += f'- {router.name} ({router.address})\n'
|
|
|
|
if len(message_text_temp + truncate_text) < message_settings.max_length:
|
|
|
|
message_text = message_text_temp
|
|
|
|
else:
|
|
|
|
message_text += truncate_text
|
|
|
|
break
|
|
|
|
|
|
|
|
message_channel_list = MessageChannel.objects.filter(enabled=True, daily_status_report=True)
|
|
|
|
for message_channel in message_channel_list:
|
|
|
|
Message.objects.create(
|
|
|
|
channel=message_channel,
|
|
|
|
subject='Daily status report',
|
|
|
|
message=message_text
|
|
|
|
)
|
|
|
|
message_settings.last_daily_status_report = timezone.now()
|
|
|
|
message_settings.save()
|
|
|
|
return
|
|
|
|
|
|
|
|
|
2024-04-16 16:07:48 -03:00
|
|
|
def send_notification_message(message: Message):
|
|
|
|
message_settings, _ = MessageSettings.objects.get_or_create(name='message_settings')
|
|
|
|
if message.status != 'pending':
|
|
|
|
return
|
|
|
|
if message.retry_count > message_settings.max_retry:
|
|
|
|
message.status = 'failed'
|
|
|
|
message.completed = timezone.now()
|
|
|
|
message.save()
|
|
|
|
return
|
|
|
|
|
|
|
|
message_response = {'status': 'pending', 'error_message': '', 'error_status_code': 0}
|
|
|
|
if message.channel.channel_type == 'callmebot':
|
|
|
|
url = f'https://api.callmebot.com/whatsapp.php?phone={message.channel.destination}&text={message.message}&apikey={message.channel.token}'
|
|
|
|
elif message.channel.channel_type == 'telegram':
|
|
|
|
url = f'https://api.telegram.org/bot{message.channel.token}/sendMessage?chat_id={message.channel.destination}&text={message.message}'
|
|
|
|
else:
|
|
|
|
message_response['status'] = 'failed'
|
|
|
|
message_response['error_message'] = 'Failed to send message: Invalid channel type'
|
|
|
|
message_response['error_status_code'] = 0
|
|
|
|
|
|
|
|
if message_response['status'] == 'pending':
|
|
|
|
try:
|
|
|
|
response = requests.get(url)
|
|
|
|
if response.status_code == 200:
|
|
|
|
message_response['status'] = 'sent'
|
|
|
|
else:
|
|
|
|
message_response['status'] = 'failed'
|
|
|
|
message_response['error_message'] = response.text
|
|
|
|
message_response['error_status_code'] = response.status_code
|
|
|
|
except:
|
|
|
|
message_response['status'] = 'failed'
|
|
|
|
message_response['error_message'] = 'Failed to send message: Request exception'
|
|
|
|
message_response['error_status_code'] = 0
|
|
|
|
|
|
|
|
if message_response['status'] == 'sent':
|
|
|
|
message.status = 'sent'
|
|
|
|
message.completed = timezone.now()
|
|
|
|
message.save()
|
|
|
|
else:
|
|
|
|
message.retry_count += 1
|
|
|
|
message.error_message = message_response['error_message']
|
|
|
|
message.error_status_code = message_response['error_status_code']
|
|
|
|
message.next_retry = timezone.now() + datetime.timedelta(seconds=message_settings.retry_interval)
|
|
|
|
message.save()
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def notify_router_status_update(router: Router):
|
|
|
|
message_channel_list = MessageChannel.objects.filter(enabled=True)
|
|
|
|
message_settings, _ = MessageSettings.objects.get_or_create(name='message_settings')
|
|
|
|
|
|
|
|
if message_settings.concatenate_status_change:
|
|
|
|
if router.routerstatus.status_online:
|
|
|
|
if message_channel_list.filter(status_change_online=True):
|
|
|
|
Notification.objects.create(notification_type='status_online', router=router)
|
|
|
|
else:
|
|
|
|
if message_channel_list.filter(status_change_offline=True):
|
|
|
|
Notification.objects.create(notification_type='status_offline', router=router)
|
|
|
|
else:
|
|
|
|
if router.routerstatus.status_online:
|
|
|
|
for message_channel in message_channel_list.filter(status_change_online=True):
|
|
|
|
Message.objects.create(
|
|
|
|
channel=message_channel,
|
|
|
|
subject='Router status change: Online',
|
|
|
|
message=f'Router {router.name} ({router.address}) is now online'
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
for message_channel in message_channel_list.filter(status_change_offline=True):
|
|
|
|
Message.objects.create(
|
|
|
|
channel=message_channel,
|
|
|
|
subject='Router status change: Offline',
|
|
|
|
message=f'Router {router.name} ({router.address}) is now offline'
|
|
|
|
)
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def notify_backup_fail(router_backup: RouterBackup):
|
|
|
|
message_settings, _ = MessageSettings.objects.get_or_create(name='message_settings')
|
|
|
|
message_channel_list = MessageChannel.objects.filter(enabled=True, backup_fail=True)
|
|
|
|
|
|
|
|
if not message_channel_list:
|
|
|
|
return
|
|
|
|
|
|
|
|
if message_settings.concatenate_backup_fails:
|
|
|
|
Notification.objects.create(notification_type='backup_fail', router=router_backup.router, router_backup=router_backup)
|
|
|
|
else:
|
|
|
|
error_message = f'Backup {router_backup.id} failed for router {router_backup.router.name} ({router_backup.router.address})'
|
|
|
|
if router_backup.error_message:
|
|
|
|
error_message += f'\n\nError message: {router_backup.error_message}'
|
|
|
|
for message_channel in message_channel_list:
|
|
|
|
Message.objects.create(
|
|
|
|
channel=message_channel,
|
|
|
|
subject=f'Backup failed: {router_backup.id}',
|
|
|
|
message=error_message
|
|
|
|
)
|
|
|
|
return
|