main.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. from flask import Blueprint, render_template, session, request, redirect, url_for
  2. from flask_login import login_required, current_user
  3. import random
  4. import string
  5. main_bp = Blueprint('main', __name__)
  6. @main_bp.route('/')
  7. def index():
  8. return render_template('index.html')
  9. @main_bp.route('/rules')
  10. def rules():
  11. return render_template('rules.html') # Need to create this or just use a placeholder
  12. @main_bp.route('/profile')
  13. @login_required
  14. def profile():
  15. from models import LinkCode, db
  16. from datetime import datetime, timedelta
  17. link_code = None
  18. if not current_user.minecraft_uuid:
  19. # Check for existing valid code
  20. existing_code = LinkCode.query.filter_by(user_id=current_user.id).first()
  21. if existing_code and existing_code.expires_at > datetime.utcnow():
  22. link_code = existing_code.code
  23. else:
  24. # Generate new code
  25. if existing_code:
  26. db.session.delete(existing_code)
  27. code = ''.join(random.choices(string.ascii_uppercase + string.digits, k=6))
  28. expires_at = datetime.utcnow() + timedelta(minutes=10)
  29. new_link_code = LinkCode(user_id=current_user.id, code=code, expires_at=expires_at)
  30. db.session.add(new_link_code)
  31. db.session.commit()
  32. link_code = code
  33. return render_template('user/profile.html', user=current_user, link_code=link_code)
  34. @main_bp.route('/apply', methods=['GET', 'POST'])
  35. @login_required
  36. def apply():
  37. if request.method == 'POST':
  38. # Save application logic here
  39. pass
  40. return render_template('apply.html')
  41. @main_bp.route('/tickets', methods=['GET', 'POST'])
  42. @login_required
  43. def tickets():
  44. from models import Ticket, TicketAssignment, db
  45. if request.method == 'POST':
  46. title = request.form.get('title')
  47. description = request.form.get('description')
  48. if title and description:
  49. ticket = Ticket(
  50. user_id=current_user.id,
  51. title=title,
  52. description=description
  53. )
  54. db.session.add(ticket)
  55. db.session.commit()
  56. # Automatically assign the creator to the ticket?
  57. # Or just rely on creator field. The user said "multiple players... assigned".
  58. # Let's assign the creator as well so they show up in the "relevant" list easily if we query by assignment.
  59. # But usually creator is separate.
  60. # Let's just save it for now.
  61. # If we want to assign admins automatically, we could do it here.
  62. return redirect(url_for('main.tickets'))
  63. # List tickets relevant to the user:
  64. # 1. Tickets created by the user
  65. # 2. Tickets assigned to the user
  66. # Using a union or simple OR query
  67. # Since we have a separate TicketAssignment model, we can join.
  68. relevant_tickets = Ticket.query.outerjoin(TicketAssignment).filter(
  69. (Ticket.user_id == current_user.id) | (TicketAssignment.user_id == current_user.id)
  70. ).all()
  71. return render_template('tickets.html', tickets=relevant_tickets)
  72. @main_bp.route('/tickets/<int:ticket_id>', methods=['GET', 'POST'])
  73. @login_required
  74. def ticket_detail(ticket_id):
  75. from models import Ticket, TicketComment, TicketAssignment, db
  76. ticket = Ticket.query.get_or_404(ticket_id)
  77. # Access Control
  78. is_creator = ticket.user_id == current_user.id
  79. is_assigned = TicketAssignment.query.filter_by(ticket_id=ticket.id, user_id=current_user.id).first() is not None
  80. is_admin = current_user.is_admin
  81. if not (is_creator or is_assigned or is_admin):
  82. return render_template('errors/403.html'), 403 # Or just redirect with flash
  83. if request.method == 'POST':
  84. action = request.form.get('action')
  85. if action == 'comment':
  86. content = request.form.get('content')
  87. is_hidden = request.form.get('is_hidden') == 'on'
  88. # Only admins can make hidden comments
  89. if is_hidden and not is_admin:
  90. is_hidden = False
  91. if content:
  92. comment = TicketComment(
  93. ticket_id=ticket.id,
  94. user_id=current_user.id,
  95. content=content,
  96. is_hidden=is_hidden
  97. )
  98. db.session.add(comment)
  99. db.session.commit()
  100. elif action == 'close':
  101. # Only creator or admin can close
  102. if not (is_creator or is_admin):
  103. return "Unauthorized", 403
  104. reason = request.form.get('reason')
  105. if reason:
  106. ticket.status = 'CLOSED'
  107. ticket.closing_reason = reason
  108. ticket.closed_by_id = current_user.id
  109. db.session.commit()
  110. elif action == 'toggle_hidden':
  111. if not is_admin:
  112. return "Unauthorized", 403
  113. comment_id = request.form.get('comment_id')
  114. comment = TicketComment.query.get(comment_id)
  115. if comment and comment.ticket_id == ticket.id:
  116. comment.is_hidden = not comment.is_hidden
  117. db.session.commit()
  118. return redirect(url_for('main.ticket_detail', ticket_id=ticket.id))
  119. return render_template('ticket_detail.html', ticket=ticket, is_admin=is_admin, is_creator=is_creator)