diff --git a/app.py b/app.py index 2538c1b..5b37dea 100644 --- a/app.py +++ b/app.py @@ -138,6 +138,77 @@ def chat(room_name): ) +@app.route("/search") +def search_page(): + keywords = request.args.get("keywords", "") + if not keywords: + return render_template("search_results.html", results=[], error="Keywords are required") + + # Call the function to search messages + search_results = search_messages(keywords) + + return render_template("search.html", results=search_results, error=None) + + +def search_messages(keywords): + search_results = {} + + # Split the keywords by spaces + keyword_list = keywords.lower().split() + + # Search for messages containing any of the keywords + messages = Message.query.filter( + db.or_(*[Message.content.ilike(f"%{keyword}%") for keyword in keyword_list]) + ).all() + + for message in messages: + room = Room.query.get(message.room_id) + if room: + # Calculate the score based on the number of occurrences of all keywords + score = sum(message.content.lower().count(keyword) for keyword in keyword_list) + + # Extract snippets with context around each occurrence of the keywords + snippets = [] + content_lower = message.content.lower() + + for keyword in keyword_list: + start_index = 0 + while start_index < len(content_lower): + start_index = content_lower.find(keyword, start_index) + if start_index == -1: + break + + # Calculate the snippet range + snippet_start = max(0, start_index - 25) + snippet_end = min(len(message.content), start_index + len(keyword) + 25) + snippet = message.content[snippet_start:snippet_end] + + snippets.append(snippet) + start_index += len(keyword) + + # Join all snippets for this message + snippet_text = " ... ".join(snippets) + + if room.id not in search_results: + search_results[room.id] = { + "room_id": room.id, + "room_name": room.name, + "room_title": room.title, + "snippets": [], + "username": message.username, + "score": 0 + } + + search_results[room.id]["snippets"].append(snippet_text) + search_results[room.id]["score"] += score + + # Convert the dictionary to a list and sort results by score in descending order + search_results_list = list(search_results.values()) + search_results_list.sort(key=lambda x: x["score"], reverse=True) + + return search_results_list + + @socketio.on("join") def on_join(data): room_name = data["room_name"] diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..bc8b63e --- /dev/null +++ b/templates/base.html @@ -0,0 +1,217 @@ + + + + + + {% block title %}Chatroom{% endblock %} + + + + + + + + + + + + + + + + + + + + + + + + 🚀 docs for interacting with language models & other commands + +
+
+ +
+
+ +
+
+ +
+ {% block content %}{% endblock %} +
+ + + + diff --git a/templates/chat.html b/templates/chat.html index 9da7eb6..9e9eced 100644 --- a/templates/chat.html +++ b/templates/chat.html @@ -1,182 +1,8 @@ - - - - - - Chatroom +{% extends "base.html" %} - - - - - - - - - - - - - - - - - - - - 🚀 docs for interacting with language models & other commands -
-
- -
+{% block title %}Chatroom{% endblock %} +{% block content %}
@@ -186,12 +12,7 @@
-
- - - + +{% endblock %} diff --git a/templates/search.html b/templates/search.html new file mode 100644 index 0000000..c4d3183 --- /dev/null +++ b/templates/search.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} + +{% block title %}Search Results{% endblock %} + +{% block content %} +
+ {% if error %} +
{{ error }}
+ {% elif results %} + {% for result in results %} +
+ + {{ result.room_name }} ({{ result.room_title or "No title" }})
+ Snippets: {{ result.snippets | join(' ... ') }}
+ Score: {{ result.score }} +
+
+
+ {% endfor %} + {% else %} +
No results found.
+ {% endif %} +
+{% endblock %}