FEAT: Added a search bar feature (to be integrated with database
UPDATE: Removed html pages, as they were no longer being used
This commit is contained in:
99
web_server/blueprints/search_bar.py
Normal file
99
web_server/blueprints/search_bar.py
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
from flask import Blueprint, jsonify
|
||||||
|
from database.database import Database
|
||||||
|
|
||||||
|
search_bp = Blueprint("search", __name__)
|
||||||
|
|
||||||
|
@search_bp.route("/search/<str:query>", methods=["GET", "POST"])
|
||||||
|
def search_results(query: str):
|
||||||
|
"""
|
||||||
|
Return the most similar search results
|
||||||
|
|
||||||
|
This is the main route that displays a subsection of each search topic
|
||||||
|
"""
|
||||||
|
# Create the connection to the database
|
||||||
|
db = Database()
|
||||||
|
db.create_connection()
|
||||||
|
|
||||||
|
# Get the most accurate search results
|
||||||
|
# 3 categories
|
||||||
|
categories = db.fetchall("""
|
||||||
|
SELECT bm25(category_fts), rank, f.category_id, f.category_name
|
||||||
|
FROM categorys AS c
|
||||||
|
INNER JOIN category_fts AS f ON c.category_id = f.category_id
|
||||||
|
WHERE category_fts MATCH ?
|
||||||
|
LIMIT 3;
|
||||||
|
""", (query,))
|
||||||
|
|
||||||
|
# 3 users
|
||||||
|
users = db.fetchall("""
|
||||||
|
SELECT bm25(user_fts), rank, f.user_id, f.username, f.is_live
|
||||||
|
FROM users u
|
||||||
|
INNER JOIN user_fts f ON u.user_id = f.user_id
|
||||||
|
WHERE user_fts MATCH ?
|
||||||
|
LIMIT 3;
|
||||||
|
""", (query,))
|
||||||
|
|
||||||
|
# 3 streams
|
||||||
|
streams = db.fetchall("""
|
||||||
|
SELECT bm25(stream_fts), rank, f.user_id, f.title, f.num_viewers, f.category_id
|
||||||
|
FROM streams s
|
||||||
|
INNER JOIN stream_fts f ON s.user_id = f.user_id
|
||||||
|
WHERE user_fts MATCH ?
|
||||||
|
LIMIT 3;
|
||||||
|
""", (query,))
|
||||||
|
|
||||||
|
db.close_connection()
|
||||||
|
|
||||||
|
return jsonify({"categories": categories, "users": users, "streams": streams})
|
||||||
|
|
||||||
|
@search_bp.route("/search/categories/<str:query>", methods=["GET", "POST"])
|
||||||
|
def search_categories(query: str):
|
||||||
|
# Create the connection to the database
|
||||||
|
db = Database()
|
||||||
|
db.create_connection()
|
||||||
|
|
||||||
|
categories = db.fetchall("""
|
||||||
|
SELECT bm25(category_fts), rank, f.category_id, f.category_name
|
||||||
|
FROM categorys AS c
|
||||||
|
INNER JOIN category_fts AS f ON c.category_id = f.category_id
|
||||||
|
WHERE category_fts MATCH ?;
|
||||||
|
""", (query,))
|
||||||
|
|
||||||
|
db.close_connection()
|
||||||
|
|
||||||
|
return jsonify({"categories": categories})
|
||||||
|
|
||||||
|
@search_bp.route("/search/users/<str:query>", methods=["GET", "POST"])
|
||||||
|
def search_users(query: str):
|
||||||
|
# Create the connection to the database
|
||||||
|
db = Database()
|
||||||
|
db.create_connection()
|
||||||
|
|
||||||
|
users = db.fetchall("""
|
||||||
|
SELECT bm25(user_fts), rank, f.user_id, f.username, f.is_live
|
||||||
|
FROM users u
|
||||||
|
INNER JOIN user_fts f ON u.user_id = f.user_id
|
||||||
|
WHERE user_fts MATCH ?;
|
||||||
|
""", (query,))
|
||||||
|
|
||||||
|
db.close_connection()
|
||||||
|
|
||||||
|
return jsonify({"users": users})
|
||||||
|
|
||||||
|
|
||||||
|
@search_bp.route("/search/streams/<str:query>", methods=["GET", "POST"])
|
||||||
|
def search_streams(query: str):
|
||||||
|
# Create the connection to the database
|
||||||
|
db = Database()
|
||||||
|
db.create_connection()
|
||||||
|
|
||||||
|
streams = db.fetchall("""
|
||||||
|
SELECT bm25(stream_fts), rank, f.user_id, f.title, f.num_viewers, f.category_id
|
||||||
|
FROM streams s
|
||||||
|
INNER JOIN stream_fts f ON s.user_id = f.user_id
|
||||||
|
WHERE user_fts MATCH ?;
|
||||||
|
""", (query,))
|
||||||
|
|
||||||
|
db.close_connection()
|
||||||
|
|
||||||
|
return jsonify({"streams": streams})
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Chat Interface</title>
|
|
||||||
|
|
||||||
<script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
|
|
||||||
<script>
|
|
||||||
// Global constants
|
|
||||||
const socket = io("http://127.0.0.1:5000"); // TODO: Change this
|
|
||||||
const stream_id = "{{ stream_id }}";
|
|
||||||
const chatter_id = "{{ chatter_id }}";
|
|
||||||
|
|
||||||
function add_to_chat(data){
|
|
||||||
const chat_container = document.getElementById("chat_container");
|
|
||||||
console.log(data)
|
|
||||||
|
|
||||||
// Add each chat message to the chat box, one by one
|
|
||||||
data.forEach((element) => {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
div.textContent = `${element.time_sent} ${element.chatter_id}: ${element.message}`;
|
|
||||||
chat_container.appendChild(div);
|
|
||||||
})
|
|
||||||
|
|
||||||
chat_container.scrollTop = chat_container.scrollHeight; // keeps you at the bottom of the chat
|
|
||||||
}
|
|
||||||
|
|
||||||
socket.on("connect", () => {
|
|
||||||
console.log("Socket Connection established!");
|
|
||||||
})
|
|
||||||
|
|
||||||
// Wait for a new message to be sent
|
|
||||||
socket.on("new_message", (data) => {
|
|
||||||
console.log("New message");
|
|
||||||
add_to_chat([data]);
|
|
||||||
});
|
|
||||||
|
|
||||||
function loadPrevChat() {
|
|
||||||
const init_chat_logs = JSON.parse('{{ chat_history | tojson }}');
|
|
||||||
add_to_chat(init_chat_logs);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendChat(){
|
|
||||||
// Get the chat message sent by user, if none, don't
|
|
||||||
const chat_message = document.getElementById("messageInput").value.trim();
|
|
||||||
if (!chat_message) return;
|
|
||||||
|
|
||||||
document.getElementById("messageInput").value = ""; // clear the chat box
|
|
||||||
|
|
||||||
// Send the message using sockets
|
|
||||||
socket.emit("send_message", {
|
|
||||||
chatter_id: chatter_id,
|
|
||||||
stream_id: stream_id,
|
|
||||||
message: chat_message
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('DOMContentLoaded', () => {
|
|
||||||
socket.emit("join", {stream_id: stream_id});
|
|
||||||
loadPrevChat();
|
|
||||||
});
|
|
||||||
|
|
||||||
window.addEventListener("beforeunload", () => {
|
|
||||||
socket.emit("leave", {stream_id: stream_id});
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Chat for Stream #{{ stream_id }}</h1>
|
|
||||||
<div id="chat_container" style="max-height: 400px; overflow-y: auto;"></div>
|
|
||||||
<input type="text" id="messageInput" placeholder="Type a message" />
|
|
||||||
<button onclick="sendChat()">Send</button>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
<html>
|
|
||||||
<body>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
|
|
||||||
<video id="video" controls></video>
|
|
||||||
<script>
|
|
||||||
if(Hls.isSupported())
|
|
||||||
{
|
|
||||||
var video = document.getElementById('video');
|
|
||||||
var hls = new Hls();
|
|
||||||
hls.loadSource('{{ video_url }}');
|
|
||||||
hls.attachMedia(video);
|
|
||||||
hls.on(Hls.Events.MANIFEST_PARSED,function()
|
|
||||||
{
|
|
||||||
video.play();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (video.canPlayType('application/vnd.apple.mpegurl'))
|
|
||||||
{
|
|
||||||
video.src = ' {{ video_url }}';
|
|
||||||
video.addEventListener('canplay',function()
|
|
||||||
{
|
|
||||||
video.play();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Reference in New Issue
Block a user