Compare commits

...

616 Commits

Author SHA1 Message Date
vabene1111
289625923f Merge pull request #261 from vabene1111/dependabot/pip/requests-2.25.1
Bump requests from 2.25.0 to 2.25.1
2020-12-17 09:36:47 +01:00
dependabot[bot]
a42a76a2cf Bump requests from 2.25.0 to 2.25.1
Bumps [requests](https://github.com/psf/requests) from 2.25.0 to 2.25.1.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/master/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.25.0...v2.25.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-17 06:23:09 +00:00
vabene1111
fd1216cd22 Merge pull request #259 from vabene1111/translations_cookbook-locale-en-lc-messages-django-po--develop_fr
Translate '/cookbook/locale/en/LC_MESSAGES/django.po' in 'fr'
2020-12-16 15:49:05 +01:00
transifex-integration[bot]
3f6a342026 Apply translations in fr
translation completed for the source file '/cookbook/locale/en/LC_MESSAGES/django.po'
on the 'fr' language.
2020-12-16 14:47:47 +00:00
vabene1111
f72fc699f8 fixed import image error 2020-12-15 22:54:10 +01:00
vabene1111
cdcca80196 Merge pull request #252 from vabene1111/dependabot/pip/django-cleanup-5.1.0
Bump django-cleanup from 4.0.0 to 5.1.0
2020-12-15 22:44:08 +01:00
vabene1111
400cd2f6a0 Merge pull request #251 from vabene1111/dependabot/pip/djangorestframework-3.12.2
Bump djangorestframework from 3.11.0 to 3.12.2
2020-12-15 22:44:02 +01:00
dependabot[bot]
37a4821d01 Bump django-cleanup from 4.0.0 to 5.1.0
Bumps [django-cleanup](https://github.com/un1t/django-cleanup) from 4.0.0 to 5.1.0.
- [Release notes](https://github.com/un1t/django-cleanup/releases)
- [Changelog](https://github.com/un1t/django-cleanup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/un1t/django-cleanup/compare/4.0.0...5.1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-15 21:44:00 +00:00
vabene1111
d165075a96 Merge pull request #250 from vabene1111/dependabot/pip/django-crispy-forms-1.10.0
Bump django-crispy-forms from 1.9.1 to 1.10.0
2020-12-15 22:43:38 +01:00
vabene1111
a062173ebd Merge pull request #249 from vabene1111/dependabot/pip/django-3.1.4
Bump django from 3.1.3 to 3.1.4
2020-12-15 22:43:31 +01:00
vabene1111
806963c396 Merge pull request #248 from vabene1111/dependabot/pip/icalendar-4.0.7
Bump icalendar from 4.0.6 to 4.0.7
2020-12-15 22:42:44 +01:00
vabene1111
851853740d added catalan language chooser 2020-12-15 22:19:36 +01:00
vabene1111
7ca88f3c0a fixed scaling for fractions 2020-12-15 22:16:15 +01:00
vabene1111
ac2e9dd6cb updated german translation 2020-12-15 22:04:40 +01:00
vabene1111
b2a34ce59a Merge pull request #255 from vabene1111/translations_cookbook-locale-en-lc-messages-django-po--develop_de
Translate '/cookbook/locale/en/LC_MESSAGES/django.po' in 'de'
2020-12-15 22:04:12 +01:00
transifex-integration[bot]
6124501f5a Apply translations in de
translation completed for the source file '/cookbook/locale/en/LC_MESSAGES/django.po'
on the 'de' language.
2020-12-15 21:03:40 +00:00
vabene1111
4ec313f752 fixed another importer issue 2020-12-15 21:59:34 +01:00
vabene1111
dd07c56ede fixed issue with new fraction importer 2020-12-15 21:52:56 +01:00
vabene1111
77fae46aee translation updates 2020-12-15 21:39:42 +01:00
vabene1111
ff573b0358 Merge pull request #254 from vabene1111/translations_cookbook-locale-en-lc-messages-django-po--develop_ca
Translate '/cookbook/locale/en/LC_MESSAGES/django.po' in 'ca'
2020-12-15 13:02:52 +01:00
transifex-integration[bot]
247eab2a4f Apply translations in ca
translation completed for the source file '/cookbook/locale/en/LC_MESSAGES/django.po'
on the 'ca' language.
2020-12-15 12:00:28 +00:00
dependabot[bot]
dc46502667 Bump djangorestframework from 3.11.0 to 3.12.2
Bumps [djangorestframework](https://github.com/encode/django-rest-framework) from 3.11.0 to 3.12.2.
- [Release notes](https://github.com/encode/django-rest-framework/releases)
- [Commits](https://github.com/encode/django-rest-framework/compare/3.11.0...3.12.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-15 06:28:44 +00:00
dependabot[bot]
ac58f1959d Bump django-crispy-forms from 1.9.1 to 1.10.0
Bumps [django-crispy-forms](https://github.com/django-crispy-forms/django-crispy-forms) from 1.9.1 to 1.10.0.
- [Release notes](https://github.com/django-crispy-forms/django-crispy-forms/releases)
- [Changelog](https://github.com/django-crispy-forms/django-crispy-forms/blob/master/CHANGELOG.md)
- [Commits](https://github.com/django-crispy-forms/django-crispy-forms/compare/1.9.1...1.10.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-15 06:28:43 +00:00
dependabot[bot]
f4543f8d65 Bump django from 3.1.3 to 3.1.4
Bumps [django](https://github.com/django/django) from 3.1.3 to 3.1.4.
- [Release notes](https://github.com/django/django/releases)
- [Commits](https://github.com/django/django/compare/3.1.3...3.1.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-15 06:28:42 +00:00
dependabot[bot]
d0ef5e27df Bump icalendar from 4.0.6 to 4.0.7
Bumps [icalendar](https://github.com/collective/icalendar) from 4.0.6 to 4.0.7.
- [Release notes](https://github.com/collective/icalendar/releases)
- [Changelog](https://github.com/collective/icalendar/blob/master/CHANGES.rst)
- [Commits](https://github.com/collective/icalendar/compare/4.0.6...4.0.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-15 06:28:41 +00:00
vabene1111
9ea90f1c87 fraction import 2020-12-14 19:56:21 +01:00
vabene1111
e7922a7e47 nutirtion fix 2020-12-14 19:12:01 +01:00
vabene1111
d3bc440c83 meal plan quality of life stuff 2020-12-14 17:37:51 +01:00
vabene1111
910b28fe2d meal plan date handling rewrite 2020-12-14 17:11:40 +01:00
vabene1111
89cd8bc2d2 fixed wrong translation 2020-12-14 15:49:32 +01:00
vabene1111
d2e9ad2ae6 requirement still needed 2020-12-14 15:14:55 +01:00
vabene1111
56c9edd328 removed deprecated psycopg2 2020-12-14 15:11:41 +01:00
vabene1111
7732aa7646 added support for fractions 2020-12-14 14:08:11 +01:00
vabene1111
9863447bac small nutrition fixes 2020-12-14 12:56:18 +01:00
vabene1111
53b00cc4c8 Merge pull request #199 from sebimarkgraf/feature/nutrition
Add nutritional values
2020-12-14 12:29:56 +01:00
vabene1111
4f34ec1be8 Merge pull request #235 from vabene1111/dependabot/pip/pillow-8.0.1
Bump pillow from 7.1.2 to 8.0.1
2020-12-14 12:08:48 +01:00
dependabot[bot]
e444ba91f0 Bump pillow from 7.1.2 to 8.0.1
Bumps [pillow](https://github.com/python-pillow/Pillow) from 7.1.2 to 8.0.1.
- [Release notes](https://github.com/python-pillow/Pillow/releases)
- [Changelog](https://github.com/python-pillow/Pillow/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-pillow/Pillow/compare/7.1.2...8.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-14 11:08:35 +00:00
vabene1111
fa3513eb65 Merge pull request #234 from vabene1111/dependabot/pip/webdavclient3-3.14.5
Bump webdavclient3 from 3.14.4 to 3.14.5
2020-12-14 12:08:29 +01:00
vabene1111
d323778f1d Merge pull request #232 from vabene1111/dependabot/pip/django-autocomplete-light-3.8.1
Bump django-autocomplete-light from 3.5.1 to 3.8.1
2020-12-14 12:08:14 +01:00
vabene1111
53cb5afef6 Merge pull request #236 from vabene1111/dependabot/pip/beautifulsoup4-4.9.3
Bump beautifulsoup4 from 4.9.2 to 4.9.3
2020-12-14 12:07:37 +01:00
vabene1111
0349301919 Merge pull request #242 from vabene1111/dependabot/pip/lxml-4.6.2
Bump lxml from 4.5.1 to 4.6.2
2020-12-14 12:07:24 +01:00
vabene1111
a5d2bd75d6 recompiled messages + added timezone setting 2020-12-14 12:03:43 +01:00
vabene1111
26499ad431 Merge pull request #229 from sebimarkgraf/fix/225-random-button
Include random in filtermixin
2020-12-14 11:51:59 +01:00
dependabot[bot]
2eb72953f0 Bump lxml from 4.5.1 to 4.6.2
Bumps [lxml](https://github.com/lxml/lxml) from 4.5.1 to 4.6.2.
- [Release notes](https://github.com/lxml/lxml/releases)
- [Changelog](https://github.com/lxml/lxml/blob/master/CHANGES.txt)
- [Commits](https://github.com/lxml/lxml/compare/lxml-4.5.1...lxml-4.6.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-30 07:22:55 +00:00
Sebastian Markgraf
422113a745 Finish editing of nutritional information 2020-11-17 22:27:01 +01:00
dependabot[bot]
e687d0e569 Bump beautifulsoup4 from 4.9.2 to 4.9.3
Bumps [beautifulsoup4](http://www.crummy.com/software/BeautifulSoup/bs4/) from 4.9.2 to 4.9.3.

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-16 07:19:43 +00:00
dependabot[bot]
76c1529ec1 Bump webdavclient3 from 3.14.4 to 3.14.5
Bumps [webdavclient3](https://github.com/ezhov-evgeny/webdav-client-python-3) from 3.14.4 to 3.14.5.
- [Release notes](https://github.com/ezhov-evgeny/webdav-client-python-3/releases)
- [Changelog](https://github.com/ezhov-evgeny/webdav-client-python-3/blob/develop/RELEASE_NOTES.md)
- [Commits](https://github.com/ezhov-evgeny/webdav-client-python-3/compare/v3.14.4...v3.14.5)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-16 07:19:41 +00:00
dependabot[bot]
d30b2b7ec8 Bump django-autocomplete-light from 3.5.1 to 3.8.1
Bumps [django-autocomplete-light](https://github.com/yourlabs/django-autocomplete-light) from 3.5.1 to 3.8.1.
- [Release notes](https://github.com/yourlabs/django-autocomplete-light/releases)
- [Changelog](https://github.com/yourlabs/django-autocomplete-light/blob/master/CHANGELOG)
- [Commits](https://github.com/yourlabs/django-autocomplete-light/compare/3.5.1...3.8.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-16 07:19:35 +00:00
Sebastian Markgraf
c4fbad614e Include random in filtermixin 2020-11-14 20:20:30 +01:00
vabene1111
4c92a4b39c fixed shopping list recipe search 2020-11-14 11:20:43 +01:00
vabene1111
3dad5132bb Merge pull request #219 from vabene1111/dependabot/pip/markdown-3.3.3
Bump markdown from 3.2.2 to 3.3.3
2020-11-14 11:16:55 +01:00
vabene1111
7d7890445e Merge pull request #220 from vabene1111/dependabot/pip/django-3.1.3
Bump django from 3.1.1 to 3.1.3
2020-11-14 11:16:49 +01:00
vabene1111
cea015f23d Merge pull request #221 from vabene1111/dependabot/pip/drf-writable-nested-0.6.2
Bump drf-writable-nested from 0.6.1 to 0.6.2
2020-11-14 11:16:43 +01:00
vabene1111
3e8610912e Merge pull request #223 from vabene1111/dependabot/pip/django-tables2-2.3.3
Bump django-tables2 from 2.3.1 to 2.3.3
2020-11-14 11:16:38 +01:00
vabene1111
ba80ca42e6 Merge pull request #226 from vabene1111/dependabot/pip/requests-2.25.0
Bump requests from 2.23.0 to 2.25.0
2020-11-14 11:16:32 +01:00
vabene1111
c413db5460 fixed english typo 2020-11-14 11:16:01 +01:00
vabene1111
0e319ff293 fixed typo in german transaltion 2020-11-14 11:15:21 +01:00
vabene1111
88e3b22dcd Merge pull request #228 from vabene1111/translations_cookbook-locale-en-lc-messages-django-po--develop_nl
Translate '/cookbook/locale/en/LC_MESSAGES/django.po' in 'nl'
2020-11-14 11:02:53 +01:00
transifex-integration[bot]
19e2094ecd Apply translations in nl
translation completed for the source file '/cookbook/locale/en/LC_MESSAGES/django.po'
on the 'nl' language.
2020-11-13 22:21:02 +00:00
dependabot[bot]
215989682b Bump requests from 2.23.0 to 2.25.0
Bumps [requests](https://github.com/psf/requests) from 2.23.0 to 2.25.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/master/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.23.0...v2.25.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-12 06:37:40 +00:00
Sebastian Markgraf
2f038edf8c Fix missing string literals for translations. 2020-11-06 17:24:20 +01:00
Sebastian Markgraf
a754002f4e Revert approach to fixed nutritional values. 2020-11-06 17:22:21 +01:00
dependabot[bot]
1af2211010 Bump django-tables2 from 2.3.1 to 2.3.3
Bumps [django-tables2](https://github.com/jieter/django-tables2) from 2.3.1 to 2.3.3.
- [Release notes](https://github.com/jieter/django-tables2/releases)
- [Changelog](https://github.com/jieter/django-tables2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jieter/django-tables2/compare/v2.3.1...v2.3.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-05 06:32:16 +00:00
dependabot[bot]
724d57ecd7 Bump django from 3.1.1 to 3.1.3
Bumps [django](https://github.com/django/django) from 3.1.1 to 3.1.3.
- [Release notes](https://github.com/django/django/releases)
- [Commits](https://github.com/django/django/compare/3.1.1...3.1.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-05 06:32:15 +00:00
dependabot[bot]
4b04fada51 Bump drf-writable-nested from 0.6.1 to 0.6.2
Bumps [drf-writable-nested](https://github.com/beda-software/drf-writable-nested) from 0.6.1 to 0.6.2.
- [Release notes](https://github.com/beda-software/drf-writable-nested/releases)
- [Changelog](https://github.com/beda-software/drf-writable-nested/blob/master/CHANGELOG.md)
- [Commits](https://github.com/beda-software/drf-writable-nested/compare/v0.6.1...v0.6.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-05 06:32:15 +00:00
dependabot[bot]
4ad7043f91 Bump markdown from 3.2.2 to 3.3.3
Bumps [markdown](https://github.com/Python-Markdown/markdown) from 3.2.2 to 3.3.3.
- [Release notes](https://github.com/Python-Markdown/markdown/releases)
- [Commits](https://github.com/Python-Markdown/markdown/compare/3.2.2...3.3.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-05 06:32:13 +00:00
vabene1111
4dfda4439c re added standard filter to recipe api 2020-11-04 16:53:49 +01:00
vabene1111
591d185b9d improved random recipe queryset function 2020-11-04 15:09:35 +01:00
vabene1111
8d582548bd Merge pull request #213 from tourn/random-recipes2
Show random recipes in meal planner
2020-11-04 15:06:50 +01:00
vabene1111
209924e5b3 Merge pull request #191 from vabene1111/dependabot/pip/psycopg2-binary-2.8.6
Bump psycopg2-binary from 2.8.5 to 2.8.6
2020-11-04 15:01:52 +01:00
dependabot[bot]
7e3e2aadaf Bump psycopg2-binary from 2.8.5 to 2.8.6
Bumps [psycopg2-binary](https://github.com/psycopg/psycopg2) from 2.8.5 to 2.8.6.
- [Release notes](https://github.com/psycopg/psycopg2/releases)
- [Changelog](https://github.com/psycopg/psycopg2/blob/master/NEWS)
- [Commits](https://github.com/psycopg/psycopg2/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-04 14:01:23 +00:00
vabene1111
0930e615f0 Merge pull request #192 from vabene1111/dependabot/pip/simplejson-3.17.2
Bump simplejson from 3.17.0 to 3.17.2
2020-11-04 15:00:59 +01:00
vabene1111
21c759b127 Merge pull request #193 from vabene1111/dependabot/pip/whitenoise-5.2.0
Bump whitenoise from 5.1.0 to 5.2.0
2020-11-04 15:00:46 +01:00
vabene1111
7d1a83440d Merge pull request #195 from vabene1111/dependabot/pip/bleach-3.2.1
Bump bleach from 3.1.5 to 3.2.1
2020-11-04 15:00:37 +01:00
vabene1111
2d75b303fd Merge pull request #210 from vabene1111/dependabot/pip/python-dotenv-0.15.0
Bump python-dotenv from 0.13.0 to 0.15.0
2020-11-04 15:00:26 +01:00
vabene1111
a1b15d46b8 fixed note only meal plan entries not working 2020-11-04 14:58:31 +01:00
tourn
69a6edee99 Show random recipes in meal planner 2020-11-03 16:46:31 +01:00
vabene1111
0ac23b4e3a Merge pull request #211 from Tmaxxrox97/develop
Username field consistency
2020-10-29 17:00:27 +01:00
Tmaxxrox97
085e777ee0 Changed Username field label from "Name" to "Username" 2020-10-29 09:52:05 -05:00
Tmaxxrox97
c31df3f7a6 Merge pull request #1 from vabene1111/develop
Update repo
2020-10-29 07:58:32 -05:00
dependabot[bot]
98e2c0acaf Bump python-dotenv from 0.13.0 to 0.15.0
Bumps [python-dotenv](https://github.com/theskumar/python-dotenv) from 0.13.0 to 0.15.0.
- [Release notes](https://github.com/theskumar/python-dotenv/releases)
- [Changelog](https://github.com/theskumar/python-dotenv/blob/master/CHANGELOG.md)
- [Commits](https://github.com/theskumar/python-dotenv/compare/v0.13.0...v0.15.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-29 06:36:05 +00:00
vabene1111
1509b8243b Update docker-publish-release.yml 2020-10-24 17:19:23 +02:00
vabene1111
e427d8b714 donst export checked items 2020-10-21 20:35:26 +02:00
vabene1111
89b8dbe57f added online check to prevent message spam 2020-10-20 23:08:30 +02:00
vabene1111
f2a17fe3bb fixed shopping list GET param regex 2020-10-20 22:51:19 +02:00
vabene1111
14e0dae6e3 compiled translations 2020-10-20 21:23:37 +02:00
vabene1111
733c281dc8 Merge pull request #200 from vabene1111/translations_cookbook-locale-en-lc-messages-django-po--develop_de
Translate '/cookbook/locale/en/LC_MESSAGES/django.po' in 'de'
2020-10-20 21:22:36 +02:00
transifex-integration[bot]
c542f3154e Apply translations in de
translation completed for the source file '/cookbook/locale/en/LC_MESSAGES/django.po'
on the 'de' language.
2020-10-20 19:22:06 +00:00
vabene1111
c6f40db7e3 shopping list tweaks 2020-10-20 20:54:15 +02:00
Sebastian Markgraf
31dabd4757 Add nutritions output 2020-10-18 17:31:56 +02:00
Sebastian Markgraf
7a89015ac5 Add migrations. 2020-10-16 23:59:19 +02:00
Sebastian Markgraf
2b1cde2efc Add basic output for nutritions. 2020-10-16 23:44:18 +02:00
vabene1111
cb3b8c931e fixed broken defautl share 2020-10-16 00:11:41 +02:00
vabene1111
72bea14c3a added sharing 2020-10-16 00:01:14 +02:00
vabene1111
cd46203d55 added permission classes for sharing + tests 2020-10-15 23:41:38 +02:00
Sebastian Markgraf
368d631602 Add nutrition to model. 2020-10-15 22:03:25 +02:00
vabene1111
5c1cecb7e7 fixed saving null units 2020-10-15 21:37:15 +02:00
vabene1111
526cf13b8d increased max text area size of instructions 2020-10-15 21:27:41 +02:00
vabene1111
3c21baf876 fixed create shopping list from recipe 2020-10-15 21:26:24 +02:00
vabene1111
2d2c38517c fixed null units breaking shopping lists 2020-10-15 21:19:49 +02:00
vabene1111
163b259bd1 fixed migrations for postgres 2020-10-14 22:05:49 +02:00
dependabot[bot]
24ced66c69 Bump bleach from 3.1.5 to 3.2.1
Bumps [bleach](https://github.com/mozilla/bleach) from 3.1.5 to 3.2.1.
- [Release notes](https://github.com/mozilla/bleach/releases)
- [Changelog](https://github.com/mozilla/bleach/blob/master/CHANGES)
- [Commits](https://github.com/mozilla/bleach/compare/v3.1.5...v3.2.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-30 06:25:32 +00:00
dependabot[bot]
6c1982cccb Bump simplejson from 3.17.0 to 3.17.2
Bumps [simplejson](https://github.com/simplejson/simplejson) from 3.17.0 to 3.17.2.
- [Release notes](https://github.com/simplejson/simplejson/releases)
- [Changelog](https://github.com/simplejson/simplejson/blob/master/CHANGES.txt)
- [Commits](https://github.com/simplejson/simplejson/compare/v3.17.0...v3.17.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-30 06:25:31 +00:00
dependabot[bot]
3bae7283d1 Bump whitenoise from 5.1.0 to 5.2.0
Bumps [whitenoise](https://github.com/evansd/whitenoise) from 5.1.0 to 5.2.0.
- [Release notes](https://github.com/evansd/whitenoise/releases)
- [Changelog](https://github.com/evansd/whitenoise/blob/master/docs/changelog.rst)
- [Commits](https://github.com/evansd/whitenoise/compare/v5.1.0...v5.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-30 06:25:31 +00:00
vabene1111
0b458f7565 update source file as well 2020-09-29 19:44:46 +02:00
vabene1111
675f30126c updated base translation files 2020-09-29 19:38:58 +02:00
vabene1111
25b051323c shopping list basic sorting 2020-09-29 18:18:43 +02:00
vabene1111
697de3d9fc small mobile layout improvements 2020-09-29 14:19:17 +02:00
vabene1111
7bc09dfe89 finishes shopping lists 2020-09-29 14:15:18 +02:00
vabene1111
711dfbe55f cleanup import 2020-09-29 13:19:06 +02:00
vabene1111
76108c66c6 Merge pull request #189 from vabene1111/dependabot/pip/drf-writable-nested-0.6.1
Bump drf-writable-nested from 0.6.0 to 0.6.1
2020-09-29 12:56:31 +02:00
dependabot[bot]
db3c390d03 Bump drf-writable-nested from 0.6.0 to 0.6.1
Bumps [drf-writable-nested](https://github.com/beda-software/drf-writable-nested) from 0.6.0 to 0.6.1.
- [Release notes](https://github.com/beda-software/drf-writable-nested/releases)
- [Changelog](https://github.com/beda-software/drf-writable-nested/blob/master/CHANGELOG.md)
- [Commits](https://github.com/beda-software/drf-writable-nested/compare/v0.6.0...v0.6.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-29 10:56:26 +00:00
vabene1111
138fb14107 Merge pull request #188 from vabene1111/dependabot/pip/django-3.1.1
Bump django from 3.0.7 to 3.1.1
2020-09-29 12:56:19 +02:00
dependabot[bot]
17ebdd7711 Bump django from 3.0.7 to 3.1.1
Bumps [django](https://github.com/django/django) from 3.0.7 to 3.1.1.
- [Release notes](https://github.com/django/django/releases)
- [Commits](https://github.com/django/django/compare/3.0.7...3.1.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-29 10:56:07 +00:00
vabene1111
fc9a42029a Merge pull request #187 from vabene1111/dependabot/pip/beautifulsoup4-4.9.2
Bump beautifulsoup4 from 4.9.1 to 4.9.2
2020-09-29 12:55:35 +02:00
vabene1111
7d942d551a Merge pull request #186 from vabene1111/dependabot/pip/django-filter-2.4.0
Bump django-filter from 2.2.0 to 2.4.0
2020-09-29 12:55:25 +02:00
vabene1111
78c94f2b64 Merge pull request #185 from vabene1111/dependabot/pip/bleach-whitelist-0.0.11
Bump bleach-whitelist from 0.0.10 to 0.0.11
2020-09-29 12:55:15 +02:00
dependabot[bot]
b317d7ba29 Bump beautifulsoup4 from 4.9.1 to 4.9.2
Bumps [beautifulsoup4](http://www.crummy.com/software/BeautifulSoup/bs4/) from 4.9.1 to 4.9.2.

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-29 10:48:54 +00:00
dependabot[bot]
71b8ddd1bf Bump django-filter from 2.2.0 to 2.4.0
Bumps [django-filter](https://github.com/carltongibson/django-filter) from 2.2.0 to 2.4.0.
- [Release notes](https://github.com/carltongibson/django-filter/releases)
- [Changelog](https://github.com/carltongibson/django-filter/blob/master/CHANGES.rst)
- [Commits](https://github.com/carltongibson/django-filter/compare/2.2.0...2.4.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-29 10:48:52 +00:00
dependabot[bot]
23de4d4239 Bump bleach-whitelist from 0.0.10 to 0.0.11
Bumps [bleach-whitelist](https://github.com/yourcelf/bleach-whitelist) from 0.0.10 to 0.0.11.
- [Release notes](https://github.com/yourcelf/bleach-whitelist/releases)
- [Commits](https://github.com/yourcelf/bleach-whitelist/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-29 10:48:50 +00:00
vabene1111
4641b81f70 Create dependabot.yml 2020-09-29 12:48:28 +02:00
vabene1111
a9bad5e5f9 create shopping from mealplan 2020-09-29 12:41:59 +02:00
vabene1111
9f7106a325 shopping list fixes 2020-09-29 11:41:10 +02:00
vabene1111
73f13f56e1 added ability to display message to users (via admin) 2020-09-22 12:36:27 +02:00
vabene1111
312c364797 fixed wrongly changed permission check order 2020-09-22 12:19:30 +02:00
vabene1111
ad9b10c9c1 allow entry deletion 2020-09-22 12:17:22 +02:00
vabene1111
678cfaca12 fixed several shopping list issues 2020-09-22 12:01:11 +02:00
vabene1111
9b36f51d16 added .env examples 2020-09-22 09:42:58 +02:00
vabene1111
fa8389d783 Merge pull request #172 from stewartadam/bugfix/configurable-urls
Permit MEDIA_URL and STATIC_URL to be set from environment variables
2020-09-22 09:29:48 +02:00
vabene1111
30d766be77 fixed clearing amount in recipe edit would result in error 2020-09-22 09:09:52 +02:00
vabene1111
5e2dba7b04 added basic exporting 2020-09-22 00:32:42 +02:00
vabene1111
70df7c5307 improved autosync data efficency 2020-09-22 00:20:44 +02:00
vabene1111
f91d9fcfe2 autosync shopping list and settings 2020-09-21 23:54:46 +02:00
vabene1111
086a4aea47 basics of shopping list working 2020-09-21 23:05:58 +02:00
vabene1111
148ce2faef shopping list item checking 2020-09-21 22:55:52 +02:00
vabene1111
4827364e37 basic acceptable design 2020-09-21 22:16:19 +02:00
vabene1111
da958faf33 basic shopping list ui cleanup 2020-09-21 22:05:53 +02:00
vabene1111
f5117abcfb fixed shopping list multipliers and recipe names 2020-09-21 11:56:39 +02:00
vabene1111
df79c8f889 basic shopping list load and save 2020-09-15 16:51:20 +02:00
vabene1111
0ff65d35dc partial shopping list saving 2020-09-07 13:09:03 +02:00
vabene1111
8239dc3604 fixed unit creation typo 2020-09-07 12:27:29 +02:00
vabene1111
4a4d4b4486 shopping display seperation 2020-09-03 11:38:22 +02:00
vabene1111
34733a427f model __str__ methods 2020-09-01 21:37:33 +02:00
vabene1111
7f68bbd25d added link based signup 2020-09-01 21:35:37 +02:00
vabene1111
392ee73719 basics of invite link creation 2020-09-01 14:57:20 +02:00
vabene1111
2a0a85018a fixed import and validation errors 2020-09-01 13:26:58 +02:00
vabene1111
62868cd2b2 added note support for recipe import 2020-09-01 11:49:19 +02:00
vabene1111
4e92be3bbc fixed scrolling issue in internal recipe edit
related to bootstrap vue issue, waiting on proper fix
2020-09-01 11:39:46 +02:00
vabene1111
14c94bf7ab WIP shopping list 2020-09-01 11:31:29 +02:00
Stewart Adam
ce3148ac89 Permit MEDIA_URL and STATIC_URL to be set from environment variables (#143) 2020-08-30 16:39:43 -07:00
vabene1111
bc39b53aad fixed typo 2020-08-27 10:06:53 +02:00
vabene1111
984192e479 basics of scaling 2020-08-26 21:41:04 +02:00
vabene1111
3c73b084cf super basic shopping list working 2020-08-26 21:11:20 +02:00
vabene1111
fc073124d4 Merge pull request #162 from LBBO/amount-without-unit
Show amounts even when unit is empty
2020-08-26 20:33:18 +02:00
Michael Kuckuk
f6fb07926e Show amounts even when unit is empty 2020-08-26 12:39:21 +02:00
vabene1111
90dddd34f3 removed test for invalid recipe as its no longer invalid due to parser improvements 2020-08-26 11:46:56 +02:00
vabene1111
0b948618f3 improved website parser 2020-08-26 11:37:59 +02:00
vabene1111
78be002134 Merge pull request #154 from Mwoua/develop
Instructions for manual installation
2020-08-21 18:09:20 +02:00
Mwoua
7acd72ff3a Clone master instead of getting release 2020-08-21 09:12:57 -04:00
Mwoua
c5edeb7e8f Missing alias for media files 2020-08-19 18:09:23 -04:00
David Lévy
5d5c5a8597 Instructions for manual installation 2020-08-19 17:32:28 -04:00
David Lévy
03bdcdf9b4 Fix markdown rules 2020-08-18 16:32:00 -04:00
vabene1111
16d755fd76 Merge pull request #150 from vabene1111/translations_cookbook-locale-en-lc-messages-django-po--develop_fr
Translate '/cookbook/locale/en/LC_MESSAGES/django.po' in 'fr'
2020-08-12 11:24:17 +02:00
transifex-integration[bot]
587426e3d3 Apply translations in fr
translation completed for the source file '/cookbook/locale/en/LC_MESSAGES/django.po'
on the 'fr' language.
2020-08-11 15:26:15 +00:00
vabene1111
be55e034bf first parts of shopping rework 2020-08-11 15:24:12 +02:00
vabene1111
8055754455 shopping list basics 2020-08-11 12:17:12 +02:00
vabene1111
82497c734a uniform button style in recipe view 2020-08-09 20:55:02 +02:00
vabene1111
b39a55ee94 removed mistakingly added language 2020-08-09 20:49:16 +02:00
vabene1111
9d837cd633 added contributers 2020-08-09 20:44:21 +02:00
vabene1111
968206a7ab compiled translations 2020-08-09 20:40:55 +02:00
vabene1111
a769fe6906 Merge pull request #148 from vabene1111/translations_cookbook-locale-en-lc-messages-django-po--develop_fr_FR
Translate '/cookbook/locale/en/LC_MESSAGES/django.po' in 'fr_FR' [manual sync]
2020-08-09 20:35:05 +02:00
vabene1111
21cf4c5d70 Merge pull request #149 from vabene1111/translations_cookbook-locale-en-lc-messages-django-po--develop_de
Translate '/cookbook/locale/en/LC_MESSAGES/django.po' in 'de' [manual sync]
2020-08-09 20:34:53 +02:00
vabene1111
6c02912dad Merge pull request #147 from vabene1111/translations_cookbook-locale-en-lc-messages-django-po--develop_nl
Translate '/cookbook/locale/en/LC_MESSAGES/django.po' in 'nl' [manual sync]
2020-08-09 20:34:26 +02:00
transifex-integration[bot]
c0756d87a6 Apply translations in de
at least 95% translated for the source file '/cookbook/locale/en/LC_MESSAGES/django.po'
on the 'de' language.

 Manual sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format
2020-08-09 18:33:53 +00:00
transifex-integration[bot]
2471c7982d Apply translations in fr_FR
at least 95% translated for the source file '/cookbook/locale/en/LC_MESSAGES/django.po'
on the 'fr_FR' language.

 Manual sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format
2020-08-09 18:33:48 +00:00
transifex-integration[bot]
b36e440920 Apply translations in nl
at least 95% translated for the source file '/cookbook/locale/en/LC_MESSAGES/django.po'
on the 'nl' language.

 Manual sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format
2020-08-09 18:33:43 +00:00
vabene1111
a8b1ee9765 changed url import api call to post url 2020-08-09 20:13:05 +02:00
vabene1111
782d276724 cleanup ids in import as well 2020-07-20 21:12:18 +02:00
vabene1111
9510562576 backup basic fixture 2020-07-15 22:05:48 +02:00
vabene1111
363a4b6ff7 fixed sys page broken html tags in german locale 2020-07-15 21:52:31 +02:00
vabene1111
f52dd9ba51 recompiled messages 2020-07-15 19:33:09 +02:00
vabene1111
4ffc4dc248 updates german translation 2020-07-15 19:26:41 +02:00
vabene1111
696791d059 url import improvements 2020-07-15 18:28:43 +02:00
vabene1111
c9f1576b24 several recipe view improvements 2020-07-15 18:05:12 +02:00
vabene1111
1cea0350c9 added todo info 2020-07-14 00:23:35 +02:00
vabene1111
e0dac67b84 fixed recipe api permissions when using shared recipes 2020-07-14 00:22:39 +02:00
vabene1111
c45472689e small fixes 2020-07-13 23:07:35 +02:00
vabene1111
5b7ec37637 hotkeys, styling, step improvements 2020-07-13 22:55:09 +02:00
vabene1111
4d08477b23 fixed decimals 2020-07-13 21:38:42 +02:00
vabene1111
9b9fbd5cab added food api view tests 2020-07-09 22:19:24 +02:00
vabene1111
8c118dbd3e use appropriate serializer for unit 2020-07-09 22:16:52 +02:00
vabene1111
bfe9e794c5 added tests for unit api view 2020-07-09 22:13:33 +02:00
vabene1111
3e16361322 added keyword api tests 2020-07-09 22:00:14 +02:00
vabene1111
35e8dc4ce9 removed keyword created by as it was never populated 2020-07-09 21:55:05 +02:00
vabene1111
8e8c7fe563 fixed sync test 2020-07-09 00:43:09 +02:00
vabene1111
69d5e628c5 sync admin view + tests 2020-07-08 23:40:53 +02:00
vabene1111
e65c8436ef sync api view + tests 2020-07-08 23:28:28 +02:00
vabene1111
e83565b1f2 added api endpoints and tests 2020-07-08 23:19:39 +02:00
vabene1111
692811f84f fixed settings dropdown being below recipe edit buttons 2020-07-08 22:26:06 +02:00
vabene1111
0aa37d176f api function queryset cleanup 2020-07-08 22:24:52 +02:00
vabene1111
92341380bc actually fixed error 2020-07-08 22:14:22 +02:00
vabene1111
19df215bd2 external recipe view vue error fix 2020-07-08 22:03:41 +02:00
vabene1111
372dd0afa1 recipe step sidebar no name 2020-07-08 21:55:17 +02:00
vabene1111
b89c38a696 error messages 2020-07-08 21:53:55 +02:00
vabene1111
f177fed8e2 Merge branch 'feature/recipe-steps' into develop 2020-07-08 21:23:58 +02:00
vabene1111
1d2976b687 create default step + view time improvement 2020-07-08 21:23:41 +02:00
vabene1111
b490673866 javascript toasts 2020-07-08 21:01:01 +02:00
vabene1111
5f2320a3e7 added save confirm 2020-07-05 22:36:39 +02:00
vabene1111
5b916e955c WIP page leave confirm 2020-07-05 22:15:00 +02:00
vabene1111
5bad507845 fixed and improved URL import 2020-07-05 21:11:25 +02:00
vabene1111
64603fca51 added time to text steps 2020-07-02 13:23:16 +02:00
vabene1111
6018101012 fixed step time calculation 2020-07-02 13:19:27 +02:00
vabene1111
ddaa9e6356 added step time calculation 2020-07-02 13:16:15 +02:00
vabene1111
98f9555ef6 check box linking 2020-07-02 12:15:30 +02:00
vabene1111
1619d4894c step header rendering 2020-07-02 12:12:17 +02:00
vabene1111
1e2d7f77af basic vue in recipe view 2020-07-02 11:20:11 +02:00
vabene1111
80423da16d removed duplicate div 2020-07-01 23:44:58 +02:00
vabene1111
67a4a2627b fixed meal plan form not own type display 2020-07-01 23:29:32 +02:00
vabene1111
0005ca243c testing around 2020-07-01 23:22:29 +02:00
vabene1111
adbc7e4a39 icons and stuff 2020-07-01 22:27:32 +02:00
vabene1111
9caec2dff2 step sidebar sorting 2020-07-01 21:53:41 +02:00
vabene1111
41eef9a913 step sorting buttons 2020-07-01 21:42:46 +02:00
vabene1111
31357c552c ui improvements 2020-07-01 21:04:28 +02:00
vabene1111
5d70dca039 time step + step delete + sorting improvement 2020-07-01 20:38:35 +02:00
vabene1111
2c5fbc558e fixed recipe image preview scaling in large search 2020-07-01 18:56:00 +02:00
vabene1111
98bdad5955 second fix 2020-06-29 22:58:31 +02:00
vabene1111
6eb41fe33f fixed keywords and food/unit loading 2020-06-29 22:41:54 +02:00
vabene1111
e94bd32a70 license update 2020-06-29 22:22:35 +02:00
vabene1111
29e2f9ee15 fixed filter for foods 2020-06-29 22:20:55 +02:00
vabene1111
357771e81b updated translation files 2020-06-29 22:20:42 +02:00
vabene1111
941264731e fixed ingredient adding attributes 2020-06-29 22:03:43 +02:00
vabene1111
2c59302fe9 conditional header/no amount render 2020-06-29 22:01:42 +02:00
vabene1111
a96bf9a4d7 license update 2020-06-29 21:07:55 +02:00
vabene1111
e2508cbc6f step ordering 2020-06-29 20:45:30 +02:00
vabene1111
577af85d38 fixed import export 2020-06-29 19:09:15 +02:00
vabene1111
38e5882376 added recipe large search context menu 2020-06-29 18:17:13 +02:00
vabene1111
08f06fe1d8 fixed non fa-fw recipe view edit icon 2020-06-29 18:16:10 +02:00
vabene1111
4ddc39f1c2 basic shopping list fix 2020-06-29 18:11:25 +02:00
vabene1111
78275145f8 one more non atomic transaction 2020-06-29 18:07:56 +02:00
vabene1111
f7b518d890 run rename migration as non atomic to support old sqlite versions 2020-06-29 18:04:56 +02:00
vabene1111
8cff44df7d recipe steps tagging support 2020-06-29 17:56:50 +02:00
vabene1111
cdee31e9af tests working again 2020-06-29 16:43:53 +02:00
vabene1111
06db7114ed basic view step design 2020-06-29 16:24:41 +02:00
vabene1111
8f28e4766d side nav in recipe edit 2020-06-29 16:12:24 +02:00
vabene1111
dbdb35e2f3 reworked base container to allow side cols 2020-06-29 15:59:19 +02:00
vabene1111
27963fcaa6 image upload working 2020-06-29 15:39:58 +02:00
vabene1111
d613da7faf mobile and large layout 2020-06-29 14:10:21 +02:00
vabene1111
d481767154 wip flex ui 2020-06-29 13:29:59 +02:00
vabene1111
8b9c7daaae fixed commas + desktop flex design 2020-06-29 12:27:54 +02:00
vabene1111
3a2ba773cf layout before flex test 2020-06-29 11:30:24 +02:00
vabene1111
642224fec9 sorting and ingredient adding 2020-06-26 15:00:41 +02:00
vabene1111
3d4aebcd9d ordering of ingredients and steps 2020-06-26 14:50:33 +02:00
vabene1111
c178aea363 nested serializers and basic recipe editing working 2020-06-26 13:41:41 +02:00
vabene1111
5e20833b7e testing with serializers 2020-06-26 13:10:23 +02:00
vabene1111
db7f0d4988 fixed recipe edit button text 2020-06-26 08:53:46 +02:00
vabene1111
381bc5ffb4 partially working steps edit view 2020-06-25 23:48:27 +02:00
vabene1111
4a6b32d9af super basic edit view 2020-06-25 23:24:09 +02:00
vabene1111
8b814669af fixed API permission denied error
forgot a return in the custom permissions wich prevent authorized useres to access certain endpoints
2020-06-25 23:23:12 +02:00
vabene1111
ae0928f85f added recipe steps 2020-06-25 22:38:17 +02:00
vabene1111
bf516d37a9 Merge branch 'develop' into feature/recipe-steps 2020-06-25 22:09:00 +02:00
vabene1111
6979bf34d9 fixed insecure uuid defaults
due to some unexpected behavior the share link uuid values were not random. All already created share links were disabled.
2020-06-25 22:01:54 +02:00
vabene1111
bda38f0647 changed recipe ingredient relation 2020-06-25 21:45:16 +02:00
vabene1111
df912b8865 renamed recipeingredient to ingredient 2020-06-25 21:37:18 +02:00
vabene1111
f685253645 renamed ingredient to food 2020-06-25 21:24:03 +02:00
vabene1111
2c5e44d73c improved recipe parser, added tests, cleaned up resources 2020-06-24 21:22:23 +02:00
vabene1111
b6d98397b5 improved recipe import 2020-06-24 20:21:48 +02:00
vabene1111
525ad6dd98 removed debug code and cdn dependencies 2020-06-23 20:36:04 +02:00
vabene1111
166833fe83 moved recipe edit button to dropdown menu 2020-06-23 19:01:35 +02:00
vabene1111
752854028a more recipe import fixes 2020-06-23 18:48:22 +02:00
vabene1111
6197cab1ed improved url import [WIP] 2020-06-23 18:13:16 +02:00
vabene1111
73f2240763 fixed import error 2020-06-23 14:00:07 +02:00
vabene1111
3ef82aee9c updated readme 2020-06-23 12:57:05 +02:00
vabene1111
e49e53e2b2 async loading of multiselect fields 2020-06-23 12:54:27 +02:00
vabene1111
0266476aef import page style update 2020-06-23 12:46:13 +02:00
vabene1111
5ed369ba69 recipe import unit/ingredeitn selection 2020-06-23 12:34:00 +02:00
vabene1111
98c278fe60 importing improvements 2020-06-23 11:04:49 +02:00
vabene1111
8594346488 basic importing working 2020-06-23 10:34:04 +02:00
vabene1111
dc91e1e8ed fixed url router and added recipe import test ressources 2020-06-22 23:35:18 +02:00
vabene1111
976dd13a31 basic importing working 2020-06-22 23:23:06 +02:00
vabene1111
8cca272bb9 import UI cleanup 2020-06-22 22:56:56 +02:00
vabene1111
f066b7097c microdata import 2020-06-22 22:47:33 +02:00
vabene1111
71b41a9ca2 refactor json ld code into helper 2020-06-22 21:35:56 +02:00
vabene1111
9e748552b2 recipe url import ld json 2020-06-22 21:16:31 +02:00
vabene1111
743d7bf608 cleanup vue debug settings 2020-06-22 12:23:49 +02:00
vabene1111
315b4521b6 test page 2020-06-22 12:14:24 +02:00
vabene1111
b558ba55b4 fixed mis-aligned menu in recipe view 2020-06-22 11:12:26 +02:00
vabene1111
0368630c92 added more view tests 2020-06-17 15:25:16 +02:00
vabene1111
02c1ba0c71 structured and extended test 2020-06-17 15:06:29 +02:00
vabene1111
83cc8832cb improved duplicate testing code 2020-06-17 14:53:00 +02:00
vabene1111
14a5d43dc8 added complete test for user preference api 2020-06-17 14:33:55 +02:00
vabene1111
bea079dd05 further permission cleanup 2020-06-17 13:23:04 +02:00
vabene1111
df8170fa55 improved permission handlin 2020-06-17 13:18:28 +02:00
vabene1111
2904d5938d fixed sync create permission 2020-06-17 13:00:13 +02:00
vabene1111
18bfecb026 fixed DRF object permission 2020-06-17 12:12:42 +02:00
vabene1111
4ee5a4fd9f testing with user permission 2020-06-17 11:06:08 +02:00
vabene1111
bbaedfad33 documentation update api 2020-06-17 10:29:01 +02:00
vabene1111
de413f1473 custom browsable api header 2020-06-17 10:12:27 +02:00
vabene1111
d012385088 WIP api stuff 2020-06-16 20:32:41 +02:00
vabene1111
d18a330135 reset log level 2020-06-16 19:56:42 +02:00
vabene1111
a8f7ef8ef7 added missing dependency 2020-06-16 19:55:48 +02:00
vabene1111
d6972cacfb pyyaml dependency 2020-06-16 19:43:44 +02:00
vabene1111
3b21e44422 log level debug 2020-06-16 18:57:08 +02:00
vabene1111
1a78ca68bb added access logging 2020-06-16 18:50:24 +02:00
vabene1111
fac7b8cd5b added gunicorn error logging 2020-06-16 18:43:16 +02:00
vabene1111
8f780545a4 api browser link 2020-06-16 18:14:41 +02:00
vabene1111
218f7d92d7 fixed password settings autofocus 2020-06-16 18:04:42 +02:00
vabene1111
621bacff1c api token settings 2020-06-16 18:01:16 +02:00
vabene1111
9a849a979c ui secret key check 2020-06-16 17:42:53 +02:00
vabene1111
e8366e5280 added secret key system check 2020-06-16 17:42:43 +02:00
vabene1111
0a8270e7cf api documentation basics 2020-06-16 17:21:50 +02:00
vabene1111
aad8b220d1 added custom 404 page 2020-06-16 16:21:15 +02:00
vabene1111
d5e0a0a623 added comment setting to user pref admin table 2020-06-16 12:45:46 +02:00
vabene1111
8cd94d49e8 added comment system preference 2020-06-16 12:44:45 +02:00
vabene1111
08b805a547 fixed meal plan delete after create 2020-06-16 12:12:37 +02:00
vabene1111
ecac30136b no sharing external recipes + hide buttons for unauth 2020-06-16 12:07:18 +02:00
vabene1111
d694408af6 share link admin 2020-06-16 12:05:36 +02:00
vabene1111
6e284f6ae8 moved all recipe button 2020-06-16 12:03:42 +02:00
vabene1111
62c049a6de fixed unauthenticated recipe viewing 2020-06-16 11:49:02 +02:00
vabene1111
dee7249347 added sharing links and appropriate tests 2020-06-16 11:23:58 +02:00
vabene1111
17946c8dac markdown hint text 2020-06-16 10:37:11 +02:00
vabene1111
fa2326949e added back markdown support to meal plannin notes 2020-06-16 10:34:20 +02:00
vabene1111
8177d9ba0f added synology install instruction 2020-06-16 10:19:24 +02:00
vabene1111
8781a6572d set some norefer labels
probably not really needed for this case but satisfies the code scanning and does not hurt to have
2020-06-16 10:13:54 +02:00
vabene1111
c7d518071c Create codeql-analysis.yml 2020-06-16 09:56:57 +02:00
vabene1111
ea96c63289 stupid apple fix 2020-06-13 14:03:50 +02:00
vabene1111
8485a64726 viewlog/cooklog admin 2020-06-12 00:07:47 +02:00
vabene1111
e89bd44412 added to string to meal plan 2020-06-11 23:43:48 +02:00
vabene1111
2e0e48bb38 removed celery 2 2020-06-11 23:29:24 +02:00
vabene1111
040fa7c192 removed celery 2020-06-11 23:29:10 +02:00
vabene1111
7000097602 fixed share reset in meal plan move 2020-06-11 22:53:04 +02:00
vabene1111
3cbc6b5609 meal type admin 2020-06-11 22:48:26 +02:00
vabene1111
8ff52f542e ingredient rounding upgrades 2020-06-11 22:32:45 +02:00
vabene1111
8cc0fcaed2 fixed properly deep copy meal_type array 2020-06-11 20:22:04 +02:00
vabene1111
d4197773bf clean up logging 2020-06-11 19:04:15 +02:00
vabene1111
f530b3dc7a dependency cleanup 2020-06-11 19:00:17 +02:00
vabene1111
d1bf4d4bbb added ical export support 2020-06-11 18:38:56 +02:00
vabene1111
d584a3db25 added more help 2020-06-11 17:57:30 +02:00
vabene1111
aaa3737ae0 help and name based type indexing 2020-06-11 17:55:24 +02:00
vabene1111
5072859e57 re enabled basic sharing 2020-06-11 17:27:27 +02:00
vabene1111
ead3c6ef76 fixed sharing 2020-06-11 17:13:31 +02:00
vabene1111
d734cb813e plan type editing 2020-06-11 16:58:57 +02:00
vabene1111
8aa24d4771 per user meal types 2020-06-11 15:19:15 +02:00
vabene1111
c714ff4dbe name function cleanup 2020-06-11 11:42:38 +02:00
vabene1111
a32545c1dc proper mobile handle 2020-06-11 11:40:32 +02:00
vabene1111
dfe8e1fd42 layout improvements 2020-06-11 10:59:26 +02:00
vabene1111
729d573460 imrpoved detail view 2020-06-11 10:26:40 +02:00
vabene1111
8472b541aa correctly update plan 2020-06-11 01:14:09 +02:00
vabene1111
7e95e985ec proper async loading 2020-06-11 01:05:02 +02:00
vabene1111
f7e2aa9b83 week switching 2020-06-11 00:49:19 +02:00
vabene1111
99cf428470 plan entry detail modal 2020-06-10 23:33:18 +02:00
vabene1111
60a533f9c8 Merge branch 'develop' into feature/meal-planning 2020-06-10 16:01:21 +02:00
vabene1111
723416575f added alt text 2020-06-10 15:52:18 +02:00
vabene1111
e34889953a cleanup and allow loading of images 2020-06-10 15:51:47 +02:00
vabene1111
ec8a879efa improved pdf viewer 2020-06-10 15:40:24 +02:00
vabene1111
f44ebe0d05 Update issue templates 2020-06-10 12:09:37 +02:00
vabene1111
13c82cdbf9 made remote auth a config setting 2020-06-10 12:02:27 +02:00
vabene1111
e9a60ece81 Merge pull request #88 from cazier/develop
Adding Reverse Proxy Authentication
2020-06-10 11:56:16 +02:00
vabene1111
9575a86480 fixed ingredient deletion error 2020-06-10 11:52:24 +02:00
vabene1111
12036b9972 fixes protect error on storage monitor delete #102 2020-06-10 11:45:52 +02:00
vabene1111
bffb260dfa fixed delete source permission 2020-06-10 11:42:44 +02:00
vabene1111
9d460a3623 Update docker-publish-release.yml 2020-06-10 11:38:45 +02:00
vabene1111
56c5f28348 Update docker-publish-latest.yml 2020-06-10 11:37:49 +02:00
vabene1111
29d4dcb73d fixed yaml formatting 2020-06-10 11:36:45 +02:00
vabene1111
e60441ec99 add version script to tagged releases 2020-06-10 11:34:05 +02:00
vabene1111
608e024caa formatting + further testing 2020-06-10 11:19:28 +02:00
vabene1111
f596b12f12 testing build ref version writing 2020-06-10 11:08:59 +02:00
vabene1111
bdd41a5ba2 removed redundant quotes 2020-06-10 10:47:47 +02:00
vabene1111
80e566917e version writer script fixes 2020-06-10 10:33:19 +02:00
vabene1111
4294c132c6 version script path fix 2020-06-10 10:24:54 +02:00
vabene1111
da12daaf03 add version to action 2020-06-10 10:15:28 +02:00
vabene1111
150cf5ebac testing auto version 2020-06-10 10:13:11 +02:00
vabene1111
01b9022451 version script test 2020-06-10 10:07:33 +02:00
vabene1111
2bda5bbbf7 note text saving 2020-06-09 20:27:31 +02:00
vabene1111
a743a4e202 basics completly working 2020-06-09 20:15:06 +02:00
vabene1111
ffa7513f9e recipes and notes basically working 2020-06-09 17:26:50 +02:00
vabene1111
8cb6ed2f60 adding items to plan 2020-06-09 13:11:01 +02:00
vabene1111
1d6375bf84 fixed pdf js files missing 2020-06-09 12:28:48 +02:00
vabene1111
cfab867e0d removed no longer valid warning 2020-06-09 00:18:28 +02:00
vabene1111
29dd7c9ee7 add port mapping to plain example 2020-06-09 00:17:17 +02:00
vabene1111
72cb046e37 updated plain example 2020-06-09 00:16:04 +02:00
vabene1111
a555906a32 fixed user setup staff permission 2020-06-06 11:31:19 +02:00
vabene1111
2e255aba0d more plan basics working 2020-06-04 19:46:35 +02:00
vabene1111
a136a18a8e basic updating and loading working 2020-06-04 19:34:47 +02:00
Brendan Cazier
cdf4c0d1bb Re-adding import statement 2020-06-04 07:51:43 -05:00
vabene1111
3aedbfbdc3 Merge branch 'develop' into feature/meal-planning
# Conflicts:
#	requirements.txt
2020-06-04 13:12:52 +02:00
vabene1111
dc7c688ed5 show english first in language chooser 2020-06-04 09:58:18 +02:00
vabene1111
8aa8f15ad7 fixed path + added language option dutch (nl) 2020-06-04 09:57:28 +02:00
vabene1111
6b8a231eee Merge pull request #95 from D0T1X/develop
added base translation file for Dutch
2020-06-04 09:33:17 +02:00
D0T1X
b0e338f08a added base translation files 2020-06-04 07:25:31 +02:00
D0T1X
1a6e0c8706 Uploaded Django.po 2020-06-04 07:24:45 +02:00
D0T1X
c7ceae4350 Create temp 2020-06-04 07:24:24 +02:00
D0T1X
caefa6099b Delete temp 2020-06-04 07:21:33 +02:00
D0T1X
2e4645bb0c Creatend nl/MC_MESSAGES folde 2020-06-04 07:20:23 +02:00
vabene1111
6c966f8ef6 added versions to requirements.txt 2020-06-03 23:43:25 +02:00
vabene1111
7140cb0f93 basic system information page 2020-06-03 23:07:19 +02:00
vabene1111
7f08815482 added .map files 2020-06-03 22:40:48 +02:00
vabene1111
6c0a81a4c5 fixed bnroken tooltips and buttons 2020-06-03 22:36:17 +02:00
vabene1111
9179bde8f9 name images with uuid instead of recipe ids
in order to stil be able to manually map images to recipes the name consists of uuid_recipeId.png
2020-06-03 22:09:07 +02:00
vabene1111
0684c47e2a addding missing cli flag to chmod 2020-06-03 21:52:42 +02:00
vabene1111
be52238413 boot script fix 2020-06-03 21:38:59 +02:00
vabene1111
a0332c432d moved permission fix to boot.sh 2020-06-03 21:31:56 +02:00
vabene1111
35b038a33c media folder permission fix 2020-06-03 21:28:42 +02:00
vabene1111
9ac3d79b95 updated examples 2020-06-03 20:54:38 +02:00
vabene1111
6f24b7d34e fixed media file serving 2020-06-03 20:38:48 +02:00
vabene1111
e84d15a7ed debugging media serving problems 2020-06-03 20:18:42 +02:00
vabene1111
8f268b3b75 corrected .env template 2020-06-03 20:00:44 +02:00
vabene1111
f9cb44c66b gunicorn media file serving 2020-06-03 19:58:01 +02:00
vabene1111
b95c3f6685 working lists 2020-06-03 18:10:34 +02:00
Brendan Cazier
81cd551975 Added some basic documentation 2020-06-03 10:40:12 -05:00
Brendan Cazier
55777fd948 Added REMOTE_USER auth 2020-06-03 10:16:17 -05:00
vabene1111
3b5b505116 basic plan table drag and drop working 2020-06-03 12:05:43 +02:00
vabene1111
aea3f62f9b event parameter 2020-06-03 11:18:37 +02:00
vabene1111
d09c6dbfed added automatic redirect for setup 2020-06-03 10:51:39 +02:00
vabene1111
201c493658 some working drag and drop stuff 2020-06-03 00:03:54 +02:00
vabene1111
8ffc6a0236 some basic drag and drop workin 2020-06-02 22:52:28 +02:00
vabene1111
84ad88b30b Merge branch 'develop' into feature/meal-planning 2020-06-02 22:32:30 +02:00
vabene1111
67d7cd1d23 Update README.md 2020-06-02 22:30:33 +02:00
vabene1111
bf3337b5e1 Update README.md 2020-06-02 22:25:28 +02:00
vabene1111
0b0d214085 update translations 2020-06-02 22:10:50 +02:00
transifex-integration[bot]
60dc008b05 Apply translations in de
translation completed for the source file '/cookbook/locale/en/LC_MESSAGES/django.po'
on the 'de' language.
2020-06-02 20:09:55 +00:00
transifex-integration[bot]
475b6e3728 Apply translations in de
at least 1% translated for the source file '/cookbook/locale/en/LC_MESSAGES/django.po'
on the 'de' language.

 Manual sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format
2020-06-02 19:51:54 +00:00
vabene1111
0e70cd83e2 added base translation files 2020-06-02 21:21:03 +02:00
vabene1111
233f2a911f nothing working yet 2020-06-02 14:33:27 +02:00
vabene1111
989d8765d7 basic vue stuff working 2020-06-02 12:47:36 +02:00
vabene1111
2fcd207dc7 basic api 2020-06-02 12:04:14 +02:00
vabene1111
a3dc5f283a dynamic meal types 2020-06-02 11:46:16 +02:00
vabene1111
27297d170a removed obsolte all_tags function 2020-06-02 11:07:11 +02:00
vabene1111
bc8f8b8138 improved keyword rendering in search + plan 2020-06-02 11:06:16 +02:00
vabene1111
87ba53fde9 remove spaces and change line break on shopping 2020-06-02 11:03:31 +02:00
vabene1111
098dda28a4 updated readme 2020-06-02 10:58:05 +02:00
vabene1111
8ffe6abb5c markdown docs lin 2020-06-02 10:56:18 +02:00
vabene1111
5706776002 added setting to disable recent viewed recipes 2020-06-02 10:53:32 +02:00
vabene1111
fbe528e935 added github link 2020-06-02 10:49:54 +02:00
vabene1111
0df86b940f setup page 2020-06-02 10:40:21 +02:00
vabene1111
81c3707090 some cleanup + env comments 2020-06-02 10:11:18 +02:00
vabene1111
9fd691b9f0 fixed ci/static path 2020-06-02 09:01:09 +02:00
vabene1111
821136787d fixed shopping list headers #78 2020-06-01 23:23:46 +02:00
vabene1111
6aedba09f3 removed some decentral cdn deps 2020-06-01 23:17:16 +02:00
vabene1111
7b17a1acfa removed all cdn dependencies 2020-06-01 23:13:38 +02:00
vabene1111
9dd538519f fixed recipe table image 2020-06-01 22:51:33 +02:00
vabene1111
b8821f1f72 Merge pull request #80 from cazier/develop
Made recipe images hyperlinked
2020-06-01 22:43:21 +02:00
Brendan Cazier
3420dcd07d Made recipe images hyperlinked 2020-06-01 12:36:47 -05:00
vabene1111
445c01bddc added basic setup template 2020-06-01 13:53:17 +02:00
vabene1111
dd5996084d make jquery local 2020-06-01 13:51:55 +02:00
vabene1111
dfb1d80ca0 fixed duplicates in recent view 2020-05-27 09:38:57 +02:00
vabene1111
744fbc7a46 revert psql distinct change 2020-05-15 13:12:52 +02:00
vabene1111
cd11cc58cf possible duplicate fix 2020-05-15 12:49:31 +02:00
vabene1111
569e385915 Revert "Create FUNDING.yml"
This reverts commit abf552cd18.
2020-05-13 13:27:46 +02:00
vabene1111
abf552cd18 Create FUNDING.yml 2020-05-13 13:22:26 +02:00
vabene1111
c6959488dc fixed typo on search page 2020-05-11 13:08:49 +02:00
vabene1111
85e3155b50 added group required filter to history view 2020-05-11 13:08:00 +02:00
vabene1111
f6aa50bbfc added history page 2020-05-11 12:59:54 +02:00
vabene1111
5ad27c015e markdown info central blockquote css 2020-05-11 12:44:31 +02:00
vabene1111
4a68a99907 show last viewd recipes on search page 2020-05-11 12:42:55 +02:00
vabene1111
123dc1a74d meal plan entry view 2020-05-08 00:10:23 +02:00
vabene1111
2e23fcfd5d added sharing to meal plan + fixed meal plan visibility 2020-05-07 23:16:24 +02:00
vabene1111
edbc21df19 Update README.md 2020-05-06 08:21:53 +02:00
vabene1111
f0e1c901c6 fixed print button tooltip messing up print 2020-05-04 20:48:17 +02:00
vabene1111
22e403e0ff added basic markdown doc 2020-05-03 00:43:13 +02:00
vabene1111
6a7b02b700 add special type of ingredients to allow headers 2020-05-02 23:46:57 +02:00
vabene1111
4aa2983681 order recipe ingredients 2020-05-02 23:05:36 +02:00
vabene1111
18888bc3ae search image heigth fixes 2020-05-02 22:10:02 +02:00
vabene1111
07a0a3f598 recipe book improvements 2020-05-02 21:59:32 +02:00
vabene1111
76e1274ba5 rating/last cooked display 2020-05-02 21:54:38 +02:00
vabene1111
598387efc8 fixed duplicate recipe books when sharing 2020-05-02 21:46:03 +02:00
vabene1111
f00ee7d9fa display log info 2020-05-02 21:44:12 +02:00
vabene1111
6abe6f2ee4 re added mistakingly deleted file 2020-05-02 21:43:53 +02:00
vabene1111
bd69f2d103 log button in view 2020-05-02 17:55:14 +02:00
vabene1111
6a963c26b2 recipe rating 2020-05-02 17:31:35 +02:00
vabene1111
4c08ade3ee fixed markdown bleach renderer again 2020-05-02 15:10:15 +02:00
vabene1111
37f7326f4c minor mealplan cleanups 2020-05-02 14:58:23 +02:00
vabene1111
c398fda15c Merge branch 'feature/plan-title' into develop 2020-05-02 14:53:26 +02:00
vabene1111
e9da17151a added title field and custom validation 2020-05-02 14:53:09 +02:00
vabene1111
fd4354f16d Merge pull request #57 from tourn/mealplan-recipes-optional
Allow mealplan items to have no recipes
2020-05-02 14:44:46 +02:00
vabene1111
0d0c6c9066 Merge branch 'feature/plan-title' into mealplan-recipes-optional 2020-05-02 14:44:15 +02:00
vabene1111
4620c78f5a user preference fixes and improvements 2020-05-02 14:41:54 +02:00
vabene1111
349b9629f8 added sharing to recipe books 2020-05-02 14:15:56 +02:00
vabene1111
64ee18c4d8 improved recipe book design 2020-05-02 13:58:42 +02:00
vabene1111
3a9e5a80ba final style touches + settings 2020-05-02 12:48:22 +02:00
vabene1111
de85a6b334 further search style improvements 2020-05-02 12:07:03 +02:00
vabene1111
25318b691d new search design improvements 2020-05-02 01:04:45 +02:00
vabene1111
77e778caac new search design basics + Boostrap fixes 2020-05-02 00:49:29 +02:00
vabene1111
b53f83a76c improved stats page 2020-04-29 17:18:12 +02:00
vabene1111
2304c43a60 fixed ingredient calculator rounding error 2020-04-29 16:21:45 +02:00
vabene1111
16963c17dc add default roles to existing users 2020-04-27 18:22:29 +02:00
vabene1111
1d9dc0f952 api permission tests 2020-04-27 17:57:43 +02:00
vabene1111
a9fe821067 added test for comments 2020-04-27 17:48:11 +02:00
vabene1111
c7b1b08516 updated tests 2020-04-27 17:13:43 +02:00
vabene1111
1617fa7a3f fixed permissions comments, books 2020-04-27 16:50:05 +02:00
vabene1111
ad467fae28 added basic group permission system 2020-04-26 17:21:44 +02:00
vabene1111
c7046bc705 fixed markdown urlize 2020-04-26 15:52:07 +02:00
vabene1111
52946a8e4c fixed broken emoji 2020-04-26 00:29:56 +02:00
vabene1111
dd6b77e029 added screenshots + refactor preview + moved docu 2020-04-26 00:28:14 +02:00
vabene1111
396c1f3d5f added tooltips to recipe view 2020-04-25 23:35:01 +02:00
vabene1111
379d5a5177 import export cleanup + features 2020-04-25 23:32:15 +02:00
vabene1111
85a4d5d432 basic import export working 2020-04-25 22:26:59 +02:00
vabene1111
43eb10e488 added basic exporting capability 2020-04-25 22:05:55 +02:00
vabene1111
d702c08a12 fixed urlize breaking markdown links 2020-04-25 10:46:27 +02:00
vabene1111
e78323d214 Update docker-publish-latest.yml 2020-04-15 15:05:36 +02:00
vabene1111
d2e866dd74 cleanup/refactor workflows 2020-04-15 14:48:18 +02:00
vabene1111
76687ad5df testing multi platform deployment 2020-04-15 12:34:58 +02:00
vabene1111
dab77e8e4f imrpoved index redirect + fixed tests 2020-04-13 23:11:33 +02:00
vabene1111
0b250c71aa actually fixed action yml 2020-04-13 22:55:50 +02:00
vabene1111
571f670db0 fixed action intendations 2020-04-13 22:54:17 +02:00
vabene1111
4e9e628162 added ability to change default page 2020-04-13 22:52:02 +02:00
vabene1111
4f49b06704 user setting default ingredient unit 2020-04-13 22:37:50 +02:00
vabene1111
8eb0c36665 fixed action invalid yaml 2020-04-13 21:53:36 +02:00
vabene1111
6f69c09aca Merge pull request #55 from hakoerber/kubernetes-manifests
Kubernetes manifests
2020-04-13 21:51:58 +02:00
vabene1111
8e6f153882 Merge pull request #56 from tourn/clickable-links
Make links in recipe clickable
2020-04-13 21:50:25 +02:00
vabene1111
07183fd40f actions testing 2020-04-13 21:39:20 +02:00
tourn
08cccfa133 Allow mealplan items to have no recipes
And display first line of notes in plan
2020-04-13 21:29:22 +02:00
tourn
04b7f0a398 Make links in recipe clickable 2020-04-13 21:27:22 +02:00
Hannes Körber
1735fda48f Add basic kubernetes manifest
Closes #50
2020-04-13 19:39:41 +02:00
Hannes Körber
1c9ea0eda7 Use relative links in README
See https://github.blog/2013-01-31-relative-links-in-markup-files/ for
more details.
2020-04-13 19:39:39 +02:00
vabene1111
83b5b6695c Update docker-release-publish.yml 2020-04-13 18:25:49 +02:00
vabene1111
342fb3c96d Update docker-release-publish.yml 2020-04-13 18:23:19 +02:00
vabene1111
b7a18466b5 testing multi plattform builds 2020-04-13 18:17:53 +02:00
vabene1111
0cdc4d51df Merge branch 'feature/webdav-root-option' into develop 2020-04-13 17:41:02 +02:00
vabene1111
e177669514 Merge pull request #51 from pataya23/develop
added 'webdav_root' option
2020-04-13 17:38:19 +02:00
pataya23
fd294dfcdd added 'webdav_root' option
otherwise I get an error (webdav3.exceptions.RemoteResourceNotFound: Remote resource: </path> not found)
2020-04-13 13:19:03 +02:00
vabene1111
bdd092e5d3 fixed ingredient amount numeric 2020-04-07 20:13:20 +02:00
vabene1111
f1c5a0ef5f character limit increased 2020-04-07 18:46:20 +02:00
vabene1111
1e8ff763d5 increased character limit keyword icon
thanks cazier for pointing out this issue and providing a PR https://github.com/vabene1111/recipes/pull/46
2020-04-07 18:46:09 +02:00
vabene1111
4cf6a3b219 Merge pull request #45 from tourn/improved-meal-plan
Add buttons to add a meal plan to a specific point in time
2020-04-05 14:47:55 +02:00
tourn
de145b6b18 Add some styling 2020-04-05 11:10:39 +02:00
vabene1111
84a8308bf3 updated tabulator js to 4.6 2020-03-31 01:20:49 +02:00
vabene1111
8d191fa1a1 set recipe name as page title 2020-03-31 01:11:14 +02:00
vabene1111
b47a0197e2 imroved recipe printing and view 2020-03-31 01:10:30 +02:00
tourn
4e7c5f9495 Add buttons to add a meal plan to a specific point in time 2020-03-30 22:06:17 +02:00
vabene1111
d704ddacdd fixed shopping list format 2020-03-27 21:47:00 +01:00
vabene1111
2c3140248c fixed broken links 2020-03-27 21:41:55 +01:00
vabene1111
6d5ea31f8e re added mistakingly removed command 2020-03-26 18:55:35 +01:00
vabene1111
b538761746 run container as root for now
since i want to realease this we will for now continue to run this as root inside the containerr. this can be fixed later, PR's welcome
2020-03-26 18:20:44 +01:00
vabene1111
913d858473 updated boot script to fix permission 2020-03-25 22:30:44 +01:00
vabene1111
574d088cdd Create docker-publish.yml 2020-03-24 18:04:52 +01:00
vabene1111
ed360ca1c7 updated readme 2020-03-24 17:37:16 +01:00
vabene1111
08848da4a3 Merge branch 'feature/docker-rewrite' into develop 2020-03-24 17:23:04 +01:00
vabene1111
3f1f63d7e0 remove image tag as it is default 2020-03-24 17:22:51 +01:00
vabene1111
3bd6557e59 use stable image 2020-03-24 17:18:27 +01:00
vabene1111
23cb98f631 Create docker-release-publish.yml 2020-03-24 17:16:24 +01:00
vabene1111
6e91c30245 fixed tests 2020-03-24 17:03:52 +01:00
vabene1111
d7e0fa821b updated examples 2020-03-24 16:44:19 +01:00
vabene1111
c67342df26 wip changes 2020-03-24 12:57:45 +01:00
vabene1111
e3b71d47f4 Merge pull request #39 from h4llow3En/develop
Run as alpine docker image and server static files with gunicorn
2020-03-23 20:03:09 +01:00
h4llow3En
1e3e03e4af Simplify first user creation 2020-03-20 10:50:34 +01:00
h4llow3En
391ab5ddac Don't use "latest" images 2020-03-20 10:02:59 +01:00
h4llow3En
e0c560c2d7 Remove debug output from Dockerfile 2020-03-20 09:28:33 +01:00
h4llow3En
be942bcb79 Fix "Update" description in readme 2020-03-19 18:02:28 +01:00
h4llow3En
6b27f0c8ab Cleanup and simplify deployment 2020-03-19 15:08:53 +01:00
h4llow3En
cc931189e8 Run as alpine docker image and server static files with gunicorn 2020-03-19 10:13:49 +01:00
vabene1111
1b45121385 case insenstitive import 2020-03-18 16:58:27 +01:00
vabene1111
97e2593f72 fixed single import 2020-03-18 16:50:28 +01:00
vabene1111
00539b9d1b fixed theme switching 2020-03-18 13:08:31 +01:00
vabene1111
1cadb1e85e added password change form 2020-03-18 13:06:39 +01:00
vabene1111
9e524a8f22 added user name change 2020-03-18 12:51:13 +01:00
vabene1111
a8a7d4e0f4 complete bottom border "hack" 2020-03-18 12:30:35 +01:00
vabene1111
d0cf396f68 ingredient mobile friendly 2020-03-18 12:29:40 +01:00
vabene1111
e45f3f3343 updated translations 2020-03-18 12:20:45 +01:00
vabene1111
13ea2ecd7d display ingredient note 2020-03-18 12:12:03 +01:00
vabene1111
25ba62e87c improved ingredient editing 2020-03-18 12:11:15 +01:00
vabene1111
48107b918d added ingredient list page 2020-03-18 11:36:39 +01:00
vabene1111
0b56e22af9 nav improvements 2020-03-18 11:36:24 +01:00
vabene1111
47128fbb79 properly align nav icon vertically 2020-03-18 11:19:17 +01:00
vabene1111
12f6aa6df7 changed docker base image for python 3.8 2020-03-17 23:55:16 +01:00
vabene1111
c2dc038ac9 note optional 2020-03-17 22:49:53 +01:00
vabene1111
0c2b3d2d03 added ingredient notes + removed null constraints 2020-03-17 22:47:17 +01:00
vabene1111
1d562452df changed behavior of delete original 2020-03-17 18:54:44 +01:00
vabene1111
4c90664aa2 fixed translation mistaek 2020-03-17 18:47:24 +01:00
vabene1111
90dbc36402 added ability to link recipes to ingredients 2020-03-17 18:44:11 +01:00
vabene1111
a60b09e491 fixed confirm message on unit/ingredeitn merge 2020-03-17 18:28:53 +01:00
vabene1111
deeda425a8 added tests for storage edit 2020-03-17 18:22:13 +01:00
vabene1111
6fcbc9f0cd some basic testing for external recipe edits 2020-03-17 17:48:23 +01:00
vabene1111
7518d8c6b1 fixed several rewrite issues 2020-03-17 17:36:05 +01:00
vabene1111
eb25a9163f fixed import log badge 2020-03-17 17:31:26 +01:00
vabene1111
e2f6e07e42 Merge branch 'develop' of https://github.com/vabene1111/recipes into develop 2020-03-17 17:23:45 +01:00
vabene1111
17b9519fa9 refactor generic url creation 2020-03-17 17:23:39 +01:00
vabene1111
adcef1d887 Update main.yml 2020-03-17 16:41:21 +01:00
vabene1111
7398304d16 Update main.yml 2020-03-17 16:40:59 +01:00
vabene1111
09ff7e82f1 django admin cleanup 2020-03-17 16:16:04 +01:00
vabene1111
47072763ee cleand up search ui 2020-03-17 15:34:17 +01:00
vabene1111
86f2c9d89c cleand up and fixed ingredient edit table 2020-03-16 23:08:52 +01:00
vabene1111
c8eaa2a349 removed js test code 2020-03-16 22:50:52 +01:00
vabene1111
9853cecabb fixed keywords without icons 2020-03-16 14:48:04 +01:00
vabene1111
7b65252d47 documentation 2020-03-12 21:48:09 +01:00
vabene1111
f62ec51c91 ignore compose 2020-03-12 21:03:34 +01:00
vabene1111
9f8b93732f removed root docker compose 2020-03-12 20:57:27 +01:00
vabene1111
bf07fc7437 restructure 2020-03-12 20:48:52 +01:00
vabene1111
08837032ce ignore docker compose 2020-03-12 20:38:48 +01:00
vabene1111
abd655ce62 moved delete to seperate file 2020-03-01 12:34:59 +01:00
vabene1111
e755068a31 added test for png's 2020-03-01 12:13:36 +01:00
vabene1111
b5e35115fa fixed png's not working in recipes 2020-03-01 12:13:06 +01:00
vabene1111
c8cc140a78 improved recipe edit tests and fixed bugs 2020-02-29 00:00:13 +01:00
vabene1111
8c7a171d56 added more tests and test structure 2020-02-28 23:17:04 +01:00
vabene1111
df62717806 removed non internal recipes from shopping 2020-02-28 22:21:03 +01:00
vabene1111
a1e6bd5441 fixed text outside of colum 2020-02-28 22:12:18 +01:00
vabene1111
034e2c612b added internal recipe filter 2020-02-28 22:12:02 +01:00
vabene1111
45c85b9de8 fixed markdown blockquotes not really rendering 2020-02-28 22:09:16 +01:00
vabene1111
a9952b8f57 improved markdown rendering of tables and images 2020-02-28 21:53:27 +01:00
vabene1111
b8f16b50a7 simplified viewer + fixed characters escaping 2020-02-19 20:19:08 +01:00
vabene1111
752df5a1d2 cleaned up viewer 2020-02-19 19:39:32 +01:00
vabene1111
fe6e351349 testing pdf viewerr 2020-02-19 19:12:11 +01:00
vabene1111
8cc9273268 basic viewer working 2020-02-19 19:02:47 +01:00
vabene1111
0c1763b347 pdf display working 2020-02-19 18:13:11 +01:00
vabene1111
88dc713683 WIP pdf embedding 2020-02-19 16:55:13 +01:00
vabene1111
fc1cc70870 basic pdf embedding 2020-02-19 00:08:32 +01:00
vabene1111
42e09fcae9 updated translations 2020-02-18 23:26:14 +01:00
vabene1111
4843568d10 added searching for ingredients 2020-02-18 23:16:05 +01:00
vabene1111
2e7e4b23dd highlight active tab 2020-02-18 23:03:37 +01:00
vabene1111
8192a8dc8f improved shopping list ui 2020-02-18 23:00:23 +01:00
vabene1111
c98dbd065e allow choosing output format of shopping list 2020-02-18 22:41:37 +01:00
vabene1111
43d03ed17d group ingredients in shopping list 2020-02-18 22:33:31 +01:00
vabene1111
8ba34414a1 added shoping to nav 2020-02-18 22:28:22 +01:00
vabene1111
46dffe2f63 added ingredient merging 2020-02-18 22:25:21 +01:00
vabene1111
04cbe6cb2c removed empty script tag when no default is given 2020-02-18 22:17:27 +01:00
vabene1111
8fd6dcc81c updated translations 2020-02-17 23:34:17 +01:00
vabene1111
b89e96476a fixed status badge
since GH actions currently dont triggert on fast forward merge pushs the badge is changed to show passing status of develop
2020-02-17 00:33:21 +01:00
472 changed files with 143448 additions and 1821 deletions

View File

@@ -7,4 +7,12 @@ docker-compose*
.gitignore
README.md
LICENSE
.vscode
.vscode
.env
.env.template
.github
.idea
LICENSE.md
docs
nginx
update.sh

View File

@@ -1,14 +1,52 @@
VIRTUAL_HOST=
LETSENCRYPT_HOST=
LETSENCRYPT_EMAIL=
# only set this to true when testing/debugging
# when unset: 1 (true) - dont unset this, just for development
DEBUG=0
DEBUG=1
# hosts the application can run under e.g. recipes.mydomain.com,cooking.mydomain.com,...
ALLOWED_HOSTS=*
# random secret key, use for example base64 /dev/urandom | head -c50 to generate one
SECRET_KEY=
DB_ENGINE=django.db.backends.postgresql_psycopg2
# your default timezone
TIMEZONE=Europe/Berlin
# add only a database password if you want to run with the default postgres, otherwise change settings accordingly
DB_ENGINE=django.db.backends.postgresql
POSTGRES_HOST=db_recipes
POSTGRES_PORT=5432
POSTGRES_USER=djangodb
POSTGRES_PASSWORD=
POSTGRES_DB=djangodb
POSTGRES_DB=djangodb
# the default value for the user preference 'fractions' (enable/disable fraction support)
# when unset: 0 (disabled)
FRACTION_PREF_DEFAULT=0
# the default value for the user preference 'comments' (enable/disable commenting system)
# when unset: 1 (true)
COMMENT_PREF_DEFAULT=1
# 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=5
# If staticfiles are stored at a different location uncomment and change accordingly
# STATIC_URL=/static/
# If mediafiles are stored at a different location uncomment and change accordingly
# MEDIA_URL=/media/
# 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.
# when unset: 1 (true) - this is temporary until an appropriate amount of time has passed for everyone to migrate
GUNICORN_MEDIA=0
# allow authentication via reverse proxy (e.g. authelia), leave of if you dont know what you are doing
# docs: https://github.com/vabene1111/recipes/tree/develop/docs/docker/nginx-proxy%20with%20proxy%20authentication
# when unset: 0 (false)
REVERSE_PROXY_AUTH=0

15
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,15 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
### Version
Please provide your current version (can be found on the system page since v0.8.4)
Version:
### Bug description
A clear and concise description of what the bug is.

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

27
.github/ISSUE_TEMPLATE/help-request.md vendored Normal file
View File

@@ -0,0 +1,27 @@
---
name: Help request
about: If there is anything wrong with your setup
title: ''
labels: setup issue
assignees: ''
---
### Version
Please provide your current version (can be found on the system page since v0.8.4)
Version:
### Issue
Please describe your problem here
### `.env`
Please include your `.env` config file (**make sure to remove/replace all secrets**)
```
env content
```
### `docker-compose.yml`
When running with docker compose please provide your `docker-compose.yml`
```
docker-compose.yml content
```

11
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "pip" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"

View File

@@ -9,18 +9,19 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: [3.7]
python-version: [3.8]
steps:
- uses: actions/checkout@v1
- name: Set up Python 3.7
- name: Set up Python 3.8
uses: actions/setup-python@v1
with:
python-version: 3.7
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
python3 manage.py collectstatic --noinput
- name: Django Testing project
run: |
python3 manage.py test

51
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,51 @@
name: "Code scanning - action"
on:
push:
pull_request:
schedule:
- cron: '0 13 * * 2'
jobs:
CodeQL-Build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
# - name: Autobuild
# uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View File

@@ -0,0 +1,26 @@
name: publish dev image docker
on:
push:
branches:
- '*'
- '*/*'
- '!master'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Update version file
uses: DamianReeves/write-file-action@v1.0
with:
path: recipes/version.py
contents: |
VERSION_NUMBER = 'develop'
BUILD_REF = '${{ github.sha }}'
write-mode: overwrite
- name: Publish to Registry
uses: elgohr/Publish-Docker-Github-Action@2.13
with:
name: vabene1111/recipes
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

View File

@@ -0,0 +1,30 @@
name: publish latest image docker
on:
push:
tags:
- '*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Get version number
id: get_version
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
- name: Update version file
uses: DamianReeves/write-file-action@v1.0
with:
path: recipes/version.py
contents: |
VERSION_NUMBER = '${{ steps.get_version.outputs.VERSION }}'
BUILD_REF = '${{ github.sha }}'
write-mode: overwrite
- name: Build and publish image
uses: ilteoood/docker_buildx@master
with:
publish: true
imageName: vabene1111/recipes
tag: latest
dockerHubUser: ${{ secrets.DOCKER_USERNAME }}
dockerHubPassword: ${{ secrets.DOCKER_PASSWORD }}

View File

@@ -0,0 +1,33 @@
name: publish tagged release docker
on:
push:
tags:
- '*'
jobs:
build:
runs-on: ubuntu-latest
name: Build image job
steps:
- name: Checkout master
uses: actions/checkout@master
- name: Get version number
id: get_version
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
- name: Update version file
uses: DamianReeves/write-file-action@v1.0
with:
path: recipes/version.py
contents: |
VERSION_NUMBER = '${{ steps.get_version.outputs.VERSION }}'
BUILD_REF = '${{ github.sha }}'
write-mode: overwrite
- name: Build and publish image
uses: ilteoood/docker_buildx@master
with:
publish: true
imageName: vabene1111/recipes
tag: ${{ steps.get_version.outputs.VERSION }}
dockerHubUser: ${{ secrets.DOCKER_USERNAME }}
dockerHubPassword: ${{ secrets.DOCKER_PASSWORD }}

22
.gitignore vendored
View File

@@ -69,29 +69,11 @@ mediafiles/
\.idea/misc\.xml
\.idea/recipes\.iml
# Deployment
\.env
staticfiles/
postgresql/
postgresql/
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
/docker-compose.override.yml

11
.idea/dictionaries/vabene1111_PC.xml generated Normal file
View File

@@ -0,0 +1,11 @@
<component name="ProjectDictionaryState">
<dictionary name="vabene1111-PC">
<words>
<w>autosync</w>
<w>csrftoken</w>
<w>gunicorn</w>
<w>ical</w>
<w>traefik</w>
</words>
</dictionary>
</component>

View File

@@ -1,14 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredPackages">
<value>
<list size="1">
<item index="0" class="java.lang.String" itemvalue="psycopg2" />
</list>
</value>
</option>
</inspection_tool>
</profile>
</component>

View File

@@ -1,6 +1,5 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="PROJECT_PROFILE" value="Default" />
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<file url="file://$PROJECT_DIR$" libraries="{jquery-3.4.1}" />
</component>
</project>

36
.idea/recipes.iml generated Normal file
View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="FacetManager">
<facet type="django" name="Django">
<configuration>
<option name="rootFolder" value="$MODULE_DIR$" />
<option name="settingsModule" value="recipes/settings.py" />
<option name="manageScript" value="$MODULE_DIR$/manage.py" />
<option name="environment" value="&lt;map/&gt;" />
<option name="doNotUseTestRunner" value="false" />
<option name="trackFilePattern" value="migrations" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/cookbook/tests/resources" />
<excludeFolder url="file://$MODULE_DIR$/staticfiles" />
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.8 (recipes)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="jquery-3.4.1" level="application" />
<orderEntry type="library" name="pretty-checkbox" level="application" />
<orderEntry type="library" name="pdf" level="application" />
<orderEntry type="library" name="pdf_viewer" level="application" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_CONFIGURATION" value="Django" />
<option name="TEMPLATE_FOLDERS">
<list>
<option value="$MODULE_DIR$/cookbook/templates" />
</list>
</option>
</component>
</module>

11
CONTRIBUTERS.md Normal file
View File

@@ -0,0 +1,11 @@
Many thanks to everyone who contributed to this project!
## Translations
### Dutch
[D0T1X](https://www.transifex.com/user/profile/D0T1X/)
### French
[jt117](https://www.transifex.com/user/profile/jt117/)
[nerdinator](https://www.transifex.com/user/profile/nerdinator/)

View File

@@ -1,24 +1,18 @@
FROM ubuntu:18.04
RUN mkdir /Recipes
WORKDIR /Recipes
ADD . /Recipes/
RUN apt-get update
RUN apt-get -y upgrade
RUN apt-get install -y \
python3 \
python3-pip \
postgresql-client \
gettext
RUN pip3 install --upgrade pip
RUN pip3 install -r requirements.txt
RUN apt-get autoremove -y
FROM python:3.8-alpine
RUN apk add --no-cache postgresql-libs gettext zlib libjpeg libxml2-dev libxslt-dev
ENV PYTHONUNBUFFERED 1
EXPOSE 8080
EXPOSE 8080
RUN mkdir /opt/recipes
WORKDIR /opt/recipes
COPY . ./
RUN chmod +x boot.sh setup.sh
RUN ln -s /opt/recipes/setup.sh /usr/local/bin/createsuperuser
RUN apk add --no-cache --virtual .build-deps gcc musl-dev postgresql-dev zlib-dev jpeg-dev && \
python -m venv venv && \
venv/bin/pip install -r requirements.txt --no-cache-dir &&\
apk --purge del .build-deps
ENTRYPOINT ["/opt/recipes/boot.sh"]

View File

@@ -1,22 +1,690 @@
“Commons Clause” License Condition v1.0
The Software is provided to you by the Licensor under the License, as defined below, subject to the following condition.
Without limiting other conditions in the License, the grant of rights under the License will not include, and the License does not grant to you, the right to Sell the Software.
For purposes of the foregoing, “Sell” means practicing any or all of the rights granted to you under the License to provide to third parties, for a fee or other consideration (including without limitation fees for hosting or consulting/ support services related to the Software), a product or service whose value derives, entirely or substantially, from the functionality of the Software. Any license notice or attribution required by the License must also include this Commons Clause License Condition notice.
Software: https://github.com/vabene1111/recipes
License: GNU AFFERO GENERAL PUBLIC LICENSE v3
Licensor: https://github.com/vabene1111
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.
---
### Prior 0.10.0
> All versions released before version 0.10. or 29.06.2020 were licensed under the following license
The MIT License (MIT)
Copyright (c) 2018
Copyright (c) 2018
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

101
README.md
View File

@@ -1,74 +1,83 @@
# Recipes ![CI](https://github.com/vabene1111/recipes/workflows/Continous%20Integration/badge.svg?branch=master)
# Recipes ![CI](https://github.com/vabene1111/recipes/workflows/Continous%20Integration/badge.svg?branch=develop)
Recipes is a Django application to manage, tag and search recipes using either built in models or external storage providers hosting PDF's, Images or other files.
![Preview](preview.png)
![Preview](docs/preview.png)
### Features
[More Screenshots](https://imgur.com/a/V01151p)
## Features
- :package: **Sync** files with Dropbox and Nextcloud (more can easily be added)
- :mag: Powerful **search** with Djangos [TrigramSimilarity](https://docs.djangoproject.com/en/3.0/ref/contrib/postgres/search/#trigram-similarity)
- :label: Create and search for **tags**, assign them in batch to all files matching certain filters
- :page_facing_up: **Create recipes** locally within a nice, standardized web interface
- :page_facing_up: **Create recipes** locally within a nice, standardized web interface
- :arrow_down: **Import recipes** from thousands of websites supporting [ld+json or microdata](https://schema.org/Recipe)
- :iphone: Optimized for use on **mobile** devices like phones and tablets
- :shopping_cart: Generate **shopping** lists from recipes
- :calendar: Create a **Plan** on what to eat when
- :person_with_blond_hair: **Share** recipes with friends and comment on them to suggest or remember changes you made
- :family: **Share** recipes with friends and comment on them to suggest or remember changes you made
- :whale: Easy setup with **Docker**
- :art: Customize your interface with **themes**
- :envelope: Export and import recipes from other users
- :heavy_plus_sign: Many more like recipe scaling, image compression, cookbooks, printing views, ...
This application is meant for people with a collection of recipes they want to share with family and friends or simply store them in a nicely organized way. A basic permission system exists but this application is not meant to be run as a public page.
# Documentation
Most things should be straight forward but there are some more complicated things.
##### Storage Backends
A `Storage Backend` is a remote storage location where files are stored. To add a new backend click on `Storage Data` and then on `Storage Backends`. There click the plus button.
Enter a name (just a display name for you to identify it) and an API access Token for the account you want to use.
Dropboxes API tokens can be found on the [Dropboxes API explorer](https://dropbox.github.io/dropbox-api-v2-explorer/#auth_token/from_oauth1)
with the button on the top right. For Nextcloud you can use a App apssword created in the settings.
##### Adding Synced Paths
To add a new path from your Storage backend to the sync list, go to `Storage Data >> Configure Sync` and select the storage backend you want to use.
Then enter the path you want to monitor starting at the storage root (e.g. `/Folder/RecipesFolder`) and save it.
##### Syncing Data
To sync the recipes app with the storage backends press `Sync now` under `Storage Data >> Configure Sync`.
##### Import Recipes
All files found by the sync can be found under `Manage Data >> Import recipes`. There you can either import all at once without modifying them or import one by one, adding tags while importing.
##### Batch Edit
If you have many untagged recipes, you may want to edit them all at once. To do so, go to
`Storage Data >> Batch Edit`. Enter a word which should be contained in the recipe name and select the tags you want to apply.
When clicking submit, every recipe containing the word will be updated (tags are added).
> Currently the only option is word contains, maybe some more SQL like operators will be added later.
This application is meant for people with a collection of recipes they want to share with family and friends or simply
store them in a nicely organized way. A basic permission system exists but this application is not meant to be run as a public page.
Some Documentation can be found [here](https://github.com/vabene1111/recipes/wiki)
## Installation
The docker image (`vabene1111/recipes`) simply exposes the application on port `8080`. You may choose any preferred installation method, the following are just examples to make it easier.
### Docker-Compose
When cloning this repository, a simple docker-compose file is included. It is made for setups already running an nginx-reverse proxy network with lets encrypt companion but can be changed easily. Copy `.env.template` to `.env` and fill in the missing values accordingly.
Now simply start the containers and run the `update.sh` script that will apply all migrations and collect static files.
Create a default user by executing into the container with `docker-compose exec web_recipes sh` and run `python3 manage.py createsuperuser`.
1. Choose one of the included configurations [here](docs/docker).
2. Download the environment (config) file template and fill it out `wget https://raw.githubusercontent.com/vabene1111/recipes/develop/.env.template -O .env`
3. Start the container `docker-compose up -d`
4. Open the page to create the first user. Alternatively use `docker-compose exec web_recipes createsuperuser`
### Manual
Copy `.env.template` to `.env` and fill in the missing values accordingly.
You can leave out the docker specific variables (VIRTUAL_HOST, LETSENCRYPT_HOST, LETSENCRYPT_EMAIL).
Make sure all variables are available to whatever serves your application.
Otherwise simply follow the instructions for any django based deployment
(for example this one http://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html).
**Python >= 3.8** is required to run this!
To start developing:
1. Clone the repository using your preferred method
2. Install requirements from `requirements.txt` either globally or in a virtual environment
3. Run migrations with `manage.py migrate`
4. Create a first user with `manage.py createsuperuser`
5. Start development server with `manage.py runserver`
Refer to [manual install](docs/manual_install) for detailled instructions.
## Updating
While intermediate updates can be skipped when updating please make sure to **read the release notes** in case some special action is required to update.
0. Before updating it is recommended to **create a backup!**
1. Stop the container using `docker-compose down`
2. Pull the latest image using `docker-compose pull`
3. Start the container again using `docker-compose up -d`
## Kubernetes
You can find a basic kubernetes setup [here](docs/k8s/). Please see the README in the folder for more detail.
## Contributing
Pull Requests and ideas are welcome, feel free to contribute in any way.
For any questions on how to work with django please refer to their excellent [documentation](https://www.djangoproject.com/start/).
### Translating
There is a [transifex project](https://www.transifex.com/django-recipes/django-cookbook/) project to enable community driven translations. If you want to contribute a new language or help maintain an already existing one feel free to create a transifex account (using the link above) and request to join the project.
It is also possible to provide the translations directly by creating a new language using `manage.py makemessages -l <language_code> -i venv`. Once finished simply open a PR with the changed files.
## License
This project is licensed under the MIT license. Even though it is not required to publish derivatives, I highly encourage pushing changes upstream and letting people profit from any work done on this project.
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 an
[common clause](https://commonsclause.com/) selling exception. See [LICENSE.md](https://github.com/vabene1111/recipes/blob/develop/LICENSE.md) for details.
**Reasoning**
**This software and *all* its features are and will always be free for everyone to use and enjoy.**
The reason for the selling exception is that a significant amount of time was spend over multiple years to develop this software.
A payed hosted version which will be identical in features and code base to the software offered in this repository will
likely be released in the future (including all features needed to sell a hosted version as they might also be useful for personal use).
This will not only benefit me personally but also everyone who self-hosts this software as any profits made trough selling the hosted option
allow me to spend more time developing and improving the software for everyone. Selling exceptions are [approved by Richard Stallman](http://www.gnu.org/philosophy/selling-exceptions.en.html) and the
common clause license is very permissive (see the [FAQ](https://commonsclause.com/)).

11
boot.sh Normal file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
source venv/bin/activate
echo "Updating database"
python manage.py migrate
python manage.py collectstatic --noinput
echo "Done"
chmod -R 755 /opt/recipes/mediafiles
exec gunicorn -b :8080 --access-logfile - --error-logfile - --log-level INFO recipes.wsgi

View File

@@ -2,10 +2,180 @@ from django.contrib import admin
from .models import *
admin.site.register(Recipe)
class SpaceAdmin(admin.ModelAdmin):
list_display = ('name', 'message')
admin.site.register(Space, SpaceAdmin)
class UserPreferenceAdmin(admin.ModelAdmin):
list_display = ('name', 'theme', 'nav_color', 'default_page', 'search_style', 'comments')
@staticmethod
def name(obj):
return obj.user.get_user_name()
admin.site.register(UserPreference, UserPreferenceAdmin)
class StorageAdmin(admin.ModelAdmin):
list_display = ('name', 'method')
admin.site.register(Storage, StorageAdmin)
class SyncAdmin(admin.ModelAdmin):
list_display = ('storage', 'path', 'active', 'last_checked')
admin.site.register(Sync, SyncAdmin)
class SyncLogAdmin(admin.ModelAdmin):
list_display = ('sync', 'status', 'msg', 'created_at')
admin.site.register(SyncLog, SyncLogAdmin)
admin.site.register(Keyword)
admin.site.register(Sync)
admin.site.register(SyncLog)
admin.site.register(RecipeImport)
admin.site.register(Storage)
class StepAdmin(admin.ModelAdmin):
list_display = ('name', 'type', 'order')
admin.site.register(Step, StepAdmin)
class RecipeAdmin(admin.ModelAdmin):
list_display = ('name', 'internal', 'created_by', 'storage')
@staticmethod
def created_by(obj):
return obj.created_by.get_user_name()
admin.site.register(Recipe, RecipeAdmin)
admin.site.register(Unit)
admin.site.register(Food)
class IngredientAdmin(admin.ModelAdmin):
list_display = ('food', 'amount', 'unit')
admin.site.register(Ingredient, IngredientAdmin)
class CommentAdmin(admin.ModelAdmin):
list_display = ('recipe', 'name', 'created_at')
@staticmethod
def name(obj):
return obj.created_by.get_user_name()
admin.site.register(Comment, CommentAdmin)
class RecipeImportAdmin(admin.ModelAdmin):
list_display = ('name', 'storage', 'file_path')
admin.site.register(RecipeImport, RecipeImportAdmin)
class RecipeBookAdmin(admin.ModelAdmin):
list_display = ('name', 'user_name')
@staticmethod
def user_name(obj):
return obj.created_by.get_user_name()
admin.site.register(RecipeBook, RecipeBookAdmin)
class RecipeBookEntryAdmin(admin.ModelAdmin):
list_display = ('book', 'recipe')
admin.site.register(RecipeBookEntry, RecipeBookEntryAdmin)
class MealPlanAdmin(admin.ModelAdmin):
list_display = ('user', 'recipe', 'meal_type', 'date')
@staticmethod
def user(obj):
return obj.created_by.get_user_name()
admin.site.register(MealPlan, MealPlanAdmin)
class MealTypeAdmin(admin.ModelAdmin):
list_display = ('name', 'created_by', 'order')
admin.site.register(MealType, MealTypeAdmin)
class ViewLogAdmin(admin.ModelAdmin):
list_display = ('recipe', 'created_by', 'created_at')
admin.site.register(ViewLog, ViewLogAdmin)
class InviteLinkAdmin(admin.ModelAdmin):
list_display = ('username', 'group', 'valid_until', 'created_by', 'created_at', 'used_by')
admin.site.register(InviteLink, InviteLinkAdmin)
class CookLogAdmin(admin.ModelAdmin):
list_display = ('recipe', 'created_by', 'created_at', 'rating', 'servings')
admin.site.register(CookLog, CookLogAdmin)
class ShoppingListRecipeAdmin(admin.ModelAdmin):
list_display = ('id', 'recipe', 'multiplier')
admin.site.register(ShoppingListRecipe, ShoppingListRecipeAdmin)
class ShoppingListEntryAdmin(admin.ModelAdmin):
list_display = ('id', 'food', 'unit', 'list_recipe', 'checked')
admin.site.register(ShoppingListEntry, ShoppingListEntryAdmin)
class ShoppingListAdmin(admin.ModelAdmin):
list_display = ('id', 'created_by', 'created_at')
admin.site.register(ShoppingList, ShoppingListAdmin)
class ShareLinkAdmin(admin.ModelAdmin):
list_display = ('recipe', 'created_by', 'uuid', 'created_at',)
admin.site.register(ShareLink, ShareLinkAdmin)
class NutritionInformationAdmin(admin.ModelAdmin):
list_display = ('id',)
admin.site.register(NutritionInformation, NutritionInformationAdmin)

View File

@@ -2,14 +2,17 @@ import django_filters
from django.contrib.postgres.search import TrigramSimilarity
from django.db.models import Q
from cookbook.forms import MultiSelectWidget
from cookbook.models import Recipe, Keyword
from cookbook.models import Recipe, Keyword, Food, ShoppingList
from django.conf import settings
from django.utils.translation import gettext as _
class RecipeFilter(django_filters.FilterSet):
name = django_filters.CharFilter(method='filter_name')
keywords = django_filters.ModelMultipleChoiceFilter(queryset=Keyword.objects.all(), widget=MultiSelectWidget,
method='filter_keywords')
foods = django_filters.ModelMultipleChoiceFilter(queryset=Food.objects.all(), widget=MultiSelectWidget,
method='filter_foods', label=_('Ingredients'))
@staticmethod
def filter_keywords(queryset, name, value):
@@ -19,6 +22,14 @@ class RecipeFilter(django_filters.FilterSet):
queryset = queryset.filter(keywords=x)
return queryset
@staticmethod
def filter_foods(queryset, name, value):
if not name == 'foods':
return queryset
for x in value:
queryset = queryset.filter(steps__ingredients__food__name=x).distinct()
return queryset
@staticmethod
def filter_name(queryset, name, value):
if not name == 'name':
@@ -32,14 +43,25 @@ class RecipeFilter(django_filters.FilterSet):
class Meta:
model = Recipe
fields = ['name', 'keywords']
fields = ['name', 'keywords', 'foods', 'internal']
class QuickRecipeFilter(django_filters.FilterSet):
class IngredientFilter(django_filters.FilterSet):
name = django_filters.CharFilter(lookup_expr='icontains')
keywords = django_filters.ModelMultipleChoiceFilter(queryset=Keyword.objects.all(), widget=MultiSelectWidget,
method='filter_keywords')
class Meta:
model = Recipe
fields = ['name', 'keywords']
model = Food
fields = ['name']
class ShoppingListFilter(django_filters.FilterSet):
def __init__(self, data=None, *args, **kwargs):
if data is not None:
data = data.copy()
data.setdefault("finished", False)
super(ShoppingListFilter, self).__init__(data, *args, **kwargs)
class Meta:
model = ShoppingList
fields = ['finished']

View File

@@ -1,6 +1,6 @@
from dal import autocomplete
from django import forms
from django.forms import widgets
from django.urls import reverse, reverse_lazy
from django.utils.translation import gettext as _
from emoji_picker.widgets import EmojiPickerTextInput
@@ -27,12 +27,39 @@ class DateWidget(forms.DateInput):
class UserPreferenceForm(forms.ModelForm):
prefix = 'preference'
class Meta:
model = UserPreference
fields = ('theme', 'nav_color')
fields = ('default_unit', 'use_fractions', '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!')
'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.'),
'use_fractions': _('Enables support for fractions in ingredient amounts (e.g. convert decimals to fractions automatically)'),
'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.'),
'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 = {
'plan_share': MultiSelectWidget
}
class UserNameForm(forms.ModelForm):
prefix = 'name'
class Meta:
model = User
fields = ('first_name', 'last_name')
help_texts = {
'first_name': _('Both fields are optional. If none are given the username will be displayed instead')
}
@@ -61,23 +88,46 @@ class InternalRecipeForm(forms.ModelForm):
class Meta:
model = Recipe
fields = ('name', 'instructions', 'image', 'working_time', 'waiting_time', 'keywords')
fields = ('name', 'image', 'working_time', 'waiting_time', 'keywords')
labels = {
'name': _('Name'),
'keywords': _('Keywords'),
'instructions': _('Instructions'),
'working_time': _('Preparation time in minutes'),
'waiting_time': _('Waiting time (cooking/baking) in minutes'),
}
widgets = {'keywords': MultiSelectWidget}
class RecipeForm(forms.Form):
class ShoppingForm(forms.Form):
recipe = forms.ModelMultipleChoiceField(
queryset=Recipe.objects.all(),
queryset=Recipe.objects.filter(internal=True).all(),
widget=MultiSelectWidget
)
markdown_format = forms.BooleanField(
help_text=_('Include <code>- [ ]</code> in list for easier usage in markdown based documents.'),
required=False,
initial=False
)
class ExportForm(forms.Form):
recipe = forms.ModelChoiceField(
queryset=Recipe.objects.filter(internal=True).all(),
widget=SelectWidget
)
image = forms.BooleanField(
help_text=_('Export Base64 encoded image?'),
required=False
)
download = forms.BooleanField(
help_text=_('Download export directly or show on page?'),
required=False
)
class ImportForm(forms.Form):
recipe = forms.CharField(widget=forms.Textarea, help_text=_('Simply paste a JSON export into this textarea and click import.'))
class UnitMergeForm(forms.Form):
@@ -97,6 +147,23 @@ class UnitMergeForm(forms.Form):
)
class FoodMergeForm(forms.Form):
prefix = 'food'
new_food = forms.ModelChoiceField(
queryset=Food.objects.all(),
widget=SelectWidget,
label=_('New Food'),
help_text=_('New food that other gets replaced by.'),
)
old_food = forms.ModelChoiceField(
queryset=Food.objects.all(),
widget=SelectWidget,
label=_('Old Food'),
help_text=_('Food that should be replaced.'),
)
class CommentForm(forms.ModelForm):
prefix = 'comment'
@@ -119,6 +186,13 @@ class KeywordForm(forms.ModelForm):
widgets = {'icon': EmojiPickerTextInput}
class FoodForm(forms.ModelForm):
class Meta:
model = Food
fields = ('name', 'recipe')
widgets = {'recipe': SelectWidget}
class StorageForm(forms.ModelForm):
username = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password'}), required=False)
password = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password', 'type': 'password'}),
@@ -175,12 +249,43 @@ class ImportRecipeForm(forms.ModelForm):
class RecipeBookForm(forms.ModelForm):
class Meta:
model = RecipeBook
fields = ('name',)
fields = ('name', 'icon', 'description', 'shared')
widgets = {'icon': EmojiPickerTextInput, 'shared': MultiSelectWidget}
class MealPlanForm(forms.ModelForm):
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', 'meal', 'note', 'date')
fields = ('recipe', 'title', 'meal_type', 'note', 'recipe_multiplier', 'date', 'shared')
widgets = {'recipe': SelectWidget, 'date': DateWidget}
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>'),
'recipe_multiplier': _('Scaling factor for recipe.')
}
widgets = {'recipe': SelectWidget, 'date': DateWidget, 'shared': MultiSelectWidget}
class InviteLinkForm(forms.ModelForm):
class Meta:
model = InviteLink
fields = ('username', 'group', 'valid_until')
help_texts = {
'username': _('A username is not required, if left blank the new user can choose one.')
}
class UserCreateForm(forms.Form):
name = forms.CharField(label='Username')
password = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password', 'type': 'password'}))
password_confirm = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password', 'type': 'password'}))

View File

@@ -1,6 +1,6 @@
from dal import autocomplete
from cookbook.models import Keyword, RecipeIngredient, Recipe, Unit, Ingredient
from cookbook.models import Keyword, Recipe, Unit, Food
class KeywordAutocomplete(autocomplete.Select2QuerySetView):
@@ -19,9 +19,9 @@ class KeywordAutocomplete(autocomplete.Select2QuerySetView):
class IngredientsAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.is_authenticated:
return Ingredient.objects.none()
return Food.objects.none()
qs = Ingredient.objects.all()
qs = Food.objects.all()
if self.q:
qs = qs.filter(name__icontains=self.q)

View File

@@ -0,0 +1,24 @@
import markdown
from markdown.treeprocessors import Treeprocessor
class StyleTreeprocessor(Treeprocessor):
def run_processor(self, node):
for child in node:
if child.tag == "table":
child.set("class", "table table-bordered")
if child.tag == "img":
child.set("class", "img-fluid")
self.run_processor(child)
return node
def run(self, root):
self.run_processor(root)
return root
class MarkdownFormatExtension(markdown.Extension):
def extendMarkdown(self, md, md_globals):
md.treeprocessors.register(StyleTreeprocessor(), 'StyleTreeprocessor', 10)

View File

@@ -0,0 +1,81 @@
"""A more liberal autolinker
Inspired by Django's urlize function.
Positive examples:
>>> import markdown
>>> md = markdown.Markdown(extensions=['urlize'])
>>> md.convert('http://example.com/')
u'<p><a href="http://example.com/">http://example.com/</a></p>'
>>> md.convert('go to http://example.com')
u'<p>go to <a href="http://example.com">http://example.com</a></p>'
>>> md.convert('example.com')
u'<p><a href="http://example.com">example.com</a></p>'
>>> md.convert('example.net')
u'<p><a href="http://example.net">example.net</a></p>'
>>> md.convert('www.example.us')
u'<p><a href="http://www.example.us">www.example.us</a></p>'
>>> md.convert('(www.example.us/path/?name=val)')
u'<p>(<a href="http://www.example.us/path/?name=val">www.example.us/path/?name=val</a>)</p>'
>>> md.convert('go to <http://example.com> now!')
u'<p>go to <a href="http://example.com">http://example.com</a> now!</p>'
Negative examples:
>>> md.convert('del.icio.us')
u'<p>del.icio.us</p>'
"""
import markdown
# Global Vars
URLIZE_RE = '(%s)' % '|'.join([
r'<(?:f|ht)tps?://[^>]*>',
r'\b(?:f|ht)tps?://[^)<>\s]+[^.,)<>\s]',
r'\bwww\.[^)<>\s]+[^.,)<>\s]',
r'[^(<\s]+\.(?:com|net|org)\b',
])
class UrlizePattern(markdown.inlinepatterns.Pattern):
""" Return a link Element given an autolink (`http://example/com`). """
def handleMatch(self, m):
url = m.group(2)
if url.startswith('<'):
url = url[1:-1]
text = url
if not url.split('://')[0] in ('http','https','ftp'):
if '@' in url and not '/' in url:
url = 'mailto:' + url
else:
url = 'http://' + url
el = markdown.util.etree.Element("a")
el.set('href', url)
el.text = markdown.util.AtomicString(text)
return el
class UrlizeExtension(markdown.Extension):
""" Urlize Extension for Python-Markdown. """
def extendMarkdown(self, md, md_globals):
""" Replace autolink with UrlizePattern """
md.inlinePatterns['autolink'] = UrlizePattern(URLIZE_RE, md)
def makeExtension(*args, **kwargs):
return UrlizeExtension(*args, **kwargs)
if __name__ == "__main__":
import doctest
doctest.testmod()

View File

@@ -0,0 +1,10 @@
# Permission Config
from cookbook.helper.permission_helper import CustomIsUser, CustomIsOwner, CustomIsAdmin, CustomIsGuest
class PermissionConfig:
BOOKS = {
'owner': True,
'groups': ['user'],
'drf': [CustomIsUser],
}

View File

@@ -0,0 +1,231 @@
"""
Source: https://djangosnippets.org/snippets/1703/
"""
from django.contrib import messages
from django.contrib.auth.decorators import user_passes_test
from django.core.exceptions import ValidationError
from django.utils.translation import gettext as _
from django.http import HttpResponseRedirect
from django.urls import reverse_lazy, reverse
from rest_framework import permissions
from rest_framework.permissions import SAFE_METHODS
from cookbook.models import ShareLink
# Helper Functions
def get_allowed_groups(groups_required):
"""
Builds a list of all groups equal or higher to the provided groups
This means checking for guest will also allow admins to access
:param groups_required: list or tuple of groups
:return: tuple of groups
"""
groups_allowed = tuple(groups_required)
if 'guest' in groups_required:
groups_allowed = groups_allowed + ('user', 'admin')
if 'user' in groups_required:
groups_allowed = groups_allowed + ('admin',)
return groups_allowed
def has_group_permission(user, groups):
"""
Tests if a given user is member of a certain group (or any higher group)
Superusers always bypass permission checks. Unauthenticated users cant be member of any
group thus always return false.
:param user: django auth user object
:param groups: list or tuple of groups the user should be checked for
:return: True if user is in allowed groups, false otherwise
"""
if not user.is_authenticated:
return False
groups_allowed = get_allowed_groups(groups)
if user.is_authenticated:
if user.is_superuser | bool(user.groups.filter(name__in=groups_allowed)):
return True
return False
def is_object_owner(user, obj):
"""
Tests if a given user is the owner of a given object
test performed by checking user against the objects user and create_by field (if exists)
superusers bypass all checks, unauthenticated users cannot own anything
:param user django auth user object
:param obj any object that should be tested
:return: true if user is owner of object, false otherwise
"""
# TODO this could be improved/cleaned up by adding get_owner methods to all models that allow owner checks
if not user.is_authenticated:
return False
if user.is_superuser:
return True
if owner := getattr(obj, 'created_by', None):
return owner == user
if owner := getattr(obj, 'user', None):
return owner == user
if getattr(obj, 'get_owner', None):
return obj.get_owner() == user
return False
def is_object_shared(user, obj):
"""
Tests if a given user is shared for a given object
test performed by checking user against the objects shared table
superusers bypass all checks, unauthenticated users cannot own anything
:param user django auth user object
:param obj any object that should be tested
:return: true if user is shared for object, false otherwise
"""
# TODO this could be improved/cleaned up by adding share checks for relevant objects
if not user.is_authenticated:
return False
if user.is_superuser:
return True
return user in obj.shared.all()
def share_link_valid(recipe, share):
"""
Verifies the validity of a share uuid
:param recipe: recipe object
:param share: share uuid
:return: true if a share link with the given recipe and uuid exists, false otherwise
"""
try:
return True if ShareLink.objects.filter(recipe=recipe, uuid=share).exists() else False
except ValidationError:
return False
# Django Views
def group_required(*groups_required):
"""
Decorator that tests the requesting user to be member of at least one of the provided groups
or higher level groups
:param groups_required: list of required groups
:return: true if member of group, false otherwise
"""
def in_groups(u):
return has_group_permission(u, groups_required)
return user_passes_test(in_groups, login_url='index')
class GroupRequiredMixin(object):
"""
groups_required - list of strings, required param
"""
groups_required = None
def dispatch(self, request, *args, **kwargs):
if not has_group_permission(request.user, self.groups_required):
messages.add_message(request, messages.ERROR, _('You do not have the required permissions to view this page!'))
return HttpResponseRedirect(reverse_lazy('index'))
return super(GroupRequiredMixin, self).dispatch(request, *args, **kwargs)
class OwnerRequiredMixin(object):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated:
messages.add_message(request, messages.ERROR, _('You are not logged in and therefore cannot view this page!'))
return HttpResponseRedirect(reverse_lazy('login'))
else:
if not is_object_owner(request.user, self.get_object()):
messages.add_message(request, messages.ERROR, _('You cannot interact with this object as its not owned by you!'))
return HttpResponseRedirect(reverse('index'))
return super(OwnerRequiredMixin, self).dispatch(request, *args, **kwargs)
# Django Rest Framework Permission classes
class CustomIsOwner(permissions.BasePermission):
"""
Custom permission class for django rest framework views
verifies user has ownership over object
(either user or created_by or user is request user)
"""
message = _('You cannot interact with this object as its not owned by you!')
def has_permission(self, request, view):
return request.user.is_authenticated
def has_object_permission(self, request, view, obj):
return is_object_owner(request.user, obj)
class CustomIsShared(permissions.BasePermission): # TODO function duplicate/too similar name
"""
Custom permission class for django rest framework views
verifies user is shared for the object he is trying to access
"""
message = _('You cannot interact with this object as its not owned by you!')
def has_permission(self, request, view):
return request.user.is_authenticated
def has_object_permission(self, request, view, obj):
return is_object_shared(request.user, obj)
class CustomIsGuest(permissions.BasePermission):
"""
Custom permission class for django rest framework views
verifies the user is member of at least the group: guest
"""
message = _('You do not have the required permissions to view this page!')
def has_permission(self, request, view):
return has_group_permission(request.user, ['guest'])
def has_object_permission(self, request, view, obj):
return has_group_permission(request.user, ['guest'])
class CustomIsUser(permissions.BasePermission):
"""
Custom permission class for django rest framework views
verifies the user is member of at least the group: user
"""
message = _('You do not have the required permissions to view this page!')
def has_permission(self, request, view):
return has_group_permission(request.user, ['user'])
class CustomIsAdmin(permissions.BasePermission):
"""
Custom permission class for django rest framework views
verifies the user is member of at least the group: admin
"""
message = _('You do not have the required permissions to view this page!')
def has_permission(self, request, view):
return has_group_permission(request.user, ['admin'])
class CustomIsShare(permissions.BasePermission):
"""
Custom permission class for django rest framework views
verifies the requesting user provided a valid share link
"""
message = _('You do not have the required permissions to view this page!')
def has_permission(self, request, view):
return request.method in SAFE_METHODS and 'pk' in view.kwargs
def has_object_permission(self, request, view, obj):
share = request.query_params.get('share', None)
if share:
return share_link_valid(obj, share)
return False

View File

@@ -0,0 +1,199 @@
import json
import random
import re
import unicodedata
from json import JSONDecodeError
import microdata
from bs4 import BeautifulSoup
from django.http import JsonResponse
from django.utils.dateparse import parse_duration
from django.utils.translation import gettext as _
from cookbook.models import Keyword
def get_from_html(html_text, url):
soup = BeautifulSoup(html_text, "html.parser")
# first try finding ld+json as its most common
for ld in soup.find_all('script', type='application/ld+json'):
try:
ld_json = json.loads(ld.string.replace('\n', ''))
if type(ld_json) != list:
ld_json = [ld_json]
for ld_json_item in ld_json:
# recipes type might be wrapped in @graph type
if '@graph' in ld_json_item:
for x in ld_json_item['@graph']:
if '@type' in x and x['@type'] == 'Recipe':
ld_json_item = x
if '@type' in ld_json_item and ld_json_item['@type'] == 'Recipe':
return find_recipe_json(ld_json_item, url)
except JSONDecodeError as e:
return JsonResponse({'error': True, 'msg': _('The requested site provided malformed data and cannot be read.')}, status=400)
# now try to find microdata
items = microdata.get_items(html_text)
for i in items:
md_json = json.loads(i.json())
if 'schema.org/Recipe' in str(md_json['type']):
return find_recipe_json(md_json['properties'], url)
return JsonResponse({'error': True, 'msg': _('The requested site does not provide any recognized data format to import the recipe from.')}, status=400)
def find_recipe_json(ld_json, url):
if type(ld_json['name']) == list:
try:
ld_json['name'] = ld_json['name'][0]
except:
ld_json['name'] = 'ERROR'
# some sites use ingredients instead of recipeIngredients
if 'recipeIngredient' not in ld_json and 'ingredients' in ld_json:
ld_json['recipeIngredient'] = ld_json['ingredients']
if 'recipeIngredient' in ld_json:
# some pages have comma separated ingredients in a single array entry
if len(ld_json['recipeIngredient']) == 1 and len(ld_json['recipeIngredient'][0]) > 30:
ld_json['recipeIngredient'] = ld_json['recipeIngredient'][0].split(',')
for x in ld_json['recipeIngredient']:
if '\n' in x:
ld_json['recipeIngredient'].remove(x)
for i in x.split('\n'):
ld_json['recipeIngredient'].insert(0, i)
ingredients = []
for x in ld_json['recipeIngredient']:
ingredient_split = x.split()
ingredient = None
amount = 0
unit = ''
if len(ingredient_split) > 2:
ingredient = " ".join(ingredient_split[2:])
unit = ingredient_split[1]
try:
if 'fraction' in unicodedata.decomposition(ingredient_split[0]):
frac_split = unicodedata.decomposition(ingredient_split[0]).split()
amount = round(float((frac_split[1]).replace('003', '')) / float((frac_split[3]).replace('003', '')), 3)
else:
raise TypeError
except TypeError: # raised by unicodedata.decomposition if there was no unicode character in parsed data
try:
amount = float(ingredient_split[0].replace(',', '.'))
except ValueError:
amount = 0
ingredient = " ".join(ingredient_split)
if len(ingredient_split) == 2:
ingredient = " ".join(ingredient_split[1:])
unit = ''
try:
amount = float(ingredient_split[0].replace(',', '.'))
except ValueError:
amount = 0
ingredient = " ".join(ingredient_split)
if len(ingredient_split) == 1:
ingredient = " ".join(ingredient_split)
if ingredient:
ingredients.append({'amount': amount, 'unit': {'text': unit, 'id': random.randrange(10000, 99999)}, 'ingredient': {'text': ingredient, 'id': random.randrange(10000, 99999)}, 'original': x})
ld_json['recipeIngredient'] = ingredients
else:
ld_json['recipeIngredient'] = []
if 'keywords' in ld_json:
keywords = []
# keywords as string
if type(ld_json['keywords']) == str:
ld_json['keywords'] = ld_json['keywords'].split(',')
# keywords as string in list
if type(ld_json['keywords']) == list and len(ld_json['keywords']) == 1 and ',' in ld_json['keywords'][0]:
ld_json['keywords'] = ld_json['keywords'][0].split(',')
# keywords as list
for kw in ld_json['keywords']:
if k := Keyword.objects.filter(name=kw).first():
keywords.append({'id': str(k.id), 'text': str(k).strip()})
else:
keywords.append({'id': "null", 'text': kw.strip()})
ld_json['keywords'] = keywords
else:
ld_json['keywords'] = []
if 'recipeInstructions' in ld_json:
instructions = ''
# flatten instructions if they are in a list
if type(ld_json['recipeInstructions']) == list:
for i in ld_json['recipeInstructions']:
if type(i) == str:
instructions += i
else:
if 'text' in i:
instructions += i['text'] + '\n\n'
elif 'itemListElement' in i:
for ile in i['itemListElement']:
if type(ile) == str:
instructions += ile + '\n\n'
elif 'text' in ile:
instructions += ile['text'] + '\n\n'
else:
instructions += str(i)
ld_json['recipeInstructions'] = instructions
ld_json['recipeInstructions'] = re.sub(r'\n\s*\n', '\n\n', ld_json['recipeInstructions'])
ld_json['recipeInstructions'] = re.sub(' +', ' ', ld_json['recipeInstructions'])
ld_json['recipeInstructions'] = ld_json['recipeInstructions'].replace('<p>', '')
ld_json['recipeInstructions'] = ld_json['recipeInstructions'].replace('</p>', '')
else:
ld_json['recipeInstructions'] = ''
ld_json['recipeInstructions'] += '\n\n' + _('Imported from ') + url
if 'image' in ld_json:
# check if list of images is returned, take first if so
if (type(ld_json['image'])) == list:
if type(ld_json['image'][0]) == str:
ld_json['image'] = ld_json['image'][0]
elif 'url' in ld_json['image'][0]:
ld_json['image'] = ld_json['image'][0]['url']
# ignore relative image paths
if 'http' not in ld_json['image']:
ld_json['image'] = ''
if 'cookTime' in ld_json:
try:
if type(ld_json['cookTime']) == list and len(ld_json['cookTime']) > 0:
ld_json['cookTime'] = ld_json['cookTime'][0]
ld_json['cookTime'] = round(parse_duration(ld_json['cookTime']).seconds / 60)
except TypeError:
ld_json['cookTime'] = 0
else:
ld_json['cookTime'] = 0
if 'prepTime' in ld_json:
try:
if type(ld_json['prepTime']) == list and len(ld_json['prepTime']) > 0:
ld_json['prepTime'] = ld_json['prepTime'][0]
ld_json['prepTime'] = round(parse_duration(ld_json['prepTime']).seconds / 60)
except TypeError:
ld_json['prepTime'] = 0
else:
ld_json['prepTime'] = 0
for key in list(ld_json):
if key not in ['prepTime', 'cookTime', 'image', 'recipeInstructions', 'keywords', 'name', 'recipeIngredient']:
ld_json.pop(key, None)
return JsonResponse(ld_json)

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
# Generated by Django 3.0.2 on 2020-02-19 15:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0025_userpreference_nav_color'),
]
operations = [
migrations.AddField(
model_name='recipe',
name='cors_link',
field=models.CharField(blank=True, max_length=1024, null=True),
),
migrations.AlterField(
model_name='recipe',
name='link',
field=models.CharField(blank=True, max_length=512, null=True),
),
]

View File

@@ -0,0 +1,19 @@
# Generated by Django 3.0.4 on 2020-03-17 17:31
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0026_auto_20200219_1605'),
]
operations = [
migrations.AddField(
model_name='ingredient',
name='recipe',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='cookbook.Recipe'),
),
]

View File

@@ -0,0 +1,19 @@
# Generated by Django 3.0.4 on 2020-03-17 18:01
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0027_ingredient_recipe'),
]
operations = [
migrations.AlterField(
model_name='recipeingredient',
name='ingredient',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='cookbook.Ingredient'),
),
]

View File

@@ -0,0 +1,19 @@
# Generated by Django 3.0.4 on 2020-03-17 18:01
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0028_auto_20200317_1901'),
]
operations = [
migrations.AlterField(
model_name='recipeingredient',
name='unit',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='cookbook.Unit'),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.0.4 on 2020-03-17 18:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0029_auto_20200317_1901'),
]
operations = [
migrations.AddField(
model_name='recipeingredient',
name='note',
field=models.CharField(blank=True, max_length=64, null=True),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.0.4 on 2020-04-07 16:41
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0030_recipeingredient_note'),
]
operations = [
migrations.AlterField(
model_name='keyword',
name='icon',
field=models.CharField(blank=True, max_length=16, null=True),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.0.4 on 2020-04-13 20:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0031_auto_20200407_1841'),
]
operations = [
migrations.AddField(
model_name='userpreference',
name='default_unit',
field=models.CharField(default='g', max_length=32),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.0.4 on 2020-04-13 20:41
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0032_userpreference_default_unit'),
]
operations = [
migrations.AddField(
model_name='userpreference',
name='default_page',
field=models.CharField(choices=[('SEARCH', 'Search'), ('PLAN', 'Meal-Plan')], default='SEARCH', max_length=64),
),
]

View File

@@ -0,0 +1,22 @@
# Generated by Django 3.0.5 on 2020-04-26 14:14
from django.db import migrations
def apply_migration(apps, schema_editor):
Group = apps.get_model('auth', 'Group')
Group.objects.bulk_create([
Group(name=u'guest'),
Group(name=u'user'),
Group(name=u'admin'),
])
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0033_userpreference_default_page'),
]
operations = [
migrations.RunPython(apply_migration)
]

View File

@@ -0,0 +1,28 @@
# Generated by Django 3.0.5 on 2020-04-27 14:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0034_auto_20200426_1614'),
]
operations = [
migrations.RenameField(
model_name='mealplan',
old_name='user',
new_name='created_by',
),
migrations.RenameField(
model_name='recipebook',
old_name='user',
new_name='created_by',
),
migrations.AlterField(
model_name='userpreference',
name='default_page',
field=models.CharField(choices=[('SEARCH', 'Search'), ('PLAN', 'Meal-Plan'), ('BOOKS', 'Books')], default='SEARCH', max_length=64),
),
]

View File

@@ -0,0 +1,22 @@
# Generated by Django 3.0.5 on 2020-04-27 16:00
from django.db import migrations
def apply_migration(apps, schema_editor):
Group = apps.get_model('auth', 'Group')
User = apps.get_model('auth', 'User')
for u in User.objects.all():
if u.groups.count() < 1:
u.groups.add(Group.objects.get(name='admin'))
u.save()
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0035_auto_20200427_1637'),
]
operations = [
migrations.RunPython(apply_migration)
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.0.5 on 2020-05-02 10:45
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0036_auto_20200427_1800'),
]
operations = [
migrations.AddField(
model_name='userpreference',
name='search_style',
field=models.CharField(choices=[('SMALL', 'Small'), ('LARGE', 'Large')], default='LARGE', max_length=64),
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 3.0.5 on 2020-05-02 10:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0037_userpreference_search_style'),
]
operations = [
migrations.AddField(
model_name='recipebook',
name='description',
field=models.TextField(blank=True),
),
migrations.AddField(
model_name='recipebook',
name='icon',
field=models.CharField(blank=True, max_length=16, null=True),
),
]

View File

@@ -0,0 +1,20 @@
# Generated by Django 3.0.5 on 2020-05-02 12:04
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cookbook', '0038_auto_20200502_1259'),
]
operations = [
migrations.AddField(
model_name='recipebook',
name='shared',
field=models.ManyToManyField(blank=True, related_name='shared_with', to=settings.AUTH_USER_MODEL),
),
]

View File

@@ -0,0 +1,22 @@
# Generated by Django 3.0.5 on 2020-05-02 12:33
import annoying.fields
from django.conf import settings
from django.db import migrations
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cookbook', '0039_recipebook_shared'),
]
operations = [
migrations.AlterField(
model_name='userpreference',
name='user',
field=annoying.fields.AutoOneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL),
),
]

View File

@@ -0,0 +1,24 @@
# Generated by Django 3.0.5 on 2020-05-02 12:46
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0040_auto_20200502_1433'),
]
operations = [
migrations.AddField(
model_name='mealplan',
name='title',
field=models.CharField(blank=True, default='', max_length=64),
),
migrations.AlterField(
model_name='mealplan',
name='recipe',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.Recipe'),
),
]

View File

@@ -0,0 +1,27 @@
# Generated by Django 3.0.5 on 2020-05-02 14:47
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cookbook', '0041_auto_20200502_1446'),
]
operations = [
migrations.CreateModel(
name='CookLog',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('rating', models.IntegerField(null=True)),
('servings', models.IntegerField(default=0)),
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('recipe', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.Recipe')),
],
),
]

View File

@@ -0,0 +1,25 @@
# Generated by Django 3.0.5 on 2020-05-07 21:02
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cookbook', '0042_cooklog'),
]
operations = [
migrations.AddField(
model_name='mealplan',
name='shared',
field=models.ManyToManyField(blank=True, related_name='plan_share', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='userpreference',
name='plan_share',
field=models.ManyToManyField(blank=True, related_name='plan_share_default', to=settings.AUTH_USER_MODEL),
),
]

View File

@@ -0,0 +1,25 @@
# Generated by Django 3.0.5 on 2020-05-11 10:21
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cookbook', '0043_auto_20200507_2302'),
]
operations = [
migrations.CreateModel(
name='ViewLog',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('recipe', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.Recipe')),
],
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.0.5 on 2020-06-02 08:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0044_viewlog'),
]
operations = [
migrations.AddField(
model_name='userpreference',
name='show_recent',
field=models.BooleanField(default=True),
),
]

View File

@@ -0,0 +1,27 @@
# Generated by Django 3.0.5 on 2020-06-02 09:33
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0045_userpreference_show_recent'),
]
operations = [
migrations.CreateModel(
name='MealType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=128)),
('order', models.IntegerField(default=0)),
],
),
migrations.AddField(
model_name='mealplan',
name='meal_type',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.MealType'),
),
]

View File

@@ -0,0 +1,51 @@
# Generated by Django 3.0.5 on 2020-06-02 09:33
from django.db import migrations
from django.utils.translation import gettext as _
def migrate_meal_types(apps, schema_editor):
MealPlan = apps.get_model('cookbook', 'MealPlan')
MealType = apps.get_model('cookbook', 'MealType')
breakfast = MealType.objects.create(
name=_('Breakfast'),
order=0,
)
lunch = MealType.objects.create(
name=_('Lunch'),
order=0,
)
dinner = MealType.objects.create(
name=_('Dinner'),
order=0,
)
other = MealType.objects.create(
name=_('Other'),
order=0,
)
for m in MealPlan.objects.all():
if m.meal == 'BREAKFAST':
m.meal_type = breakfast
if m.meal == 'LUNCH':
m.meal_type = lunch
if m.meal == 'DINNER':
m.meal_type = dinner
if m.meal == 'OTHER':
m.meal_type = other
m.save()
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0046_auto_20200602_1133'),
]
operations = [
migrations.RunPython(migrate_meal_types),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 3.0.5 on 2020-06-02 09:40
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0047_auto_20200602_1133'),
]
operations = [
migrations.RemoveField(
model_name='mealplan',
name='meal',
),
migrations.AlterField(
model_name='mealplan',
name='meal_type',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.MealType'),
),
]

View File

@@ -0,0 +1,21 @@
# Generated by Django 3.0.7 on 2020-06-11 13:08
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cookbook', '0048_auto_20200602_1140'),
]
operations = [
migrations.AddField(
model_name='mealtype',
name='created_by',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
]

View File

@@ -0,0 +1,30 @@
# Generated by Django 3.0.7 on 2020-06-11 13:09
from django.db import migrations
from django.db.models import Q
def migrate_meal_types(apps, schema_editor):
MealPlan = apps.get_model('cookbook', 'MealPlan')
MealType = apps.get_model('cookbook', 'MealType')
User = apps.get_model('auth', 'User')
for u in User.objects.all():
for t in MealType.objects.filter(created_by=None).all():
user_type = MealType.objects.create(
name=t.name,
created_by=u,
)
MealPlan.objects.filter(Q(created_by=u) and Q(meal_type=t)).update(meal_type=user_type)
MealType.objects.filter(created_by=None).delete()
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0049_mealtype_created_by'),
]
operations = [
migrations.RunPython(migrate_meal_types),
]

View File

@@ -0,0 +1,21 @@
# Generated by Django 3.0.7 on 2020-06-11 13:18
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cookbook', '0050_auto_20200611_1509'),
]
operations = [
migrations.AlterField(
model_name='mealtype',
name='created_by',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-06-11 20:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0051_auto_20200611_1518'),
]
operations = [
migrations.AddField(
model_name='userpreference',
name='ingredient_decimals',
field=models.IntegerField(default=2),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-06-11 20:17
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0052_userpreference_ingredient_decimals'),
]
operations = [
migrations.AlterField(
model_name='recipeingredient',
name='amount',
field=models.DecimalField(decimal_places=16, default=0, max_digits=32),
),
]

View File

@@ -0,0 +1,27 @@
# Generated by Django 3.0.7 on 2020-06-16 08:57
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cookbook', '0053_auto_20200611_2217'),
]
operations = [
migrations.CreateModel(
name='ShareLink',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('uuid', models.UUIDField(default=uuid.UUID('dbbf5150-0795-4305-b9bd-3952dfa2264b'))),
('created_at', models.DateTimeField(auto_now_add=True)),
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('recipe', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.Recipe')),
],
),
]

View File

@@ -0,0 +1,24 @@
# Generated by Django 3.0.7 on 2020-06-16 10:36
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0054_sharelink'),
]
operations = [
migrations.AddField(
model_name='userpreference',
name='comments',
field=models.BooleanField(default=True),
),
migrations.AlterField(
model_name='sharelink',
name='uuid',
field=models.UUIDField(default=uuid.UUID('a6e8f192-cc03-4dd4-8a03-58d7ab6b7df7')),
),
]

View File

@@ -0,0 +1,29 @@
# Generated by Django 3.0.7 on 2020-06-25 19:18
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
atomic = False
dependencies = [
('cookbook', '0055_auto_20200616_1236'),
]
operations = [
migrations.RenameModel(
old_name='Ingredient',
new_name='Food',
),
migrations.AddField(
model_name='recipe',
name='ingredients',
field=models.ManyToManyField(blank=True, related_name='tmp_ingredients', to='cookbook.RecipeIngredient'),
),
migrations.AlterField(
model_name='sharelink',
name='uuid',
field=models.UUIDField(default=uuid.UUID('a5f12617-9e4b-41e3-87ee-49db96090974')),
),
]

View File

@@ -0,0 +1,25 @@
# Generated by Django 3.0.7 on 2020-06-25 19:57
from django.db import migrations, models
import uuid
def invalidate_shares(apps, schema_editor):
ShareLink = apps.get_model('cookbook', 'ShareLink')
ShareLink.objects.all().delete()
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0055_auto_20200616_1236'),
]
operations = [
migrations.AlterField(
model_name='sharelink',
name='uuid',
field=models.UUIDField(default=uuid.uuid4),
),
migrations.RunPython(invalidate_shares)
]

View File

@@ -0,0 +1,24 @@
# Generated by Django 3.0.7 on 2020-06-25 19:27
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0056_auto_20200625_2118'),
]
operations = [
migrations.RenameField(
model_name='recipeingredient',
old_name='ingredient',
new_name='food',
),
migrations.AlterField(
model_name='sharelink',
name='uuid',
field=models.UUIDField(default=uuid.UUID('4a604ec8-c158-4011-ab5d-ddad7604c1e3')),
),
]

View File

@@ -0,0 +1,24 @@
# Generated by Django 3.0.7 on 2020-06-25 19:28
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
atomic = False
dependencies = [
('cookbook', '0057_auto_20200625_2127'),
]
operations = [
migrations.RenameModel(
old_name='RecipeIngredient',
new_name='Ingredient',
),
migrations.AlterField(
model_name='sharelink',
name='uuid',
field=models.UUIDField(default=uuid.UUID('27328011-54fb-46fa-8846-424d5828d858')),
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 3.0.7 on 2020-06-25 19:37
from django.db import migrations
def migrate_ingredients(apps, schema_editor):
Recipe = apps.get_model('cookbook', 'Recipe')
Ingredient = apps.get_model('cookbook', 'Ingredient')
for r in Recipe.objects.all():
for i in Ingredient.objects.filter(recipe=r).all():
r.ingredients.add(i)
r.save()
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0058_auto_20200625_2128'),
]
operations = [
migrations.RunPython(migrate_ingredients),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 3.0.7 on 2020-06-25 19:44
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0059_auto_20200625_2137'),
]
operations = [
migrations.RemoveField(
model_name='ingredient',
name='recipe',
),
migrations.AlterField(
model_name='sharelink',
name='uuid',
field=models.UUIDField(default=uuid.UUID('a7a91b2e-ad33-4159-a35e-828a5244ede9')),
),
]

View File

@@ -0,0 +1,14 @@
# Generated by Django 3.0.7 on 2020-06-25 20:09
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0056_auto_20200625_2157'),
('cookbook', '0060_auto_20200625_2144'),
]
operations = [
]

View File

@@ -0,0 +1,47 @@
# Generated by Django 3.0.7 on 2020-06-25 20:19
from django.db import migrations, models
def create_default_step(apps, schema_editor):
Recipe = apps.get_model('cookbook', 'Recipe')
Step = apps.get_model('cookbook', 'Step')
for r in Recipe.objects.filter(internal=True).all():
s = Step.objects.create(
instruction=r.instructions
)
for i in r.ingredients.all():
s.ingredients.add(i)
s.save()
r.steps.add(s)
r.save()
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0061_merge_20200625_2209'),
]
operations = [
migrations.AlterField(
model_name='recipe',
name='ingredients',
field=models.ManyToManyField(blank=True, to='cookbook.Ingredient'),
),
migrations.CreateModel(
name='Step',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('kind', models.CharField(choices=[('TEXT', 'Text')], default='TEXT', max_length=16)),
('instruction', models.TextField(blank=True)),
('ingredients', models.ManyToManyField(blank=True, to='cookbook.Ingredient')),
],
),
migrations.AddField(
model_name='recipe',
name='steps',
field=models.ManyToManyField(blank=True, to='cookbook.Step'),
),
migrations.RunPython(create_default_step)
]

View File

@@ -0,0 +1,21 @@
# Generated by Django 3.0.7 on 2020-06-25 20:30
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0062_auto_20200625_2219'),
]
operations = [
migrations.RemoveField(
model_name='recipe',
name='ingredients',
),
migrations.RemoveField(
model_name='recipe',
name='instructions',
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 3.0.7 on 2020-06-25 21:29
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0063_auto_20200625_2230'),
]
operations = [
migrations.AlterField(
model_name='recipe',
name='file_path',
field=models.CharField(blank=True, default='', max_length=512),
),
migrations.AlterField(
model_name='recipe',
name='file_uid',
field=models.CharField(blank=True, default='', max_length=256),
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 3.0.7 on 2020-06-26 12:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0064_auto_20200625_2329'),
]
operations = [
migrations.AddField(
model_name='ingredient',
name='order',
field=models.IntegerField(default=0),
),
migrations.AddField(
model_name='step',
name='order',
field=models.IntegerField(default=0),
),
]

View File

@@ -0,0 +1,26 @@
# Generated by Django 3.0.7 on 2020-06-26 12:55
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0065_auto_20200626_1444'),
]
operations = [
migrations.AlterModelOptions(
name='ingredient',
options={'ordering': ['order', 'pk']},
),
migrations.AlterModelOptions(
name='step',
options={'ordering': ['order', 'pk']},
),
migrations.AddField(
model_name='step',
name='name',
field=models.CharField(blank=True, default='', max_length=128),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-06-29 13:08
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0066_auto_20200626_1455'),
]
operations = [
migrations.AlterField(
model_name='ingredient',
name='note',
field=models.CharField(blank=True, max_length=256, null=True),
),
]

View File

@@ -0,0 +1,55 @@
# Generated by Django 3.0.7 on 2020-06-29 19:27
from django.db import migrations, models
import django.db.models.deletion
def convert_old_specials(apps, schema_editor):
Ingredient = apps.get_model('cookbook', 'Ingredient')
Food = apps.get_model('cookbook', 'Food')
Unit = apps.get_model('cookbook', 'Unit')
for i in Ingredient.objects.all():
if i.amount == 0:
i.no_amount = True
if i.unit.name == 'Special:Header':
i.header = True
i.unit = None
i.food = None
i.save()
try:
Unit.objects.filter(name='Special:Header').delete()
Food.objects.filter(name='Header').delete()
except Exception:
pass
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0067_auto_20200629_1508'),
]
operations = [
migrations.AddField(
model_name='ingredient',
name='header',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='ingredient',
name='no_amount',
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='ingredient',
name='food',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='cookbook.Food'),
),
migrations.AlterField(
model_name='ingredient',
name='unit',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='cookbook.Unit'),
),
migrations.RunPython(convert_old_specials)
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-06-29 19:34
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0068_auto_20200629_2127'),
]
operations = [
migrations.RenameField(
model_name='ingredient',
old_name='header',
new_name='is_header',
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 3.0.7 on 2020-07-01 18:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0069_auto_20200629_2134'),
]
operations = [
migrations.AddField(
model_name='step',
name='time',
field=models.IntegerField(blank=True, default=0),
),
migrations.AlterField(
model_name='step',
name='kind',
field=models.CharField(choices=[('TEXT', 'Text'), ('TIME', 'Time')], default='TEXT', max_length=16),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-07-01 18:48
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0070_auto_20200701_2007'),
]
operations = [
migrations.RenameField(
model_name='step',
old_name='kind',
new_name='type',
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-07-02 10:00
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0071_auto_20200701_2048'),
]
operations = [
migrations.AddField(
model_name='step',
name='show_as_header',
field=models.BooleanField(default=True),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-07-08 21:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0072_step_show_as_header'),
]
operations = [
migrations.AlterField(
model_name='sync',
name='last_checked',
field=models.DateTimeField(null=True),
),
]

View File

@@ -0,0 +1,17 @@
# Generated by Django 3.0.7 on 2020-07-09 19:54
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0073_auto_20200708_2311'),
]
operations = [
migrations.RemoveField(
model_name='keyword',
name='created_by',
),
]

View File

@@ -0,0 +1,49 @@
# Generated by Django 3.0.7 on 2020-08-11 10:14
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cookbook', '0074_remove_keyword_created_by'),
]
operations = [
migrations.CreateModel(
name='ShoppingListRecipe',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('multiplier', models.IntegerField(default=1)),
('recipe', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.Recipe')),
],
),
migrations.CreateModel(
name='ShoppingListEntry',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('amount', models.IntegerField(default=1)),
('order', models.IntegerField(default=0)),
('checked', models.BooleanField(default=False)),
('food', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.Food')),
('list_recipe', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.ShoppingListRecipe')),
('unit', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.Unit')),
],
),
migrations.CreateModel(
name='ShoppingList',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('uuid', models.UUIDField(default=uuid.uuid4)),
('note', models.TextField(blank=True, null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('recipes', models.ManyToManyField(blank=True, to='cookbook.ShoppingListRecipe')),
('shared', models.ManyToManyField(blank=True, related_name='list_share', to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-08-26 18:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0075_shoppinglist_shoppinglistentry_shoppinglistrecipe'),
]
operations = [
migrations.AddField(
model_name='shoppinglist',
name='entries',
field=models.ManyToManyField(blank=True, to='cookbook.ShoppingListEntry'),
),
]

View File

@@ -0,0 +1,29 @@
# Generated by Django 3.0.7 on 2020-09-01 11:31
import datetime
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cookbook', '0076_shoppinglist_entries'),
]
operations = [
migrations.CreateModel(
name='InviteLink',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('uuid', models.UUIDField(default=uuid.uuid4)),
('username', models.CharField(blank=True, max_length=64)),
('valid_until', models.DateField(default=datetime.date(2020, 9, 15))),
('created_at', models.DateTimeField(auto_now_add=True)),
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

Some files were not shown because too many files have changed in this diff Show More