Skip to the content.

Cpt_ppr_ipynb_2_

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
}

Censored text in action

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.

Chats after being deleted


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.