Purpose of the Chatroom Censor and Program
- The purpose of the program is to develop a chatroom application that incorporates:
- sending and receiving user messages
- censoring inappropriate content
- storing and retrieving chat messages from a database
- managing chat history for user interactions
All of which ensures a functoinal, ethical, and moderated communication environment.
Key Features and Their Purpose:
- User Input Handling: Allows users to send messages through a web interface
- Message Censorship: Filters out inappropriate words before storing messages.
- Database Storage: Saves and retrieves chat messages for long-term history.
- API Integration: Enables seamless frontend-backend interaction.
Handling User Input and Output
- Frontend message submission:
Backend Processing:
from flask import Flask, request, jsonify
from database import db, ChatMessage
app = Flask(__name__)
def filter_message(message):
banned_words = ["badword", "inappropriate"]
for word in banned_words:
message = message.replace(word, "****")
return message
@app.route('/send_message', methods=['POST'])
def send_message():
data = request.json
message = data['message']
user_id = data['user_id']
censored_message = filter_message(message)
chat = ChatMessage(user_id=user_id, message=censored_message)
db.session.add(chat)
db.session.commit()
return jsonify({
"message": "Message sent successfully",
"original_message": message,
"censored_message": censored_message
})
Database Operations
Storing Messages:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class ChatMessage(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, nullable=False)
message = db.Column(db.String(500), nullable=False)
def init_db():
db.create_all()
Retrieving Messages:
@app.route('/get_messages', methods=['GET'])
def get_messages():
messages = ChatMessage.query.all()
return jsonify([{ "user_id": msg.user_id, "message": msg.message } for msg in messages])
Algorithm: Filtering Messages
- This algorithm demonstrates sequencing, selection, and iteration:
how it works:
- Sequencing: The function executes in order, first defining banned words, then processing the message.
- Selection: If a banned word exists in the message, it gets replaced.
- Iteration: Loops through each banned word to check for occurrences.
def filter_message(message):
banned_words = ["badword", "inappropriate"] # List for filtering
for word in banned_words: # Iteration through words
message = message.replace(word, "****") # Selection: Replace if found
return message
API REQUEST (Postman Example)
This HTML form collects user input and sends a POST request to the Flask backend. The backend will process the message, censor inappropriate content, and store it in the database.
<form id="chatForm">
<input type="text" id="messageInput" placeholder="Enter your message">
<button type="submit">Send Message</button>
</form>
<img alt="Chatroom running in frontend" src="/rowan_2025/images/frontend.png">
<script>
document.getElementById('chatForm').addEventListener('submit', async function(event) {
event.preventDefault();
const message = document.getElementById('messageInput').value;
const response = await fetch('http://localhost:8887/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ message: message, user_id: 1 })
});
const data = await response.json();
console.log(data);
});
</script>
What happens here?
- The user inputs a message, and when the form is submitted, the JavaScript fetches the message and sends it as a JSON body to the Flask backend.
- The backend processes the message, censors any inappropriate content, and stores the message in the database.
In Postman, we can test the POST request to the /chat
endpoint.
Method: POST
URL: http://localhost:8887/chat
Body (JSON format):
{
"message": "This is an inappropriate message.",
"user_id": 1
}
The backend will process the message, censor any inappropriate content, and respond with a JSON object.
API Response (JSON format):
{
"message": "Message sent successfully",
"original_message": "This is an inappropriate message.",
"censored_message": "This is an ************ message."
}
What happens here?
- We test the API in Postman by sending a POST request with a message to the
/chat
endpoint. - The API processes the message, returns a success message, and includes both the original and censored versions of the message.
Database Operations: Using db_init, db_restore, db_backup
To demonstrate how the database handles data creation and recovery, we use functions such as db_init, db_restore, and db_backup.
db_init: Create Tester Data
This function initializes the database and adds test data to the censor
table.
# db_init.py
def db_init():
"""Create the database and add tester data"""
with app.app_context():
db.create_all()
c1 = Censor(name='John Doe', uid='johndoe123', submission_text='Test message', censored_text='Test message', submission_date=date.today(), flagged_words='')
db.session.add(c1)
db.session.commit()
db_restore: Restore Data to Original State
This function drops all tables and calls db_init
to restore the original state of the database.
# db_restore.py
def db_restore():
"""Restore the database to the original state"""
with app.app_context():
db.drop_all()
db_init()
db_backup: Back Up Data
This function allows us to back up the current state of the database.
# db_backup.py
def db_backup():
"""Backup the current database state"""
with app.app_context():
# Your backup logic here (e.g., export database to a file)
pass
Working with Lists and Dictionaries
We use lists and dictionaries to store and manipulate data in our API and database.
List of Rows: Fetching Multiple Records
In the database, each record is represented as a row, and when we retrieve multiple records, they are returned as a list of rows. For example:
chats = MusicChat.query.all()
This query returns all chat records as a list of rows, and we can iterate over this list to display each message.
Dictionaries for Columns: Structuring Data
When fetching a specific record, each record is returned as a dictionary where the column names are the keys, and the column values are the corresponding values. For example:
chat_data = chat.read() # Returns a dictionary
Each message will be represented as a dictionary, which allows us to easily format the data for API responses.
Formatting Response Data (JSON)
The response data from the API is formatted as JSON to ensure compatibility with frontend applications and other services. For example:
@app.route('/chat', methods=['GET'])
def get_all_chats():
chats = MusicChat.query.all()
return jsonify([chat.read() for chat in chats]), 200
This endpoint returns a list of all chat messages, formatted as JSON.
Queries from Database: Extracting Python Lists
Queries from the database return Python lists, which can be used to display or process data. For example:
chat_history = MusicChat.query.filter(
(MusicChat._user_id == user1) | (MusicChat._user_id == user2)
).all()
This query returns a list of chat messages between two users, which is then processed and returned as a JSON response.
Working with Columns: CRUD Operations
The Censor
class is designed to handle CRUD operations for database records. Each method (create, read, update, delete) interacts with the columns of the censor
table.
Create Method
def create(self, inputs=None):
try:
db.session.add(self)
db.session.commit()
return self
except IntegrityError:
db.session.rollback()
return None
The create
method adds a new record to the database.
Read Method
def read(self):
data = {
"id": self.id,
"name": self.name,
"uid": self.uid,
"submission_text": self.submission_text,
"censored_text": self.censored_text,
"submission_date": self.submission_date,
"flagged_words": self.flagged_words
}
return data
The read
method retrieves the data from the database and returns it as a dictionary.
Update Method
def update(self, inputs):
self.submission_text = inputs.get("submission_text", self.submission_text)
self.censored_text = inputs.get("censored_text", self.censored_text)
self.flagged_words = inputs.get("flagged_words", self.flagged_words)
db.session.commit()
The update
method updates specific columns of a record in the database.
Delete Method
def delete(self):
db.session.delete(self)
db.session.commit()
The delete
method removes a record from the database.
Algorithmic Code for API Requests
We will now demonstrate the code for handling an API request. This includes the use of sequencing, selection, and iteration within the code.
Handling API Request
@app.route('/chat', methods=['POST'])
def send_message():
data = request.json
message = data["message"]
user_id = data["user_id"]
# Censor the message before saving it
censored_message = censor_message(message)
chat = MusicChat(message=message, censored_message=censored_message, user_id=user_id)
chat.create()
return jsonify({
"message": "Message sent successfully",
"original_message": message,
"censored_message": censored_message
}), 200
What happens here?
- This code listens for a POST request at the
/chat
endpoint, processes the message, and stores it in the database after censoring. - The sequence of actions involves receiving the data, selecting the relevant message field, and iterating over the database to store the information.