148 lines
6.4 KiB
Python
148 lines
6.4 KiB
Python
from flask import Blueprint, render_template, request, redirect, url_for, flash, make_response, jsonify, abort
|
|
from app.models.messages import Message
|
|
from app.util import auth, turnstile, websiteFeatures
|
|
from app.extensions import db, csrf, limiter, redis_controller
|
|
from app.models.user import User
|
|
from app.util.textfilter import FilterText
|
|
from sqlalchemy import or_
|
|
|
|
MessageRoute = Blueprint('message', __name__, template_folder="pages")
|
|
|
|
def CreateSystemMessage( subject : str, message : str, userid : int ):
|
|
"""
|
|
Creates a system message from the system user to the specified user
|
|
"""
|
|
TargetUser = User.query.filter_by(id=userid).first()
|
|
if TargetUser is None:
|
|
return False
|
|
NewMessage : Message = Message(
|
|
subject=subject,
|
|
content=message,
|
|
sender_id=1,
|
|
recipient_id=userid
|
|
)
|
|
db.session.add(NewMessage)
|
|
db.session.commit()
|
|
return True
|
|
|
|
@MessageRoute.route("/my/messages", methods=["GET"])
|
|
@auth.authenticated_required
|
|
def my_messages():
|
|
return redirect("/messages")
|
|
|
|
@MessageRoute.route("/new/<userid>", methods=["GET"])
|
|
@auth.authenticated_required
|
|
def new_message(userid):
|
|
TargetUser = User.query.filter_by(id=userid).first()
|
|
if TargetUser is None:
|
|
return "User not found",404
|
|
if TargetUser.accountstatus == 4 or TargetUser.accountstatus == 3:
|
|
abort(404)
|
|
|
|
AuthenticatedUser = auth.GetCurrentUser()
|
|
if AuthenticatedUser.id == TargetUser.id:
|
|
return "You cannot message yourself",400
|
|
|
|
MessageReplyContext = request.args.get("reply", default=None, type=int)
|
|
if MessageReplyContext is not None:
|
|
ReplyMessage = Message.query.filter_by( id = MessageReplyContext ).filter( or_( Message.sender_id == AuthenticatedUser.id, Message.recipient_id == AuthenticatedUser.id ) ).first()
|
|
else:
|
|
ReplyMessage = None
|
|
|
|
return render_template("messages/new.html", targetuser=TargetUser, replymessage=ReplyMessage)
|
|
|
|
@MessageRoute.route("/new/<userid>", methods=["POST"])
|
|
@auth.authenticated_required
|
|
@limiter.limit("10/minute")
|
|
def send_message(userid):
|
|
if 'cf-turnstile-response' not in request.form or request.form.get('cf-turnstile-response') == '':
|
|
flash("Please complete the captcha", "error")
|
|
return redirect(f"/messages/new/{userid}")
|
|
if 'message' not in request.form or request.form.get('message') == '':
|
|
flash("Please enter a message", "error")
|
|
return redirect(f"/messages/new/{userid}")
|
|
if 'subject' not in request.form or request.form.get('subject') == '':
|
|
flash("Please enter a subject", "error")
|
|
return redirect(f"/messages/new/{userid}")
|
|
if not websiteFeatures.GetWebsiteFeature("MessageSending"):
|
|
flash("Message sending is temporarily disabled", "error")
|
|
return redirect(f"/messages/new/{userid}")
|
|
TargetUser : User | None = User.query.filter_by(id=userid).first()
|
|
if TargetUser is None:
|
|
abort(404)
|
|
if TargetUser.accountstatus == 4 or TargetUser.accountstatus == 3:
|
|
abort(404)
|
|
|
|
AuthenticatedUser = auth.GetCurrentUser()
|
|
if AuthenticatedUser.id == TargetUser.id:
|
|
abort(400)
|
|
|
|
if len(request.form.get("message")) > 1024:
|
|
flash("Your message is too long", "error")
|
|
return redirect(f"/messages/new/{TargetUser.id}")
|
|
if len(request.form.get('subject')) > 64:
|
|
flash("Your subject is too long", "error")
|
|
return redirect(f"/messages/new/{TargetUser.id}")
|
|
|
|
if not turnstile.VerifyToken(request.form.get('cf-turnstile-response')):
|
|
flash("Invalid captcha", "error")
|
|
return redirect(f"/messages/new/{TargetUser.id}")
|
|
if redis_controller.get(f"message:{TargetUser.id}:{AuthenticatedUser.id}") is not None:
|
|
flash("You are sending messages too quickly", "error")
|
|
return redirect(f"/messages/new/{TargetUser.id}")
|
|
NewLineCount = request.form.get('message').count("\n")
|
|
if NewLineCount > 10:
|
|
flash("Your message has too many newlines", "error")
|
|
return redirect(f"/messages/new/{TargetUser.id}")
|
|
redis_controller.set(f"message:{TargetUser.id}:{AuthenticatedUser.id}", "1", ex=60)
|
|
|
|
FilteredSubject = FilterText(request.form.get('subject'))
|
|
FilteredMessage = FilterText(request.form.get('message'))
|
|
|
|
NewMessage = Message(
|
|
sender_id=AuthenticatedUser.id,
|
|
recipient_id=TargetUser.id,
|
|
subject=FilteredSubject,
|
|
content=FilteredMessage
|
|
)
|
|
db.session.add(NewMessage)
|
|
db.session.commit()
|
|
|
|
return redirect(f"/messages/view/{NewMessage.id}")
|
|
|
|
@MessageRoute.route("/view/<messageid>", methods=["GET"])
|
|
@auth.authenticated_required
|
|
def view_message(messageid):
|
|
MessageObj : Message = Message.query.filter_by(id=messageid).first()
|
|
if MessageObj is None:
|
|
abort(404)
|
|
AuthenicatatedUser = auth.GetCurrentUser()
|
|
if AuthenicatatedUser.id != MessageObj.sender_id and AuthenicatatedUser.id != MessageObj.recipient_id:
|
|
abort(404)
|
|
if AuthenicatatedUser.id == MessageObj.recipient_id:
|
|
MessageObj.read = True
|
|
db.session.commit()
|
|
SenderObj = User.query.filter_by(id=MessageObj.sender_id).first()
|
|
RecieverObj = User.query.filter_by(id=MessageObj.recipient_id).first()
|
|
MessageCreated = MessageObj.created.strftime("%b %d, %Y %I:%M %p")
|
|
|
|
messagelines = MessageObj.content.split("\n")
|
|
return render_template("messages/view.html", message=MessageObj, created=MessageCreated,sender=SenderObj, reciever=RecieverObj, messagelines=messagelines)
|
|
|
|
@MessageRoute.route("/", methods=['GET'])
|
|
@auth.authenticated_required
|
|
def messages():
|
|
AuthenticatedUser : User = auth.GetCurrentUser()
|
|
PageNumber = max( request.args.get('page', default=1, type=int), 1 )
|
|
UserMessagesList = Message.query.filter_by(recipient_id = AuthenticatedUser.id).order_by(Message.created.desc()).paginate(page = PageNumber, per_page = 10, error_out = False)
|
|
|
|
return render_template("messages/index.html", UserMessages=UserMessagesList, isOutgoing=False)
|
|
|
|
@MessageRoute.route("/outgoing", methods=['GET'])
|
|
@auth.authenticated_required
|
|
def outgoing_messages():
|
|
AuthenticatedUser : User = auth.GetCurrentUser()
|
|
PageNumber = max( request.args.get('page', default=1, type=int), 1 )
|
|
UserMessagesList = Message.query.filter_by(sender_id = AuthenticatedUser.id).order_by(Message.created.desc()).paginate(page = PageNumber, per_page = 10, error_out = False)
|
|
|
|
return render_template("messages/index.html", UserMessages=UserMessagesList, isOutgoing=True) |