From f91d9fcfe239566df877af560745efbf9dc04308 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Mon, 21 Sep 2020 23:54:46 +0200 Subject: [PATCH] autosync shopping list and settings --- .env.template | 5 ++++ cookbook/forms.py | 7 ++++-- .../migrations/0080_auto_20200921_2331.py | 24 +++++++++++++++++++ .../migrations/0081_auto_20200921_2349.py | 18 ++++++++++++++ cookbook/models.py | 1 + cookbook/templates/shopping_list.html | 7 +++++- cookbook/views/views.py | 5 ++++ recipes/settings.py | 5 ++++ 8 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 cookbook/migrations/0080_auto_20200921_2331.py create mode 100644 cookbook/migrations/0081_auto_20200921_2349.py diff --git a/.env.template b/.env.template index 9ae5d9756..18fb16abe 100644 --- a/.env.template +++ b/.env.template @@ -16,6 +16,11 @@ POSTGRES_USER=djangodb POSTGRES_PASSWORD= POSTGRES_DB=djangodb +# Users can set a amount of time after which the shopping list is refreshed when they are in viewing mode +# This is the minimum interval users can set. Setting this to low will allow users to refresh very frequently which +# might cause high load on the server. (Technically they can obviously refresh as often as they want with their own scripts) +SHOPPING_MIN_AUTOSYNC_INTERVAL=5000 + # Serve mediafiles directly using gunicorn. Basically everyone recommends not doing this. Please use any of the examples # provided that include an additional nxginx container to handle media file serving. # If you know what you are doing turn this back on (1) to serve media files using djangos serve() method. diff --git a/cookbook/forms.py b/cookbook/forms.py index e0dc3801c..856010f90 100644 --- a/cookbook/forms.py +++ b/cookbook/forms.py @@ -31,7 +31,7 @@ class UserPreferenceForm(forms.ModelForm): class Meta: model = UserPreference - fields = ('default_unit', 'theme', 'nav_color', 'default_page', 'show_recent', 'search_style', 'plan_share', 'ingredient_decimals', 'comments') + fields = ('default_unit', 'theme', 'nav_color', 'default_page', 'show_recent', 'search_style', 'plan_share', 'ingredient_decimals', 'shopping_auto_sync', 'comments') help_texts = { 'nav_color': _('Color of the top navigation bar. Not all colors work with all themes, just try them out!'), @@ -39,7 +39,10 @@ class UserPreferenceForm(forms.ModelForm): 'plan_share': _('Default user to share newly created meal plan entries with.'), 'show_recent': _('Show recently viewed recipes on search page.'), 'ingredient_decimals': _('Number of decimals to round ingredients.'), - 'comments': _('If you want to be able to create and see comments underneath recipes.') + 'comments': _('If you want to be able to create and see comments underneath recipes.'), + 'shopping_auto_sync': _( + 'Setting to 0 will disable auto sync. When viewing a shopping list the list is updated every set seconds to sync changes someone else might have made. Useful when shopping with multiple people but might use a little bit ' + 'of mobile data. If lower than instance limit it is reset when saving.') } widgets = { diff --git a/cookbook/migrations/0080_auto_20200921_2331.py b/cookbook/migrations/0080_auto_20200921_2331.py new file mode 100644 index 000000000..b499bea37 --- /dev/null +++ b/cookbook/migrations/0080_auto_20200921_2331.py @@ -0,0 +1,24 @@ +# Generated by Django 3.0.7 on 2020-09-21 21:31 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cookbook', '0079_invitelink_group'), + ] + + operations = [ + migrations.AddField( + model_name='userpreference', + name='shopping_auto_sync', + field=models.BooleanField(default=True), + ), + migrations.AlterField( + model_name='invitelink', + name='valid_until', + field=models.DateField(default=datetime.date(2020, 10, 5)), + ), + ] diff --git a/cookbook/migrations/0081_auto_20200921_2349.py b/cookbook/migrations/0081_auto_20200921_2349.py new file mode 100644 index 000000000..fc2d4d786 --- /dev/null +++ b/cookbook/migrations/0081_auto_20200921_2349.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.7 on 2020-09-21 21:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cookbook', '0080_auto_20200921_2331'), + ] + + operations = [ + migrations.AlterField( + model_name='userpreference', + name='shopping_auto_sync', + field=models.IntegerField(default=5), + ), + ] diff --git a/cookbook/models.py b/cookbook/models.py index 4e607fefd..1f5d9ae58 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -69,6 +69,7 @@ class UserPreference(models.Model): plan_share = models.ManyToManyField(User, blank=True, related_name='plan_share_default') ingredient_decimals = models.IntegerField(default=2) comments = models.BooleanField(default=COMMENT_PREF_DEFAULT) + shopping_auto_sync = models.IntegerField(default=5) def __str__(self): return str(self.user) diff --git a/cookbook/templates/shopping_list.html b/cookbook/templates/shopping_list.html index ad8dd298a..6c6f67fd2 100644 --- a/cookbook/templates/shopping_list.html +++ b/cookbook/templates/shopping_list.html @@ -293,8 +293,13 @@ } this.loading = false } - }, + {% if request.user.userpreference.shopping_auto_sync > 0 %} + setInterval(() => { + this.loadShoppingList() + }, {{ request.user.userpreference.shopping_auto_sync }} * 1000 ) + {% endif %} + }, methods: { /* warnPageLeave: function (event) { diff --git a/cookbook/views/views.py b/cookbook/views/views.py index dae322b77..e4a3ef37e 100644 --- a/cookbook/views/views.py +++ b/cookbook/views/views.py @@ -192,6 +192,11 @@ def user_settings(request): up.plan_share.set(form.cleaned_data['plan_share']) up.ingredient_decimals = form.cleaned_data['ingredient_decimals'] up.comments = form.cleaned_data['comments'] + + up.shopping_auto_sync = form.cleaned_data['shopping_auto_sync'] + if up.shopping_auto_sync < settings.SHOPPING_MIN_AUTOSYNC_INTERVAL: + up.shopping_auto_sync = settings.SHOPPING_MIN_AUTOSYNC_INTERVAL + up.save() if 'user_name_form' in request.POST: diff --git a/recipes/settings.py b/recipes/settings.py index e08b8c0e9..c9997821c 100644 --- a/recipes/settings.py +++ b/recipes/settings.py @@ -24,12 +24,17 @@ SECRET_KEY = os.getenv('SECRET_KEY') if os.getenv('SECRET_KEY') else 'INSECURE_S DEBUG = bool(int(os.getenv('DEBUG', True))) +# allow djangos wsgi server to server mediafiles GUNICORN_MEDIA = bool(int(os.getenv('GUNICORN_MEDIA', True))) REVERSE_PROXY_AUTH = bool(int(os.getenv('REVERSE_PROXY_AUTH', False))) +# default value for user preference 'comment' COMMENT_PREF_DEFAULT = bool(int(os.getenv('COMMENT_PREF_DEFAULT', True))) +# minimum interval that users can set for automatic sync of shopping lists +SHOPPING_MIN_AUTOSYNC_INTERVAL = int(os.getenv('SHOPPING_MIN_AUTOSYNC_INTERVAL', 5)) + ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS').split(',') if os.getenv('ALLOWED_HOSTS') else ['*'] CORS_ORIGIN_ALLOW_ALL = True