diff --git a/api/quizgrading.py b/api/quizgrading.py new file mode 100644 index 0000000..5700b3c --- /dev/null +++ b/api/quizgrading.py @@ -0,0 +1,81 @@ +import jwt +from flask import Blueprint, request, jsonify, current_app, Response, g +from flask_restful import Api, Resource # used for REST API building +from datetime import datetime +from __init__ import app +from api.jwt_authorize import token_required +from model.quizgrading import quizgrading +from model.user import User +from model.section import Section + +quizgrading_api = Blueprint('quizgrading_api', __name__, url_prefix='/api') + +api = Api(quizgrading_api) + +class GroupAPI: + """ + The API CRUD endpoints correspond to common HTTP methods: + - post: create a new group + - get: read groups + - put: update a group + - delete: delete a group + """ + class _CRUD(Resource): + + def post(self): + """ + Create a new group. + """ + # Obtain the request data sent by the RESTful client API + data = request.get_json() + # Create a new group object using the data from the request + chat = quizgrading(data['quizgrade'], data['attempt']) + # Save the chat object using the Object Relational Mapper (ORM) method defined in the model + chat.create() + # Return response to the client in JSON format, converting Python dictionaries to JSON format + return jsonify(chat.read()) + + def get(self): + chats = quizgrading.query.all() + allChats = [] + for i in range(len(chats)): + allChats.append(chats[i].read()) + + # Return a JSON restful response to the client + return jsonify(allChats) + + def put(self): + # Obtain the current user + # Obtain the request data + data = request.get_json() + # Find the current post from the database table(s) + post = quizgrading.query.get(data['id']) + # Update the post + post._quizgrade = data['quizgrade'] + post._attempt = data['attempt'] + # Save the post + post.update() + # Return response + return jsonify(post.read()) + + def delete(self): + # Obtain the request data + data = request.get_json() + # Find the current post from the database table(s) + post = quizgrading.query.get(data['id']) + # Delete the post using the ORM method defined in the model + post.delete() + # Return response + return jsonify({"message": "Post deleted"}) + + """ + Map the _CRUD class to the API endpoints for /post. + - The API resource class inherits from flask_restful.Resource. + - The _CRUD class defines the HTTP methods for the API. + """ + + api.add_resource(_CRUD, '/quizgrading') + +if __name__ == '__main__': + app.run(debug=True) + diff --git a/main.py b/main.py index 0ebc801..2fb22b5 100644 --- a/main.py +++ b/main.py @@ -22,7 +22,7 @@ from api.group import group_api from api.section import section_api from api.nestPost import nestPost_api # Justin added this, custom format for his website -from api.binaryhistory import binary_history_api +from api.quizgrading import quizgrading_api from api.messages_api import messages_api # Adi added this, messages for his website from api.carphoto import car_api from api.carChat import car_chat_api @@ -39,6 +39,7 @@ from model.nestPost import initNestPosts # under development from model.binaryLearningGame import initBinaryLearningGameScores +from model.quizgrading import initquizgrading # server only Views # register URIs for api endpoints @@ -49,10 +50,10 @@ app.register_blueprint(post_api) app.register_blueprint(channel_api) app.register_blueprint(section_api) -# apis under development -app.register_blueprint(quizCreation_api) -app.register_blueprint(binaryConverter_api) -app.register_blueprint(binary_history_api) +app.register_blueprint(binaryLearningGameScores_api) +app.register_blueprint(student_api) +app.register_blueprint(quizgrading_api) +# API's following this are under development # Tell Flask-Login the view function name of your login route login_manager.login_view = "login" @@ -161,6 +162,8 @@ def generate_data(): initNestPosts() # New data being tested initBinaryLearningGameScores() + initquizquestions() + initquizgrading() # Backup the old database def backup_database(db_uri, backup_uri): diff --git a/model/lgatedata.py b/model/lgatedata.py index 7ece1e8..ca732cf 100644 --- a/model/lgatedata.py +++ b/model/lgatedata.py @@ -1,39 +1,19 @@ -# post.py from sqlite3 import IntegrityError -from sqlalchemy import Text from __init__ import app, db from model.user import User -from model.group import Group -class LogicGates(db.Model): - """ - LogicGates Model - - The Post class represents an individual contribution or discussion within a group. - - Attributes: - id (db.Column): The primary key, an integer representing the unique identifier for the post. - _title (db.Column): A string representing the title of the post. - _content (db.Column): A Text blob representing the content of the post. - """ - __tablename__ = 'LogicGates' +class quizgrading(db.Model): + __tablename__ = 'quizgrading' id = db.Column(db.Integer, primary_key=True) - _name = db.Column(db.String(255), nullable=False) - _score = db.Column(Text, nullable=False) + _quizgrade = db.Column(db.Integer, nullable=False) + _attempt = db.Column(db.Integer, nullable=False) _user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) - def __init__(self, name, score, user_id): - """ - Constructor, 1st step in object creation. - - Args: - title (str): The title of the post. - score (str): The score of the post. - user_id (int): The user who created the post. - """ - self._name = name - self._score = score + def __init__(self, quizgrade, attempt, user_id): + + self._quizgrade = quizgrade + self._attempt = attempt self._user_id = user_id def __repr__(self): @@ -44,7 +24,7 @@ def __repr__(self): Returns: str: A text representation of how to create the object. """ - return f"Post(id={self.id}, name={self._name}, score={self._score}, user_id={self._user_id})" + return f"Post(id={self.id}, quizgrade={self._quizgrade}, attempt={self._attempt}, user_id={self._user_id})" def create(self): """ @@ -76,10 +56,9 @@ def read(self): user = User.query.get(self._user_id) data = { "id": self.id, - "name": self._name, - "score": self._score, + "quizgrade": self._quizgrade, + "attempt": self._attempt, "user_name": user.name if user else None, - # Review information as this may not work as this is a quick workaround } return data @@ -116,7 +95,7 @@ def delete(self): db.session.rollback() raise e -def initLogicGatess(): +def initquizgrading(): """ The initPosts function creates the Post table and adds tester data to the table. @@ -134,11 +113,12 @@ def initLogicGatess(): db.create_all() """Tester data for table""" - p1 = LogicGates(name='Lars', score='17/18', user_id=1) - p2 = LogicGates(name='Rutvik', score='15/18', user_id=2) - p3 = LogicGates(name='Shaurya', score='18/18', user_id=3) + p1 = quizgrading(quizgrade=50, attempt=1, user_id=1) + p2 = quizgrading(quizgrade=60, attempt=2, user_id=1) + p3 = quizgrading(quizgrade=70, attempt=3, user_id=1) + p4 = quizgrading(quizgrade=80, attempt=4, user_id=1) - for post in [p1, p2, p3]: + for post in [p1, p2, p3, p4]: try: post.create() print(f"Record created: {repr(post)}") diff --git a/model/quizgrading.py b/model/quizgrading.py new file mode 100644 index 0000000..78f7305 --- /dev/null +++ b/model/quizgrading.py @@ -0,0 +1,125 @@ +from sqlite3 import IntegrityError +from __init__ import app, db +from model.user import User + +class quizgrading(db.Model): + __tablename__ = 'quizgrading' + + id = db.Column(db.Integer, primary_key=True) + _quizgrade = db.Column(db.String, nullable=False) + _attempt = db.Column(db.String, nullable=False) + + def __init__(self, quizgrade, attempt): + + self._quizgrade = quizgrade + self._attempt = attempt + + def __repr__(self): + """ + The __repr__ method is a special method used to represent the object in a string format. + Called by the repr(post) built-in function, where post is an instance of the Post class. + + Returns: + str: A text representation of how to create the object. + """ + return f"" + + def create(self): + """ + The create method adds the object to the database and commits the transaction. + + Uses: + The db ORM methods to add and commit the transaction. + + Raises: + Exception: An error occurred when adding the object to the database. + """ + try: + db.session.add(self) + db.session.commit() + except Exception as e: + db.session.rollback() + raise e + + def read(self): + """ + The read method retrieves the object data from the object's attributes and returns it as a dictionary. + + Uses: + The Group.query and User.query methods to retrieve the group and user objects. + + Returns: + dict: A dictionary containing the post data, including user and group names. + """ + data = { + "id": self.id, + "quizgrade": self._quizgrade, + "attempt": self._attempt, + } + return data + + def update(self): + """ + The update method commits the transaction to the database. + + Uses: + The db ORM method to commit the transaction. + + Raises: + Exception: An error occurred when updating the object in the database. + """ + try: + db.session.commit() + except Exception as e: + db.session.rollback() + raise e + + def delete(self): + """ + The delete method removes the object from the database and commits the transaction. + + Uses: + The db ORM methods to delete and commit the transaction. + + Raises: + Exception: An error occurred when deleting the object from the database. + """ + try: + db.session.delete(self) + db.session.commit() + except Exception as e: + db.session.rollback() + raise e + +def initquizgrading(): + """ + The initPosts function creates the Post table and adds tester data to the table. + + Uses: + The db ORM methods to create the table. + + Instantiates: + Post objects with tester data. + + Raises: + IntegrityError: An error occurred when adding the tester data to the table. + """ + with app.app_context(): + """Create database and tables""" + db.create_all() + """Tester data for table""" + + entries = [ + quizgrading(quizgrade=50, attempt=1), + quizgrading(quizgrade=60, attempt=2), + quizgrading(quizgrade=70, attempt=3), + quizgrading(quizgrade=80, attempt=4) + ] + for entry in entries: + try: + db.session.add(entry) + db.session.commit() + except IntegrityError: + '''fails with bad or duplicate data''' + db.session.rollback() + print(f"Record creation failed: {entry}") \ No newline at end of file