Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
vabene1111 committed Nov 27, 2023
2 parents d42d784 + 7e2aee5 commit 75523c0
Show file tree
Hide file tree
Showing 178 changed files with 8,737 additions and 9,632 deletions.
17 changes: 14 additions & 3 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,18 @@ DEBUG_TOOLBAR=0
# hosts the application can run under e.g. recipes.mydomain.com,cooking.mydomain.com,...
ALLOWED_HOSTS=*

# Cross Site Request Forgery protection
# (https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS)
# CSRF_TRUSTED_ORIGINS = []

# Cross Origin Resource Sharing
# (https://github.com/adamchainz/django-cors-header)
# CORS_ALLOW_ALL_ORIGINS = True

# random secret key, use for example `base64 /dev/urandom | head -c50` to generate one
# ---------------------------- REQUIRED -------------------------
# ---------------------------- AT LEAST ONE REQUIRED -------------------------
SECRET_KEY=
SECRET_KEY_FILE=
# ---------------------------------------------------------------

# your default timezone See https://timezonedb.com/time-zones for a list of timezones
Expand All @@ -27,8 +36,9 @@ DB_ENGINE=django.db.backends.postgresql
POSTGRES_HOST=db_recipes
POSTGRES_PORT=5432
POSTGRES_USER=djangouser
# ---------------------------- REQUIRED -------------------------
# ---------------------------- AT LEAST ONE REQUIRED -------------------------
POSTGRES_PASSWORD=
POSTGRES_PASSWORD_FILE=
# ---------------------------------------------------------------
POSTGRES_DB=djangodb

Expand Down Expand Up @@ -113,7 +123,8 @@ REMOTE_USER_AUTH=0
# SPACE_DEFAULT_MAX_FILES=0 # Maximum file storage for space in MB. 0 for unlimited, -1 to disable file upload.
# SPACE_DEFAULT_ALLOW_SHARING=1 # Allow users to share recipes with public links

# allow people to create accounts on your application instance (without an invite link)
# allow people to create local accounts on your application instance (without an invite link)
# social accounts will always be able to sign up
# when unset: 0 (false)
# ENABLE_SIGNUP=0

Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/build-docker-open-data.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,25 +64,25 @@ jobs:
run: yarn build

- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
- name: Set up Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v2
uses: docker/login-action@v3
if: github.secret_source == 'Actions'
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
uses: docker/login-action@v3
if: github.secret_source == 'Actions'
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
uses: docker/metadata-action@v5
with:
images: |
vabene1111/recipes
Expand All @@ -97,7 +97,7 @@ jobs:
type=semver,suffix=-open-data-plugin,pattern={{major}}
type=ref,suffix=-open-data-plugin,event=branch
- name: Build and Push
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
context: .
file: ${{ matrix.dockerfile }}
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/build-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,25 +48,25 @@ jobs:
run: yarn build

- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
- name: Set up Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v2
uses: docker/login-action@v3
if: github.secret_source == 'Actions'
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
uses: docker/login-action@v3
if: github.secret_source == 'Actions'
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
uses: docker/metadata-action@v5
with:
images: |
vabene1111/recipes
Expand All @@ -81,7 +81,7 @@ jobs:
type=semver,pattern={{major}}
type=ref,event=branch
- name: Build and Push
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
context: .
file: ${{ matrix.dockerfile }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ mediafiles/
\.env
staticfiles/
postgresql/
data/


/docker-compose.override.yml
Expand Down
20 changes: 15 additions & 5 deletions boot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ if [ ! -f "$NGINX_CONF_FILE" ] && [ $GUNICORN_MEDIA -eq 0 ]; then
display_warning "Nginx configuration file could not be found at the default location!\nPath: ${NGINX_CONF_FILE}"
fi

# SECRET_KEY must be set in .env file
# SECRET_KEY (or a valid file at SECRET_KEY_FILE) must be set in .env file

if [ -f "${SECRET_KEY_FILE}" ]; then
export SECRET_KEY=$(cat "$SECRET_KEY_FILE")
fi

if [ -z "${SECRET_KEY}" ]; then
display_warning "The environment variable 'SECRET_KEY' is not set but REQUIRED for running Tandoor!"
display_warning "The environment variable 'SECRET_KEY' (or 'SECRET_KEY_FILE' that points to an existing file) is not set but REQUIRED for running Tandoor!"
fi


Expand All @@ -30,11 +35,16 @@ echo "Waiting for database to be ready..."
attempt=0
max_attempts=20

if [ "${DB_ENGINE}" != 'django.db.backends.sqlite3' ]; then
if [ "${DB_ENGINE}" == 'django.db.backends.postgresql' ] || [ "${DATABASE_URL}" == 'postgres'* ]; then

# POSTGRES_PASSWORD (or a valid file at POSTGRES_PASSWORD_FILE) must be set in .env file

if [ -f "${POSTGRES_PASSWORD_FILE}" ]; then
export POSTGRES_PASSWORD=$(cat "$POSTGRES_PASSWORD_FILE")
fi

# POSTGRES_PASSWORD must be set in .env file
if [ -z "${POSTGRES_PASSWORD}" ]; then
display_warning "The environment variable 'POSTGRES_PASSWORD' is not set but REQUIRED for running Tandoor!"
display_warning "The environment variable 'POSTGRES_PASSWORD' (or 'POSTGRES_PASSWORD_FILE' that points to an existing file) is not set but REQUIRED for running Tandoor!"
fi

while pg_isready --host=${POSTGRES_HOST} --port=${POSTGRES_PORT} --user=${POSTGRES_USER} -q; status=$?; attempt=$((attempt+1)); [ $status -ne 0 ] && [ $attempt -le $max_attempts ]; do
Expand Down
18 changes: 9 additions & 9 deletions cookbook/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@

from cookbook.managers import DICTIONARY

from .models import (Automation, BookmarkletImport, Comment, CookLog, Food, FoodInheritField,
ImportLog, Ingredient, InviteLink, Keyword, MealPlan, MealType,
NutritionInformation, Property, PropertyType, Recipe, RecipeBook,
RecipeBookEntry, RecipeImport, SearchPreference, ShareLink, ShoppingList,
ShoppingListEntry, ShoppingListRecipe, Space, Step, Storage, Supermarket,
SupermarketCategory, SupermarketCategoryRelation, Sync, SyncLog, TelegramBot,
Unit, UnitConversion, UserFile, UserPreference, UserSpace, ViewLog)
from .models import (BookmarkletImport, Comment, CookLog, Food, ImportLog, Ingredient, InviteLink,
Keyword, MealPlan, MealType, NutritionInformation, Property, PropertyType,
Recipe, RecipeBook, RecipeBookEntry, RecipeImport, SearchPreference, ShareLink,
ShoppingList, ShoppingListEntry, ShoppingListRecipe, Space, Step, Storage,
Supermarket, SupermarketCategory, SupermarketCategoryRelation, Sync, SyncLog,
TelegramBot, Unit, UnitConversion, UserFile, UserPreference, UserSpace,
ViewLog)


class CustomUserAdmin(UserAdmin):
Expand Down Expand Up @@ -192,7 +192,7 @@ class RecipeAdmin(admin.ModelAdmin):
def created_by(obj):
return obj.created_by.get_user_display_name()

if settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2', 'django.db.backends.postgresql']:
if settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql':
actions = [rebuild_index]


Expand Down Expand Up @@ -277,7 +277,7 @@ class RecipeBookEntryAdmin(admin.ModelAdmin):


class MealPlanAdmin(admin.ModelAdmin):
list_display = ('user', 'recipe', 'meal_type', 'date')
list_display = ('user', 'recipe', 'meal_type', 'from_date', 'to_date')

@staticmethod
def user(obj):
Expand Down
75 changes: 14 additions & 61 deletions cookbook/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
from django_scopes.forms import SafeModelChoiceField, SafeModelMultipleChoiceField
from hcaptcha.fields import hCaptchaField

from .models import (Comment, Food, InviteLink, Keyword, MealPlan, MealType, Recipe, RecipeBook,
RecipeBookEntry, SearchPreference, Space, Storage, Sync, User, UserPreference)
from .models import (Comment, Food, InviteLink, Keyword, Recipe, RecipeBook, RecipeBookEntry,
SearchPreference, Space, Storage, Sync, User, UserPreference)


class SelectWidget(widgets.Select):
Expand Down Expand Up @@ -45,8 +45,7 @@ class Meta:
model = UserPreference
fields = (
'default_unit', 'use_fractions', 'use_kj', 'theme', 'nav_color',
'sticky_navbar', 'default_page', 'plan_share', 'ingredient_decimals', 'comments', 'left_handed',
'show_step_ingredients',
'sticky_navbar', 'default_page', 'plan_share', 'ingredient_decimals', 'comments', 'left_handed', 'show_step_ingredients',
)

labels = {
Expand All @@ -67,21 +66,19 @@ class Meta:

help_texts = {
'nav_color': _('Color of the top navigation bar. Not all colors work with all themes, just try them out!'),

'default_unit': _('Default Unit to be used when inserting a new ingredient into a recipe.'),
'default_unit': _('Default Unit to be used when inserting a new ingredient into a recipe.'),
'use_fractions': _(
'Enables support for fractions in ingredient amounts (e.g. convert decimals to fractions automatically)'),

'use_kj': _('Display nutritional energy amounts in joules instead of calories'),
'use_kj': _('Display nutritional energy amounts in joules instead of calories'),
'plan_share': _('Users with whom newly created meal plans should be shared by default.'),
'shopping_share': _('Users with whom to share shopping lists.'),
'ingredient_decimals': _('Number of decimals to round ingredients.'),
'comments': _('If you want to be able to create and see comments underneath recipes.'),
'ingredient_decimals': _('Number of decimals to round ingredients.'),
'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.'
'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.'
),
'sticky_navbar': _('Makes the navbar stick to the top of the page.'),
'sticky_navbar': _('Makes the navbar stick to the top of the page.'),
'mealplan_autoadd_shopping': _('Automatically add meal plan ingredients to shopping list.'),
'mealplan_autoexclude_onhand': _('Exclude ingredients that are on hand.'),
'left_handed': _('Will optimize the UI for use with your left hand.'),
Expand Down Expand Up @@ -187,6 +184,7 @@ def clean(self, data, initial=None):
result = single_file_clean(data, initial)
return result


class ImportForm(ImportExportBase):
files = MultipleFileField(required=True)
duplicates = forms.BooleanField(help_text=_(
Expand Down Expand Up @@ -325,50 +323,6 @@ class Meta:
}


# TODO deprecate
class MealPlanForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['recipe'].queryset = Recipe.objects.filter(space=space).all()
self.fields['meal_type'].queryset = MealType.objects.filter(space=space).all()
self.fields['shared'].queryset = User.objects.filter(userpreference__space=space).all()

def clean(self):
cleaned_data = super(MealPlanForm, self).clean()

if cleaned_data['title'] == '' and cleaned_data['recipe'] is None:
raise forms.ValidationError(
_('You must provide at least a recipe or a title.')
)

return cleaned_data

class Meta:
model = MealPlan
fields = (
'recipe', 'title', 'meal_type', 'note',
'servings', 'date', 'shared'
)

help_texts = {
'shared': _('You can list default users to share recipes with in the settings.'),
'note': _('You can use markdown to format this field. See the <a href="/docs/markdown/">docs here</a>')

}

widgets = {
'recipe': SelectWidget,
'date': DateWidget,
'shared': MultiSelectWidget
}
field_classes = {
'recipe': SafeModelChoiceField,
'meal_type': SafeModelChoiceField,
'shared': SafeModelMultipleChoiceField,
}


class InviteLinkForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
Expand Down Expand Up @@ -509,8 +463,8 @@ class Meta:
help_texts = {
'shopping_share': _('Users will see all items you add to your shopping list. They must add you to see items on their list.'),
'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.'
'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.'
),
'mealplan_autoadd_shopping': _('Automatically add meal plan ingredients to shopping list.'),
'mealplan_autoinclude_related': _('When adding a meal plan to the shopping list (manually or automatically), include all related recipes.'),
Expand Down Expand Up @@ -554,11 +508,10 @@ def __init__(self, *args, **kwargs):
class Meta:
model = Space

fields = ('food_inherit', 'reset_food_inherit', 'show_facet_count', 'use_plural')
fields = ('food_inherit', 'reset_food_inherit', 'use_plural')

help_texts = {
'food_inherit': _('Fields on food that should be inherited by default.'),
'show_facet_count': _('Show recipe counts on search filters'),
'use_plural': _('Use the plural form for units and food inside this space.'),
}

Expand Down
14 changes: 8 additions & 6 deletions cookbook/helper/AllAuthCustomAdapter.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import datetime

from django.conf import settings
from gettext import gettext as _

from allauth.account.adapter import DefaultAccountAdapter
from django.conf import settings
from django.contrib import messages
from django.core.cache import caches
from gettext import gettext as _

from cookbook.models import InviteLink

Expand All @@ -17,10 +16,13 @@ def is_open_for_signup(self, request):
Whether to allow sign-ups.
"""
signup_token = False
if 'signup_token' in request.session and InviteLink.objects.filter(valid_until__gte=datetime.datetime.today(), used_by=None, uuid=request.session['signup_token']).exists():
if 'signup_token' in request.session and InviteLink.objects.filter(
valid_until__gte=datetime.datetime.today(), used_by=None, uuid=request.session['signup_token']).exists():
signup_token = True

if (request.resolver_match.view_name == 'account_signup' or request.resolver_match.view_name == 'socialaccount_signup') and not settings.ENABLE_SIGNUP and not signup_token:
if request.resolver_match.view_name == 'account_signup' and not settings.ENABLE_SIGNUP and not signup_token:
return False
elif request.resolver_match.view_name == 'socialaccount_signup' and len(settings.SOCIAL_PROVIDERS) < 1:
return False
else:
return super(AllAuthCustomAdapter, self).is_open_for_signup(request)
Expand All @@ -33,7 +35,7 @@ def send_mail(self, template_prefix, email, context):
if c == default:
try:
super(AllAuthCustomAdapter, self).send_mail(template_prefix, email, context)
except Exception: # dont fail signup just because confirmation mail could not be send
except Exception: # dont fail signup just because confirmation mail could not be send
pass
else:
messages.add_message(self.request, messages.ERROR, _('In order to prevent spam, the requested email was not send. Please wait a few minutes and try again.'))
Expand Down
Loading

0 comments on commit 75523c0

Please sign in to comment.