Compare commits

..

No commits in common. "211afa39668a494a02064b829dc931471c333e38" and "93e9a1990a4634af6ae66f841e25edcbbfacba31" have entirely different histories.

7 changed files with 46 additions and 63 deletions

View File

@ -1,5 +1,5 @@
[tool.bumpversion] [tool.bumpversion]
current_version = "1.2.19" current_version = "1.2.18"
commit = true commit = true
tag = true tag = true
tag_name = "{new_version}" tag_name = "{new_version}"

View File

@ -1 +1 @@
1.2.19 1.2.18

View File

@ -3,7 +3,7 @@ import sys
from dotenv import load_dotenv from dotenv import load_dotenv
import mysql.connector import mysql.connector
from datetime import datetime, timedelta from datetime import datetime, timedelta
from ktvmanager.lib.notifications import send_notification from routes.api import send_notification
from ktvmanager.lib.database import get_push_subscriptions, _execute_query from ktvmanager.lib.database import get_push_subscriptions, _execute_query
# Add the project root to the Python path # Add the project root to the Python path
@ -33,11 +33,10 @@ def get_all_accounts(db_connection: MySQLConnection) -> List[Dict[str, Any]]:
return accounts return accounts
def send_expiry_notifications(app) -> None: def send_expiry_notifications() -> None:
""" """
Sends notifications to users with accounts expiring in the next 30 days. Sends notifications to users with accounts expiring in the next 30 days.
""" """
with app.app_context():
now = datetime.now() now = datetime.now()
thirty_days_later = now + timedelta(days=30) thirty_days_later = now + timedelta(days=30)
now_timestamp = int(now.timestamp()) now_timestamp = int(now.timestamp())
@ -52,10 +51,6 @@ def send_expiry_notifications(app) -> None:
expiring_accounts = _execute_query(query, (now_timestamp, thirty_days_later_timestamp)) expiring_accounts = _execute_query(query, (now_timestamp, thirty_days_later_timestamp))
for account in expiring_accounts: for account in expiring_accounts:
expiry_date = datetime.fromtimestamp(account['expiaryDate'])
days_to_expiry = (expiry_date - now).days
if days_to_expiry == 30 or days_to_expiry == 7:
user_id = account['user_id'] user_id = account['user_id']
subscriptions = get_push_subscriptions(user_id) subscriptions = get_push_subscriptions(user_id)
for sub in subscriptions: for sub in subscriptions:
@ -64,10 +59,10 @@ def send_expiry_notifications(app) -> None:
last_notified_result = _execute_query(last_notified_query, (sub['id'],)) last_notified_result = _execute_query(last_notified_query, (sub['id'],))
last_notified = last_notified_result[0]['last_notified'] if last_notified_result and last_notified_result[0]['last_notified'] else None last_notified = last_notified_result[0]['last_notified'] if last_notified_result and last_notified_result[0]['last_notified'] else None
if last_notified and last_notified.date() == now.date(): if last_notified and last_notified > now - timedelta(days=1):
continue continue
message = f"Your account {account['username']} is due to expire in {days_to_expiry} days." message = f"Your account {account['username']} is due to expire on {datetime.fromtimestamp(account['expiaryDate']).strftime('%d-%m-%Y')}."
send_notification(sub['subscription_json'], message) send_notification(sub['subscription_json'], message)
# Update the last notified timestamp # Update the last notified timestamp

View File

@ -1,17 +0,0 @@
from flask import current_app
from pywebpush import webpush, WebPushException
def send_notification(subscription_info, message_body):
try:
webpush(
subscription_info=subscription_info,
data=message_body,
vapid_private_key=current_app.config["VAPID_PRIVATE_KEY"],
vapid_claims={"sub": current_app.config["VAPID_CLAIM_EMAIL"]},
)
except WebPushException as ex:
print(f"Web push error: {ex}")
# You might want to remove the subscription if it's invalid
if ex.response and ex.response.status_code == 410:
print("Subscription is no longer valid, removing from DB.")
# Add logic to remove the subscription from your database

View File

@ -4,8 +4,6 @@ from dotenv import load_dotenv
from ktvmanager.config import DevelopmentConfig, ProductionConfig from ktvmanager.config import DevelopmentConfig, ProductionConfig
from routes.api import api_blueprint from routes.api import api_blueprint
from ktvmanager.lib.database import initialize_db_pool from ktvmanager.lib.database import initialize_db_pool
from ktvmanager.account_checker import send_expiry_notifications
from apscheduler.schedulers.background import BackgroundScheduler
def create_app(): def create_app():
app = Flask(__name__) app = Flask(__name__)
@ -19,12 +17,6 @@ def create_app():
with app.app_context(): with app.app_context():
initialize_db_pool() initialize_db_pool()
# Schedule the daily account check
scheduler = BackgroundScheduler()
# Pass the app instance to the job
scheduler.add_job(func=lambda: send_expiry_notifications(app), trigger="interval", days=1)
scheduler.start()
# Register blueprints # Register blueprints
app.register_blueprint(api_blueprint) app.register_blueprint(api_blueprint)

View File

@ -39,4 +39,3 @@ python-dotenv
python-dotenv python-dotenv
pywebpush==1.13.0 pywebpush==1.13.0
stem==1.8.2 stem==1.8.2
APScheduler==3.10.4

View File

@ -18,7 +18,7 @@ import re
import base64 import base64
from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.asymmetric import ec
from ktvmanager.lib.notifications import send_notification from pywebpush import webpush, WebPushException
api_blueprint = Blueprint("api", __name__) api_blueprint = Blueprint("api", __name__)
@ -196,6 +196,20 @@ def save_subscription(username: str, password: str) -> Response:
return jsonify({"message": "Subscription saved."}) return jsonify({"message": "Subscription saved."})
def send_notification(subscription_info, message_body):
try:
webpush(
subscription_info=subscription_info,
data=message_body,
vapid_private_key=current_app.config["VAPID_PRIVATE_KEY"],
vapid_claims={"sub": current_app.config["VAPID_CLAIM_EMAIL"]},
)
except WebPushException as ex:
print(f"Web push error: {ex}")
# You might want to remove the subscription if it's invalid
if ex.response and ex.response.status_code == 410:
print("Subscription is no longer valid, removing from DB.")
# Add logic to remove the subscription from your database
@api_blueprint.route("/send-expiry-notifications", methods=["POST"]) @api_blueprint.route("/send-expiry-notifications", methods=["POST"])