Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 47 additions & 105 deletions conditional/blueprints/major_project_submission.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import json
import os

import requests
import boto3

from flask import Blueprint
from flask import request
Expand All @@ -12,7 +9,6 @@
from sqlalchemy import desc

import structlog
from werkzeug.utils import secure_filename

from conditional.util.context_processors import get_member_name

Expand All @@ -26,162 +22,108 @@

logger = structlog.get_logger()

major_project_bp = Blueprint('major_project_bp', __name__)
major_project_bp = Blueprint("major_project_bp", __name__)


@major_project_bp.route('/major_project/')
@major_project_bp.route("/major_project/")
@auth.oidc_auth("default")
@get_user
def display_major_project(user_dict=None):
log = logger.new(request=request, auth_dict=user_dict)
log.info('Display Major Project Page')
log.info("Display Major Project Page")

major_projects = [
{
'username': p.uid,
'name': ldap_get_member(p.uid).cn,
'proj_name': p.name,
'status': p.status,
'description': p.description,
'id': p.id,
'is_owner': bool(user_dict['username'] == p.uid)
} for p in
MajorProject.query.filter(
MajorProject.date > start_of_year()).order_by(
desc(MajorProject.id))]
"username": p.uid,
"name": ldap_get_member(p.uid).cn,
"proj_name": p.name,
"status": p.status,
"description": p.description,
"id": p.id,
"is_owner": bool(user_dict["username"] == p.uid),
}
for p in MajorProject.query.filter(
MajorProject.date > start_of_year()
).order_by(desc(MajorProject.id))
]

major_projects_len = len(major_projects)
# return names in 'first last (username)' format
return render_template('major_project_submission.html',
major_projects=major_projects,
major_projects_len=major_projects_len,
username=user_dict['username'])

@major_project_bp.route('/major_project/upload', methods=['POST'])
@auth.oidc_auth("default")
@get_user
def upload_major_project_files(user_dict=None):
log = logger.new(request=request, auth_dict=user_dict)
log.info('Uploading Major Project File(s)')

return render_template(
"major_project_submission.html",
major_projects=major_projects,
major_projects_len=major_projects_len,
username=user_dict["username"],
)

if len(list(request.files.keys())) < 1:
return "No file", 400

# Temporarily save files to a place, to be uploaded on submit

for _, file in request.files.lists():
file = file[0] # remove it from the list because this is not the best
safe_name = secure_filename(file.filename)
filename = f"/tmp/{user_dict['username']}/{safe_name}"

os.makedirs(os.path.dirname(filename), exist_ok=True)
file.save(filename)

return jsonify({"success": True}), 200



@major_project_bp.route('/major_project/submit', methods=['POST'])
@major_project_bp.route("/major_project/submit", methods=["POST"])
@auth.oidc_auth("default")
@get_user
def submit_major_project(user_dict=None):
log = logger.new(request=request, auth_dict=user_dict)
log.info('Submit Major Project')
log.info("Submit Major Project")

post_data = request.get_json()
print(post_data)
name = post_data['projectName']
tldr = post_data['projectTldr']
time_spent = post_data['projectTimeSpent']
skills = post_data['projectSkills']
description = post_data['projectDescription']

user_id = user_dict['username']

print(skills)
name = post_data["projectName"]
description = post_data["projectDescription"]

if name == "" or len(description.strip().split()) < 50: # check for 50 word minimum
if name == "" or description == "":
return jsonify({"success": False}), 400
project = MajorProject(user_id, name, tldr, time_spent, description)
project = MajorProject(user_dict["username"], name, description)

username = user_dict["username"]
send_slack_ping(
{
"text": f"<!subteam^S5XENJJAH> *{get_member_name(username)}* ({username})"
f" submitted their major project, *{name}*!"
}
)
db.session.add(project)
db.session.commit()

# This allows us to get a project with a database ID
project = MajorProject.query.filter(
MajorProject.name == name and MajorProject.uid == user_id
).first()

if project is None:
return jsonify({"success": False}), 500

# Don't send slack ping until after we are sure the DB worked fine
send_slack_ping({"text":f"<!subteam^S5XENJJAH> *{get_member_name(user_id)}* ({user_id})"
f" submitted their major project, *{name}*!"})

# Acquire S3 Bucket instance
s3 = boto3.resource("s3", endpoint_url="https://s3.csh.rit.edu")
bucket = s3.create_bucket(Bucket="major-project-media")
# Collect all the locally cached files and put them in the bucket
for file in os.listdir(f"/tmp/{user_id}"):
filepath = f"/tmp/{user_id}/{file}"
print(filepath)
bucket.upload_file(filepath, f"{project.id}-{file}")
os.remove(filepath)
os.rmdir(f"/tmp/{user_id}")

return jsonify({"success": True}), 200


@major_project_bp.route('/major_project/review', methods=['POST'])
@major_project_bp.route("/major_project/review", methods=["POST"])
@auth.oidc_auth("default")
@get_user
def major_project_review(user_dict=None):
log = logger.new(request=request, auth_dict=user_dict)

if not ldap_is_eval_director(user_dict['account']):
if not ldap_is_eval_director(user_dict["account"]):
return redirect("/dashboard", code=302)

post_data = request.get_json()
pid = post_data['id']
status = post_data['status']
pid = post_data["id"]
status = post_data["status"]

log.info(f'{status} Major Project ID: {pid}')
log.info(f"{status} Major Project ID: {pid}")

print(post_data)
MajorProject.query.filter(
MajorProject.id == pid). \
update(
{
'status': status
})
MajorProject.query.filter(MajorProject.id == pid).update({"status": status})
db.session.flush()
db.session.commit()
return jsonify({"success": True}), 200


@major_project_bp.route('/major_project/delete/<pid>', methods=['DELETE'])
@major_project_bp.route("/major_project/delete/<pid>", methods=["DELETE"])
@auth.oidc_auth("default")
@get_user
def major_project_delete(pid, user_dict=None):
log = logger.new(request=request, auth_dict=user_dict)
log.info(f'Delete Major Project ID: {pid}')
log.info(f"Delete Major Project ID: {pid}")

major_project = MajorProject.query.filter(
MajorProject.id == pid
).first()
major_project = MajorProject.query.filter(MajorProject.id == pid).first()
creator = major_project.uid

if creator == user_dict['username'] or ldap_is_eval_director(user_dict['account']):
MajorProject.query.filter(
MajorProject.id == pid
).delete()
if creator == user_dict["username"] or ldap_is_eval_director(user_dict["account"]):
MajorProject.query.filter(MajorProject.id == pid).delete()
db.session.flush()
db.session.commit()
return jsonify({"success": True}), 200

return "Must be project owner to delete!", 401


def send_slack_ping(payload):
requests.post(app.config['WEBHOOK_URL'], json.dumps(payload), timeout=120)
requests.post(app.config["WEBHOOK_URL"], json.dumps(payload), timeout=120)
8 changes: 2 additions & 6 deletions conditional/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,20 +134,16 @@ class MajorProject(db.Model):
date = Column(Date, nullable=False)
uid = Column(String(32), nullable=False)
name = Column(String(64), nullable=False)
tldr = Column(String(128), nullable=False)
time = Column(Text, nullable=False)
description = Column(Text, nullable=False)
description = Column(Text)
active = Column(Boolean, nullable=False)
status = Column(Enum('Pending', 'Passed', 'Failed',
name="major_project_enum"),
nullable=False)

def __init__(self, uid, name, tldr, time, desc): # pylint: disable=too-many-positional-arguments,redefined-outer-name
def __init__(self, uid, name, desc):
self.uid = uid
self.date = datetime.now()
self.name = name
self.tldr = tldr
self.time = time
self.description = desc
self.status = 'Pending'
self.active = True
Expand Down
Loading