Skip to content

Commit

Permalink
Merge pull request #4 from D-I-S-H/chartwells_api_script
Browse files Browse the repository at this point in the history
Chartwells api script
  • Loading branch information
That-Thing authored Nov 1, 2024
2 parents d4481d5 + d203aac commit bbea249
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 12 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Provides a REST API with MTU dinner menus from dineoncampus for quicker access f
```sh
./gradlew bootRun
```
Note: make sure to re-run the java application to regenerate the database before calling chartwells_query.py.

2. **Access the API:**
- The API will be available at `http://localhost:8080`
Expand Down
132 changes: 132 additions & 0 deletions chartwells_query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import sqlite3
import requests
import json
from datetime import datetime, timezone, timedelta
import time

#used to access the chartwells api from the viewpoint of a user normal
headers = {
'User-Agent': 'Mozilla/5.0'
}

#database_path = "database.db"
database_path = "Database/dish.db"

date_today = datetime.now(timezone(timedelta(hours=-4))).strftime('%Y-%m-%d')
date_tomorrow = (datetime.now(timezone(timedelta(hours=-4))) + timedelta(1)).strftime('%Y-%m-%d')
dates = {"today":date_today}#,"tomorrow":date_tomorrow}

#used to grab period data for a day and location
period_request = "https://api.dineoncampus.com/v1/location/{location}/periods?platform=0&date={date}"

#used to grab meal data for a given location, period, and date
meal_data_request = "https://api.dineoncampus.com/v1/location/{location}/periods/{period}?platform=0&date={date}"

dining_locations = {"Wadsworth":"64b9990ec625af0685fb939d"}#,"McNair":"64a6b628351d5305dde2bc08","DHH":"64e3da15e45d430b80c9b981"}

def main():
db_conection = sqlite3.connect(database_path)
db_cursor = db_conection.cursor()

for date in dates:
for location in dining_locations:
print(f"Grabbing periods for {date} {location}")
periods = get_periods(date, location)

print(periods)

#db_cursor.executemany("DELETE FROM time WHERE mealTime=:name", periods)
db_cursor.executemany("INSERT OR REPLACE INTO time VALUES (:name, :UUID)", periods)

for period in periods:
meal_json = get_meal_data(period["UUID"], date, location)
if meal_json != -1:
for station in meal_json["menu"]["periods"]["categories"]:
station["location"] = location
db_cursor.executemany("INSERT OR REPLACE INTO stations VALUES (:name, :location)", meal_json["menu"]["periods"]["categories"])

for station in meal_json["menu"]["periods"]["categories"]:
for item in station["items"]:
item["time"] = period["name"]
item["location"] = location
item["station"] = station["name"]
item["nutrients_json"] = handle_nutrients(db_cursor, item)

allergens_list = []
filters_list = []
for filter in item["filters"]:
if filter["type"] == "allergen":
allergens_list.append(filter["name"])
else:
filters_list.append(filter["name"])
item["allergens_json"] = str(allergens_list)
item["filters_json"] = str(filters_list)

db_cursor.executemany("INSERT OR REPLACE INTO menuItems VALUES (:name, :station, :ingredients, :portion, :desc, :nutrients_json, :calories, :time, :location, :allergens_json, :filters_json)", station["items"])

for item in station["items"]:
db_cursor.executemany("INSERT OR REPLACE INTO menuFilters VALUES (:name, :type)", item["filters"])
for filter in item["filters"]:
db_cursor.execute("INSERT OR REPLACE INTO itemFilterAssociations VALUES (?, ?, ?, ?, ?)", [item["name"], item["location"], item["time"], item["station"], filter["name"]])


db_conection.commit()


def get_periods(date, location):
request_string = period_request.format(date = dates[date], location = dining_locations[location])
print(request_string)
response = requests.get(request_string, headers=headers, timeout=10)
time.sleep(6)
response.raise_for_status()
if response.status_code != 204:
response_json = response.json()

period_list = []
if not response_json["closed"]:
for period in response_json["periods"]:
periods = {}
periods["name"] = period["name"]
periods["UUID"] = period["id"]
period_list.append(periods)
return period_list
else:
#TODO: Throw a nasty error here or something
print(f"ERROR: status code 204 not returned for {date} {location}")
return []

def get_meal_data(period, date, location):
request_string = meal_data_request.format(period = period, date = dates[date], location = dining_locations[location])
print(request_string)
response = requests.get(request_string, headers=headers, timeout=10)
time.sleep(6)
response.raise_for_status()
if response.status_code != 204:
response_json = response.json()

return response_json
else:
#TODO: Throw a nasty error here or something
print(f"ERROR: status code 204 not returned for {period} {date} {location}")
return -1

def handle_nutrients(db_cursor, item):
nutrients_list = []
nutrients_association_list = []
for nutrient in item["nutrients"]:
dictionary = {}
dictionary["name"] = nutrient["name"]
dictionary["value"] = nutrient["value"]
dictionary["uom"] = nutrient["uom"]
nutrients_list.append(dictionary.copy())
dictionary["itemName"] = item["name"]
dictionary["itemLocation"] = item["location"]
dictionary["itemTime"] = item["time"]
dictionary["itemStation"] = item["station"]
nutrients_association_list.append(dictionary.copy())
db_cursor.executemany("INSERT OR REPLACE INTO menuNutrients VALUES (:name, :value, :uom, :value_numeric)", item["nutrients"])
db_cursor.executemany("INSERT OR REPLACE INTO itemNutrientAssociations VALUES (:itemName, :itemLocation, :itemTime, :itemStation, :name, :value)", nutrients_association_list)
return str(nutrients_list)

if __name__=="__main__":
main()
85 changes: 73 additions & 12 deletions src/main/resources/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ PRAGMA foreign_keys = ON;

CREATE TABLE IF NOT EXISTS locations (
name TEXT PRIMARY KEY,
apiuuid CHAR(24)
apiUUID CHAR(24)
);

CREATE TABLE IF NOT EXISTS accounts (
Expand All @@ -12,31 +12,92 @@ CREATE TABLE IF NOT EXISTS accounts (
);

CREATE TABLE IF NOT EXISTS time (
mealTime TEXT PRIMARY KEY
mealTime TEXT PRIMARY KEY,
apiUUID CHAR(24)
);

CREATE TABLE IF NOT EXISTS stations (
stationName TEXT,
locationName TEXT,
PRIMARY KEY (stationName, locationName),
FOREIGN KEY (locationName) REFERENCES locations(name)
);

CREATE TABLE IF NOT EXISTS menuItems (
name TEXT,
station TEXT,
ingredients TEXT,
portion TEXT,
description TEXT,
nutrients TEXT,
calories INTEGER,
time TEXT,
location TEXT,
Allergens TEXT,
PRIMARY KEY (name, location),
allergens TEXT,
labels TEXT,
PRIMARY KEY (name, location, time, station),
FOREIGN KEY (time) REFERENCES time(mealTime),
FOREIGN KEY (location) REFERENCES location(name),
FOREIGN KEY (station) references stations(stationName)
);

CREATE TABLE IF NOT EXISTS menuFilters (
name TEXT primary key,
type TEXT
);

CREATE TABLE IF NOT EXISTS itemFilterAssociations (
itemName TEXT,
itemLocation TEXT,
itemTime TEXT,
itemStation TEXT,
filterName TEXT,
PRIMARY KEY (itemName, itemLocation, itemTime, itemStation, filterName),
FOREIGN KEY (itemName) REFERENCES menuItems(name),
FOREIGN KEY (itemLocation) REFERENCES menuItems(location),
FOREIGN KEY (itemTime) REFERENCES menuItems(time),
FOREIGN KEY (itemStation) REFERENCES menuItems(station),
FOREIGN KEY (filterName) REFERENCES menuItems(name)
);

CREATE TABLE IF NOT EXISTS menuNutrients (
name TEXT,
value TEXT,
uom TEXT,
valueNumeric TEXT,
PRIMARY KEY (name, value)
);

CREATE TABLE IF NOT EXISTS itemNutrientAssociations (
itemName TEXT,
itemLocation TEXT,
itemTime TEXT,
itemStation TEXT,
nutrientName TEXT,
nutrientValue TEXT,
PRIMARY KEY (itemName, itemLocation, itemTime, itemStation, nutrientName, nutrientValue),
FOREIGN KEY (itemName) REFERENCES menuItems(name),
FOREIGN KEY (itemLocation) REFERENCES menuItems(location),
FOREIGN KEY (itemTime) REFERENCES menuItems(time),
FOREIGN KEY (itemStation) REFERENCES menuItems(station),
FOREIGN KEY (nutrientName) REFERENCES menuNutrients(name),
FOREIGN KEY (nutrientValue) REFERENCES menuNutrients(value)
);

INSERT INTO locations(name, apiUUID) VALUES
('Wadsworth', '64b9990ec625af0685fb939d'),
('McNair', '64a6b628351d5305dde2bc08'),
('DHH', '64e3da15e45d430b80c9b981');
FOREIGN KEY (location) REFERENCES location(name)
);

CREATE TABLE IF NOT EXISTS ratings (
menuItemName TEXT,
menuItemLocation TEXT,
accountUsername TEXT,
rating INTEGER,
PRIMARY KEY (menuItemName, accountUsername),
FOREIGN KEY (menuItemName) REFERENCES menuItems(name),
FOREIGN KEY (menuItemLocation) REFERENCES menuItems(location),
FOREIGN KEY (accountUsername) REFERENCES accounts(username)
menuItemName TEXT,
menuItemLocation TEXT,
accountUsername TEXT,
rating INTEGER,
PRIMARY KEY (menuItemName, accountUsername),
FOREIGN KEY (menuItemName) REFERENCES menuItems(name),
FOREIGN KEY (menuItemLocation) REFERENCES menuItems(location),
FOREIGN KEY (accountUsername) REFERENCES accounts(username)
);

0 comments on commit bbea249

Please sign in to comment.