Skip to content

Commit

Permalink
Merge pull request #56 from HungrySlugs-CSE115A/simple-backend-webscr…
Browse files Browse the repository at this point in the history
…aper-update

locations will update on there own now
  • Loading branch information
IanHollow authored May 7, 2024
2 parents 70ba251 + 7bf8c09 commit c8cc81f
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 65 deletions.
10 changes: 5 additions & 5 deletions app/[dh_choice]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export default function Page({ searchParams }) {

useEffect(() => {
axios
.get("http://localhost:8000/myapi/dining-halls/")
.get("http://localhost:8000/myapi/locations/")
.then((response) => {
const dhs = response.data.locations;
const dh_index = name_to_dh_index(searchParams.name, dhs);
Expand All @@ -95,7 +95,7 @@ export default function Page({ searchParams }) {
alert("No food categories found");
return;
}
const timeOfDay = getTimeOfDay();
const timeOfDay = getTimeOfDay();
const timeIndex = a_dh.categories.findIndex(category => category.name.toLowerCase() === timeOfDay);
if (timeIndex !== -1) {
setExpandedCategory(timeIndex);
Expand All @@ -109,7 +109,7 @@ export default function Page({ searchParams }) {


useEffect(() => {
const timeOfDay = getTimeOfDay();
const timeOfDay = getTimeOfDay();
const timeIndex = categories.findIndex(category => category.name.toLowerCase() === timeOfDay);
if (timeIndex !== -1) {
setExpandedCategory(timeIndex);
Expand All @@ -131,7 +131,7 @@ export default function Page({ searchParams }) {
function getTimeOfDay(): string {
const currentTime = new Date();
const currentHour = currentTime.getHours();

if (currentHour >= 7 && currentHour < 11) {
return "breakfast";
} else if (currentHour >= 11 && currentHour < 16) {
Expand Down Expand Up @@ -161,7 +161,7 @@ export default function Page({ searchParams }) {
<main>
<div className="container mx-auto">
<h2 className="text-2xl mb-4">{searchParams.name}</h2>

{/* Search button */}
<div>
<button onClick={handleSearch}>Search</button>
Expand Down
2 changes: 1 addition & 1 deletion app/global_search/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const BarebonesComponent = () => {

useEffect(() => {
axios
.get('http://localhost:8000/myapi/dining-halls/')
.get('http://localhost:8000/myapi/locations/')
.then((response) => {
const dhsData: DiningHall[] = response.data.locations;
setDhs(dhsData);
Expand Down
6 changes: 3 additions & 3 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function Home() {

useEffect(() => {
axios
.get("http://localhost:8000/myapi/dining-halls/")
.get("http://localhost:8000/myapi/locations/")
.then((response) => {
const dhs: DiningHall[] = response.data["locations"];
setDhs(dhs);
Expand Down Expand Up @@ -119,7 +119,7 @@ function Home() {
</ul>
</div>
)}

{noFoodsFound && (
<div>
<h3>No foods found at this dining hall.</h3>
Expand Down Expand Up @@ -183,4 +183,4 @@ export default function Page() {
<button onClick={handleLogout} className="p-2 mt-2 text-white bg-red-600 rounded">Logout</button>
</GoogleOAuthProvider>
);
}
}
6 changes: 3 additions & 3 deletions app/search/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const BarebonesComponent = () => {

useEffect(() => {
axios
.get('http://localhost:8000/myapi/dining-halls/')
.get('http://localhost:8000/myapi/locations/')
.then((response) => {
const dhsData: DiningHall[] = response.data.locations;
setDhs(dhsData);
Expand Down Expand Up @@ -70,7 +70,7 @@ const BarebonesComponent = () => {
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
{/* Dining Hall Name */}
<h2 style={{ fontSize: '60px', marginBottom: '20px' }}>{diningHall} Search</h2>

{/* Search bar */}
<div className="search-bar" style={{ marginTop: '20px' }}> {/* Adjust margin as needed */}
<input
Expand All @@ -81,7 +81,7 @@ const BarebonesComponent = () => {
/>
<button onClick={handleSearch}>Search</button>
</div>

{/* Display search results if button clicked */}
{showSearchResults && (
<div>
Expand Down
31 changes: 0 additions & 31 deletions backend/myapi/db_functions/dining_halls.py

This file was deleted.

31 changes: 31 additions & 0 deletions backend/myapi/db_functions/locations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from ..models import locations_collection


def remove_locations_from_db(names: list[str]) -> None:
for name in names:
locations_collection.delete_many({"name": name})


def add_locations_to_db(locations: list[dict]) -> None:
for dh in locations:
locations_collection.insert_one(dh)


def get_names_of_locations(locations: list[dict]) -> list[str]:
names = []
for dh in locations:
names.append(dh["name"])
return names


def remove_add_locations_to_db(locations: list[dict]) -> None:
# get names of locations
names = get_names_of_locations(locations)
# remove locations with the names
remove_locations_from_db(names)
# add locations to db
add_locations_to_db(locations)


def get_all_locations_from_db() -> list[dict]:
return list(locations_collection.find({}))
61 changes: 61 additions & 0 deletions backend/myapi/db_functions/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from celery.app import task
from ..models import tasks_collection
from datetime import datetime

# import time from django
from django.utils import timezone

"""
name: str
last_update: str
"""

def set_task_last_update(task_name: str) -> None:
"""
Set the time that the task were last update the time should be based upon the database time
"""
# get the time from django
time_now: datetime = timezone.now()

# convert the time to a string
time_str = time_now.strftime("%Y-%m-%d %H:%M:%S")

# get the task from the tasks collection
task: dict | None = tasks_collection.find_one({"name": task_name})

# check if the task exists
if task is None:
# create a new task
task = {
"name": task_name,
"last_update": time_str
}
# insert the task into the tasks collection
tasks_collection.insert_one(task)
else:
# update the task
tasks_collection.update_one(
{"name": task_name},
{"$set": {"last_update": time_str}}
)

def get_task_last_update(task_name: str) -> datetime | None:
"""
Get the last update time of the task from the database
"""
# find the task in the tasks collection
task: dict | None = tasks_collection.find_one({"name": task_name})

# check if the location exists
if task is None:
return None

# get the last update time
last_update = task["last_update"]

# convert the string to a datetime object
last_update_time = datetime.strptime(last_update, "%Y-%m-%d %H:%M:%S")

return last_update_time


32 changes: 19 additions & 13 deletions backend/myapi/models.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
from django.db import models
from django.conf.locale import ta
from celery.app import task
from requests import get
from db_connection import db

# Create your models here.

# Dining Hall Model
dining_hall_collection = db["dining_hall"]
# locations Model
locations_collection = db["locations"]

# Food Rating Model
foods_collection = db["food_rating"]
# Food Model
foods_collection = db["food"]

# Users Model
users_collection = db["users"]

# Tasks Model
tasks_collection = db["tasks"]

# NOTE: This is temporary and will be replaced with a background task
from webscraper.food_locations import FoodLocations

# Fetch dining halls
fo = FoodLocations()
# Get dining halls as a list of json objects
dining_halls: list[dict] = [dh.to_dict() for dh in fo.get_locations()]
# Add dining halls to db
from .db_functions.dining_halls import remove_add_dining_halls_to_db
# # NOTE: This is temporary and will be replaced with a background task
# from webscraper.food_locations import FoodLocations

remove_add_dining_halls_to_db(dining_halls)
# # Fetch dining halls
# fo = FoodLocations()
# # Get dining halls as a list of json objects
# dining_halls: list[dict] = [dh.to_dict() for dh in fo.get_locations()]
# # Add dining halls to db
# from .db_functions.dining_halls import remove_add_dining_halls_to_db

# remove_add_dining_halls_to_db(dining_halls)
2 changes: 1 addition & 1 deletion backend/myapi/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@

urlpatterns = [
path("hello-world/", views.hello_world, name="hello_world"),
path("dining-halls/", views.get_dining_halls, name="dining_halls"),
path("locations/", views.get_locations, name="locations"),
]
47 changes: 39 additions & 8 deletions backend/myapi/views.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,57 @@
from django.conf.locale import fr
from rest_framework.response import Response
from rest_framework.decorators import api_view

from .db_functions.dining_halls import get_all_dining_halls_from_db
from .db_functions.locations import get_all_locations_from_db, remove_add_locations_to_db
from .db_functions.tasks import set_task_last_update, get_task_last_update
from webscraper.food_locations import FoodLocations


from django.utils import timezone
from datetime import datetime

# Create your views here.
@api_view(["GET"])
def hello_world(request):
return Response({"message": "Hello, world!"})


# Get the list of dining halls
# Get the list of locations at UCSC and their information
@api_view(["GET"])
def get_dining_halls(request):
# Get all dining halls from the db
dining_halls: list[dict] = get_all_dining_halls_from_db()
def get_locations(request):
# Get the last update time of the locations
last_update: datetime | None = get_task_last_update(task_name="locations")

# get the current time and make it naive
time_now: datetime = timezone.now()
time_now = time_now.replace(tzinfo=None)

print("Last time : ", last_update)
print("Current time: ", time_now)

# check if not updated in the last hour
if last_update is None or (time_now - last_update).seconds > 3600:
print("Locations need to be updated...")
# fetch the locations from the web scraper and add them to the db
fo = FoodLocations()
locations: list[dict] = [dh.to_dict() for dh in fo.get_locations()]
# add the locations to the db
remove_add_locations_to_db(locations)

# update the last update time
set_task_last_update(task_name="locations")

else:
print("Locations are up to date. Getting from DB...")
# Get all locations from the db
locations: list[dict] = get_all_locations_from_db()

# remove the _id field from each dining hall
for dh in dining_halls:
dh.pop("_id")
for dh in locations:
if "_id" in dh:
dh.pop("_id")

# Convert the list of dining halls to json
json_data = {"locations": dining_halls}
json_data = {"locations": locations}

return Response(json_data)

0 comments on commit c8cc81f

Please sign in to comment.