diff --git a/.github/workflows/build-docker-open-data.yml b/.github/workflows/build-docker-open-data.yml
index 09df1956..22b3af12 100644
--- a/.github/workflows/build-docker-open-data.yml
+++ b/.github/workflows/build-docker-open-data.yml
@@ -21,7 +21,7 @@ jobs:
suffix: ""
continue-on-error: false
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Get version number
id: get_version
@@ -43,7 +43,7 @@ jobs:
path: ./recipes/plugins/open_data_plugin
# Build Vue frontend
- - uses: actions/setup-node@v3
+ - uses: actions/setup-node@v4
with:
node-version: '18'
cache: yarn
diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml
index 8c29b9fe..b61169d5 100644
--- a/.github/workflows/build-docker.yml
+++ b/.github/workflows/build-docker.yml
@@ -21,7 +21,7 @@ jobs:
suffix: ""
continue-on-error: false
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Get version number
id: get_version
@@ -35,7 +35,7 @@ jobs:
fi
# Build Vue frontend
- - uses: actions/setup-node@v3
+ - uses: actions/setup-node@v4
with:
node-version: '18'
cache: yarn
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cb72bc0c..f33ea1df 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -21,7 +21,7 @@ jobs:
# Setup python & dependencies
- name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
@@ -45,7 +45,7 @@ jobs:
# Build Vue frontend & Dependencies
- name: Set up Node ${{ matrix.node-version }}
if: steps.django_cache.outputs.cache-hit != 'true'
- uses: actions/setup-node@v3
+ - uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 4166aae3..fcdd8926 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
@@ -25,7 +25,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@v2
+ uses: github/codeql-action/init@v3
# Override language selection by uncommenting this and choosing your languages
with:
languages: python, javascript
@@ -47,6 +47,6 @@ jobs:
# make release
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v2
+ uses: github/codeql-action/analyze@v3
with:
languages: javascript, python
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 7a35555b..6956ee7f 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -9,8 +9,8 @@ jobs:
if: github.repository_owner == 'TandoorRecipes'
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-python@v4
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
with:
python-version: 3.x
- run: pip install mkdocs-material mkdocs-include-markdown-plugin
diff --git a/README.md b/README.md
index 28dc83ed..4398c00f 100644
--- a/README.md
+++ b/README.md
@@ -96,7 +96,7 @@ Share some information on how you use Tandoor to help me improve the application
Beginning with version 0.10.0 the code in this repository is licensed under the [GNU AGPL v3](https://www.gnu.org/licenses/agpl-3.0.de.html) license with a
[common clause](https://commonsclause.com/) selling exception. See [LICENSE.md](https://github.com/vabene1111/recipes/blob/develop/LICENSE.md) for details.
-> NOTE: There appears to be a whole range of legal issues with licensing anything else then the standard completely open licenses.
+> NOTE: There appears to be a whole range of legal issues with licensing anything other than the standard completely open licenses.
> I am in the process of getting some professional legal advice to sort out these issues.
> Please also see [Issue 238](https://github.com/vabene1111/recipes/issues/238) for some discussion and **reasoning** regarding the topic.
diff --git a/boot.sh b/boot.sh
index 3faacad7..97a94f47 100644
--- a/boot.sh
+++ b/boot.sh
@@ -76,4 +76,4 @@ echo "Done"
chmod -R 755 /opt/recipes/mediafiles
-exec gunicorn -b :$TANDOOR_PORT --workers $GUNICORN_WORKERS --threads $GUNICORN_THREADS --access-logfile - --error-logfile - --log-level $GUNICORN_LOG_LEVEL recipes.wsgi
+exec gunicorn -b "[::]:$TANDOOR_PORT" --workers $GUNICORN_WORKERS --threads $GUNICORN_THREADS --access-logfile - --error-logfile - --log-level $GUNICORN_LOG_LEVEL recipes.wsgi
diff --git a/cookbook/forms.py b/cookbook/forms.py
index dd62aa0b..4226af9c 100644
--- a/cookbook/forms.py
+++ b/cookbook/forms.py
@@ -450,7 +450,7 @@ class SpacePreferenceForm(forms.ModelForm):
class Meta:
model = Space
- fields = ('food_inherit', 'reset_food_inherit', 'use_plural')
+ fields = ('food_inherit', 'reset_food_inherit',)
help_texts = {
'food_inherit': _('Fields on food that should be inherited by default.'),
diff --git a/cookbook/helper/template_helper.py b/cookbook/helper/template_helper.py
index 016779a7..4db1f5bc 100644
--- a/cookbook/helper/template_helper.py
+++ b/cookbook/helper/template_helper.py
@@ -14,12 +14,14 @@ class IngredientObject(object):
unit = ""
food = ""
note = ""
+ numeric_amount = 0
def __init__(self, ingredient):
if ingredient.no_amount:
self.amount = ""
else:
self.amount = f""
+ self.numeric_amount = float(ingredient.amount)
if ingredient.unit:
if ingredient.unit.plural_name in (None, ""):
self.unit = bleach.clean(str(ingredient.unit))
@@ -83,9 +85,12 @@ def render_instructions(step): # TODO deduplicate markdown cleanup code
for i in step.ingredients.all():
ingredients.append(IngredientObject(i))
+ def scale(number):
+ return f""
+
try:
template = Template(instructions)
- instructions = template.render(ingredients=ingredients)
+ instructions = template.render(ingredients=ingredients, scale=scale)
except TemplateSyntaxError:
return _('Could not parse template code.') + ' Error: Template Syntax broken'
except UndefinedError:
diff --git a/cookbook/migrations/0204_propertytype_fdc_id.py b/cookbook/migrations/0204_propertytype_fdc_id.py
index 70598463..e57dea39 100644
--- a/cookbook/migrations/0204_propertytype_fdc_id.py
+++ b/cookbook/migrations/0204_propertytype_fdc_id.py
@@ -4,11 +4,6 @@ from django.db import migrations, models
from django_scopes import scopes_disabled
-def fix_fdc_ids(apps, schema_editor):
- with scopes_disabled():
- # in case any food had a non digit fdc ID before this migration, remove it
- Food = apps.get_model('cookbook', 'Food')
- Food.objects.exclude(fdc_id__regex=r'^\d+$').exclude(fdc_id=None).update(fdc_id=None)
class Migration(migrations.Migration):
@@ -17,7 +12,6 @@ class Migration(migrations.Migration):
]
operations = [
- migrations.RunPython(fix_fdc_ids),
migrations.AddField(
model_name='propertytype',
name='fdc_id',
diff --git a/cookbook/migrations/0205_alter_food_fdc_id_alter_propertytype_fdc_id.py b/cookbook/migrations/0205_alter_food_fdc_id_alter_propertytype_fdc_id.py
index 9f57e443..96b19f26 100644
--- a/cookbook/migrations/0205_alter_food_fdc_id_alter_propertytype_fdc_id.py
+++ b/cookbook/migrations/0205_alter_food_fdc_id_alter_propertytype_fdc_id.py
@@ -1,15 +1,23 @@
# Generated by Django 4.2.7 on 2023-11-29 19:44
from django.db import migrations, models
+from django_scopes import scopes_disabled
+
+
+def fix_fdc_ids(apps, schema_editor):
+ with scopes_disabled():
+ # in case any food had a non digit fdc ID before this migration, remove it
+ Food = apps.get_model('cookbook', 'Food')
+ Food.objects.exclude(fdc_id__regex=r'^\d+$').exclude(fdc_id=None).update(fdc_id=None)
class Migration(migrations.Migration):
-
dependencies = [
('cookbook', '0204_propertytype_fdc_id'),
]
operations = [
+ migrations.RunPython(fix_fdc_ids),
migrations.AlterField(
model_name='food',
name='fdc_id',
diff --git a/cookbook/migrations/0208_space_app_name_userpreference_max_owned_spaces.py b/cookbook/migrations/0208_space_app_name_userpreference_max_owned_spaces.py
new file mode 100644
index 00000000..44837d48
--- /dev/null
+++ b/cookbook/migrations/0208_space_app_name_userpreference_max_owned_spaces.py
@@ -0,0 +1,23 @@
+# Generated by Django 4.2.7 on 2024-01-14 23:06
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('cookbook', '0207_space_logo_color_128_space_logo_color_144_and_more'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='space',
+ name='app_name',
+ field=models.CharField(blank=True, max_length=40, null=True),
+ ),
+ migrations.AddField(
+ model_name='userpreference',
+ name='max_owned_spaces',
+ field=models.IntegerField(default=100),
+ ),
+ ]
diff --git a/cookbook/migrations/0209_remove_space_use_plural.py b/cookbook/migrations/0209_remove_space_use_plural.py
new file mode 100644
index 00000000..37a4b6fc
--- /dev/null
+++ b/cookbook/migrations/0209_remove_space_use_plural.py
@@ -0,0 +1,17 @@
+# Generated by Django 4.2.7 on 2024-01-28 07:42
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('cookbook', '0208_space_app_name_userpreference_max_owned_spaces'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='space',
+ name='use_plural',
+ ),
+ ]
diff --git a/cookbook/models.py b/cookbook/models.py
index 0614c974..9954133d 100644
--- a/cookbook/models.py
+++ b/cookbook/models.py
@@ -24,7 +24,7 @@ from PIL import Image
from treebeard.mp_tree import MP_Node, MP_NodeManager
from recipes.settings import (COMMENT_PREF_DEFAULT, FRACTION_PREF_DEFAULT, KJ_PREF_DEFAULT,
- SORT_TREE_BY_NAME, STICKY_NAV_PREF_DEFAULT)
+ SORT_TREE_BY_NAME, STICKY_NAV_PREF_DEFAULT, MAX_OWNED_SPACES_PREF_DEFAULT)
def get_user_display_name(self):
@@ -288,7 +288,7 @@ class Space(ExportModelOperationsMixin('space'), models.Model):
nav_logo = models.ForeignKey("UserFile", on_delete=models.SET_NULL, null=True, blank=True, related_name='space_nav_logo')
nav_bg_color = models.CharField(max_length=8, default='', blank=True, )
nav_text_color = models.CharField(max_length=16, choices=NAV_TEXT_COLORS, default=BLANK)
-
+ app_name = models.CharField(max_length=40, null=True, blank=True, )
logo_color_32 = models.ForeignKey("UserFile", on_delete=models.SET_NULL, null=True, blank=True, related_name='space_logo_color_32')
logo_color_128 = models.ForeignKey("UserFile", on_delete=models.SET_NULL, null=True, blank=True, related_name='space_logo_color_128')
logo_color_144 = models.ForeignKey("UserFile", on_delete=models.SET_NULL, null=True, blank=True, related_name='space_logo_color_144')
@@ -303,7 +303,6 @@ class Space(ExportModelOperationsMixin('space'), models.Model):
max_recipes = models.IntegerField(default=0)
max_file_storage_mb = models.IntegerField(default=0, help_text=_('Maximum file storage for space in MB. 0 for unlimited, -1 to disable file upload.'))
max_users = models.IntegerField(default=0)
- use_plural = models.BooleanField(default=True)
allow_sharing = models.BooleanField(default=True)
no_sharing_limit = models.BooleanField(default=False)
demo = models.BooleanField(default=False)
@@ -409,7 +408,7 @@ class UserPreference(models.Model, PermissionModelMixin):
nav_text_color = models.CharField(max_length=16, choices=NAV_TEXT_COLORS, default=DARK)
nav_show_logo = models.BooleanField(default=True)
nav_sticky = models.BooleanField(default=STICKY_NAV_PREF_DEFAULT)
-
+ max_owned_spaces = models.IntegerField(default=MAX_OWNED_SPACES_PREF_DEFAULT)
default_unit = models.CharField(max_length=32, default='g')
use_fractions = models.BooleanField(default=FRACTION_PREF_DEFAULT)
use_kj = models.BooleanField(default=KJ_PREF_DEFAULT)
@@ -434,6 +433,15 @@ class UserPreference(models.Model, PermissionModelMixin):
created_at = models.DateTimeField(auto_now_add=True)
objects = ScopedManager(space='space')
+ def save(self, *args, **kwargs):
+ if not self.pk:
+ self.max_owned_spaces = MAX_OWNED_SPACES_PREF_DEFAULT
+ self.comments = COMMENT_PREF_DEFAULT
+ self.nav_sticky = STICKY_NAV_PREF_DEFAULT
+ self.use_kj = KJ_PREF_DEFAULT
+ self.use_fractions = FRACTION_PREF_DEFAULT
+
+ return super().save(*args, **kwargs)
def __str__(self):
return str(self.user)
diff --git a/cookbook/serializer.py b/cookbook/serializer.py
index d4f7bd47..09e57103 100644
--- a/cookbook/serializer.py
+++ b/cookbook/serializer.py
@@ -311,7 +311,7 @@ class SpaceSerializer(WritableNestedModelSerializer):
fields = (
'id', 'name', 'created_by', 'created_at', 'message', 'max_recipes', 'max_file_storage_mb', 'max_users',
'allow_sharing', 'demo', 'food_inherit', 'user_count', 'recipe_count', 'file_size_mb',
- 'image', 'nav_logo', 'space_theme', 'custom_space_theme', 'nav_bg_color', 'nav_text_color', 'use_plural',
+ 'image', 'nav_logo', 'space_theme', 'custom_space_theme', 'nav_bg_color', 'nav_text_color',
'logo_color_32', 'logo_color_128', 'logo_color_144', 'logo_color_180', 'logo_color_192', 'logo_color_512', 'logo_color_svg',)
read_only_fields = (
'id', 'created_by', 'created_at', 'max_recipes', 'max_file_storage_mb', 'max_users', 'allow_sharing',
diff --git a/cookbook/templates/base.html b/cookbook/templates/base.html
index d84ccbd4..51f4d9f1 100644
--- a/cookbook/templates/base.html
+++ b/cookbook/templates/base.html
@@ -10,7 +10,7 @@
{% block title %}
{% endblock %}
-
+
@@ -481,6 +481,14 @@
overflow-x: hidden;
}
}
+
+ #id_base_container {
+ padding-bottom: env(safe-area-inset-bottom);
+ }
+
+ .fixed-bottom {
+ padding-bottom: max(0.5rem, calc(env(safe-area-inset-bottom) - 0.5rem)) !important;
+ }