E-Mail template first steps
This commit is contained in:
parent
fc6c6179b8
commit
02947ce6e5
15
misc/notification_element.html
Normal file
15
misc/notification_element.html
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; box-sizing: border-box; width: 100%; min-width: 100%;" width="100%">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td align="left" style="font-family: Helvetica, sans-serif; font-size: 16px; vertical-align: top; padding-bottom: 16px;" valign="top">
|
||||||
|
<table role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: auto;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="font-family: Helvetica, sans-serif; font-size: 16px; vertical-align: top; border-radius: 4px; text-align: center; background-color: #0867ec;" valign="top" align="center" bgcolor="#0867ec"> <a href="https://www.bremen-calling.de" target="_blank" style="border: solid 2px #0867ec; border-radius: 4px; box-sizing: border-box; cursor: pointer; display: inline-block; font-size: 16px; font-weight: bold; margin: 0; padding: 12px 24px; text-decoration: none; text-transform: capitalize; background-color: #0867ec; border-color: #0867ec; color: #ffffff;">Call To Action</a> </td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
144
misc/notification_template.html
Normal file
144
misc/notification_template.html
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<title>Bremen calling Benachrichtigung</title>
|
||||||
|
<style media="all" type="text/css">
|
||||||
|
@media all {
|
||||||
|
.btn-primary table td:hover {
|
||||||
|
background-color: #ec0867 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a:hover {
|
||||||
|
background-color: #ec0867 !important;
|
||||||
|
border-color: #ec0867 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 640px) {
|
||||||
|
.main p,
|
||||||
|
.main td,
|
||||||
|
.main span {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
padding: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 0 !important;
|
||||||
|
padding-top: 8px !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
border-left-width: 0 !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
border-right-width: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table {
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn a {
|
||||||
|
font-size: 16px !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media all {
|
||||||
|
.ExternalClass {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ExternalClass,
|
||||||
|
.ExternalClass p,
|
||||||
|
.ExternalClass span,
|
||||||
|
.ExternalClass font,
|
||||||
|
.ExternalClass td,
|
||||||
|
.ExternalClass div {
|
||||||
|
line-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apple-link a {
|
||||||
|
color: inherit !important;
|
||||||
|
font-family: inherit !important;
|
||||||
|
font-size: inherit !important;
|
||||||
|
font-weight: inherit !important;
|
||||||
|
line-height: inherit !important;
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#MessageViewBody a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
font-weight: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body style="font-family: Helvetica, sans-serif; -webkit-font-smoothing: antialiased; font-size: 16px; line-height: 1.3; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; background-color: #f4f5f6; margin: 0; padding: 0;">
|
||||||
|
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; background-color: #f4f5f6; width: 100%;" width="100%" bgcolor="#f4f5f6">
|
||||||
|
<tr>
|
||||||
|
<td style="font-family: Helvetica, sans-serif; font-size: 16px; vertical-align: top;" valign="top"> </td>
|
||||||
|
<td class="container" style="font-family: Helvetica, sans-serif; font-size: 16px; vertical-align: top; max-width: 600px; padding: 0; padding-top: 24px; width: 600px; margin: 0 auto;" width="600" valign="top">
|
||||||
|
<div class="content" style="box-sizing: border-box; display: block; margin: 0 auto; max-width: 600px; padding: 0;">
|
||||||
|
|
||||||
|
<!-- START CENTERED WHITE CONTAINER -->
|
||||||
|
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">Benachrichtung von Bremen calling!</span>
|
||||||
|
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; background: #ffffff; border: 1px solid #eaebed; border-radius: 16px; width: 100%;" width="100%">
|
||||||
|
|
||||||
|
<!-- START MAIN CONTENT AREA -->
|
||||||
|
<tr>
|
||||||
|
<td class="wrapper" style="font-family: Helvetica, sans-serif; font-size: 16px; vertical-align: top; box-sizing: border-box; padding: 24px;" valign="top">
|
||||||
|
<p style="font-family: Helvetica, sans-serif; font-size: 16px; font-weight: normal; margin: 0; margin-bottom: 16px;">Hallo,</p>
|
||||||
|
<p style="font-family: Helvetica, sans-serif; font-size: 16px; font-weight: normal; margin: 0; margin-bottom: 16px;">Sie erhalten eine oder mehrere Benachrichtigungen von Bremen calling:</p>
|
||||||
|
|
||||||
|
<!--[[NOTIFICATION_ELEMENTS]]-->
|
||||||
|
|
||||||
|
<p style="font-family: Helvetica, sans-serif; font-size: 16px; font-weight: normal; margin: 0; margin-bottom: 16px;">Wenn Sie diese E-Mails nicht länger erhalten wollen, loggen Sie sich bitte in der Bremen Calling App ein. Im Bereich "Passwort ändern"
|
||||||
|
können Sie auch die Benachrichtungen anpassen.
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- END MAIN CONTENT AREA -->
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- START FOOTER -->
|
||||||
|
<div class="footer" style="clear: both; padding-top: 24px; text-align: center; width: 100%;">
|
||||||
|
<table role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;" width="100%">
|
||||||
|
<tr>
|
||||||
|
<td class="content-block" style="font-family: Helvetica, sans-serif; vertical-align: top; color: #9a9ea6; font-size: 16px; text-align: center;" valign="top" align="center">
|
||||||
|
<span class="apple-link" style="color: #9a9ea6; font-size: 16px; text-align: center;">Bremer Schiffsmeldedienst GbR - Hafenkopf II / Überseetor 20 - 28217 Bremen / Germany</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="content-block powered-by" style="font-family: Helvetica, sans-serif; vertical-align: top; color: #9a9ea6; font-size: 16px; text-align: center;" valign="top" align="center">
|
||||||
|
Kontaktieren Sie uns unter <a href="mailto:bremencalling@bsmd.de" style="color: #9a9ea6; font-size: 16px; text-align: center;">bremencalling@bsmd.de</a>.<br />
|
||||||
|
<a href="https://www.bsmd.de" style="color: #9a9ea6; font-size: 16px; text-align: center;">www.bsmd.de</a><br />
|
||||||
|
Tel.: +49 421 38 48 27
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- END FOOTER -->
|
||||||
|
|
||||||
|
<!-- END CENTERED WHITE CONTAINER --></div>
|
||||||
|
</td>
|
||||||
|
<td style="font-family: Helvetica, sans-serif; font-size: 16px; vertical-align: top;" valign="top"> </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -8,8 +8,8 @@ from .. import local_db
|
|||||||
from ..services.auth_guard import check_jwt
|
from ..services.auth_guard import check_jwt
|
||||||
|
|
||||||
from BreCal.database.update_database import evaluate_shipcall_state
|
from BreCal.database.update_database import evaluate_shipcall_state
|
||||||
from BreCal.database.sql_utils import get_notification_for_shipcall_and_type
|
from BreCal.database.sql_utils import get_notification_for_shipcall_and_type, get_ship_data_for_id
|
||||||
from BreCal.database.sql_queries import create_sql_query_shipcall_get, create_sql_query_shipcall_post, create_sql_query_shipcall_put, create_sql_query_history_post, create_sql_query_history_put, SQLQuery
|
from BreCal.database.sql_queries import create_sql_query_shipcall_get
|
||||||
from marshmallow import Schema, fields, ValidationError
|
from marshmallow import Schema, fields, ValidationError
|
||||||
from BreCal.validators.validation_error import create_validation_error_response
|
from BreCal.validators.validation_error import create_validation_error_response
|
||||||
|
|
||||||
@ -76,6 +76,7 @@ def PostShipcalls(schemaModel):
|
|||||||
commands = pydapper.using(pooledConnection)
|
commands = pydapper.using(pooledConnection)
|
||||||
|
|
||||||
# query = SQLQuery.get_shipcall_post(schemaModel) # create_sql_query_shipcall_post(schemaModel)
|
# query = SQLQuery.get_shipcall_post(schemaModel) # create_sql_query_shipcall_post(schemaModel)
|
||||||
|
|
||||||
query = "INSERT INTO shipcall ("
|
query = "INSERT INTO shipcall ("
|
||||||
isNotFirst = False
|
isNotFirst = False
|
||||||
for key in schemaModel.keys():
|
for key in schemaModel.keys():
|
||||||
@ -134,15 +135,26 @@ def PostShipcalls(schemaModel):
|
|||||||
# new_id = commands.execute_scalar(lquery)
|
# new_id = commands.execute_scalar(lquery)
|
||||||
new_id = commands.execute_scalar("select last_insert_id()")
|
new_id = commands.execute_scalar("select last_insert_id()")
|
||||||
|
|
||||||
|
shipdata = get_ship_data_for_id(schemaModel["ship_id"])
|
||||||
|
message = {shipdata['name']}
|
||||||
|
if "type_value" in schemaModel:
|
||||||
|
match schemaModel["type_value"]:
|
||||||
|
case 1:
|
||||||
|
message += " [ARRIVAL]"
|
||||||
|
case 2:
|
||||||
|
message += " [DEPARTURE]"
|
||||||
|
case 3:
|
||||||
|
message += " [SHIFTING]"
|
||||||
|
|
||||||
# add participant assignments if we have a list of participants
|
# add participant assignments if we have a list of participants
|
||||||
if 'participants' in schemaModel:
|
if 'participants' in schemaModel:
|
||||||
# pquery = SQLQuery.get_shipcall_post_update_shipcall_participant_map()
|
# pquery = SQLQuery.get_shipcall_post_update_shipcall_participant_map()
|
||||||
pquery = "INSERT INTO shipcall_participant_map (shipcall_id, participant_id, type) VALUES (?shipcall_id?, ?participant_id?, ?type?)"
|
pquery = "INSERT INTO shipcall_participant_map (shipcall_id, participant_id, type) VALUES (?shipcall_id?, ?participant_id?, ?type?)"
|
||||||
nquery = "INSERT INTO notification (shipcall_id, participant_id, level, type) VALUES (?shipcall_id?, ?participant_id?, 0, 1)" # type = 1 is assignment
|
nquery = "INSERT INTO notification (shipcall_id, participant_id, level, type, message) VALUES (?shipcall_id?, ?participant_id?, 0, 1, ?message?)" # type = 1 is assignment
|
||||||
|
|
||||||
for participant_assignment in schemaModel["participants"]:
|
for participant_assignment in schemaModel["participants"]:
|
||||||
commands.execute(pquery, param={"shipcall_id" : new_id, "participant_id" : participant_assignment["participant_id"], "type" : participant_assignment["type"]})
|
commands.execute(pquery, param={"shipcall_id" : new_id, "participant_id" : participant_assignment["participant_id"], "type" : participant_assignment["type"]})
|
||||||
commands.execute(nquery, param={"shipcall_id" : new_id, "participant_id" : participant_assignment["participant_id"]})
|
commands.execute(nquery, param={"shipcall_id" : new_id, "participant_id" : participant_assignment["participant_id"], "message" : message})
|
||||||
|
|
||||||
# apply 'Traffic Light' evaluation to obtain 'GREEN', 'YELLOW' or 'RED' evaluation state. The function internally updates the mysql database
|
# apply 'Traffic Light' evaluation to obtain 'GREEN', 'YELLOW' or 'RED' evaluation state. The function internally updates the mysql database
|
||||||
# evaluate_shipcall_state(mysql_connector_instance=pooledConnection, shipcall_id=new_id) # new_id (last insert id) refers to the shipcall id
|
# evaluate_shipcall_state(mysql_connector_instance=pooledConnection, shipcall_id=new_id) # new_id (last insert id) refers to the shipcall id
|
||||||
@ -189,8 +201,7 @@ def PutShipcalls(schemaModel):
|
|||||||
# test if object to update is found
|
# test if object to update is found
|
||||||
|
|
||||||
sentinel = object()
|
sentinel = object()
|
||||||
# query = SQLQuery.get_shipcall_by_id()
|
|
||||||
# theshipcall = commands.query_single_or_default(query, sentinel, param={"id" : schemaModel["id"]})
|
|
||||||
theshipcall = commands.query_single_or_default("SELECT * FROM shipcall where id = ?id?", sentinel, param={"id" : schemaModel["id"]})
|
theshipcall = commands.query_single_or_default("SELECT * FROM shipcall where id = ?id?", sentinel, param={"id" : schemaModel["id"]})
|
||||||
if theshipcall is sentinel:
|
if theshipcall is sentinel:
|
||||||
pooledConnection.close()
|
pooledConnection.close()
|
||||||
@ -230,6 +241,17 @@ def PutShipcalls(schemaModel):
|
|||||||
|
|
||||||
affected_rows = commands.execute(query, param=schemaModel)
|
affected_rows = commands.execute(query, param=schemaModel)
|
||||||
|
|
||||||
|
shipdata = get_ship_data_for_id(schemaModel["ship_id"])
|
||||||
|
message = {shipdata['name']}
|
||||||
|
if "type_value" in schemaModel:
|
||||||
|
match schemaModel["type_value"]:
|
||||||
|
case 1:
|
||||||
|
message += " [ARRIVAL]"
|
||||||
|
case 2:
|
||||||
|
message += " [DEPARTURE]"
|
||||||
|
case 3:
|
||||||
|
message += " [SHIFTING]"
|
||||||
|
|
||||||
# pquery = SQLQuery.get_shipcall_participant_map_by_shipcall_id()
|
# pquery = SQLQuery.get_shipcall_participant_map_by_shipcall_id()
|
||||||
pquery = "SELECT id, participant_id, type FROM shipcall_participant_map where shipcall_id = ?id?"
|
pquery = "SELECT id, participant_id, type FROM shipcall_participant_map where shipcall_id = ?id?"
|
||||||
pdata = commands.query(pquery,param={"id" : schemaModel["id"]}) # existing list of assignments
|
pdata = commands.query(pquery,param={"id" : schemaModel["id"]}) # existing list of assignments
|
||||||
@ -256,8 +278,8 @@ def PutShipcalls(schemaModel):
|
|||||||
found_notification = True
|
found_notification = True
|
||||||
break
|
break
|
||||||
if not found_notification:
|
if not found_notification:
|
||||||
nquery = "INSERT INTO notification (shipcall_id, participant_id, level, type) VALUES (?shipcall_id?, ?participant_id?, 0, 1)" # type = 1 is assignment
|
nquery = "INSERT INTO notification (shipcall_id, participant_id, level, type, message) VALUES (?shipcall_id?, ?participant_id?, 0, 1, ?message?)" # type = 1 is assignment
|
||||||
commands.execute(nquery, param={"shipcall_id" : schemaModel["id"], "participant_id" : participant_assignment["participant_id"]})
|
commands.execute(nquery, param={"shipcall_id" : schemaModel["id"], "participant_id" : participant_assignment["participant_id"], "message" : message})
|
||||||
|
|
||||||
# loop across existing pdata entries, deleting those not present in participant list
|
# loop across existing pdata entries, deleting those not present in participant list
|
||||||
for elem in pdata:
|
for elem in pdata:
|
||||||
@ -278,8 +300,8 @@ def PutShipcalls(schemaModel):
|
|||||||
commands.execute(nquery, param={"nid" : existing_notification["id"]})
|
commands.execute(nquery, param={"nid" : existing_notification["id"]})
|
||||||
else:
|
else:
|
||||||
# create un-assignment notification
|
# create un-assignment notification
|
||||||
nquery = "INSERT INTO notification (shipcall_id, participant_id, level, type) VALUES (?shipcall_id?, ?participant_id?, 0, 5)"
|
nquery = "INSERT INTO notification (shipcall_id, participant_id, level, type, message) VALUES (?shipcall_id?, ?participant_id?, 0, 5, ?message?)"
|
||||||
commands.execute(nquery, param={"shipcall_id" : schemaModel["id"], "participant_id" : elem["participant_id"]})
|
commands.execute(nquery, param={"shipcall_id" : schemaModel["id"], "participant_id" : elem["participant_id"], "message" : message})
|
||||||
break
|
break
|
||||||
|
|
||||||
# save history data
|
# save history data
|
||||||
|
|||||||
@ -4,8 +4,7 @@ import logging
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import schemas.defs as defs
|
from BreCal.schemas import defs
|
||||||
|
|
||||||
config_path = None
|
config_path = None
|
||||||
|
|
||||||
def initPool(instancePath, connection_filename="connection_data_devel.json"):
|
def initPool(instancePath, connection_filename="connection_data_devel.json"):
|
||||||
@ -14,7 +13,7 @@ def initPool(instancePath, connection_filename="connection_data_devel.json"):
|
|||||||
if(config_path == None):
|
if(config_path == None):
|
||||||
config_path = os.path.join(instancePath,f'../../../secure/{connection_filename}') #connection_data_devel.json');
|
config_path = os.path.join(instancePath,f'../../../secure/{connection_filename}') #connection_data_devel.json');
|
||||||
|
|
||||||
config_path = "E:/temp/connection_data.json"
|
config_path = "C:/temp/connection_data_devel.json"
|
||||||
print (config_path)
|
print (config_path)
|
||||||
|
|
||||||
if not os.path.exists(config_path):
|
if not os.path.exists(config_path):
|
||||||
@ -35,9 +34,13 @@ def initPool(instancePath, connection_filename="connection_data_devel.json"):
|
|||||||
|
|
||||||
credentials_file = "email_credentials_devel.json"
|
credentials_file = "email_credentials_devel.json"
|
||||||
credentials_path = os.path.join(instancePath,f'../../../secure/{credentials_file}')
|
credentials_path = os.path.join(instancePath,f'../../../secure/{credentials_file}')
|
||||||
|
|
||||||
|
credentials_path = "C:/temp/email_credentials_devel.json"
|
||||||
|
|
||||||
if not os.path.exists(credentials_path):
|
if not os.path.exists(credentials_path):
|
||||||
print ('cannot find ' + os.path.abspath(credentials_path))
|
print ('cannot find ' + os.path.abspath(credentials_path))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
f = open(credentials_path);
|
f = open(credentials_path);
|
||||||
defs.email_credentials = json.load(f)
|
defs.email_credentials = json.load(f)
|
||||||
f.close()
|
f.close()
|
||||||
|
|||||||
@ -552,6 +552,9 @@ class User:
|
|||||||
created: datetime
|
created: datetime
|
||||||
modified: datetime
|
modified: datetime
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(id)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Ship:
|
class Ship:
|
||||||
id: int
|
id: int
|
||||||
|
|||||||
@ -61,7 +61,7 @@ def UpdateNotifications():
|
|||||||
pooledConnection = getPoolConnection()
|
pooledConnection = getPoolConnection()
|
||||||
commands = pydapper.using(pooledConnection)
|
commands = pydapper.using(pooledConnection)
|
||||||
|
|
||||||
query = "SELECT * FROM notification WHERE level = 0 AND created < DATE(NOW() - INTERVAL 10 MINUTE)"
|
query = "SELECT * FROM notification WHERE level = 0 AND created < TIMESTAMP(NOW() - INTERVAL 10 MINUTE)"
|
||||||
data = commands.query(query, model=model.Notification)
|
data = commands.query(query, model=model.Notification)
|
||||||
for notification in data:
|
for notification in data:
|
||||||
commands.execute("UPDATE notification SET level = 1 WHERE id = ?id?", param={"id":notification.id})
|
commands.execute("UPDATE notification SET level = 1 WHERE id = ?id?", param={"id":notification.id})
|
||||||
@ -75,7 +75,7 @@ def SendEmails(email_dict):
|
|||||||
This function sends emails to all users in the emaildict
|
This function sends emails to all users in the emaildict
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
conn = smtplib.SMTP_SSL(defs.email_credentials["server"], defs.email_credentials["port"])
|
conn = smtplib.SMTP(defs.email_credentials["server"], defs.email_credentials["port"])
|
||||||
conn.set_debuglevel(1)
|
conn.set_debuglevel(1)
|
||||||
conn.ehlo()
|
conn.ehlo()
|
||||||
conn.starttls()
|
conn.starttls()
|
||||||
@ -91,12 +91,13 @@ def SendEmails(email_dict):
|
|||||||
# TODO: pretty-print and format message according to template
|
# TODO: pretty-print and format message according to template
|
||||||
msg.set_content(message)
|
msg.set_content(message)
|
||||||
|
|
||||||
conn.sendmail(user.user_email, user.user_email, msg.as_string())
|
conn.sendmail(defs.email_credentials["sender"], user.user_email, msg.as_string())
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
finally:
|
finally:
|
||||||
conn.quit()
|
if conn is not None:
|
||||||
|
conn.quit()
|
||||||
|
|
||||||
|
|
||||||
def SendNotifications():
|
def SendNotifications():
|
||||||
@ -134,22 +135,24 @@ def SendNotifications():
|
|||||||
for user in users:
|
for user in users:
|
||||||
# send notification to user
|
# send notification to user
|
||||||
if user.notify_email:
|
if user.notify_email:
|
||||||
|
if user not in email_dict:
|
||||||
|
email_dict[user] = ""
|
||||||
match notification.type:
|
match notification.type:
|
||||||
case 1: # assignment
|
case 1: # assignment
|
||||||
email_dict[user] += "\n"
|
email_dict[user] += "\n"
|
||||||
email_dict[user] += "You have been assigned to a new shipcall: " + notification.message
|
email_dict[user] += "You have been assigned to a new shipcall: " + str(notification.message or "")
|
||||||
case 2: # next 24 hours
|
case 2: # next 24 hours
|
||||||
email_dict[user] += "\n"
|
email_dict[user] += "\n"
|
||||||
email_dict[user] += "A shipcall is scheduled for the next 24 hours: " + notification.message
|
email_dict[user] += "A shipcall is scheduled for the next 24 hours: " + str(notification.message or "")
|
||||||
case 3: # Time conflict
|
case 3: # Time conflict
|
||||||
email_dict[user] += "\n"
|
email_dict[user] += "\n"
|
||||||
email_dict[user] += "There is a time conflict in a shipcall: " + notification.message
|
email_dict[user] += "There is a time conflict in a shipcall: " + str(notification.message or "")
|
||||||
case 4: # Time conflict resolved
|
case 4: # Time conflict resolved
|
||||||
email_dict[user] += "\n"
|
email_dict[user] += "\n"
|
||||||
email_dict[user] += "A time conflict in a shipcall has been resolved: " + notification.message
|
email_dict[user] += "A time conflict in a shipcall has been resolved: " + str(notification.message or "")
|
||||||
case 5: # unassigned
|
case 5: # unassigned
|
||||||
email_dict[user] += "\n"
|
email_dict[user] += "\n"
|
||||||
email_dict[user] += "You have been unassigned from a shipcall: " + notification.message
|
email_dict[user] += "You have been unassigned from a shipcall: " + str(notification.message or "")
|
||||||
if user.notify_whatsapp:
|
if user.notify_whatsapp:
|
||||||
# TBD
|
# TBD
|
||||||
pass
|
pass
|
||||||
@ -161,10 +164,13 @@ def SendNotifications():
|
|||||||
|
|
||||||
# send emails (if any)
|
# send emails (if any)
|
||||||
if len(email_dict) > 0:
|
if len(email_dict) > 0:
|
||||||
SendEmails(email_dict)
|
SendEmails(email_dict)
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
|
finally:
|
||||||
|
if pooledConnection is not None:
|
||||||
|
pooledConnection.close()
|
||||||
|
|
||||||
def add_function_to_schedule__update_shipcalls(interval_in_minutes:int, options:dict={'past_days':2}):
|
def add_function_to_schedule__update_shipcalls(interval_in_minutes:int, options:dict={'past_days':2}):
|
||||||
kwargs_ = {"options":options}
|
kwargs_ = {"options":options}
|
||||||
@ -207,6 +213,10 @@ def eval_next_24_hrs():
|
|||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
if pooledConnection is not None:
|
||||||
|
pooledConnection.close()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def setup_schedule(update_shipcalls_interval_in_minutes:int=60):
|
def setup_schedule(update_shipcalls_interval_in_minutes:int=60):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user