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

Dev hp main deployment #165

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 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
1 change: 0 additions & 1 deletion app/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
# The sole purpose of this file was to waste my precious 15 minutes fixing the import errors
11 changes: 8 additions & 3 deletions app/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@
import os.path
import os

from app.main import db, es # db is for database and es is for elasticsearch
from app.globals import Role
from app.main import db # db is for database
from app.globals import Role, USE_SIMPLE_SEARCH
from app.auth import organizer_required, user_required
from app.database import Credentials, EventRegistration, EventDetails, EventRating
from app.forms import EventCreateForm
from app.analytics import get_user_analytics, get_avg_rating

if not USE_SIMPLE_SEARCH:
from app.main import es # es is for elasticsearch

events = Blueprint("events", __name__)


Expand Down Expand Up @@ -190,7 +193,8 @@ def create_event():
db.session.add(new_event)
db.session.commit()

add_event_to_index(new_event)
if not USE_SIMPLE_SEARCH:
add_event_to_index(new_event)

return redirect(url_for("events.show_event_admin", id=new_event.id))

Expand Down Expand Up @@ -332,6 +336,7 @@ def register_for_event(event_id):
4: If the user is already registered for the event
401 error: If the event is a past event
"""

# Check for valid event ID
if event_id is None:
logging.info("Cannot register user with an event ID: None")
Expand Down
3 changes: 2 additions & 1 deletion app/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ class Role(Enum):
# NOTE: Do not add a tag named "clear", since it has a special functionality
FILTERS = ["In-Person", "Today", "Free", *EVENT_CATEGORIES, "Past Events"]

DB_NAME = "database.db"
DB_NAME = "database.db"
USE_SIMPLE_SEARCH=True
51 changes: 26 additions & 25 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
## Initialize and import databases schemas
db = SQLAlchemy()
from app.database import Credentials, EventDetails
from app.globals import DB_NAME, USE_SIMPLE_SEARCH

# Initialize logger module
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
Expand Down Expand Up @@ -37,10 +38,9 @@ def create_elasticsearch(elasticsearch_host, max_retries=60, retry_delay=5):

return es

elasticsearch_host = os.environ["ELASTICSEARCH_HOST"]
es = create_elasticsearch(elasticsearch_host)

from app.globals import DB_NAME
if not USE_SIMPLE_SEARCH:
elasticsearch_host = os.environ["ELASTICSEARCH_HOST"]
es = create_elasticsearch(elasticsearch_host)

def create_app(debug):
app = Flask(__name__)
Expand Down Expand Up @@ -81,27 +81,28 @@ def create_app(debug):

# Index the events database using elasticsearch
# Scrape any existing "junk" data
if es.indices.exists(index="events"):
es.options(ignore_status=[400, 404]).indices.delete(index="events")
# Initialize the events index to an empty dict
if not es.indices.exists(index="events"):
es.index(index="events", document={})

events_data = EventDetails.query.all()
for row in events_data:
event_detail = {
"id": str(getattr(row, "id")),
"name": str(getattr(row, "name")),
"description": str(getattr(row, "short_description")),
"category": str(getattr(row, "category")),
"venue": str(getattr(row, "venue")),
"additional_info": str(getattr(row, "additional_info")),
}
logging.info("The event dict for indexing:", event_detail)
es.index(index="events", document=event_detail)

es.indices.refresh(index="events")
logging.info(es.cat.count(index="events", format="json"))
if not USE_SIMPLE_SEARCH:
if es.indices.exists(index="events"):
es.options(ignore_status=[400, 404]).indices.delete(index="events")
# Initialize the events index to an empty dict
if not es.indices.exists(index="events"):
es.index(index="events", document={})

events_data = EventDetails.query.all()
for row in events_data:
event_detail = {
"id": str(getattr(row, "id")),
"name": str(getattr(row, "name")),
"description": str(getattr(row, "short_description")),
"category": str(getattr(row, "category")),
"venue": str(getattr(row, "venue")),
"additional_info": str(getattr(row, "additional_info")),
}
logging.info("The event dict for indexing:", event_detail)
es.index(index="events", document=event_detail)

es.indices.refresh(index="events")
logging.info(es.cat.count(index="events", format="json"))

login_manager = LoginManager()
login_manager.init_app(app)
Expand Down
76 changes: 69 additions & 7 deletions app/search.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
from flask import Blueprint, render_template, request, redirect, url_for
import logging

from app.main import es

from app.globals import USE_SIMPLE_SEARCH
from app.auth import login_required
from app.database import EventDetails

# To switch between two different serach implementation
if not USE_SIMPLE_SEARCH:
from app.main import es

search = Blueprint("search", __name__)

Expand All @@ -13,6 +19,35 @@ def search_autocomplete():
# Login won't be required for this method

query = request.args["search"].lower()

if USE_SIMPLE_SEARCH:
# Using database for autocomplete suggestions
# Use simple search algorithm
result = []

# If empty query return empty list
if (query == ""):
return result

# Query the events database
events_data = EventDetails.query.all()

for row in events_data:
# Check if title matches
event_name = str(getattr(row, "name"))
event_id = str(getattr(row, "id"))

if (query in event_name.lower()):
logging.info("Query matched event: %s - %s", event_name, event_id)

# Append the IDS
result.append([event_name, event_id])

else:
logging.info("Query did not match event: %s", event_name)

return result

tokens = query.split(" ")

logging.info("Search autocomplete received the query: ", tokens)
Expand Down Expand Up @@ -75,11 +110,37 @@ def search_events(filter="all"):
# Primary ElasticSearch retrival logic
# Gets the events depending on the search query
def get_eventids_matching_search_query(query):

query = query.lower()

if USE_SIMPLE_SEARCH:
# Use simple search algorithm
list_event_ids = []

# Query the events database
events_data = EventDetails.query.all()

for row in events_data:
# Check if title matches
event_name = str(getattr(row, "name")).lower()

if (query in event_name):
logging.info("Query matched event: %s", event_name)

# Append the IDS
list_event_ids.append(getattr(row, "id"))

else:
logging.info("Query did not match event: %s", event_name)

return list_event_ids

# Here we use elastic search if config USE_SIMPLE_SEARCH is False
tokens = query.split(" ")

# This block creates a list of clauses, each specifying a fuzzy matching criterion for a token in the 'tokens' list.
# Each clause is configured to perform a fuzzy match on the 'name' field of the Elasticsearch documents.
# Make a JSON query to elastic search to get the list of relevant events
# This block creates a list of clauses, each specifying a fuzzy matching criterion for a token in the 'tokens' list.
# Each clause is configured to perform a fuzzy match on the 'name' field of the Elasticsearch documents.
# Make a JSON query to elastic search to get the list of relevant events
clauses = [
{
"span_multi": {
Expand All @@ -89,14 +150,15 @@ def get_eventids_matching_search_query(query):
for i in tokens
]

# Constructing the search query parameters.
# This operation looks for proximity matches of the clauses with zero distance and not necessarily in order.
# Constructing the search query parameters.
# This operation looks for proximity matches of the clauses with zero distance and not necessarily in order.
payload = {
"bool": {
"must": [{"span_near": {"clauses": clauses, "slop": 0, "in_order": False}}]
}
}
# It searches the 'events' index and retrieves a maximum of 10 matching results.

# It searches the 'events' index and retrieves a maximum of 10 matching results.
resp = es.search(index="events", query=payload, size=10)

## Make a dict for relevant event details
Expand Down
2 changes: 1 addition & 1 deletion app/templates/user_events.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ <h1>My Events</h1>

<!-- <div class="col-xs-12 col-sm-12" style="text-align: center; display: block; position: relative;"> -->
<!-- The text box to display autocomplete suggestions -->
<div class="dropdown-menu autocomplete-drop-down"></div>
<!-- <div class="dropdown-menu autocomplete-drop-down"></div> -->
<!-- </div> -->
</div>
</div>
Expand Down
36 changes: 18 additions & 18 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,29 @@ services:
- "5000:5000"
environment:
- FLASK_APP=app/main.py
- ELASTICSEARCH_HOST=elasticsearch
depends_on:
- elasticsearch
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are removing elastic search then we don't necessarily need this file because we can run the flask app using the Dockerfile

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, the change was made to alter the GitHub workflow

# - ELASTICSEARCH_HOST=elasticsearch
# depends_on:
# - elasticsearch
networks:
- elk
volumes:
- ./app:/app # mounting local directory with container directory to reflect changes to flask application.

elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.7.0
ports:
- "9200:9200"
- "9300:9300"
environment:
- "xpack.security.enabled=false"
- "discovery.type=single-node"
networks:
- elk
healthcheck:
test: ["CMD", "curl", "-f", "http://elasticsearch:9200"]
interval: "30s"
timeout: "10s"
retries: 5
# elasticsearch:
# image: docker.elastic.co/elasticsearch/elasticsearch:8.7.0
# ports:
# - "9200:9200"
# - "9300:9300"
# environment:
# - "xpack.security.enabled=false"
# - "discovery.type=single-node"
# networks:
# - elk
# healthcheck:
# test: ["CMD", "curl", "-f", "http://elasticsearch:9200"]
# interval: "30s"
# timeout: "10s"
# retries: 5

networks:
elk:
Expand Down
Loading