added get_thread_messages and create_forum_thread endpoints
This commit is contained in:
1 parent
c9cf3412d8
commit
6ef93e751b
11 files changed
+109
-31
No files matched your search
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
__pycache__
|
__pycache__
|
||||||
|
|
||||||
*.db
|
*.db
|
||||||
@@ -51,3 +51,12 @@ CREATE TABLE IF NOT EXISTS "attachments" (
|
|||||||
FOREIGN KEY ("message_id") REFERENCES "messages"("id")
|
FOREIGN KEY ("message_id") REFERENCES "messages"("id")
|
||||||
ON UPDATE NO ACTION ON DELETE NO ACTION
|
ON UPDATE NO ACTION ON DELETE NO ACTION
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "user_forum_owners" (
|
||||||
|
"user_id" INTEGER NOT NULL,
|
||||||
|
"forum_id" INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY ("user_id") REFERENCES "users"("id")
|
||||||
|
ON UPDATE NO ACTION ON DELETE NO ACTION,
|
||||||
|
FOREIGN KEY ("forum_id") REFERENCES "forums"("id")
|
||||||
|
ON UPDATE NO ACTION ON DELETE NO ACTION
|
||||||
|
);
|
||||||
@@ -2,7 +2,6 @@ import flask
|
|||||||
|
|
||||||
from . import user_api
|
from . import user_api
|
||||||
from . import forum_api
|
from . import forum_api
|
||||||
from . import thread_api
|
|
||||||
|
|
||||||
api = flask.Blueprint(
|
api = flask.Blueprint(
|
||||||
name='api',
|
name='api',
|
||||||
@@ -11,4 +10,3 @@ api = flask.Blueprint(
|
|||||||
)
|
)
|
||||||
api.register_blueprint(user_api.user)
|
api.register_blueprint(user_api.user)
|
||||||
api.register_blueprint(forum_api.forum)
|
api.register_blueprint(forum_api.forum)
|
||||||
api.register_blueprint(thread_api.thread)
|
|
||||||
+54
-4
@@ -16,7 +16,7 @@ forum = flask.Blueprint(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@forum.route('/forum/send_message', methods=['POST'])
|
@forum.route('/send_message', methods=['POST'])
|
||||||
@flask_login.login_required
|
@flask_login.login_required
|
||||||
def send_message() -> tuple[str, int]:
|
def send_message() -> tuple[str, int]:
|
||||||
|
|
||||||
@@ -42,16 +42,16 @@ def send_message() -> tuple[str, int]:
|
|||||||
|
|
||||||
return '', 201
|
return '', 201
|
||||||
|
|
||||||
@forum.route('/forum/get_threads')
|
@forum.route('/get_threads')
|
||||||
@flask_login.login_required
|
@flask_login.login_required
|
||||||
def get_forum_threads() -> tuple[flask.Response, int]:
|
def get_forum_threads() -> tuple[flask.Response, int]:
|
||||||
"""
|
"""
|
||||||
Get all threads from forums the current user has access to.
|
Get all threads from forums the current user has access to.
|
||||||
"""
|
"""
|
||||||
user_id: str = flask_login.current_user.get_id()
|
user_id: int = flask_login.current_user.get_id()
|
||||||
|
|
||||||
# Get all forums the user has access to
|
# Get all forums the user has access to
|
||||||
user_forums: list[mgU.Forum] = database.get_user_forums(int(user_id))
|
user_forums: list[mgU.Forum] = database.get_user_forums(user_id)
|
||||||
|
|
||||||
if not user_forums:
|
if not user_forums:
|
||||||
return flask.jsonify({"threads": []}), 200
|
return flask.jsonify({"threads": []}), 200
|
||||||
@@ -68,3 +68,53 @@ def get_forum_threads() -> tuple[flask.Response, int]:
|
|||||||
|
|
||||||
return flask.jsonify(threads_dict), 200
|
return flask.jsonify(threads_dict), 200
|
||||||
|
|
||||||
|
@forum.route('/get_messages')
|
||||||
|
@flask_login.login_required
|
||||||
|
def get_thread_messages() -> tuple[flask.Response, int]:
|
||||||
|
thread_id = flask.request.args.get("thread", type=int)
|
||||||
|
if thread_id is None:
|
||||||
|
return flask.jsonify({"error": "Missing thread parameter"}), 400
|
||||||
|
|
||||||
|
messages = database.get_messages_by_thread(thread_id)
|
||||||
|
messages_dicts = {"messages" : [dataclasses.asdict(msg) for msg in messages]}
|
||||||
|
return flask.jsonify(messages_dicts), 200
|
||||||
|
|
||||||
|
@forum.route('/create_thread', methods=['POST'])
|
||||||
|
@flask_login.login_required
|
||||||
|
def create_forum_thread() -> tuple[flask.Response, int] | tuple[str, int]:
|
||||||
|
|
||||||
|
data = flask.request.json
|
||||||
|
|
||||||
|
if not data:
|
||||||
|
return '', 400
|
||||||
|
|
||||||
|
if any([not key in data for key in ['forum_id', 'name']]):
|
||||||
|
return '', 400
|
||||||
|
|
||||||
|
if type(data['forum_id']) != int:
|
||||||
|
return '', 400
|
||||||
|
|
||||||
|
forum_id: int = data.get('forum_id')
|
||||||
|
thread_name: str = data.get('name')
|
||||||
|
|
||||||
|
if not thread_name or not thread_name.strip():
|
||||||
|
return flask.jsonify({"error": "Thread name cannot be empty"}), 400
|
||||||
|
|
||||||
|
user_id: int = flask_login.current_user.get_id()
|
||||||
|
|
||||||
|
user_owns_forum: bool = helpers.user_owns_forum(user_id, forum_id)
|
||||||
|
|
||||||
|
if not user_owns_forum:
|
||||||
|
return flask.jsonify({"error": "You don't have permission to create threads in this forum"}), 403
|
||||||
|
|
||||||
|
# Create the thread
|
||||||
|
new_thread = database.create_thread(thread_name.strip(), forum_id)
|
||||||
|
|
||||||
|
if new_thread is None:
|
||||||
|
return flask.jsonify({"error": "Failed to create thread"}), 500
|
||||||
|
|
||||||
|
# Return the created thread
|
||||||
|
thread_dict = dataclasses.asdict(new_thread)
|
||||||
|
return flask.jsonify({"thread": thread_dict, "message": "Thread created successfully"}), 201
|
||||||
|
|
||||||
|
|
||||||
@@ -24,3 +24,11 @@ def user_in_thread(user_id: int, thread_id: int) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def user_owns_forum(user_id: int, forum_id: int) -> bool:
|
||||||
|
forum_owner_ids: list[int] = database.get_forum_owners(forum_id)
|
||||||
|
|
||||||
|
if not forum_owner_ids:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return user_id in forum_owner_ids
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import dataclasses
|
|
||||||
|
|
||||||
import flask
|
|
||||||
import flask_login
|
|
||||||
|
|
||||||
import database
|
|
||||||
|
|
||||||
|
|
||||||
thread = flask.Blueprint(
|
|
||||||
name='thread_api',
|
|
||||||
import_name=__name__,
|
|
||||||
url_prefix='/thread/'
|
|
||||||
)
|
|
||||||
|
|
||||||
@thread.route('/get_messages')
|
|
||||||
@flask_login.login_required
|
|
||||||
def get_thread_messages() -> tuple[flask.Response, int]:
|
|
||||||
thread_id = flask.request.args.get("thread", type=int)
|
|
||||||
if thread_id is None:
|
|
||||||
return flask.jsonify({"error": "Missing thread parameter"}), 400
|
|
||||||
|
|
||||||
messages = database.get_messages_by_thread(thread_id)
|
|
||||||
messages_dicts = {"messages" : [dataclasses.asdict(msg) for msg in messages]}
|
|
||||||
return flask.jsonify(messages_dicts), 200
|
|
||||||
@@ -165,3 +165,35 @@ def get_user(username: str, api_key: str) -> User | None:
|
|||||||
|
|
||||||
return User(str(user_id), str(user_name))
|
return User(str(user_id), str(user_name))
|
||||||
|
|
||||||
|
# Returns a list of user_ids that are owners of a forum
|
||||||
|
def get_forum_owners(forum_id: int) -> list[int]:
|
||||||
|
|
||||||
|
q = load_query("get_forum_owners")
|
||||||
|
with Opener() as (conn, cur):
|
||||||
|
cur.execute(q)
|
||||||
|
results = cur.fetchall()
|
||||||
|
|
||||||
|
if not results:
|
||||||
|
return []
|
||||||
|
|
||||||
|
user_ids: list[int] = [row[0] for row in results]
|
||||||
|
|
||||||
|
return user_ids
|
||||||
|
|
||||||
|
def create_thread(name: str, forum_id: int) -> mgU.Thread | None:
|
||||||
|
"""
|
||||||
|
Create a new thread in the specified forum.
|
||||||
|
Returns the created Thread object with id, or None if creation fails.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with Opener() as (conn, cur):
|
||||||
|
q = load_query("insert_thread")
|
||||||
|
cur.execute(q, [name, forum_id])
|
||||||
|
thread_id = cur.lastrowid
|
||||||
|
|
||||||
|
return mgU.Thread(name=name, forum=forum_id, id=thread_id)
|
||||||
|
except sqlite3.IntegrityError:
|
||||||
|
# Forum doesn't exist or other constraint violation
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
SELECT user_id
|
||||||
|
FROM user_forum_owners
|
||||||
|
WHERE forum_id = ?;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
INSERT INTO threads (name, forum)
|
||||||
|
VALUES (?, ?);
|
||||||
Reference in new issue
Block a user