main.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. from email.policy import default
  2. import os
  3. import re
  4. import bcrypt
  5. import dotenv
  6. from flask import (
  7. Flask,
  8. flash,
  9. redirect,
  10. render_template,
  11. request,
  12. session,
  13. url_for,
  14. )
  15. from flask_sqlalchemy import SQLAlchemy
  16. from sqlalchemy.orm import DeclarativeBase
  17. from sqlalchemy.sql import func
  18. dotenv.load_dotenv()
  19. app = Flask(__name__)
  20. app.secret_key = os.getenv("SECRET_KEY", "whataloadofnonsense")
  21. class Base(DeclarativeBase):
  22. pass
  23. app.config["SQLALCHEMY_DATABASE_URI"] = (
  24. "mysql://root:root@localhost:3306/topperstasks"
  25. )
  26. db = SQLAlchemy(model_class=Base)
  27. db.init_app(app)
  28. class User(db.Model):
  29. __tablename__ = "users"
  30. id = db.Column(db.Integer, primary_key=True)
  31. username = db.Column(db.String, unique=True, nullable=False)
  32. passhash = db.Column(db.String, nullable=False)
  33. is_admin = db.Column(db.Boolean, default=False)
  34. tasks = db.relationship("Task", back_populates="user")
  35. task_assignments = db.relationship("Task_Assignment", back_populates="user")
  36. class Task(db.Model):
  37. __tablename__ = "tasks"
  38. id = db.Column(db.Integer, primary_key=True)
  39. created_datetime = db.Column(db.String, nullable=False, default=func.now())
  40. tasktext = db.Column(db.String, nullable=False)
  41. created_by = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)
  42. due = db.Column(db.String)
  43. completed = db.Column(db.Boolean, default=False)
  44. deleted = db.Column(db.Boolean, default=False)
  45. user = db.relationship(User, back_populates="tasks")
  46. task_assignments = db.relationship("Task_Assignment", back_populates="task")
  47. class Task_Assignment(db.Model):
  48. __tablename__ = "task_assignments"
  49. id = db.Column(db.Integer, primary_key=True)
  50. user_id = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)
  51. task_id = db.Column(db.Integer, db.ForeignKey(Task.id), nullable=False)
  52. user = db.relationship(User, back_populates="task_assignments")
  53. task = db.relationship(Task, back_populates="task_assignments")
  54. @app.route("/")
  55. def home():
  56. if not session.get("userid"):
  57. return redirect(url_for("login"))
  58. tasks = db.session.execute(
  59. db.select(Task).where(Task.deleted == False)
  60. ).scalars()
  61. return render_template("home.html", tasks=tasks)
  62. @app.route("/login", methods=["GET", "POST"])
  63. def login():
  64. if request.method == "POST":
  65. try:
  66. username = request.form.get("user")
  67. password = request.form.get("password")
  68. user: User = db.session.execute(
  69. db.select(User).where(User.username == username)
  70. ).scalar_one_or_none()
  71. if not user:
  72. flash("Failed to login", category="warning")
  73. return redirect(url_for("login"))
  74. if not user.passhash:
  75. salt = bcrypt.gensalt()
  76. user.passhash = bcrypt.hashpw(password.encode(), salt)
  77. db.session.commit()
  78. flash("Password set succesfully!", category="success")
  79. return redirect(url_for("login"))
  80. if bcrypt.checkpw(password.encode(), user.passhash.encode()):
  81. session["userid"] = user.id
  82. return redirect(url_for("home"))
  83. else:
  84. flash("Failed to login", category="warning")
  85. return redirect(url_for("login"))
  86. except:
  87. flash("Critical Error, contact Peter pls", category="error")
  88. return redirect(url_for("login"))
  89. return render_template("login.html")
  90. @app.route("/addtask", methods=["POST"])
  91. def addtask():
  92. try:
  93. tasktext = request.form.get("task-text")
  94. user_id = session.get("userid")
  95. if not tasktext:
  96. flash("Invalid task text", category="warning")
  97. return redirect(url_for("home"))
  98. if not user_id:
  99. return redirect(url_for("login"))
  100. newtask = Task(tasktext=tasktext, created_by=user_id)
  101. db.session.add(newtask)
  102. db.session.commit()
  103. except:
  104. flash("Critical Error, contact Peter pls", category="error")
  105. return redirect(url_for("home"))
  106. return redirect(url_for("home"))
  107. @app.route("/updatetask", methods=["POST"])
  108. def updatetask():
  109. if "task-id" not in request.form:
  110. flash("Failed to find task", category="warning")
  111. return redirect(url_for("home"))
  112. task = db.session.execute(
  113. db.select(Task).where(Task.id == request.form.get("task-id"))
  114. ).scalar_one_or_none()
  115. if not task:
  116. flash("Failed to find task", category="warning")
  117. return redirect(url_for("home"))
  118. if "due" in request.form:
  119. if not task.due:
  120. flash("Invalid due date", category="warning")
  121. return redirect(url_for("home"))
  122. datetime_str = request.form.get("due")
  123. datetime_str = datetime_str.replace("T", " ")
  124. datetime_str += ":00"
  125. task.due = datetime_str
  126. db.session.commit()
  127. return redirect(url_for("home"))
  128. if __name__ == "__main__":
  129. app.run(host="0.0.0.0", debug=True)