Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changing the backend for search to query the database #71

Merged
merged 5 commits into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 41 additions & 116 deletions backend/api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from flask import jsonify, request
import re

from datetime import datetime, timedelta, timezone
from flask_jwt_extended import (
create_access_token,
Expand All @@ -11,40 +13,51 @@
import json
import bcrypt

# from datalayer_event import EventDataLayer


def get_matched_events(query, detailed=False):
if not query:
return []

# Once database is setup, a query will be executed here
matched_events = [
event
for event in mockEvents
if event["title"].lower().startswith(query.lower())
]

if detailed:
return matched_events
else:
titles = [event["title"] for event in matched_events]
return titles


def setup_routes(app):
@app.route("/api/autosuggest", methods=["GET"])
def autosuggest():
query = request.args.get("query")
results = get_matched_events(query)
return jsonify(results)
query = request.args.get("query").lower()
print('query: ', query)
try:
from datalayer_event import EventDataLayer
event_data = EventDataLayer()
results = event_data.get_search_results_by_keyword(query)
suggestions = []
for event in results:
if any(word.lower().startswith(query) for word in re.findall(r'\b\w+\b', event.title)):
suggestions.append(event.title)
if event.club and any(word.lower().startswith(query) for word in re.findall(r'\b\w+\b', event.club)):
suggestions.append(event.club)
return jsonify(list(set(suggestions)))
except Exception as e:
error_message = str(e)
return jsonify({"error": "Failed to look and display post title", "error_message":error_message}), 500


@app.route("/api/search", methods=["GET"])
def search():
query = request.args.get("query")
results = get_matched_events(query, detailed=True)
return jsonify(results)

print("Printing query: ", query)
try:
from datalayer_event import EventDataLayer
event_data = EventDataLayer()
results = event_data.get_search_results_by_keyword(query)
json_event = [
{
'id': event.id,
'title': event.title,
'description': event.description,
'location': event.location,
'start_time': event.start_time.strftime("%Y-%m-%d %H:%M:%S"),
'end_time': event.end_time.strftime("%Y-%m-%d %H:%M:%S"),
} for event in results
]
return jsonify(json_event)
except Exception as e:
error_message = str(e)
return jsonify({"error": "Failed to look for post", "error_message":error_message}), 500

@app.route("/api/update-post/<int:post_id>", methods=["POST"])
def update_post(post_id):
try:
Expand Down Expand Up @@ -72,7 +85,7 @@ def update_post(post_id):
),
500,
)

@app.route("/api/create-post", methods=["POST"])
def create_post():
try:
Expand Down Expand Up @@ -124,7 +137,7 @@ def create_post():
),
500,
)

@app.route("/api/", methods=["GET"])
def index():
try:
Expand Down Expand Up @@ -350,91 +363,3 @@ def my_profile():
return response_body


# TODO: Remove once database is setup
# TODO: add extendedDescription field, image url,
mockEvents = [
{
"event_id": 0,
"title": "Sample Event 0",
"description": "This is the first sample event.",
"location": "Sample Location 1",
"start_time": "2023-11-01T08:00:00",
"end_time": "2023-11-01T17:00:00",
"user_id": 1,
"is_published": True,
"is_public": True,
"like_count": 25,
},
{
"event_id": 1,
"title": "Sample Event 1",
"description": "This is the first sample event.",
"location": "Sample Location 1",
"start_time": "2023-11-01T08:00:00",
"end_time": "2023-11-01T17:00:00",
"user_id": 1,
"is_published": True,
"is_public": True,
"like_count": 25,
},
{
"event_id": 2,
"title": "Sample Event 2",
"description": "A different kind of event.",
"location": "Sample Location 2",
"start_time": "2023-11-05T10:00:00",
"end_time": "2023-11-05T16:00:00",
"user_id": 2,
"is_published": True,
"is_public": True,
"like_count": 10,
},
{
"event_id": 3,
"title": "Another Event",
"description": "Details about another event.",
"location": "Sample Location 3",
"start_time": "2023-11-10T12:00:00",
"end_time": "2023-11-10T20:00:00",
"user_id": 1,
"is_published": True,
"is_public": True,
"like_count": 30,
},
{
"event_id": 4,
"title": "Tech Conference 2023",
"description": "Join us for the latest in tech trends.",
"location": "Convention Center",
"start_time": "2023-11-15T09:00:00",
"end_time": "2023-11-17T18:00:00",
"user_id": 3,
"is_published": True,
"is_public": True,
"like_count": 75,
},
{
"event_id": 5,
"title": "Music Festival",
"description": "A three-day music extravaganza.",
"location": "Outdoor Arena",
"start_time": "2023-11-20T16:00:00",
"end_time": "2023-11-22T23:00:00",
"user_id": 2,
"is_published": True,
"is_public": True,
"like_count": 120,
},
{
"event_id": 6,
"title": "Local Charity Run",
"description": "Support a good cause while staying fit.",
"location": "City Park",
"start_time": "2023-11-25T07:30:00",
"end_time": "2023-11-25T11:00:00",
"user_id": 4,
"is_published": True,
"is_public": True,
"like_count": 40,
},
]
18 changes: 9 additions & 9 deletions backend/create_mock_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ def create_mock_events():
image=image_data
),[]),
(Event(
title="Skateboard Contest",
description="Compete or just have fun at our skateboard contest.",
extended_description="Our annual skateboard contest is back, bigger and better than ever. Skateboarders from all over the city will come together to showcase their skills and compete for prizes. With categories for different age groups and skill levels, everyone from novices to pros can participate. Even if you're not competing, come enjoy the vibrant atmosphere and cheer on your favorite skaters.",
location="Galbraith",
title="Hockey Game",
description="Come watch our varsity team play.",
extended_description="Join us at the Varisty Arena to watch our varsity hockey team play against Waterloo",
location="Varsity Arena",
start_time=start_time,
end_time=end_time,
author_id=None,
Expand All @@ -108,16 +108,16 @@ def create_mock_events():
),
["Clubs & Organizations", "Arts & Culture"]),
(Event(
title="Community Soccer Match",
description="Join us for a friendly soccer match.",
extended_description="The community soccer match is a weekly event that invites players of all skill levels to enjoy a fun and competitive game. It's a fantastic opportunity to stay active, meet new friends, and indulge in the love of the sport. Whether you're an experienced player or just looking to kick the ball around, the event is open to everyone.",
location="Varsity Stadium",
title="Spanish Lessons",
description="Want to learn Spanish? Join our club.",
extended_description="The spanish lesson meetup is a weekly event that invites non native spanish speakers to learn.",
location="Bahen",
start_time=start_time,
end_time=end_time,
author_id=None,
is_published=True,
like_count=5,
club="Skule Soccer",
club="Lesa",
image=image_data
),[]),
(Event(
Expand Down
45 changes: 9 additions & 36 deletions backend/datalayer_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from datalayer_abstract import DataLayer
from datalayer_tag import TagDataLayer
import logging
from sqlalchemy import or_

'''
class Event(db.Model):
Expand Down Expand Up @@ -101,6 +102,14 @@ def create_event(self, title, description, extended_description, location, start
# Commit the changes to the session after adding tags
db.session.commit()

def get_search_results_by_keyword(self, keyword):
keyword_word_pattern = "% {}%".format(keyword)
keyword_start_pattern = "{}%".format(keyword)
with app.app_context():
query = Event.query.filter(or_(Event.title.ilike(keyword_word_pattern), Event.club.ilike(keyword_word_pattern), Event.title.ilike(keyword_start_pattern), Event.club.ilike(keyword_start_pattern)))
results = query.all()
return results


def update_event(self, event_id, title, description, extended_description, location, image=None, is_published=True, start_time=None, end_time=None):
# get the event by event_id
Expand Down Expand Up @@ -133,42 +142,6 @@ def update_event(self, event_id, title, description, extended_description, locat

db.session.commit()

# if start_time is None:
# logging.info("Start time should not be empty")
# raise TypeError("Start time should not be empty")
# try:
# temp_start_datetime = datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S")
# except ValueError:
# logging.info("Start time is not given in correct format")
# raise ValueError("Start time is not given in correct format")

# if end_time is None:
# logging.info("End time should not be empty")
# raise TypeError("End time should not be empty")
# try:
# temp_end_datetime = datetime.strptime(end_time, "%Y-%m-%d %H:%M:%S")
# except ValueError:
# logging.info("End time is not given in correct format")
# raise ValueError("End time is not given in correct format")

# if temp_end_datetime < temp_start_datetime:
# logging.info("Start time should be after end time")
# raise ValueError("Start time should be after end time")
# event.start_time = temp_start_datetime
# event.end_time = temp_end_datetime

# with app.app_context():
# author = User.query.filter_by(username=author_name).first()
# if author is None:
# logging.info(f"Username {author_name} unable to post")
# raise TypeError(f"Username {author_name} unable to post")
# event.author_id = author.id

# if is_published is None:
# logging.info("Event was not published")
# raise TypeError("Event was not published")
# event.is_published = is_published

def get_all_events(self):
with app.app_context():
events = Event.query.all()
Expand Down
53 changes: 51 additions & 2 deletions backend/tests/test_datalayer_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ def test_event_by_id(test_client):

with app.app_context():
assert event.title == "Event 1"

def test_null_club(test_client):
user = UserDataLayer()
user.create_user(
Expand Down Expand Up @@ -494,4 +494,53 @@ def test_null_club(test_client):

with app.app_context():
event = Event.query.filter_by(title="Event 1").first()
assert event.club == None
assert event.club == None

def test_search_by_keyword(test_client):
user = UserDataLayer()
user.create_user(
username="testuser1",
email="[email protected]",
password_hash="testpassword",
password_salt="testpassword",
)

event = EventDataLayer()
event.create_event(
title="Event 1",
description="Kickoff for club 1",
extended_description="Extended decription for event 1 for club 1 that is much longer than just the description",
location="Toronto",
start_time="2023-10-03 3:30:00",
end_time="2023-10-03 4:00:00",
author_name='testuser1',
club="club 1",
is_published=True,
image=None,
)
event.create_event(
title="Faculty party planning",
description="Join us at our meeting",
extended_description="Extended decription for faculty party planning, longer than the description",
location="UC college",
start_time="2023-10-03 3:30:00",
end_time="2023-10-03 4:00:00",
author_name='testuser1',
club="Faculty Event Planning",
is_published=True,
image=None,
)

try:
query_results = event.get_search_results_by_keyword(keyword='Ev')
except ValueError as value_error:
logging.debug(f'Error: {value_error}')
assert value_error == None
except TypeError as type_error:
logging.debug(f'Error: {type_error}')
assert type_error == None

with app.app_context():
assert len(query_results) == 2
assert query_results[0].title == "Event 1"
assert query_results[1].club == "Faculty Event Planning"
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.