Fix typos
This commit is contained in:
parent
0f7dc096cb
commit
c20e982fb1
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: Continous Integration
|
name: Continuous Integration
|
||||||
|
|
||||||
on: [push]
|
on: [push]
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<h4 align="center">The recipe manager that allows you to manage your ever growing collection of digital recipes.</h4>
|
<h4 align="center">The recipe manager that allows you to manage your ever growing collection of digital recipes.</h4>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/vabene1111/recipes/actions" target="_blank" rel="noopener noreferrer"><img src="https://github.com/vabene1111/recipes/workflows/Continous%20Integration/badge.svg?branch=master" ></a>
|
<a href="https://github.com/vabene1111/recipes/actions" target="_blank" rel="noopener noreferrer"><img src="https://github.com/vabene1111/recipes/workflows/Continuous%20Integration/badge.svg?branch=master" ></a>
|
||||||
<a href="https://github.com/vabene1111/recipes/stargazers" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/github/stars/vabene1111/recipes" ></a>
|
<a href="https://github.com/vabene1111/recipes/stargazers" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/github/stars/vabene1111/recipes" ></a>
|
||||||
<a href="https://github.com/vabene1111/recipes/network/members" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/github/forks/vabene1111/recipes" ></a>
|
<a href="https://github.com/vabene1111/recipes/network/members" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/github/forks/vabene1111/recipes" ></a>
|
||||||
<a href="https://discord.gg/RhzBrfWgtp" target="_blank" rel="noopener noreferrer"><img src="https://badgen.net/badge/icon/discord?icon=discord&label" ></a>
|
<a href="https://discord.gg/RhzBrfWgtp" target="_blank" rel="noopener noreferrer"><img src="https://badgen.net/badge/icon/discord?icon=discord&label" ></a>
|
||||||
|
@ -7,4 +7,4 @@ Since this software is still considered beta/WIP support is always only given fo
|
|||||||
## Reporting a Vulnerability
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
Please open a normal public issue if you have any security related concerns. If you feel like the issue should not be discussed in
|
Please open a normal public issue if you have any security related concerns. If you feel like the issue should not be discussed in
|
||||||
public just open a generic issue and we will discuss further communitcation there (since GitHub does not allow everyone to create a security advisory :/).
|
public just open a generic issue and we will discuss further communication there (since GitHub does not allow everyone to create a security advisory :/).
|
||||||
|
@ -442,7 +442,7 @@ class SearchPreferenceForm(forms.ModelForm):
|
|||||||
|
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'search': _(
|
'search': _(
|
||||||
'Select type method of search. Click <a href="/docs/search/">here</a> for full desciption of choices.'),
|
'Select type method of search. Click <a href="/docs/search/">here</a> for full description of choices.'),
|
||||||
'lookup': _('Use fuzzy matching on units, keywords and ingredients when editing and importing recipes.'),
|
'lookup': _('Use fuzzy matching on units, keywords and ingredients when editing and importing recipes.'),
|
||||||
'unaccent': _(
|
'unaccent': _(
|
||||||
'Fields to search ignoring accents. Selecting this option can improve or degrade search quality depending on language'),
|
'Fields to search ignoring accents. Selecting this option can improve or degrade search quality depending on language'),
|
||||||
@ -461,7 +461,7 @@ class SearchPreferenceForm(forms.ModelForm):
|
|||||||
'lookup': _('Fuzzy Lookups'),
|
'lookup': _('Fuzzy Lookups'),
|
||||||
'unaccent': _('Ignore Accent'),
|
'unaccent': _('Ignore Accent'),
|
||||||
'icontains': _("Partial Match"),
|
'icontains': _("Partial Match"),
|
||||||
'istartswith': _("Starts Wtih"),
|
'istartswith': _("Starts With"),
|
||||||
'trigram': _("Fuzzy Search"),
|
'trigram': _("Fuzzy Search"),
|
||||||
'fulltext': _("Full Text")
|
'fulltext': _("Full Text")
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ def has_group_permission(user, groups):
|
|||||||
"""
|
"""
|
||||||
Tests if a given user is member of a certain group (or any higher group)
|
Tests if a given user is member of a certain group (or any higher group)
|
||||||
Superusers always bypass permission checks.
|
Superusers always bypass permission checks.
|
||||||
Unauthenticated users cant be member of any group thus always return false.
|
Unauthenticated users can't be member of any group thus always return false.
|
||||||
:param user: django auth user object
|
:param user: django auth user object
|
||||||
:param groups: list or tuple of groups the user should be checked for
|
:param groups: list or tuple of groups the user should be checked for
|
||||||
:return: True if user is in allowed groups, false otherwise
|
:return: True if user is in allowed groups, false otherwise
|
||||||
|
@ -126,7 +126,7 @@ def list_from_recipe(list_recipe=None, recipe=None, mealplan=None, servings=None
|
|||||||
add_ingredients = set(add_ingredients) - set(existing_list.values_list('ingredient__id', flat=True))
|
add_ingredients = set(add_ingredients) - set(existing_list.values_list('ingredient__id', flat=True))
|
||||||
add_ingredients = Ingredient.objects.filter(id__in=add_ingredients, space=space)
|
add_ingredients = Ingredient.objects.filter(id__in=add_ingredients, space=space)
|
||||||
|
|
||||||
# if servings have changed, update the ShoppingListRecipe and existing Entrys
|
# if servings have changed, update the ShoppingListRecipe and existing Entries
|
||||||
if servings <= 0:
|
if servings <= 0:
|
||||||
servings = 1
|
servings = 1
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ def list_from_recipe(list_recipe=None, recipe=None, mealplan=None, servings=None
|
|||||||
sle.amount = sle.ingredient.amount * Decimal(servings_factor)
|
sle.amount = sle.ingredient.amount * Decimal(servings_factor)
|
||||||
sle.save()
|
sle.save()
|
||||||
|
|
||||||
# add any missing Entrys
|
# add any missing Entries
|
||||||
for i in [x for x in add_ingredients if x.food]:
|
for i in [x for x in add_ingredients if x.food]:
|
||||||
|
|
||||||
ShoppingListEntry.objects.create(
|
ShoppingListEntry.objects.create(
|
||||||
|
@ -27,7 +27,7 @@ class RecetteTek(Integration):
|
|||||||
|
|
||||||
def get_recipe_from_file(self, file):
|
def get_recipe_from_file(self, file):
|
||||||
|
|
||||||
# Create initial recipe with just a title and a decription
|
# Create initial recipe with just a title and a description
|
||||||
recipe = Recipe.objects.create(name=file['title'], created_by=self.request.user, internal=True, space=self.request.space, )
|
recipe = Recipe.objects.create(name=file['title'], created_by=self.request.user, internal=True, space=self.request.space, )
|
||||||
|
|
||||||
# set the description as an empty string for later use for the source URL, in case there is no description text.
|
# set the description as an empty string for later use for the source URL, in case there is no description text.
|
||||||
|
@ -15,7 +15,7 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
if settings.DATABASES['default']['ENGINE'] not in ['django.db.backends.postgresql_psycopg2', 'django.db.backends.postgresql']:
|
if settings.DATABASES['default']['ENGINE'] not in ['django.db.backends.postgresql_psycopg2', 'django.db.backends.postgresql']:
|
||||||
self.stdout.write(self.style.WARNING(_('Only Postgress databases use full text search, no index to rebuild')))
|
self.stdout.write(self.style.WARNING(_('Only Postgresql databases use full text search, no index to rebuild')))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
language = DICTIONARY.get(translation.get_language(), 'simple')
|
language = DICTIONARY.get(translation.get_language(), 'simple')
|
||||||
|
@ -515,7 +515,7 @@ class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def reset_inheritance(space=None):
|
def reset_inheritance(space=None):
|
||||||
# resets inheritted fields to the space defaults and updates all inheritted fields to root object values
|
# resets inherited fields to the space defaults and updates all inherited fields to root object values
|
||||||
inherit = space.food_inherit.all()
|
inherit = space.food_inherit.all()
|
||||||
|
|
||||||
# remove all inherited fields from food
|
# remove all inherited fields from food
|
||||||
|
@ -33,7 +33,7 @@ class Nextcloud(Provider):
|
|||||||
try:
|
try:
|
||||||
files.pop(0) # remove first element because its the folder itself
|
files.pop(0) # remove first element because its the folder itself
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass # folder is emtpy, no recipes will be imported
|
pass # folder is empty, no recipes will be imported
|
||||||
|
|
||||||
import_count = 0
|
import_count = 0
|
||||||
for file in files:
|
for file in files:
|
||||||
|
@ -865,7 +865,7 @@ class AutomationSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
|
|
||||||
# CORS, REST and Scopes aren't currently working
|
# CORS, REST and Scopes aren't currently working
|
||||||
# Scopes are evaluating before REST has authenticated the user assiging a None space
|
# Scopes are evaluating before REST has authenticated the user assigning a None space
|
||||||
# I've made the change below to fix the bookmarklet, other serializers likely need a similar/better fix
|
# I've made the change below to fix the bookmarklet, other serializers likely need a similar/better fix
|
||||||
class BookmarkletImportSerializer(serializers.ModelSerializer):
|
class BookmarkletImportSerializer(serializers.ModelSerializer):
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
|
@ -72,7 +72,7 @@ def update_food_inheritance(sender, instance=None, created=False, **kwargs):
|
|||||||
return
|
return
|
||||||
|
|
||||||
inherit = inherit.values_list('field', flat=True)
|
inherit = inherit.values_list('field', flat=True)
|
||||||
# apply changes from parent to instance for each inheritted field
|
# apply changes from parent to instance for each inherited field
|
||||||
if instance.parent and inherit.count() > 0:
|
if instance.parent and inherit.count() > 0:
|
||||||
parent = instance.get_parent()
|
parent = instance.get_parent()
|
||||||
if 'ignore_shopping' in inherit:
|
if 'ignore_shopping' in inherit:
|
||||||
|
@ -82,7 +82,7 @@
|
|||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
<h2>{% trans 'Lists' %}</h2>
|
<h2>{% trans 'Lists' %}</h2>
|
||||||
{% trans 'Lists can ordered or unorderd. It is <b>important to leave a blank line before the list!</b>' %}
|
{% trans 'Lists can ordered or unordered. It is <b>important to leave a blank line before the list!</b>' %}
|
||||||
<pre class="intro-code code-block"><code>
|
<pre class="intro-code code-block"><code>
|
||||||
{% trans 'Ordered List' %}
|
{% trans 'Ordered List' %}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
{% endblocktrans %}</p>
|
{% endblocktrans %}</p>
|
||||||
<h4>{% trans 'Simple' %}</h4>
|
<h4>{% trans 'Simple' %}</h4>
|
||||||
<p> {% blocktrans %}
|
<p> {% blocktrans %}
|
||||||
Simple searches ignore punctuation and common words such as 'the', 'a', 'and'. And will treat seperate words as required.
|
Simple searches ignore punctuation and common words such as 'the', 'a', 'and'. And will treat separate words as required.
|
||||||
Searching for 'apple or flour' will return any recipe that includes both 'apple' and 'flour' anywhere in the fields that have been selected for a full text search.
|
Searching for 'apple or flour' will return any recipe that includes both 'apple' and 'flour' anywhere in the fields that have been selected for a full text search.
|
||||||
{% endblocktrans %}</p>
|
{% endblocktrans %}</p>
|
||||||
<h4>{% trans 'Phrase' %}</h4>
|
<h4>{% trans 'Phrase' %}</h4>
|
||||||
@ -39,7 +39,7 @@
|
|||||||
<p> {% blocktrans %}
|
<p> {% blocktrans %}
|
||||||
Web searches simulate functionality found on many web search sites supporting special syntax.
|
Web searches simulate functionality found on many web search sites supporting special syntax.
|
||||||
Placing quotes around several words will convert those words into a phrase.
|
Placing quotes around several words will convert those words into a phrase.
|
||||||
'or' is recongized as searching for the word (or phrase) immediately before 'or' OR the word (or phrase) directly after.
|
'or' is recognized as searching for the word (or phrase) immediately before 'or' OR the word (or phrase) directly after.
|
||||||
'-' is recognized as searching for recipes that do not include the word (or phrase) that comes immediately after.
|
'-' is recognized as searching for recipes that do not include the word (or phrase) that comes immediately after.
|
||||||
For example searching for 'apple pie' or cherry -butter will return any recipe that includes the phrase 'apple pie' or the word 'cherry'
|
For example searching for 'apple pie' or cherry -butter will return any recipe that includes the phrase 'apple pie' or the word 'cherry'
|
||||||
in any field included in the full text search but exclude any recipe that has the word 'butter' in any field included.
|
in any field included in the full text search but exclude any recipe that has the word 'butter' in any field included.
|
||||||
@ -59,7 +59,7 @@
|
|||||||
{% blocktrans %}
|
{% blocktrans %}
|
||||||
Another approach to searching that also requires Postgresql is fuzzy search or trigram similarity. A trigram is a group of three consecutive characters.
|
Another approach to searching that also requires Postgresql is fuzzy search or trigram similarity. A trigram is a group of three consecutive characters.
|
||||||
For example searching for 'apple' will create x trigrams 'app', 'ppl', 'ple' and will create a score of how closely words match the generated trigrams.
|
For example searching for 'apple' will create x trigrams 'app', 'ppl', 'ple' and will create a score of how closely words match the generated trigrams.
|
||||||
One benefit of searching trigams is that a search for 'sandwich' will find mispelled words such as 'sandwhich' that would be missed by other methods.
|
One benefit of searching trigams is that a search for 'sandwich' will find misspelled words such as 'sandwhich' that would be missed by other methods.
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@
|
|||||||
{% if request.user.userpreference.shopping_auto_sync > 0 %}
|
{% if request.user.userpreference.shopping_auto_sync > 0 %}
|
||||||
<div class="row" v-if="!onLine">
|
<div class="row" v-if="!onLine">
|
||||||
<div class="col col-md-12">
|
<div class="col col-md-12">
|
||||||
<div class="alert alert-warning" role="alert">{% trans 'You are offline, shopping list might not syncronize.' %}</div>
|
<div class="alert alert-warning" role="alert">{% trans 'You are offline, shopping list might not synchronize.' %}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -634,7 +634,7 @@
|
|||||||
console.log('updating recipe', this.shopping_list.recipes[i])
|
console.log('updating recipe', this.shopping_list.recipes[i])
|
||||||
recipe_promises.push(this.$http.post("{% url 'api:shoppinglistrecipe-list' %}", this.shopping_list.recipes[i], {}).then((response) => {
|
recipe_promises.push(this.$http.post("{% url 'api:shoppinglistrecipe-list' %}", this.shopping_list.recipes[i], {}).then((response) => {
|
||||||
let old_id = this.shopping_list.recipes[i].id
|
let old_id = this.shopping_list.recipes[i].id
|
||||||
console.log("list recipe create respose ", response.body)
|
console.log("list recipe create response ", response.body)
|
||||||
this.$set(this.shopping_list.recipes, i, response.body)
|
this.$set(this.shopping_list.recipes, i, response.body)
|
||||||
for (let e of this.shopping_list.entries.filter(item => item.list_recipe === old_id)) {
|
for (let e of this.shopping_list.entries.filter(item => item.list_recipe === old_id)) {
|
||||||
console.log("found recipe updating ID")
|
console.log("found recipe updating ID")
|
||||||
|
@ -1088,7 +1088,7 @@ def recipe_from_source(request):
|
|||||||
return JsonResponse(
|
return JsonResponse(
|
||||||
{
|
{
|
||||||
'error': True,
|
'error': True,
|
||||||
'msg': _('No useable data could be found.')
|
'msg': _('No usable data could be found.')
|
||||||
},
|
},
|
||||||
status=400
|
status=400
|
||||||
)
|
)
|
||||||
|
@ -411,7 +411,7 @@ def user_settings(request):
|
|||||||
if (api_token := Token.objects.filter(user=request.user).first()) is None:
|
if (api_token := Token.objects.filter(user=request.user).first()) is None:
|
||||||
api_token = Token.objects.create(user=request.user)
|
api_token = Token.objects.create(user=request.user)
|
||||||
|
|
||||||
# these fields require postgress - just disable them if postgress isn't available
|
# these fields require postgresql - just disable them if postgresql isn't available
|
||||||
if not settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2',
|
if not settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2',
|
||||||
'django.db.backends.postgresql']:
|
'django.db.backends.postgresql']:
|
||||||
search_form.fields['search'].disabled = True
|
search_form.fields['search'].disabled = True
|
||||||
|
@ -51,7 +51,7 @@ In technical terms it is a multi tenant system.
|
|||||||
You can compare a space to something like google drive or dropbox.
|
You can compare a space to something like google drive or dropbox.
|
||||||
There is only one installation of the Dropbox system, but it handles multiple users without them noticing each other.
|
There is only one installation of the Dropbox system, but it handles multiple users without them noticing each other.
|
||||||
For Tandoor that means all people that work together on one recipe collection can be in one space.
|
For Tandoor that means all people that work together on one recipe collection can be in one space.
|
||||||
If you want to host the collection of your friends family or your neighbor you can create a separate space for them (trough the admin interface).
|
If you want to host the collection of your friends family or your neighbor you can create a separate space for them (through the admin interface).
|
||||||
|
|
||||||
Sharing between spaces is currently not possible but is planned for future releases.
|
Sharing between spaces is currently not possible but is planned for future releases.
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@ SOCIAL_PROVIDERS=allauth.socialaccount.providers.github,allauth.socialaccount.pr
|
|||||||
The exact formatting is important so make sure to follow the steps explained here!
|
The exact formatting is important so make sure to follow the steps explained here!
|
||||||
|
|
||||||
Depending on your authentication provider you **might need** to configure it.
|
Depending on your authentication provider you **might need** to configure it.
|
||||||
This needs to be done trough the settings system. To make the system flexible (allow multiple providers) and to
|
This needs to be done through the settings system. To make the system flexible (allow multiple providers) and to
|
||||||
not require another file to be mounted into the container the configuration ins done trough a single
|
not require another file to be mounted into the container the configuration ins done through a single
|
||||||
environment variable. The downside of this approach is that the configuration needs to be put into a single line
|
environment variable. The downside of this approach is that the configuration needs to be put into a single line
|
||||||
as environment files loaded by docker compose don't support multiple lines for a single variable.
|
as environment files loaded by docker compose don't support multiple lines for a single variable.
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ The basic configuration is the same for all providers.
|
|||||||
### Local
|
### Local
|
||||||
|
|
||||||
!!! info
|
!!! info
|
||||||
There is currently no way to upload files trough the webinterface. This is a feature that might be added later.
|
There is currently no way to upload files through the webinterface. This is a feature that might be added later.
|
||||||
|
|
||||||
The local provider does not need any configuration.
|
The local provider does not need any configuration.
|
||||||
For the monitor you will need to define a valid path on your host system.
|
For the monitor you will need to define a valid path on your host system.
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<h4 align="center">The recipe manager that allows you to manage your ever growing collection of digital recipes.</h4>
|
<h4 align="center">The recipe manager that allows you to manage your ever growing collection of digital recipes.</h4>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/vabene1111/recipes/actions" target="_blank" rel="noopener noreferrer"><img src="https://github.com/vabene1111/recipes/workflows/Continous%20Integration/badge.svg?branch=master" ></a>
|
<a href="https://github.com/vabene1111/recipes/actions" target="_blank" rel="noopener noreferrer"><img src="https://github.com/vabene1111/recipes/workflows/Continuous%20Integration/badge.svg?branch=master" ></a>
|
||||||
<a href="https://github.com/vabene1111/recipes/stargazers" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/github/stars/vabene1111/recipes" ></a>
|
<a href="https://github.com/vabene1111/recipes/stargazers" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/github/stars/vabene1111/recipes" ></a>
|
||||||
<a href="https://github.com/vabene1111/recipes/network/members" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/github/forks/vabene1111/recipes" ></a>
|
<a href="https://github.com/vabene1111/recipes/network/members" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/github/forks/vabene1111/recipes" ></a>
|
||||||
<a href="https://discord.gg/RhzBrfWgtp" target="_blank" rel="noopener noreferrer"><img src="https://badgen.net/badge/icon/discord?icon=discord&label" ></a>
|
<a href="https://discord.gg/RhzBrfWgtp" target="_blank" rel="noopener noreferrer"><img src="https://badgen.net/badge/icon/discord?icon=discord&label" ></a>
|
||||||
@ -85,7 +85,7 @@ there are some greater overall goals for the future (in no particular order)
|
|||||||
|
|
||||||
- Improve the UI! The Design is inconsistent and many pages work but don't look great. This needs to change.
|
- Improve the UI! The Design is inconsistent and many pages work but don't look great. This needs to change.
|
||||||
- I strongly believe in Open Data and Systems. Thus adding importers and exporters for all relevant other recipe management systems is something i really want to do.
|
- I strongly believe in Open Data and Systems. Thus adding importers and exporters for all relevant other recipe management systems is something i really want to do.
|
||||||
- Move all Javascript Libraries to a packet manger and clean up some of the mess I made in the early days
|
- Move all Javascript Libraries to a packet manager and clean up some of the mess I made in the early days
|
||||||
- Improve Test coverage and also the individual tests themselves
|
- Improve Test coverage and also the individual tests themselves
|
||||||
- Improve the documentation for all features and aspects of this project and add some application integrated help
|
- Improve the documentation for all features and aspects of this project and add some application integrated help
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# K8s Setup
|
# K8s Setup
|
||||||
|
|
||||||
This is a setup which should be sufficent for production use. Be sure to replace the default secrets!
|
This is a setup which should be sufficient for production use. Be sure to replace the default secrets!
|
||||||
|
|
||||||
# Files
|
# Files
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ The creation of the persistent volume claims for media and static content. May y
|
|||||||
|
|
||||||
## 40-sts-postgresql.yaml
|
## 40-sts-postgresql.yaml
|
||||||
|
|
||||||
The PostgreSQL stateful set, based on a bitnami image. It runs a init container as root to do the preparations. The postgres container itsef runs as a lower privileged user. The recipes app uses the database super user (postgres) as the recipies app is doing some db migrations on startup, which needs super user privileges.
|
The PostgreSQL stateful set, based on a bitnami image. It runs a init container as root to do the preparations. The postgres container itself runs as a lower privileged user. The recipes app uses the database super user (postgres) as the recipes app is doing some db migrations on startup, which needs super user privileges.
|
||||||
|
|
||||||
## 45-service-db.yaml
|
## 45-service-db.yaml
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ Creating the database service.
|
|||||||
|
|
||||||
## 50-deployment.yaml
|
## 50-deployment.yaml
|
||||||
|
|
||||||
The deployment first fires up a init container to do the database migrations and file modifications. This init container runs as root. The init conainer runs part of the [boot.sh](https://github.com/TandoorRecipes/recipes/blob/develop/boot.sh) script from the `vabene1111/recipes` image.
|
The deployment first fires up a init container to do the database migrations and file modifications. This init container runs as root. The init container runs part of the [boot.sh](https://github.com/TandoorRecipes/recipes/blob/develop/boot.sh) script from the `vabene1111/recipes` image.
|
||||||
|
|
||||||
The deployment then runs two containers, the recipes-nginx and the recipes container which runs the gunicorn app. The nginx container gets it's nginx.conf via config map to deliver static content `/static` and `/media`. The guincorn container gets it's secret key and the database password from the secret `recipes`. `gunicorn` runs as user `nobody`.
|
The deployment then runs two containers, the recipes-nginx and the recipes container which runs the gunicorn app. The nginx container gets it's nginx.conf via config map to deliver static content `/static` and `/media`. The guincorn container gets it's secret key and the database password from the secret `recipes`. `gunicorn` runs as user `nobody`.
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Manual installation instructions
|
# Manual installation instructions
|
||||||
|
|
||||||
These intructions are inspired from a standard django/gunicorn/postgresql instructions ([for example](https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-16-04))
|
These instructions are inspired from a standard django/gunicorn/postgresql instructions ([for example](https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-16-04))
|
||||||
|
|
||||||
!!! warning
|
!!! warning
|
||||||
Be sure to use python 3.9 and pip related to python 3.9. Depending on your distribution calling `python` or `pip` will use python2 instead of python 3.9.
|
Be sure to use python 3.9 and pip related to python 3.9. Depending on your distribution calling `python` or `pip` will use python2 instead of python 3.9.
|
||||||
@ -115,7 +115,7 @@ ExecStart=/var/www/recipes/bin/gunicorn --error-logfile /tmp/gunicorn_err.log --
|
|||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
```
|
```
|
||||||
|
|
||||||
*Note*: `-error-logfile /tmp/gunicorn_err.log --log-level debug --capture-output` are usefull for debugging and can be removed later
|
*Note*: `-error-logfile /tmp/gunicorn_err.log --log-level debug --capture-output` are useful for debugging and can be removed later
|
||||||
|
|
||||||
*Note2*: Fix the path in the `ExecStart` line to where you gunicorn and recipes are
|
*Note2*: Fix the path in the `ExecStart` line to where you gunicorn and recipes are
|
||||||
|
|
||||||
|
@ -57,4 +57,4 @@ apache:
|
|||||||
|
|
||||||
I used two paths `<sub path>` and `<www path>` for simplicity. In my case I have `<sub path> = recipes` and `<www path> = serve/recipes`. One could also change the matching rules of traefik to have everything under one path.
|
I used two paths `<sub path>` and `<www path>` for simplicity. In my case I have `<sub path> = recipes` and `<www path> = serve/recipes`. One could also change the matching rules of traefik to have everything under one path.
|
||||||
|
|
||||||
I left out the TLS config in this example for simplicty.
|
I left out the TLS config in this example for simplicity.
|
||||||
|
@ -78,7 +78,7 @@ Easiest way is to do it via Reverse Proxy
|
|||||||
- insert name
|
- insert name
|
||||||
- Source:
|
- Source:
|
||||||
- Protocol: HTTPS
|
- Protocol: HTTPS
|
||||||
- Hostname: URL if you acces from outside, otherwise ip in network
|
- Hostname: URL if you access from outside, otherwise ip in network
|
||||||
- Port: The port you want to access, has to be a different one that the one in the docker-compose file
|
- Port: The port you want to access, has to be a different one that the one in the docker-compose file
|
||||||
- HSTS can be enabled
|
- HSTS can be enabled
|
||||||
- Destination:
|
- Destination:
|
||||||
@ -88,14 +88,14 @@ Easiest way is to do it via Reverse Proxy
|
|||||||
- Click on Custom Header and press Create -> Websocket
|
- Click on Custom Header and press Create -> Websocket
|
||||||
- Save
|
- Save
|
||||||
- Control Panel -> Security -> Firewall -> Edit Rules -> Create
|
- Control Panel -> Security -> Firewall -> Edit Rules -> Create
|
||||||
- Ports: Select form a list of build-in applications -> Select -> You find your Reverse Proxy, enable it
|
- Ports: Select form a list of built-in applications -> Select -> You find your Reverse Proxy, enable it
|
||||||
- Source IP: Depends, All allows access from outside, i use specific to only connect in my network
|
- Source IP: Depends, All allows access from outside, i use specific to only connect in my network
|
||||||
- Action: Allow
|
- Action: Allow
|
||||||
- Save and make sure it's above the deny rules
|
- Save and make sure it's above the deny rules
|
||||||
|
|
||||||
[Deprecated, Note: ssl Path changed for DSM 7]
|
[Deprecated, Note: ssl Path changed for DSM 7]
|
||||||
6.1 Additional SSL Setup
|
6.1 Additional SSL Setup
|
||||||
- create foler `ssl` inside `nginx` folder
|
- create folder `ssl` inside `nginx` folder
|
||||||
- download your ssl certificate from `security` tab in dsm `control panel`
|
- download your ssl certificate from `security` tab in dsm `control panel`
|
||||||
- or create a task in `task manager` because Synology will update the certificate every few months
|
- or create a task in `task manager` because Synology will update the certificate every few months
|
||||||
- set task to repeat every day
|
- set task to repeat every day
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
!!! danger
|
!!! danger
|
||||||
Please refer to [the offical documentation](https://doc.traefik.io/traefik/).
|
Please refer to [the official documentation](https://doc.traefik.io/traefik/).
|
||||||
This example just shows something similar to my setup in case you dont understand the offical documentation.
|
This example just shows something similar to my setup in case you dont understand the official documentation.
|
||||||
|
|
||||||
You need to create a network called `traefik` using `docker network create traefik`.
|
You need to create a network called `traefik` using `docker network create traefik`.
|
||||||
## docker-compose.yml
|
## docker-compose.yml
|
||||||
|
@ -18,7 +18,7 @@ After that, you can go to the "Apps" tab in unRAID and search for Recipes and lo
|
|||||||

|

|
||||||
|
|
||||||
The default settings should by fine for most users, just be sure to enter a secret key that is randomly generated.
|
The default settings should by fine for most users, just be sure to enter a secret key that is randomly generated.
|
||||||
Then chooose apply.
|
Then choose apply.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ There is currently no "good" way of backing up your data implemented in the appl
|
|||||||
This mean that you will be responsible for backing up your data.
|
This mean that you will be responsible for backing up your data.
|
||||||
|
|
||||||
It is planned to add a "real" backup feature similar to applications like homeassistant where a snapshot can be
|
It is planned to add a "real" backup feature similar to applications like homeassistant where a snapshot can be
|
||||||
downloaded and restored trough the web interface.
|
downloaded and restored through the web interface.
|
||||||
|
|
||||||
!!! warning
|
!!! warning
|
||||||
When developing a new backup strategy, make sure to also test the restore process!
|
When developing a new backup strategy, make sure to also test the restore process!
|
||||||
|
@ -21,13 +21,13 @@ The following table roughly defines the capabilities of each role
|
|||||||
!!! warning
|
!!! warning
|
||||||
Users without groups cannot do anything. Make sure to assign them a group!
|
Users without groups cannot do anything. Make sure to assign them a group!
|
||||||
|
|
||||||
You can either create new users trough the admin interface or by sending them invite links.
|
You can either create new users through the admin interface or by sending them invite links.
|
||||||
|
|
||||||
Invite links can be generated on the System page. If you specify a username during the creation of the link
|
Invite links can be generated on the System page. If you specify a username during the creation of the link
|
||||||
the person using it won't be able to change that name.
|
the person using it won't be able to change that name.
|
||||||
|
|
||||||
## Managing Permissions
|
## Managing Permissions
|
||||||
Management of permissions can currently only be achieved trough the django admin interface.
|
Management of permissions can currently only be achieved through the django admin interface.
|
||||||
|
|
||||||
!!! warning
|
!!! warning
|
||||||
Please do not rename the groups as this breaks the permission system.
|
Please do not rename the groups as this breaks the permission system.
|
||||||
|
@ -407,7 +407,7 @@ TEST_RUNNER = "cookbook.helper.CustomTestRunner.CustomTestRunner"
|
|||||||
# settings for cross site origin (CORS)
|
# settings for cross site origin (CORS)
|
||||||
# all origins allowed to support bookmarklet
|
# all origins allowed to support bookmarklet
|
||||||
# all of this may or may not work with nginx or other web servers
|
# all of this may or may not work with nginx or other web servers
|
||||||
# TODO make this user configureable - enable or disable bookmarklets
|
# TODO make this user configurable - enable or disable bookmarklets
|
||||||
# TODO since token auth is enabled - this all should be https by default
|
# TODO since token auth is enabled - this all should be https by default
|
||||||
CORS_ORIGIN_ALLOW_ALL = True
|
CORS_ORIGIN_ALLOW_ALL = True
|
||||||
|
|
||||||
|
@ -1152,7 +1152,7 @@ export default {
|
|||||||
updateFood: function (food, field) {
|
updateFood: function (food, field) {
|
||||||
let api = new ApiApiFactory()
|
let api = new ApiApiFactory()
|
||||||
if (field) {
|
if (field) {
|
||||||
// assume if field is changing it should no longer be inheritted
|
// assume if field is changing it should no longer be inherited
|
||||||
food.inherit_fields = food.inherit_fields.filter((x) => x.field !== field)
|
food.inherit_fields = food.inherit_fields.filter((x) => x.field !== field)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ export default {
|
|||||||
addShopping() {
|
addShopping() {
|
||||||
if (this.shopping) {
|
if (this.shopping) {
|
||||||
return
|
return
|
||||||
} // if item already in shopping list, excution handled after confirmation
|
} // if item already in shopping list, execution handled after confirmation
|
||||||
let params = {
|
let params = {
|
||||||
id: this.item.id,
|
id: this.item.id,
|
||||||
amount: 1,
|
amount: 1,
|
||||||
|
@ -116,7 +116,7 @@ export default {
|
|||||||
},
|
},
|
||||||
addNew(e) {
|
addNew(e) {
|
||||||
this.$emit("new", e)
|
this.$emit("new", e)
|
||||||
// could refactor as Promise - seems unecessary
|
// could refactor as Promise - seems unnecessary
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.search("")
|
this.search("")
|
||||||
}, 750)
|
}, 750)
|
||||||
|
@ -77,7 +77,7 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.id = Math.random()
|
this.id = Math.random()
|
||||||
this.$root.$on("change", this.storeValue) // boostrap modal placed at document so have to listen at root of component
|
this.$root.$on("change", this.storeValue) // bootstrap modal placed at document so have to listen at root of component
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
buttonLabel() {
|
buttonLabel() {
|
||||||
|
Loading…
Reference in New Issue
Block a user