You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
12 KiB
Python
143 lines
12 KiB
Python
from django.shortcuts import get_object_or_404
|
|
from django.core.exceptions import ObjectDoesNotExist
|
|
from django.utils.dateparse import parse_date
|
|
|
|
from .models import *
|
|
|
|
from collections import OrderedDict
|
|
|
|
import datetime
|
|
import requests
|
|
|
|
|
|
example_json = [
|
|
{"day": "2022-12-19", "menus": [{"art": "Mensa", "name": "Spaghetti Carbonara", "price": "2,35 € / 4,15 € / 4,85 €", "allergens": ["GlW", "Mi"], "types": ["S", "IN"]}, {"art": "Mensa", "name": "Currywurst VEGAN Hot Pot(t) Karamellisierte Balsamico Zwiebeln Kartoffelspalten", "price": "4,05 € / 5,85 € / 6,55 €", "allergens": ["Sf", "Sl", "So", "Sw"], "types": ["ve", "vn"]}, {"art": "Mensa", "name": "Schupfnudeln, Schmorgemüse, Sojasoße", "price": "3,95 € / 5,75 € / 6,45 €", "allergens": ["GlW", "Se", "So"], "types": ["ve", "vn"]}, {"art": "Cafeteria", "name": "Currywurst Pommes Frites", "price": "4,70 € / 4,70 € / 4,70 €", "allergens": ["Sf"], "types": ["AGS"]}, {"art": "Cafeteria", "name": "Hähnchenschnitzel, Knuspermantel", "price": "2,95 € / 2,95 € / 2,95 €", "allergens": ["GlW", "GlG"], "types": ["G"]}, {"art": "Cafeteria", "name": "Kartoffelgratin, Erbsen, Karotten, Gouda", "price": "3,60 € / 3,60 € / 3,60 €", "allergens": ["Ei", "Mi"], "types": ["ve"]}, {"art": "Cafeteria", "name": "Kartoffelgratin, Hähnchenbruststreifen, Gouda", "price": "3,95 € / 3,95 € / 3,95 €", "allergens": ["Ei", "Mi"], "types": ["G"]}, {"art": "Cafeteria", "name": "Ofenkartoffel mit Sour Creme [Bio]", "price": "3,30 € / 3,30 € / 3,30 €", "allergens": ["Mi"], "types": ["ve", "BIO"]}, {"art": "Cafeteria", "name": "OfenkartoffelTomaten- Zwiebel- Marmelade", "price": "3,30 € / 3,30 € / 3,30 €", "allergens": ["Sf", "Sw"], "types": ["ve", "vn"]}, {"art": "Cafeteria", "name": "Ofenkartoffel Hähnchenstreifen", "price": "3,80 € / 3,80 € / 3,80 €", "allergens": ["Mi"], "types": ["G"]}]},
|
|
{"day": "2022-12-20", "menus": [{"art": "Mensa", "name": "Linseneintopf Baguettebrot", "price": "2,35 € / 4,15 € / 4,85 €", "allergens": ["Sl", "Sw", "GlW"], "types": ["ve", "vn"]}, {"art": "Mensa", "name": "Phat Krapao Würzige Thai Soja Bolognese, Ingwer, Basilikum, Koriander, Limettenblätter, Mienudeln", "price": "2,80 € / 4,60 € / 5,30 €", "allergens": ["GlW", "GlG", "So"], "types": ["IN", "ve", "vn"]}, {"art": "Mensa", "name": "Bockwurst zum Eintopf", "price": "1,00 € / 1,10 € / 1,20 €", "allergens": [], "types": ["S"]}, {"art": "Mensa", "name": "Filipino Beef Caldereta Basmatireis", "price": "3,50 € / 5,30 € / 6,00 €", "allergens": ["Fi", "GlW", "Mi", "Sf", "So"], "types": ["G", "R", "IN"]}, {"art": "Cafeteria", "name": "Hähnchenschnitzel, Knuspermantel", "price": "2,95 € / 2,95 € / 2,95 €", "allergens": ["GlW", "GlG"], "types": ["G"]}, {"art": "Cafeteria", "name": "Currywurst Pommes Frites", "price": "4,70 € / 4,70 € / 4,70 €", "allergens": ["Sf"], "types": ["AGS"]}, {"art": "Cafeteria", "name": "Kartoffelgratin, Hähnchenbruststreifen, Gouda", "price": "3,95 € / 3,95 € / 3,95 €", "allergens": ["Ei", "Mi"], "types": ["G"]}, {"art": "Cafeteria", "name": "Kartoffelgratin, Erbsen, Karotten, Gouda", "price": "3,60 € / 3,60 € / 3,60 €", "allergens": ["Ei", "Mi"], "types": ["ve"]}, {"art": "Cafeteria", "name": "OfenkartoffelTomaten- Zwiebel- Marmelade", "price": "3,30 € / 3,30 € / 3,30 €", "allergens": ["Sf", "Sw"], "types": ["ve", "vn"]}, {"art": "Cafeteria", "name": "Ofenkartoffel mit Sour Creme [Bio]", "price": "3,30 € / 3,30 € / 3,30 €", "allergens": ["Mi"], "types": ["ve", "BIO"]}, {"art": "Cafeteria", "name": "Ofenkartoffel Hähnchenstreifen", "price": "3,80 € / 3,80 € / 3,80 €", "allergens": ["Mi"], "types": ["G"]}]},
|
|
{"day": "2022-12-21", "menus": [{"art": "Mensa", "name": "Currywurst Hot Pot(t) Kartoffelspalten", "price": "3,90 € / 5,70 € / 6,40 €", "allergens": ["Sf", "Sl", "GlW"], "types": ["AGS"]}, {"art": "Mensa", "name": "Pasta, Kürbis- Ricotta- Soße, Walnüsse", "price": "2,35 € / 4,15 € / 4,85 €", "allergens": ["GlW", "Mi", "NW"], "types": ["ve"]}, {"art": "Mensa", "name": "Rindfleischcurry, Kokos, Karotten, Koriander Basmatireis", "price": "4,10 € / 5,90 € / 6,60 €", "allergens": ["GlW", "Mi", "Sf", "So"], "types": ["R"]}, {"art": "Cafeteria", "name": "Kartoffelgratin, Erbsen, Karotten, Gouda", "price": "3,60 € / 3,60 € / 3,60 €", "allergens": ["Ei", "Mi"], "types": ["ve"]}, {"art": "Cafeteria", "name": "Kartoffelgratin, Hähnchenbruststreifen, Gouda", "price": "3,95 € / 3,95 € / 3,95 €", "allergens": ["Ei", "Mi"], "types": ["G"]}, {"art": "Cafeteria", "name": "Ofenkartoffel Hähnchenstreifen", "price": "3,80 € / 3,80 € / 3,80 €", "allergens": ["Mi"], "types": ["G"]}, {"art": "Cafeteria", "name": "Ofenkartoffel mit Sour Creme [Bio]", "price": "3,30 € / 3,30 € / 3,30 €", "allergens": ["Mi"], "types": ["ve", "BIO"]}, {"art": "Cafeteria", "name": "OfenkartoffelTomaten- Zwiebel- Marmelade", "price": "3,30 € / 3,30 € / 3,30 €", "allergens": ["Sf", "Sw"], "types": ["ve", "vn"]}]},
|
|
{"day": "2022-12-22", "menus": [{"art": "Mensa", "name": "Spaghetti Carbonara", "price": "2,35 € / 4,15 € / 4,85 €", "allergens": ["Ei", "GlW", "Mi"], "types": ["S", "IN"]}, {"art": "Mensa", "name": "Tortellini, Kicherbsen, Spitzkohl, Cashewkerne und Rosmarin", "price": "3,50 € / 5,30 € / 6,00 €", "allergens": ["GlW", "NC"], "types": ["ve", "vn"]}, {"art": "Mensa", "name": "Bockwurst zum Eintopf", "price": "", "allergens": [], "types": ["S"]}, {"art": "Mensa", "name": "Vegetarisches Schnitzel, mediterran gefüllt Kartoffelpüree Gurkensalat", "price": "3,65 € / 5,45 € / 6,15 €", "allergens": ["Ei", "GlW", "GlH", "Mi"], "types": ["ve"]}, {"art": "Mensa", "name": "Linseneintopf", "price": "2,00 € / 3,80 € / 4,50 €", "allergens": ["Sl", "Sw"], "types": ["ve", "vn"]}, {"art": "Cafeteria", "name": "Kartoffelgratin, Hähnchenbruststreifen, Gouda", "price": "3,95 € / 3,95 € / 3,95 €", "allergens": ["Ei", "Mi"], "types": ["G"]}, {"art": "Cafeteria", "name": "Kartoffelgratin, Erbsen, Karotten, Gouda", "price": "3,60 € / 3,60 € / 3,60 €", "allergens": ["Ei", "Mi"], "types": ["ve"]}, {"art": "Cafeteria", "name": "Ofenkartoffel mit Sour Creme [Bio]", "price": "3,30 € / 3,30 € / 3,30 €", "allergens": ["Mi"], "types": ["ve", "BIO"]}, {"art": "Cafeteria", "name": "Ofenkartoffel Hähnchenstreifen", "price": "3,80 € / 3,80 € / 3,80 €", "allergens": ["Mi"], "types": ["G"]}, {"art": "Cafeteria", "name": "OfenkartoffelTomaten- Zwiebel- Marmelade", "price": "", "allergens": ["Sf", "Sw"], "types": ["ve", "vn"]}]},
|
|
{"day": "2022-12-23", "menus": [{"art": "Mensa", "name": "Spaghetti Carbonara", "price": "2,35 € / 4,15 € / 4,85 €", "allergens": ["Ei", "GlW", "Mi"], "types": ["S", "IN"]}, {"art": "Mensa", "name": "Tortellini, Kicherbsen, Spitzkohl, Cashewkerne und Rosmarin", "price": "3,50 € / 5,30 € / 6,00 €", "allergens": ["GlW", "NC"], "types": ["ve", "vn"]}, {"art": "Mensa", "name": "Bockwurst zum Eintopf", "price": "", "allergens": [], "types": ["S"]}, {"art": "Mensa", "name": "Vegetarisches Schnitzel, mediterran gefüllt Kartoffelpüree Gurkensalat", "price": "3,65 € / 5,45 € / 6,15 €", "allergens": ["Ei", "GlW", "GlH", "Mi"], "types": ["ve"]}, {"art": "Mensa", "name": "Linseneintopf", "price": "2,00 € / 3,80 € / 4,50 €", "allergens": ["Sl", "Sw"], "types": ["ve", "vn"]}, {"art": "Cafeteria", "name": "Kartoffelgratin, Hähnchenbruststreifen, Gouda", "price": "3,95 € / 3,95 € / 3,95 €", "allergens": ["Ei", "Mi"], "types": ["G"]}, {"art": "Cafeteria", "name": "Kartoffelgratin, Erbsen, Karotten, Gouda", "price": "3,60 € / 3,60 € / 3,60 €", "allergens": ["Ei", "Mi"], "types": ["ve"]}, {"art": "Cafeteria", "name": "Ofenkartoffel mit Sour Creme [Bio]", "price": "3,30 € / 3,30 € / 3,30 €", "allergens": ["Mi"], "types": ["ve", "BIO"]}, {"art": "Cafeteria", "name": "Ofenkartoffel Hähnchenstreifen", "price": "3,80 € / 3,80 € / 3,80 €", "allergens": ["Mi"], "types": ["G"]}, {"art": "Cafeteria", "name": "OfenkartoffelTomaten- Zwiebel- Marmelade", "price": "", "allergens": ["Sf", "Sw"], "types": ["ve", "vn"]}]}]
|
|
|
|
|
|
def load_data(locations, checked_types, status):
|
|
current_week = datetime.date.today().isocalendar().week
|
|
days = Day.objects.filter(date__week=current_week)
|
|
|
|
for location in locations:
|
|
menus = Menu.objects.filter(days__in=days, locations=location)
|
|
if not menus.exists():
|
|
fetched_data = fetch(location.mensa_id)
|
|
store(fetched_data, location)
|
|
|
|
data = formatted_menu_data(locations, checked_types, status)
|
|
return data
|
|
|
|
|
|
def formatted_menu_data(locations, checked_types, status):
|
|
current_week = datetime.date.today().isocalendar().week
|
|
days = Day.objects.filter(date__week=current_week)
|
|
|
|
formatted_data = {}
|
|
|
|
for day in days:
|
|
formatted_data[str(day.date)] = []
|
|
|
|
for day in days:
|
|
for location in locations:
|
|
menus = Menu.objects.filter(days=day, locations=location)
|
|
for menu in menus:
|
|
|
|
|
|
# AND or OR filter ???
|
|
if set(checked_types).issubset(set(menu.types)): # <-- AND
|
|
|
|
|
|
|
|
formatted_data[str(day.date)].append({
|
|
'art': menu.art,
|
|
'name': menu.name,
|
|
'price': menu.price if status is None else menu.get_price[status],
|
|
'allergens': menu.get_allergens,
|
|
'types': menu.get_types,
|
|
'likes': menu.likes,
|
|
'location': location.name,
|
|
'pk': menu.pk,
|
|
})
|
|
return formatted_data
|
|
|
|
|
|
def store(data, location):
|
|
for day_json in data:
|
|
date_string= day_json['day']
|
|
menus_json = day_json['menus']
|
|
|
|
date = parse_date(date_string)
|
|
|
|
if not Day.objects.filter(date=date).exists():
|
|
Day(date=date).save()
|
|
|
|
day = Day.objects.get(date=date)
|
|
|
|
for menu_json in menus_json:
|
|
art = menu_json['art']
|
|
name = menu_json['name']
|
|
price = menu_json['price'] or "0,00€ / 0,00€ / 0,00€"
|
|
allergens = menu_json['allergens']
|
|
types = menu_json['types']
|
|
|
|
menu_exists = Menu.objects.filter(art=art, name=name, price=price, allergens=allergens, types=types).exists()
|
|
|
|
if not menu_exists:
|
|
Menu(art=art, name=name, price=price, allergens=allergens, types=types).save()
|
|
|
|
menu = Menu.objects.get(art=art, name=name, price=price, allergens=allergens, types=types)
|
|
menu.locations.add(location)
|
|
menu.days.add(day)
|
|
menu.save()
|
|
|
|
|
|
def fetch(mensa_id: int):
|
|
res = requests.get('https://mensa.fly.dev/' + str(mensa_id))
|
|
if res.status_code != 200:
|
|
raise Exception('request failed')
|
|
return res.json()
|
|
|
|
|
|
def models_from_json(mensa_id: int):
|
|
for day_json in fetch_menus(mensa_id):
|
|
day_date = datetime.datetime.strptime(day_json['day'], '%Y-%m-%d').date()
|
|
|
|
if not Day.objects.filter(mensa_id=mensa_id, date__contains=day_date):
|
|
# create new day model ONLY if it does not yet exist for the given
|
|
# day_date(s) and mensa_id.
|
|
|
|
Day(mensa_id=mensa_id, date=day_date).save()
|
|
day = Day.objects.get(mensa_id=mensa_id, date=day_date)
|
|
|
|
for menu_json in day_json['menus']:
|
|
# if meal already exists, simply add day to related menus.
|
|
# otherwise, build new meal model from json with the specified menu
|
|
# as the first related menu.
|
|
|
|
if not Menu.objects.filter(name=menu_json['name']):
|
|
Menu.from_json(menu_json, day).save()
|
|
|
|
day.menus.add(Menu.objects.get(name=menu_json['name']))
|
|
|
|
|
|
def days_as_json(mensa_ids: list, types_filter: list, price_filter: str):
|
|
cw = datetime.date.today().isocalendar().week
|
|
dates = list(dict.fromkeys([day.date for day in Day.objects.filter(date__week=cw)]))
|
|
|
|
days_list = []
|
|
for date in dates:
|
|
day_json = { 'day': date, 'menus': [] }
|
|
for mensa_id in mensa_ids:
|
|
try:
|
|
day = Day.objects.get(mensa_id=mensa_id, date=date)
|
|
for menu in Menu.objects.filter(day=day, related_types__in=Type.objects.filter(type__in=types_filter) if types_filter else Type.objects.all()).distinct():
|
|
day_json['menus'].append({ 'menu': menu, 'mensa_id': mensa_id })
|
|
except ObjectDoesNotExist:
|
|
pass
|
|
days_list.append(day_json)
|
|
return days_list
|