diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..d1080d5 --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'webprog5.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/mensa/__init__.py b/mensa/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mensa/admin.py b/mensa/admin.py new file mode 100644 index 0000000..e7e2e27 --- /dev/null +++ b/mensa/admin.py @@ -0,0 +1,19 @@ +from django.contrib import admin +from .models import Meal, Comment, DailyMenu, Mensa + +# Register your models here. +@admin.register(Mensa) +class MensaAdmin(admin.ModelAdmin): + pass + +@admin.register(Meal) +class MealAdmin(admin.ModelAdmin): + pass + +@admin.register(Comment) +class CommentAdmin(admin.ModelAdmin): + pass + +@admin.register(DailyMenu) +class DailyMenuAdmin(admin.ModelAdmin): + pass diff --git a/mensa/apps.py b/mensa/apps.py new file mode 100644 index 0000000..b052559 --- /dev/null +++ b/mensa/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class MensaConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'mensa' diff --git a/mensa/forms.py b/mensa/forms.py new file mode 100644 index 0000000..ff83c6d --- /dev/null +++ b/mensa/forms.py @@ -0,0 +1,10 @@ +from django import forms + +class FilterForm(forms.Form): + vegan = forms.BooleanField(label="Vegan", label_suffix="", required=False) + vegetarian = forms.BooleanField(label="Vegetarisch", label_suffix="", required=False) + price_for = forms.ChoiceField(choices=(('s', 'Student'), ('e','Employee'), ('g', 'Guest')), widget=forms.RadioSelect) + +class CommentForm(forms.Form): + username = forms.CharField(max_length=100) + text = forms.CharField(max_length=700) diff --git a/mensa/helpers.py b/mensa/helpers.py new file mode 100644 index 0000000..f3763a2 --- /dev/null +++ b/mensa/helpers.py @@ -0,0 +1,102 @@ +from .models import Mensa, DailyMenu, Meal + +import requests +import datetime + + +def fetch_mensa(mensa_id): + res = requests.get('https://mensa.fly.dev/' + str(mensa_id)) + if res.status_code != 200: + raise Exception('request failed') + return res.json() + + +def save_in_database(mensa_id): + # save mensa with mensa_id 'mensa_id' in database if entry does not exit yet + if mensa_id not in [m.mensa_id for m in Mensa.objects.all()]: + Mensa(mensa_id=mensa_id).save() + + # get mensa with 'mensa_id' from database + mensa = Mensa.objects.get(mensa_id=mensa_id) + + # cycle through days listed in fetched data + for day in fetch_mensa(mensa_id): + # save daily_menu for mensa with 'mensa_id' in database if entry does not exist yet + if day['day'] + str(mensa_id) not in [str(day.date) + str(day.mensa) for day in DailyMenu.objects.all()]: + DailyMenu(date=day['day'], mensa=mensa).save() + + # get this mensas daily_menu for current day from database + daily_menu = DailyMenu.objects.get(date=day['day'], mensa=mensa) + + # cycle through meals listed in current day + for meal in day['menus']: + name = meal['name'] + + # if meal with name 'name' already exists in database + if name in [meal_object.name for meal_object in Meal.objects.all()]: + # simply add current daily_menu to it's related_daily_menus + Meal.objects.get(name=name).related_daily_menus.add(daily_menu) + + # otherwise + else: + # create new meal object, save in database and add current daily_menu to it's related_daily_menus + art = meal['art'] + types = ' '.join(meal['types']) + allergens = ' '.join(meal['allergens']) + price_student = 0 + price_employee = 0 + price_guest = 0 + if " / " in meal['price']: + price_student = float(meal['price'].split(' / ')[0].replace('€', '').replace(',', '.')) + price_employee = float(meal['price'].split(' / ')[1].replace('€', '').replace(',', '.')) + price_guest = float(meal['price'].split(' / ')[2].replace('€', '').replace(',', '.')) + + new_meal = Meal(art=art, name=name, price_student=price_student, price_employee=price_employee, price_guest=price_guest, allergens=allergens, types=types) + new_meal.save() + new_meal.related_daily_menus.add(daily_menu) + new_meal.save() + + +def get_filtered_plan(mensa_id, flags): + + + + week = [] + for menu in DailyMenu.objects.filter(mensa=Mensa.objects.get(mensa_id=mensa_id), date__week=datetime.date.today().isocalendar().week): + meals = [] + for meal in Meal.objects.filter(related_daily_menus=menu, types__contains='vn' if flags['vegan'] else 've' if flags['vegetarian'] else ''): + meals.append({ + 'art': meal.art, + 'name': meal.name, + 'price': meal.price_student if flags['price_for'] == 's' else meal.price_employee if flags['price_for'] == 'e' else meal.price_guest, + 'allergens': meal.allergens, + 'types': meal.types, + 'likes': meal.likes, + 'dislikes': meal.dislikes, + 'pk': meal.pk + }) + week.append({'date': menu.date, 'meals': meals}) + return week + + +def filter_plan_old(plan, flags): + for day in plan: + filtered_menus = [] + for menu in day['menus']: + if ' / ' in menu['price']: + if flags['price_for'] == 's': + menu['price'] = menu['price'].split(' / ')[0] + elif flags['price_for'] == 'e': + menu['price'] = menu['price'].split(' / ')[1] + elif flags['price_for'] == 'g': + menu['price'] = menu['price'].split(' / ')[2] + if flags['vegan'] == True: + if 'vn' in menu['types']: + filtered_menus.append(menu) + elif flags['vegetarian'] == True: + if 've' in menu['types']: + filtered_menus.append(menu) + else: + filtered_menus.append(menu) + day['menus'] = filtered_menus + return plan diff --git a/mensa/migrations/0001_initial.py b/mensa/migrations/0001_initial.py new file mode 100644 index 0000000..58c301e --- /dev/null +++ b/mensa/migrations/0001_initial.py @@ -0,0 +1,24 @@ +# Generated by Django 4.1.3 on 2022-11-29 16:06 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='dish', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('priceStudent', models.DecimalField(decimal_places=4, max_digits=6)), + ('priceEmployee', models.DecimalField(decimal_places=4, max_digits=6)), + ('priceGast', models.DecimalField(decimal_places=4, max_digits=6)), + ], + ), + ] diff --git a/mensa/migrations/0002_dish_allergens_dish_types_alter_dish_priceemployee_and_more.py b/mensa/migrations/0002_dish_allergens_dish_types_alter_dish_priceemployee_and_more.py new file mode 100644 index 0000000..2a47425 --- /dev/null +++ b/mensa/migrations/0002_dish_allergens_dish_types_alter_dish_priceemployee_and_more.py @@ -0,0 +1,38 @@ +# Generated by Django 4.1.3 on 2022-11-29 16:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='dish', + name='allergens', + field=models.CharField(default='green', max_length=100), + ), + migrations.AddField( + model_name='dish', + name='types', + field=models.CharField(default='vegan', max_length=100), + ), + migrations.AlterField( + model_name='dish', + name='priceEmployee', + field=models.DecimalField(decimal_places=4, default=4.34, max_digits=6), + ), + migrations.AlterField( + model_name='dish', + name='priceGast', + field=models.DecimalField(decimal_places=4, default=5.34, max_digits=6), + ), + migrations.AlterField( + model_name='dish', + name='priceStudent', + field=models.DecimalField(decimal_places=4, default=3.34, max_digits=6), + ), + ] diff --git a/mensa/migrations/0003_alter_dish_priceemployee_alter_dish_pricegast_and_more.py b/mensa/migrations/0003_alter_dish_priceemployee_alter_dish_pricegast_and_more.py new file mode 100644 index 0000000..dcc8061 --- /dev/null +++ b/mensa/migrations/0003_alter_dish_priceemployee_alter_dish_pricegast_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 4.1.3 on 2022-12-02 16:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0002_dish_allergens_dish_types_alter_dish_priceemployee_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='dish', + name='priceEmployee', + field=models.CharField(max_length=100), + ), + migrations.AlterField( + model_name='dish', + name='priceGast', + field=models.CharField(max_length=100), + ), + migrations.AlterField( + model_name='dish', + name='priceStudent', + field=models.CharField(max_length=100), + ), + ] diff --git a/mensa/migrations/0004_dish_dislikes_dish_likes_alter_dish_allergens_and_more.py b/mensa/migrations/0004_dish_dislikes_dish_likes_alter_dish_allergens_and_more.py new file mode 100644 index 0000000..a10dc61 --- /dev/null +++ b/mensa/migrations/0004_dish_dislikes_dish_likes_alter_dish_allergens_and_more.py @@ -0,0 +1,42 @@ +# Generated by Django 4.1.3 on 2022-12-02 17:09 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0003_alter_dish_priceemployee_alter_dish_pricegast_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='dish', + name='dislikes', + field=models.IntegerField(default=0, max_length=100), + ), + migrations.AddField( + model_name='dish', + name='likes', + field=models.IntegerField(default=0, max_length=100), + ), + migrations.AlterField( + model_name='dish', + name='allergens', + field=models.CharField(max_length=100), + ), + migrations.AlterField( + model_name='dish', + name='types', + field=models.CharField(max_length=100), + ), + migrations.CreateModel( + name='comments', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('comment', models.CharField(max_length=700)), + ('dish', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mensa.dish')), + ], + ), + ] diff --git a/mensa/migrations/0005_rename_comments_comment_and_more.py b/mensa/migrations/0005_rename_comments_comment_and_more.py new file mode 100644 index 0000000..507eb49 --- /dev/null +++ b/mensa/migrations/0005_rename_comments_comment_and_more.py @@ -0,0 +1,32 @@ +# Generated by Django 4.1.4 on 2022-12-12 16:28 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0004_dish_dislikes_dish_likes_alter_dish_allergens_and_more'), + ] + + operations = [ + migrations.RenameModel( + old_name='comments', + new_name='Comment', + ), + migrations.RenameField( + model_name='dish', + old_name='priceEmployee', + new_name='price_employee', + ), + migrations.RenameField( + model_name='dish', + old_name='priceGast', + new_name='price_guest', + ), + migrations.RenameField( + model_name='dish', + old_name='priceStudent', + new_name='price_student', + ), + ] diff --git a/mensa/migrations/0006_day_menu_alter_comment_dish_delete_dish.py b/mensa/migrations/0006_day_menu_alter_comment_dish_delete_dish.py new file mode 100644 index 0000000..a30a2bf --- /dev/null +++ b/mensa/migrations/0006_day_menu_alter_comment_dish_delete_dish.py @@ -0,0 +1,44 @@ +# Generated by Django 4.1.4 on 2022-12-12 16:58 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0005_rename_comments_comment_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='Day', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ], + ), + migrations.CreateModel( + name='Menu', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('price_student', models.CharField(max_length=100)), + ('price_employee', models.CharField(max_length=100)), + ('price_guest', models.CharField(max_length=100)), + ('allergens', models.CharField(max_length=100)), + ('types', models.CharField(max_length=100)), + ('likes', models.IntegerField(default=0, max_length=100)), + ('dislikes', models.IntegerField(default=0, max_length=100)), + ('day', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mensa.day')), + ], + ), + migrations.AlterField( + model_name='comment', + name='dish', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mensa.menu'), + ), + migrations.DeleteModel( + name='dish', + ), + ] diff --git a/mensa/migrations/0007_alter_menu_day_alter_menu_dislikes_alter_menu_likes.py b/mensa/migrations/0007_alter_menu_day_alter_menu_dislikes_alter_menu_likes.py new file mode 100644 index 0000000..74e1f62 --- /dev/null +++ b/mensa/migrations/0007_alter_menu_day_alter_menu_dislikes_alter_menu_likes.py @@ -0,0 +1,29 @@ +# Generated by Django 4.1.4 on 2022-12-12 17:20 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0006_day_menu_alter_comment_dish_delete_dish'), + ] + + operations = [ + migrations.AlterField( + model_name='menu', + name='day', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='day', to='mensa.day'), + ), + migrations.AlterField( + model_name='menu', + name='dislikes', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='menu', + name='likes', + field=models.IntegerField(default=0), + ), + ] diff --git a/mensa/migrations/0008_mensa_day_mensa.py b/mensa/migrations/0008_mensa_day_mensa.py new file mode 100644 index 0000000..b852a47 --- /dev/null +++ b/mensa/migrations/0008_mensa_day_mensa.py @@ -0,0 +1,26 @@ +# Generated by Django 4.1.4 on 2022-12-12 18:01 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0007_alter_menu_day_alter_menu_dislikes_alter_menu_likes'), + ] + + operations = [ + migrations.CreateModel( + name='Mensa', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('mensa_id', models.CharField(max_length=100)), + ], + ), + migrations.AddField( + model_name='day', + name='mensa', + field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to='mensa.mensa'), + ), + ] diff --git a/mensa/migrations/0009_alter_mensa_mensa_id.py b/mensa/migrations/0009_alter_mensa_mensa_id.py new file mode 100644 index 0000000..43f3ac7 --- /dev/null +++ b/mensa/migrations/0009_alter_mensa_mensa_id.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.4 on 2022-12-12 18:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0008_mensa_day_mensa'), + ] + + operations = [ + migrations.AlterField( + model_name='mensa', + name='mensa_id', + field=models.IntegerField(), + ), + ] diff --git a/mensa/migrations/0010_rename_day_dayplan.py b/mensa/migrations/0010_rename_day_dayplan.py new file mode 100644 index 0000000..18f8e6f --- /dev/null +++ b/mensa/migrations/0010_rename_day_dayplan.py @@ -0,0 +1,17 @@ +# Generated by Django 4.1.4 on 2022-12-12 19:21 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0009_alter_mensa_mensa_id'), + ] + + operations = [ + migrations.RenameModel( + old_name='Day', + new_name='DayPlan', + ), + ] diff --git a/mensa/migrations/0011_rename_day_menu_day_plan.py b/mensa/migrations/0011_rename_day_menu_day_plan.py new file mode 100644 index 0000000..00f3746 --- /dev/null +++ b/mensa/migrations/0011_rename_day_menu_day_plan.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.4 on 2022-12-12 19:22 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0010_rename_day_dayplan'), + ] + + operations = [ + migrations.RenameField( + model_name='menu', + old_name='day', + new_name='day_plan', + ), + ] diff --git a/mensa/migrations/0012_remove_menu_day_plan_menu_day_plans.py b/mensa/migrations/0012_remove_menu_day_plan_menu_day_plans.py new file mode 100644 index 0000000..9094236 --- /dev/null +++ b/mensa/migrations/0012_remove_menu_day_plan_menu_day_plans.py @@ -0,0 +1,22 @@ +# Generated by Django 4.1.4 on 2022-12-12 19:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0011_rename_day_menu_day_plan'), + ] + + operations = [ + migrations.RemoveField( + model_name='menu', + name='day_plan', + ), + migrations.AddField( + model_name='menu', + name='day_plans', + field=models.ManyToManyField(to='mensa.dayplan'), + ), + ] diff --git a/mensa/migrations/0013_meal_remove_comment_dish_rename_dayplan_dailymenu_and_more.py b/mensa/migrations/0013_meal_remove_comment_dish_rename_dayplan_dailymenu_and_more.py new file mode 100644 index 0000000..ccc3c53 --- /dev/null +++ b/mensa/migrations/0013_meal_remove_comment_dish_rename_dayplan_dailymenu_and_more.py @@ -0,0 +1,49 @@ +# Generated by Django 4.1.4 on 2022-12-12 20:18 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0012_remove_menu_day_plan_menu_day_plans'), + ] + + operations = [ + migrations.CreateModel( + name='Meal', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('price_student', models.CharField(max_length=100)), + ('price_employee', models.CharField(max_length=100)), + ('price_guest', models.CharField(max_length=100)), + ('allergens', models.CharField(max_length=100)), + ('types', models.CharField(max_length=100)), + ('likes', models.IntegerField(default=0)), + ('dislikes', models.IntegerField(default=0)), + ], + ), + migrations.RemoveField( + model_name='comment', + name='dish', + ), + migrations.RenameModel( + old_name='DayPlan', + new_name='DailyMenu', + ), + migrations.DeleteModel( + name='Menu', + ), + migrations.AddField( + model_name='meal', + name='related_daily_menus', + field=models.ManyToManyField(to='mensa.dailymenu'), + ), + migrations.AddField( + model_name='comment', + name='meal', + field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='mensa.meal'), + ), + ] diff --git a/mensa/migrations/0014_week_dailymenu_week.py b/mensa/migrations/0014_week_dailymenu_week.py new file mode 100644 index 0000000..fdce591 --- /dev/null +++ b/mensa/migrations/0014_week_dailymenu_week.py @@ -0,0 +1,25 @@ +# Generated by Django 4.1.4 on 2022-12-12 21:12 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0013_meal_remove_comment_dish_rename_dayplan_dailymenu_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='Week', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + ), + migrations.AddField( + model_name='dailymenu', + name='week', + field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to='mensa.week'), + ), + ] diff --git a/mensa/migrations/0015_remove_dailymenu_week_delete_week.py b/mensa/migrations/0015_remove_dailymenu_week_delete_week.py new file mode 100644 index 0000000..70b7fe3 --- /dev/null +++ b/mensa/migrations/0015_remove_dailymenu_week_delete_week.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.4 on 2022-12-13 02:17 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0014_week_dailymenu_week'), + ] + + operations = [ + migrations.RemoveField( + model_name='dailymenu', + name='week', + ), + migrations.DeleteModel( + name='Week', + ), + ] diff --git a/mensa/migrations/0016_meal_art.py b/mensa/migrations/0016_meal_art.py new file mode 100644 index 0000000..ce2ebbb --- /dev/null +++ b/mensa/migrations/0016_meal_art.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.4 on 2022-12-13 02:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0015_remove_dailymenu_week_delete_week'), + ] + + operations = [ + migrations.AddField( + model_name='meal', + name='art', + field=models.CharField(default=None, max_length=100), + ), + ] diff --git a/mensa/migrations/0017_alter_meal_price_employee_alter_meal_price_guest_and_more.py b/mensa/migrations/0017_alter_meal_price_employee_alter_meal_price_guest_and_more.py new file mode 100644 index 0000000..23af4c8 --- /dev/null +++ b/mensa/migrations/0017_alter_meal_price_employee_alter_meal_price_guest_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 4.1.4 on 2022-12-13 03:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0016_meal_art'), + ] + + operations = [ + migrations.AlterField( + model_name='meal', + name='price_employee', + field=models.FloatField(max_length=100), + ), + migrations.AlterField( + model_name='meal', + name='price_guest', + field=models.FloatField(max_length=100), + ), + migrations.AlterField( + model_name='meal', + name='price_student', + field=models.FloatField(max_length=100), + ), + ] diff --git a/mensa/migrations/0018_comment_username.py b/mensa/migrations/0018_comment_username.py new file mode 100644 index 0000000..cd251cf --- /dev/null +++ b/mensa/migrations/0018_comment_username.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.4 on 2022-12-13 04:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mensa', '0017_alter_meal_price_employee_alter_meal_price_guest_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='comment', + name='username', + field=models.CharField(default='anon', max_length=100), + ), + ] diff --git a/mensa/migrations/__init__.py b/mensa/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mensa/models.py b/mensa/models.py new file mode 100644 index 0000000..16ff1d4 --- /dev/null +++ b/mensa/models.py @@ -0,0 +1,37 @@ +from django.db import models + +class Mensa(models.Model): + mensa_id = models.IntegerField() + + def __str__(self): + return str(self.mensa_id) + + +class DailyMenu(models.Model): + date = models.DateField() + mensa = models.ForeignKey(Mensa, on_delete=models.CASCADE, default=0) + + def __str__(self): + return f"Mensa {self.mensa} - {self.date}" + + +class Meal(models.Model): + related_daily_menus = models.ManyToManyField(DailyMenu) + name = models.CharField(max_length=100) + art = models.CharField(max_length=100, default=None) + price_student = models.FloatField(max_length=100) + price_employee = models.FloatField(max_length=100) + price_guest = models.FloatField(max_length=100) + allergens = models.CharField(max_length=100) + types = models.CharField(max_length=100) + likes = models.IntegerField(default=0) + dislikes = models.IntegerField(default=0) + + def __str__(self): + return self.name + + +class Comment(models.Model): + meal = models.ForeignKey(Meal, on_delete=models.CASCADE, default=None) + username = models.CharField(max_length=100, default='anon') + comment = models.CharField(max_length=700) diff --git a/mensa/templates/base.html b/mensa/templates/base.html new file mode 100644 index 0000000..813d174 --- /dev/null +++ b/mensa/templates/base.html @@ -0,0 +1,15 @@ + + + + + MensaApp + + + +
+

Mensapläne Flensburg

+ {% block content %} + {% endblock content %} +
+ + diff --git a/mensa/templates/by_id.html b/mensa/templates/by_id.html new file mode 100644 index 0000000..fd6baff --- /dev/null +++ b/mensa/templates/by_id.html @@ -0,0 +1,63 @@ +{% extends 'base.html' %} +{% block content %} + +
+ {% csrf_token %} + | + +
+ +
+ +
+ +
+ +
+ + +

Mensaplan

+
+ + {% for day in mensa_plan %} +
+

{{ day.day }}

+ + {% for item in day.menus %} +
+ {{ item.name }} +

{{ item.price }}

+

+ {% for allergy in item.allergens %} + {{ allergy }} + {% endfor %} +

+

+ {% for type in item.types %} + {{ type }} + {% endfor %} +

+
+ {% endfor %} + +
+ {% endfor %} + +
+ +{% endblock content %} diff --git a/mensa/templates/forms.html b/mensa/templates/forms.html new file mode 100644 index 0000000..0de2fdd --- /dev/null +++ b/mensa/templates/forms.html @@ -0,0 +1,57 @@ +{% extends 'base.html' %} +{% block content %} +
+ {% csrf_token %} + + + + + + + + + + + +
+ + Zurück + + + {% endblock content %} \ No newline at end of file diff --git a/mensa/templates/meal.html b/mensa/templates/meal.html new file mode 100644 index 0000000..e98c17b --- /dev/null +++ b/mensa/templates/meal.html @@ -0,0 +1,38 @@ +{% extends 'base.html' %} +{% block content %} + +

{{meal.name}}

+

{{meal.art}}

+

Preis für Studenten: {{meal.price_student}}

+

Preis für Mitarbeiter: {{meal.price_employee}}

+

Preis für Gäste: {{meal.price_guest}}

+

Types: {{meal.types}}

+

Allergene: {{meal.allergens}}

+

{{meal.likes}}

+

{{meal.dislikes}}

+ + +
+ {% csrf_token %} + {{ form }} + +
+ +
+ {% csrf_token %} + +
+ +
+ {% csrf_token %} + +
+ +
+ {% for comment in comments %} +

{{comment.username}}

+

{{comment.comment}}

+ {% endfor %} +
+ +{% endblock content %} diff --git a/mensa/templates/mensa_list.html b/mensa/templates/mensa_list.html new file mode 100644 index 0000000..0e308ec --- /dev/null +++ b/mensa/templates/mensa_list.html @@ -0,0 +1,56 @@ +{% extends 'base.html' %} +{% block content %} + +
+ {% csrf_token %} +
+ {{ form.vegan.errors }} + {{ form.vegan.label_tag }} + {{ form.vegan }} +
+
+ {{ form.vegetarian.errors }} + {{ form.vegetarian.label_tag }} + {{ form.vegetarian }} +
+
+ {{ form.price_for.errors }} + {{ form.price_for.label_tag }} + {{ form.price_for }} +
+ +
+ + + + Neues Gericht hizufügen. + + + + +{% for name, plan in mensa_list.items %} +

{{ name }}

+
+ + {% for day in plan %} +
+

{{ day.date }}

+ + {% for item in day.meals %} +
+

{{ item.art }}

+ {{ item.name }} +

Preis: {{ item.price }}€

+

{{ item.types }}

+

Allergene: {{ item.allergens }}

+ {{ item.pk }} +
+ {% endfor %} + +
+ {% endfor %} + +
+{% endfor %} + +{% endblock content %} diff --git a/mensa/tests.py b/mensa/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/mensa/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/mensa/urls.py b/mensa/urls.py new file mode 100644 index 0000000..ef49dd8 --- /dev/null +++ b/mensa/urls.py @@ -0,0 +1,13 @@ +from django.urls import path +from . import views + +app_name = 'mensa' +urlpatterns = [ + path('', views.mensa_flensburg, name='mensa_flensburg'), + path('mensa/', views.mensa_by_id, name='mensa_by_id'), + path('meal/', views.meal, name='meal'), + path('meal/form', views.meal_form, name='meal_form'), + path('save/', views.meal_save, name='save'), + path('update//', views.meal_update, name='update'), + path('delete//', views.meal_delet, name='meal_delet') +] diff --git a/mensa/views.py b/mensa/views.py new file mode 100644 index 0000000..9f2f0cf --- /dev/null +++ b/mensa/views.py @@ -0,0 +1,128 @@ +from django.shortcuts import render +from django.http import HttpResponse +from django.views.decorators.cache import cache_page +from django.views.generic import DetailView +from django.shortcuts import redirect + +from .helpers import get_filtered_plan +from .models import Meal, DailyMenu, Mensa, Comment +from .forms import FilterForm, CommentForm + +@cache_page(60 * 15) +def mensa_flensburg(request): + flags = {'vegan': None, 'vegetarian': None, 'price_for': None,} + + if request.method == 'POST': + form = FilterForm(request.POST) + if form.is_valid(): + flags['vegan'] = form.cleaned_data['vegan'] + flags['vegetarian'] = form.cleaned_data['vegetarian'] + flags['price_for'] = form.cleaned_data['price_for'] + else: + flags['vegan'] = request.COOKIES.get('vegan') + flags['vegetarian'] = request.COOKIES.get('vegetarian') + flags['price_for'] = request.COOKIES.get('price_for') + form = FilterForm(request.COOKIES) + + context = { + 'mensa_list': { + 'Hauptmensa': get_filtered_plan(7, flags), + 'B-Mensa': get_filtered_plan(14, flags), + }, + 'form': form, + } + + response = render(request, 'mensa_list.html', context) + response.set_cookie('vegan', flags['vegan']) + response.set_cookie('vegetarian', flags['vegetarian']) + response.set_cookie('price_for', flags['price_for']) + return response + + +def meal(request, meal_id): + form = CommentForm() + + if request.method == 'POST': + if request.POST['button'] == 'comment': + form = CommentForm(request.POST) + if form.is_valid(): + username = form.cleaned_data['username'] + text = form.cleaned_data['text'] + Comment(meal=Meal.objects.get(pk=meal_id), username=username, comment=text).save() + elif request.POST['button'] == 'like': + meal = Meal.objects.get(pk=meal_id) + meal.likes += 1 + meal.save() + elif request.POST['button'] == 'dislike': + meal = Meal.objects.get(pk=meal_id) + meal.dislikes += 1 + meal.save() + else: + form = CommentForm() + + context = { + 'meal': Meal.objects.get(pk=meal_id), + 'form': form, + 'comments': Comment.objects.filter(meal=Meal.objects.get(pk=meal_id)) + } + return render(request, 'meal.html', context) + + +@cache_page(60 * 15) +def mensa_by_id(request, mensa_id): + flags = {'vegan': None, 'vegetarian': None, 'price_for': None,} + + if request.method == 'POST': + for key in flags: + flags[key] = request.POST.get(key) + else: + for key in flags: + flags[key] = request.COOKIES.get(key) + + context = { + 'mensa_list': { + f'Mensa {mensa_id}': get_filtered_plan((mensa_id), flags), + }, + 'flags': flags, + } + + response = render(request, 'mensa_list.html', context) + response.set_cookie('vegan', flags['vegan']) + response.set_cookie('vegetarian', flags['vegetarian']) + response.set_cookie('price_for', flags['price_for']) + return response + +def meal_form(request): + return render(request, 'forms.html') + +def meal_delet(request): + return + +def meal_update(request): + return + +def meal_save(request): + #mensa = request.POST.get('mensa') + id = request.POST.get('id') + name = request.POST.get('name') + art = request.POST.get('art') + priceStudents = request.POST.get('priceStudents') + priceEmployee = request.POST.get('priceEmployee') + priceGast = request.POST.get('priceGast') + allergens = request.POST.get('allergens') + types = request.POST.get('types') + + b = None + if id: + b = Meal.objects.get(id=id) + b.name = name + b.art = art + b.priceStudents = priceStudents + b.priceEmployee = priceEmployee + b.priceGast = priceGast + b.allergens = allergens + b.types = types + else: + b = Meal(name=name, art=art, price_student=priceStudents,price_employee=priceEmployee,price_guest=priceGast,allergens=allergens,types=types) + b.save() + return redirect('mensa:mensa_flensburg') \ No newline at end of file diff --git a/static/base.css b/static/base.css new file mode 100644 index 0000000..b85f554 --- /dev/null +++ b/static/base.css @@ -0,0 +1,45 @@ +.main { + gap: 1rem; + +} + +body { + color:rgba(255, 255, 255, 0.8); + background-color: rgba(24, 24, 24, 0.979); + font-family: sans-serif; +} + +.card { + display: flex; + flex-direction: column; + box-shadow: 0px 0px 8px rgb(190, 190, 190, 0.8); + background-color: rgb(238, 148, 204); + margin: 1rem; + padding: 0.5rem; + font-family: sans-serif; + color:rgb(0, 0, 0); + +} + +.cards { + display: flex; + flex-flow: column; + flex-basis: 10rem; + flex-shrink: 0; + flex-grow: 1; + color:rgba(255, 255, 255, 0.8); + font-family: sans-serif; +} + +.plan { + display: flex; + flex-flow: row; + font-family: sans-serif; +} +form { + display: flex; + flex-direction: column; +} +a{ + color: white; +} diff --git a/webprog5/__init__.py b/webprog5/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/webprog5/asgi.py b/webprog5/asgi.py new file mode 100644 index 0000000..bcf2a9c --- /dev/null +++ b/webprog5/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for webprog5 project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'webprog5.settings') + +application = get_asgi_application() diff --git a/webprog5/settings.py b/webprog5/settings.py new file mode 100644 index 0000000..8473d6d --- /dev/null +++ b/webprog5/settings.py @@ -0,0 +1,138 @@ +""" +Django settings for webprog5 project. + +Generated by 'django-admin startproject' using Django 4.1.3. + +For more information on this file, see +https://docs.djangoproject.com/en/4.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/4.1/ref/settings/ +""" + +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-axv=x^^fm+u6fy)#@e77(x+!zl8#i4mbsi=c3one%2e3eqisr)' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'mensa.apps.MensaConfig', + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles' + +] + +MIDDLEWARE = [ + 'django.middleware.cache.UpdateCacheMiddleware', + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'django.middleware.cache.FetchFromCacheMiddleware', +] + +ROOT_URLCONF = 'webprog5.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'webprog5.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/4.1/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} + + +# Password validation +# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/4.1/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.1/howto/static-files/ + +STATIC_URL = 'static/' + +STATICFILES_DIRS = [ + BASE_DIR/"static", +] + +CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', + 'LOCATION': 'c:\django-cache' + } +} + +# Default primary key field type +# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/webprog5/urls.py b/webprog5/urls.py new file mode 100644 index 0000000..0e712f8 --- /dev/null +++ b/webprog5/urls.py @@ -0,0 +1,22 @@ +"""webprog5 URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/4.1/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('mensa.urls')), +] diff --git a/webprog5/wsgi.py b/webprog5/wsgi.py new file mode 100644 index 0000000..8a26374 --- /dev/null +++ b/webprog5/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for webprog5 project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'webprog5.settings') + +application = get_wsgi_application()