Compare commits

...

5 Commits

Author SHA1 Message Date
Hayden
e2b9f02f55 Update dockerbuild.release.yml 2021-06-16 22:27:25 -08:00
Hayden
82da1e51db Update dockerbuild.prod.yml 2021-06-16 22:27:09 -08:00
Hayden
0addb3fe6b v0.5.0 (#532)
* fix links

* actually fix #238

* Feature/mkdocs version bump (#240)

* fix links (#239)

Co-authored-by: hay-kot <hay-kot@pm.me>

* fix #238

* bump mkdocs version

* light/dark toggle

* light/dark mode css

* API_DOCS defaults to True

* disable build on push for master

Co-authored-by: hay-kot <hay-kot@pm.me>

* Feature/recipe viewer (#244)

* fix dialog placement

* markdown support in ingredients

* fix line render issue

* fix tag rendering bug

* change ingredients to text area

* no slug error

* add tag pages

* remove console.logs

Co-authored-by: hay-kot <hay-kot@pm.me>

* changelog v0.4.1

* bug/backup-download (#245)

* fix blocked download

* + download blocked

Co-authored-by: hay-kot <hay-kot@pm.me>

* Feature/meal planner (#246)

* fixes duplicate recipes in meal-plan #221

* add quick week option

* scope css

* add mealplanner info

Co-authored-by: hay-kot <hay-kot@pm.me>

* Nextcloud Import Bugs - #248 (#250)

* parses datetime properly + clean category - #248

* add default credentials to docs

Co-authored-by: hay-kot <hay-kot@pm.me>

* Add bulk import examples to docs. (#252)

* Add bulk import examples to docs.

* Update api-usage.md

* Add Python example for bulk import.

* Change IP address in API example.

* Refactor/app settings (#251)

* fix env setup bugs

* remove unused import

* fix layout issues

* changelog

Co-authored-by: hay-kot <hay-kot@pm.me>

* env setup fixes

* Feature/about api (#253)

* fix settings

* app info cleanup

Co-authored-by: hay-kot <hay-kot@pm.me>

* Feature/image minify (#256)

* fix settings

* app info cleanup

* bottom-bar experiment

* remove dup key

* type hints

* add dependency

* updated image with query parameters

* read image options

* add image minification

* add image minification step

* alt image routes

* add image minification

* set mobile bar to top

Co-authored-by: hay-kot <hay-kot@pm.me>

* Feature/additional endpoints (#257)

* new recipe summary route

* add categories to cards

* add pillow

* show tags instead of categories

* additional debug info

* add todays meal image url

* about page

* fix reactive tag

* changelog + docs

* bump version

Co-authored-by: hay-kot <hay-kot@pm.me>

* add pillow dependencies (#258)

Co-authored-by: hay-kot <hay-kot@pm.me>

* Feature/search page (#259)

* add pillow dependencies

* advanced search page

* advanced search apge

* remove extra dependencies

* add pre-run script

Co-authored-by: hay-kot <hay-kot@pm.me>

* no image assignment

* advanced search

* fix docker dev build

* Do not force theme settings on login form (#260)

* Fix docker dev db persistence (#264)

* Fix docker dev db persistence

* Make run.sh the only startup script for prod + dev

Credits to @hay-kot for run.sh script logic

* Restore dev backend initialization in non-docker setup

* Make run.sh POSIX-friendly

* Allow dev backend to auto-reload in Docker

* Frontend Refactor + Bug Fixes

* merge category and tag selector

* unifiy category selector

* add hint

* spacing

* fix nextcloud migration

* simplify email validator #261

* formatting

* cleanup

* auto-gen

* format

* update run script

* unified category/tag selector

* rename component

* Add advanced search link

* remove old code

* convert keywords to tags

* add proper behavior on rename

* proper image name association on rename

* fix test cleanup

* changelog

* set docker comppand

* minify on migration

Co-authored-by: hay-kot <hay-kot@pm.me>

* bug-fixes/category-tag-creator (#266)

* fix category labels

* set loader for migration

* v0.4.1

Co-authored-by: hay-kot <hay-kot@pm.me>

* Hot Fix (#269)

* fix category labels

* set loader for migration

* v0.4.1

* reorganize API docs

Co-authored-by: hay-kot <hay-kot@pm.me>

* Fix some pytests (#265)

* Fix encoding issue in cleaner unit test

* Add VS Code task to run pytests

* Fix FileExistsError when running Windows

* Add Portuguese Translation (#232)

* Add Portuguese Translation

* add portuguese translation option

* formatting

* add missing }

* specify absolute path

* Feature/migration-rewrite (#278)

* start

* migration rewrite

* update name

* convert chowdown to new methods

* refactor/remove duplicate code

* refactor to unify logger + log to file

* remove toolbox

* Display report on UI

Co-authored-by: hay-kot <hay-kot@pm.me>

* refactor/image-minification (#285)

* refactor image minification calls

* remove nusiance logs

Co-authored-by: hay-kot <hay-kot@pm.me>

* feature/debug-info (#286)

* rename 'ENV' to 'PRODUCTION' and default to true

* set env PRODUCTION

* refactor file download process

* add last_recipe.json and log downloads

* changelog + version bump

* set env on workflows

* bump version

Co-authored-by: hay-kot <hay-kot@pm.me>

* Basic nutrition editor (#288)

* Basic nutrition editor

* fix no image on scrape

* nutrition display

* add recipe images

* update by url

* new upload options

Co-authored-by: hay-kot <hay-kot@pm.me>

* Sanitize recipe backup filenames (#287)

Fixes #275

* fix page creation fixes #290

* Display categories in sidebar if no pages set (#292)

Fixes  #291

* Enrich page title with context (#296)

- Static pages have their own titles
- The name of the recipe is displayed when viewing it

* fix: translates phrase for locale de (#298)

Co-authored-by: Jonas  Schubert <jonas.schubert.1990@web.de>

* Fix ingredient checkbox click (#305)

Fixes #304
v-list-item already flips the checkbox

* Localize custom pages and search page (#299)

* Localize custom pages and search page

* Fix FR translation for step

* fixes #306

* fixes #297

* Update changelog

* generate docs

* fix broken upload button on migrations

* docs update

* bump version

* fix discord link

* add TOKEN_TIME and DEFAULT_EMAIL

* docs

* fixes #312

* fixes #314

* fixes #315

* fix language hydration

* v0.4.3 docs

* Crowdin integration (#319)

* Fix portuguese localization files

* Use 4-letter code for locales ID

* Update Crowdin configuration file

* Make vuetify locales match with new VueI18n standard

* Fix old locale ID default setting

* Hide project hierarchy from Crowdin

* add dateTimeFormats to Crowdin

* New Crowdin updates (#322) - Initial Merge

* New translations en-US.json (French)

* New translations en-US.json (French)

* New translations en-US.json (Danish)

* New translations en-US.json (Danish)

* New translations en-US.json (German)

* New translations en-US.json (German)

* New translations en-US.json (Polish)

* New translations en-US.json (Polish)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Swedish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Chinese Traditional)

* New Crowdin updates (#323)

* New translations en-US.json (French)

* New translations en-US.json (French)

* New translations en-US.json (Danish)

* New translations en-US.json (Danish)

* New translations en-US.json (German)

* New translations en-US.json (German)

* New translations en-US.json (Polish)

* New translations en-US.json (Polish)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Swedish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Romanian)

* New translations en-US.json (Korean)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (English)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Japanese)

* New translations en-US.json (Italian)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (German)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (French) (#324)

* update lock

* ENV -> PRODUCTION

* New Crowdin updates (#327)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Chinese Simplified)

* Make first day of week in calendar view customizable (#263)

* Make first day of the week customizable

New settings section 'Locale settings'
New setting 'First day of week'
New date picker reusable UI that uses the new setting
Meal planner now uses this new date picker

* Clean up unused code in settings page

* Fix First day of week mapping

* Replace missing v-date-picker with custom card DatePicker

* Mention first day of the week feature in change log

* Fix date picker not properly localized (#330)

* Fix language in date picker

Vuetify allows custom-named locales,
but the date-picker really only works with BCP 47 language tag

* Save lang at proper time + Update Vuetify lang on the fly

* Add tip to fix rpi host running docker container (#335)

Per issue #249, tip gives guidance for running Mealie in a docker linux/arm/v7 container.

* New Crowdin updates (#328)

* New translations en-US.json (German)

* New translations en-US.json (Korean)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Japanese)

* New translations en-US.json (French)

* New translations en-US.json (Italian)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (French)

* es-ES.json (#334)

* es-ES.json

Spanish translation

* Update es-ES.json

* feature/editor-improvements (#289)

* pin editor buttons on scroll

* scaler scratch

* fix langauge assignment 1st pass

* set lang on navigate

* refactor/breakup router

* unify style for language selectro

* refactor/code-cleanup

* refactor/page specific components to page folder

* Fix time card layout issue

* fix timecard display

* update mobile cards / fix overflow errors

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#340)

* New translations en-US.json (French)

* New translations en-US.json (French)

* New translations en-US.json (French)

* New translations en-US.json (French)

* New translations en-US.json (Dutch)

* New translations en-US.json (Dutch)

* Document new translation process with Crowdin (#342)

* Localize more dates and texts (#341)

* Localize more dates and texts

* Adapt source language to 4-letter code for VS code

* Make page titles more reactive to language change

* Translate missing text + fix missed refactoring

* Fix missed page titles refactoring

* Translate nutrition view

* Translate Image upload vue

* Fix default text being defined twice in upload btn

* Get Recipes Route Rewrite (#339)

* deprecate old route

* auto-gen

* recipe card infinite scroll

* fix datatable

* set hard-limit option

* add loader

* set scroll on navigation

* add auto-import

* fix slow initial load

* remove console.logs

Co-authored-by: hay-kot <hay-kot@pm.me>

* Fix ingredients not refreshed upon recipe change (#343)

* New Crowdin updates (#344)

* New translations en-US.json (Romanian)

* New translations en-US.json (French)

* New translations en-US.json (Romanian)

* New translations en-US.json (Spanish)

* New translations en-US.json (French)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Arabic)

* New translations en-US.json (Catalan)

* New translations en-US.json (Czech)

* New translations en-US.json (Danish)

* New translations en-US.json (Greek)

* New translations en-US.json (Finnish)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Italian)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Korean)

* New translations en-US.json (Dutch)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Polish)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Russian)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Swedish)

* New translations en-US.json (Japanese)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Italian)

* New translations en-US.json (Spanish)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Arabic)

* New translations en-US.json (Catalan)

* New translations en-US.json (Czech)

* New translations en-US.json (Danish)

* New translations en-US.json (German)

* New translations en-US.json (German)

* New translations en-US.json (Greek)

* New translations en-US.json (Finnish)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Japanese)

* New translations en-US.json (English)

* New translations en-US.json (Korean)

* New translations en-US.json (Dutch)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Polish)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Russian)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Swedish)

* New translations en-US.json (Turkish)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Portuguese, Brazilian)

* New Crowdin updates (#345)

* New translations en-US.json (French)

* New translations en-US.json (German)

* New translations en-US.json (German)

* New translations en-US.json (French)

* New translations en-US.json (German)

* New translations en-US.json (German)

* Fix infinite loop in meal planner randomizer (#346)

Infinite loop would happen if there were more days than recipes

* More localization (#348)

* Translate about page

* Sort messages by keys

* Remove unused strings

* Localize date in meal planner

* Fix quick week not starting on Monday for UTC+x

* New Crowdin updates (#349)

* New translations en-US.json (Dutch)

* New translations en-US.json (Dutch)

* New Crowdin updates (#351)

* New translations en-US.json (German)

* New translations en-US.json (Korean)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Japanese)

* New translations en-US.json (French)

* New translations en-US.json (Italian)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (German)

* New translations en-US.json (French)

* New translations en-US.json (Dutch)

* App Bar Rewrite (#347)

* Dummy Commit

* consolidate sidebar and app bar

* fix image error

* consolidate sidebar

* new icon for user menu

* fixes #329

* fix double click on mobile

* swap to computed properties

* fix open/close bug

* rewrite search for mobile

* fix ingredient checkbox

* cleanup console.logs

* set default lang + bump version

* draft changelog

* reword

* update env variables

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#355)

* New translations en-US.json (German)

* New translations en-US.json (Korean)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Japanese)

* New translations en-US.json (French)

* New translations en-US.json (Italian)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (German)

* New translations en-US.json (French)

* New translations en-US.json (French)

* feature/category-tag-crud (#354)

* update tag route

* search.and

* offset for mobile

* relative imports

* get settings

* new page

* category/tag CRUD

* bulk assign frontend

* Bulk assign

* debounce search

* remove dev data

* recipe store refactor

* fix mobile view

* fix failing tests

* commit test data

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#359)

* New translations en-US.json (German)

* New translations en-US.json (Korean)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Japanese)

* New translations en-US.json (French)

* New translations en-US.json (Italian)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* toolbox reference

* New Crowdin updates (#361)

* New translations en-US.json (Polish)

* New translations en-US.json (Polish)

* New translations en-US.json (Polish)

* New translations en-US.json (German)

* Remove dead code (#362)

* Remove BackupCard.vue

Unused - moved to NewBackupCard.vue

* Remove unused method

* New Crowdin updates (#363)

* New translations en-US.json (French)

* New translations en-US.json (Polish)

* feature/new-recipe-features (#360)

* unify button styles

* fix drag on mobile

* recipe instructions section

* add carbs

* refactor component location

* asset start

* consolidate view/edit components

* asset api

* base dialog event

* Remove 'content'

* remove console.log

* add slug prop

* remove console.log

* recipe assets first pass

* add recipeSettings model

* fix hide/show when no tags/categories

* fix typo

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#365)

* New translations en-US.json (German)

* New translations en-US.json (Korean)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Japanese)

* New translations en-US.json (French)

* New translations en-US.json (Italian)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* refactor/recipe-to-snake-case (#364)

* formatting

* snake case all recipes entries

* set foreign key to int

* run scheduler at startup and not import

* set SQLite file path before imports

Co-authored-by: hay-kot <hay-kot@pm.me>

* fix missed commits

* More localization (#358)

* Translate missing items on About page

* Localize import summary dialog

* Make site menu translation reactive

* Localize import options

* Include semi colon in string

* Move API texts to frontend + better status codes

* Provide feedback to user when no meal is planned

* Fix API tests after latest rework

* Add warning for API changes in changelog

* Refactor API texts handling

* Refactor API texts handling #2

* Better API feedback

* Rearrange strings hierarchy

* Add messages upon recipe updated

* Fix 'recipe effected' typo

* Remove snackbar usage in backend

* Translate toolbox

* Provide feedback for tags CRUD

* Fix messed up merge

* Translate sign-up form

* Better feedback for sign-up CRUD

* Refactor log-in API texts handling

* No error message when user is not authenticated

* Remove unimportant console log

* New Crowdin updates (#366)

* New translations en-US.json (German)

* New translations en-US.json (French)

* New translations en-US.json (Dutch)

* New translations en-US.json (Polish)

* New translations en-US.json (Dutch)

* Hide user ID + Reset password when creating a user (#367)

* refactor/docker-updates (#369)

* convert all images to webp

* consolidate docker files

* serve images wiith caddy

* consolidate docker files

* new slim-buster image

* set image url

* add image path

* remove print

* set image path correctly

* cleanup

* caddy proxy path

* docs

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#368)

* New translations en-US.json (German)

* New translations en-US.json (Korean)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Japanese)

* New translations en-US.json (French)

* New translations en-US.json (Italian)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (French)

* add python3-dev

* add all cryptography deps 🤞

* remove 32bit arm support

* Refactor/recipe routes (#370)

* format with black

* black format

* flake8

* remove bar exceptions

* remove test for depreciated route

* recipe settings editr

* add sqlite

Co-authored-by: hay-kot <hay-kot@pm.me>

* Api refactoring fixes (#372)

* Fix JS error when logging in with bad credentials

* Remove duplicate error message if bad credentials

Error is already nicely displayed in LoginForm

* More localization (#373)

* Translate missing string

* Display language in original language + English

* Translate assets

* Translate recipe settings

* New Crowdin updates (#374)

* New translations en-US.json (German)

* New translations en-US.json (German)

* New translations en-US.json (German)

* New translations en-US.json (French)

* New translations en-US.json (German)

* Shopping list fixes (#376)

* Refactor recipe to snake case

* Initialize raw ingredients

Fixes #356

* New Crowdin updates (#377)

* New translations en-US.json (German)

* New translations en-US.json (Italian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (French)

* New translations en-US.json (Japanese)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Arabic)

* New translations en-US.json (Romanian)

* New translations en-US.json (Spanish)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Catalan)

* New translations en-US.json (Czech)

* New translations en-US.json (Danish)

* New translations en-US.json (Greek)

* New translations en-US.json (Finnish)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (Dutch) (#378)

* New translations en-US.json (French) (#379)

* New Crowdin updates (#380)

* New translations en-US.json (French)

* New translations en-US.json (Dutch)

* New translations en-US.json (Dutch)

* Remove former profile image upon new upload (#381)

* Remove former profile image upon new upload

* Fix test

* feature/additional-db (#371)

* add support for setting db_url

* fix tests

* add db_username/password env variables

* init db if super user doesn't exist

* fix tests

* fix tests

* set SQLite default DB_URL

* don't run tests on draft PRs

* add lint/black tests

* add test-all

* spell check settings

* black/flake8

* check format fail

* new badges

* rename workflow

* fix formatting

* remove white-space

* test connection arguments for pg

* format

* add new values to template

* format

* remove old script

* monkeypatch test db

* working docker-compose for postgres

* update docs

* test pg workflow

* format

* add driver

* install w/ poetry

* setup container

* change image

* set database to localhost

* update tests

* set url

* fix url path

* disable cache

* database init

* bust cache

* get by name

Co-authored-by: hay-kot <hay-kot@pm.me>

* feature/recipe-patch-improvements (#382)

* automated docs update

* recipe rating component

* recipe partial updates - closes #25

* use Vue.delete to update store

* format

* arrow functions

* fix tests

* format

* initial context menu

* localize

* add confirmation dialog

* context menu

* fix bare exception

* update line length

* format all file with prettier

* update changelog

* download as json

* update python dependencies

* update javascript dependencies

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#383)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New Crowdin updates (#385)

* New translations en-US.json (Spanish)

* New translations en-US.json (Spanish)

* New translations en-US.json (French)

* feature/finish-recipe-assets (#384)

* add features to readme

* Copy markdown reference

* prop as whole recipe

* parameter as url instead of query

* add card styling to editor

* move images to /recipes/{slug}/images

* add image to breaking changes

* fix delete and import errors

* fix debug/about response

* logger updates

* dashboard ui

* add server side events

* unorganized routes

* default slot

* add backup viewer to dashboard

* format

* add dialog to backup imports

* initial event support

* delete assets when removed

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#386)

* New translations en-US.json (Romanian)

* New translations en-US.json (Italian)

* New translations en-US.json (Romanian)

* New translations en-US.json (Spanish)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Arabic)

* New translations en-US.json (Catalan)

* New translations en-US.json (Czech)

* New translations en-US.json (Danish)

* New translations en-US.json (Greek)

* New translations en-US.json (Finnish)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Japanese)

* New translations en-US.json (French)

* New translations en-US.json (Korean)

* New translations en-US.json (Dutch)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Polish)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Russian)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Swedish)

* New translations en-US.json (Turkish)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (French)

* New translations en-US.json (Italian)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Arabic)

* New translations en-US.json (Catalan)

* New translations en-US.json (Czech)

* New translations en-US.json (Danish)

* New translations en-US.json (German)

* New translations en-US.json (German)

* New translations en-US.json (Greek)

* New translations en-US.json (Finnish)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Korean)

* New translations en-US.json (Dutch)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Polish)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Russian)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Swedish)

* New translations en-US.json (Turkish)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Portuguese, Brazilian)

* dashboard notes

* fix image display

* New Crowdin updates (#387)

* New translations en-US.json (Italian)

* New translations en-US.json (Italian)

* New translations en-US.json (Italian)

* Refactor/backend routers (#388)

* update router

* update caddy file

* setup depends in docker-fole

* make changes for serving on subpath

* set dev config

* fix router signups

* consolidate links

* backup-functionality to dashboard

* new user card

* consolidate theme into profile

* fix theme tests

* fix pg tests

* fix pg tests

* remove unused import

* mobile margin

Co-authored-by: hay-kot <hay-kot@pm.me>

* feature/new-feature-cleanup (#389)

* add json editor to theme editor

* add toolbars tools to recipe sections

* fix recipe yield

* add updated_date to recipe schema

* update time cards

* fix mobile buttons

* fix asset URL

* fix PG errors CRUD

* remove -d from docker-pro

* fix theme tests

* remvoe old typing

* abstract count function

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#390)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (German)

* New translations en-US.json (French)

* feature/profile-cards (#391)

* unify format

* pass variables

* remove namespace

* rename

* group-card init

* shuffle + icons

* remove console.logs

* token CRUD

* update changelog

* add profile link

* consolidate mealplan to profile dashboard

* update docs

* add query parameter to search page

* update test routes

* update python depts

* basic token tests

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#392)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (French)

* New translations en-US.json (German)

* New translations en-US.json (French)

* New translations en-US.json (Dutch)

* New translations en-US.json (Dutch)

* More localization (#393)

* Translate sidebar

* Do not force 12-hour format worldwide

Vue-i18n knows which locales prefer 12-hour format over 24-hour format

* Translate new tiles in profile page

* Translate new tiles in dashboard

* backend-events + code-cleanup (#395)

* additional server events

* sort 'recent recipes' by updated

* remove duplicate code

* fixes #396

* set color

* consolidate tag/category pages

* set colors

* list unorganized recipes

* cleanup old code

* remove flash message, switch to global snackbar

* cancel to close

* cleanup

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#394)

* New translations en-US.json (Romanian)

* New translations en-US.json (Italian)

* New translations en-US.json (Romanian)

* New translations en-US.json (Spanish)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Arabic)

* New translations en-US.json (Catalan)

* New translations en-US.json (Czech)

* New translations en-US.json (Danish)

* New translations en-US.json (Greek)

* New translations en-US.json (Finnish)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Japanese)

* New translations en-US.json (French)

* New translations en-US.json (Korean)

* New translations en-US.json (Dutch)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Polish)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Russian)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Swedish)

* New translations en-US.json (Turkish)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (French)

* New translations en-US.json (Italian)

* New translations en-US.json (Spanish)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Arabic)

* New translations en-US.json (Catalan)

* New translations en-US.json (Czech)

* New translations en-US.json (Danish)

* New translations en-US.json (German)

* New translations en-US.json (German)

* New translations en-US.json (Greek)

* New translations en-US.json (Finnish)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Korean)

* New translations en-US.json (Dutch)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Polish)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Russian)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Swedish)

* New translations en-US.json (Turkish)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (Polish)

* New translations en-US.json (Polish)

* Feature/event notifications (#399)

* additional server events

* sort 'recent recipes' by updated

* remove duplicate code

* fixes #396

* set color

* consolidate tag/category pages

* set colors

* list unorganized recipes

* cleanup old code

* remove flash message, switch to global snackbar

* cancel to close

* cleanup

* notifications first pass

* test notification

* complete notification feature

* use background tasks

* add url param

* update documentation

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#398)

* New translations en-US.json (Dutch)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* Bug/misc bug fixes (#400)

* potentiall fix #329

* typo

* auto purge events

* image error

* update import dialog

* fix scheduler interval time

* adjust icon position

* check for property

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#401)

* New translations en-US.json (Spanish)

* New translations en-US.json (Spanish)

* New translations en-US.json (French)

* New Crowdin updates (#402)

* New translations en-US.json (French)

* New translations en-US.json (French)

* New translations en-US.json (Dutch)

* More localization (#403)

* Translate toolbox tab headers

* Use plural form in recipe organizer header

* Feature/copy icon (#406)

* add copy tooltip

* transparent scrollbar

* add version to header

* localize

Co-authored-by: hay-kot <hay-kot@pm.me>

* set proper demo link

* New Crowdin updates (#404)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (French)

* New translations en-US.json (Dutch)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* add print-view component (#407)

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#408)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* notification import/export (#413)

Co-authored-by: hay-kot <hay-kot@pm.me>

* fallback to icon when no image (#414)

Co-authored-by: hay-kot <hay-kot@pm.me>

* image bug fix

* Add some padding to search panel (#416)

* New Crowdin updates (#410)

* New translations en-US.json (Dutch)

* New translations en-US.json (Dutch)

* New translations en-US.json (Dutch)

* New translations en-US.json (Dutch)

* New translations en-US.json (Spanish)

* New translations en-US.json (Dutch)

* New translations en-US.json (Dutch)

* feature/mealplanner-rewrite (#417)

* multiple recipes per day

* fix update

* meal-planner rewrite

* disable meal-tests

* spacing

Co-authored-by: hay-kot <hay-kot@pm.me>

* Feature/style unification (#420)

* set global icons

* fixes #419

* button style docs

* category/tag page updates

* dynamic router imports

Co-authored-by: hay-kot <hay-kot@pm.me>

* bug/bug-fixes (#424)

* fix image write/caching

* Caddyfile Caching header

* more aggressive caching

Co-authored-by: hay-kot <hay-kot@pm.me>

* Add web manifest (#422)

This provides a more app-like experience for mobile users that use the
"add to homescreen" functionality of their web browsers.

* TheButton global component (#425)

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#423)

* New translations en-US.json (German)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Dutch)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Spanish)

* New translations en-US.json (Chinese Simplified)

* bug/mobile-fixes (#426)

* search dialog rewrite

* lazy-load shopping list

* fit search bar

* event table

* set urls for static content

Co-authored-by: hay-kot <hay-kot@pm.me>

* feature/mobile-layout (#431)

* lazy load cards

* shopping list recipe search bug

* admin layout fluid

* site loader

* username support

* mobile tabs

* set username at signup

* update user tests

* patch bug on shopping list

* public mealplan links

* support link (I'm a monster)

* icon only on mobile

* padding

Co-authored-by: hay-kot <hay-kot@pm.me>

* Changing docs with reverse proxy (#436)

Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com>

* New Crowdin updates (#432)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (German)

* New translations en-US.json (German)

* New translations en-US.json (Swedish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Swedish)

* Support PWA (#437)

* add PWA

* cleanup

* add offline cache

* Localize new strings (#445)

* New translations en-US.json (French) (#444)

* New Crowdin updates (#447)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* feature/favorite-recipes (#443)

* add favorites options

* bump dependencies

* add badges to all cards

* typo

* remove console.log

* fix site-loader viewport

Co-authored-by: hay-kot <hay-kot@pm.me>

* feature/recipe-comments (#448)

* fix favorite color issue

* db and models for comments

* rename files

* initial UI for comments

* fix format

* import / export

* fixes #428

* format

Co-authored-by: hay-kot <hay-kot@pm.me>

* fix column type

* Bug/general fixes (#450)

* Fix asset link

* remove unused var

* fix no meal-plan returned

* cleanup redundant code

* Fix dates off in UI

* quick set dark/light mode

* user image fixes

Co-authored-by: hay-kot <hay-kot@pm.me>

* fix pwa not working behind an authenticated proxy (#452)

* New Crowdin updates (#449)

* New translations en-US.json (French)

* New translations en-US.json (Dutch)

* New translations en-US.json (Dutch)

* New translations en-US.json (Swedish)

* New translations en-US.json (German)

* New translations en-US.json (Spanish)

* New translations en-US.json (Spanish)

* New translations en-US.json (Catalan)

* Add Dashboard documentation (#466)

Add toolbox documentation in organizing-recipes.md
Update Images for site settings
Update site-settings.md

* New Crowdin updates (#455)

* New translations en-US.json (German)

* New translations en-US.json (German)

* New translations en-US.json (German)

* New translations en-US.json (Dutch)

* Fixed backup, updated backup docu (#430)

* Fixed backup, updated docu

* reformatted

* Bug Fixes (#467)

* fixes #463

* fixes #465

* fixes #461

* fixes #458 key error

* Fixes #459

* Fixes comments shown when printing

* fix meal-image not return on API call

* return better status

* reorganize docs

Co-authored-by: hay-kot <hay-kot@pm.me>

* Add Web Share api to ContextMenu.vue (#462)

* Add Web Share api to ContextMenu.vue. Copy to clipboard is the fallback

* Add Web Share api to ContextMenu.vue. Copy to clipboard is the fallback

* Add translation

* New translations en-US.json (Spanish) (#468)

* docs/update outline (#471)

* docs update

* reorganize

* plausible analytics

Co-authored-by: hay-kot <hay-kot@pm.me>

* Add Dutch language (#473)

* Add Dutch language

* Sort language list alphabetically

Except English which stays on top

* Feature/improve error message on scrape (#476)

* add better feedback on failed scrape

* fix json download link

* add better recipe parser

* dump deps

* fix force open on mobile

* formatting

* rewrite scraper to use new library

* fix failing tests

* bookmarklet support

* bookmarklet instructions

* recipes changelog

Co-authored-by: hay-kot <hay-kot@pm.me>

* fix clean_string error (#481)

* add soft fail user dependency (#479)

* add soft fail user dependency

* filter private recipes on get_recipe_summary

* code clean-up

* restrict single recipe

* cleanup dependencies

* add auto_error oauth2 scheme

* update make file

* update make file

* fix early return

* bump python deps

* restrict category/tags

* format deps

Co-authored-by: hay-kot <hay-kot@pm.me>

* Rewrite Recipe Editor Buttons Bar (#482)

* rewrite editor button row

* add context menu items to recipe page

Co-authored-by: hay-kot <hay-kot@pm.me>

* fixes #485 (#494)

Co-authored-by: hay-kot <hay-kot@pm.me>

* use psycopg2 instead of psycopg2-binary on prod (#483)

* New Crowdin updates (#470)

* New translations en-US.json (German)

* New translations en-US.json (Czech)

* New translations en-US.json (French)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Russian)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Italian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Japanese)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (French)

* New translations en-US.json (Dutch)

* New translations en-US.json (Swedish)

* New translations en-US.json (Dutch)

* New translations en-US.json (Dutch)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (Swedish)

* New translations en-US.json (German)

* New translations en-US.json (French)

* New translations en-US.json (Dutch)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (Swedish)

* New translations en-US.json (Dutch)

* New translations en-US.json (Dutch)

* New translations en-US.json (Polish)

* New translations en-US.json (Polish)

* Documentation (#474)

Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com>

* Docs/v0.5.0 second pass (#496)

* update docs

* use auto-gen routes

* dumb deps

* remove whitespace

* github action to build dev docs container

* no cache

Co-authored-by: hay-kot <hay-kot@pm.me>

* fix build context

* fix context

* change registry

* new flow

* context

* context

* spelling

* add tooltip to fab (#497)

* New Crowdin updates (#498)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Swedish)

* fix unauthorized recipe (#499)

* fix docs links (#500)

* add translate on toggle theme mode (#501)

* Images and demo custom pages (#502)

* Add Database Layer for Recipe Scaling (#506)

* move badge

* fix add individual ingredient

* fix redirect issue

Co-authored-by: hay-kot <hay-kot@pm.me>

* New Crowdin updates (#503)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* fix docs (#505)

* fix docs

* undo makefile alignment

Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com>

* Add Spanish language (#510)

* New translations en-US.json (Spanish)

* Add Spanish language

Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com>

* New Crowdin updates (#508)

* New translations en-US.json (Spanish)

* New translations en-US.json (Swedish)

* Improve Test Coverage (#511)

* add recipe scaling notes

* test theme rename

* fix coverage call to use poetry

* remove print

* remove async

* consolidate test case data

* fix mealplan tests

* remove redundant else

Co-authored-by: hay-kot <hay-kot@pm.me>

* Bug/fix infinite loop (#512)

* fix infinite loop with safe get method

* fix ingredients

Co-authored-by: hay-kot <hay-kot@pm.me>

* Feature/add cofirmation dialogs (#513)

* add category/tag confirmation dialog

* add page delete confirmation

Co-authored-by: hay-kot <hay-kot@pm.me>

* remove old dependencies

* move strip suffix

* build no cache

* Frontend Fixes + Adjust Caddyfile (#518)

* token error handling

* Add additional settings to recipes

* fixes #515

* remove index.html

Co-authored-by: hay-kot <hay-kot@pm.me>

* add prefix

* disable service worker

* reenable sw

* remove service work from webpack

* undo disable sw

* code splitting

* Make string 'Refresh' and 'New update available' translatable (#524)

* Make string 'Refresh' and 'New update available' translatable

* Fix change password string

* More localization (#525)

* More localization

* Localize search dialog

* Fix "about" page title

* Fix Users API Token API path  (#526)

* Fix Users API Token API path

* Change CRLF to LF

* Fix route generation when route contains /api

* New Crowdin updates (#514)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (German)

* New translations en-US.json (Dutch)

* New translations en-US.json (Swedish)

* New translations en-US.json (Spanish)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New translations en-US.json (Swedish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Dutch)

* New translations en-US.json (Spanish)

* New translations en-US.json (French)

* New translations en-US.json (Dutch)

* New translations en-US.json (German)

* New translations en-US.json (Japanese)

* New translations en-US.json (Vietnamese)

* New translations en-US.json (Chinese Traditional)

* New translations en-US.json (Ukrainian)

* New translations en-US.json (Turkish)

* New translations en-US.json (Swedish)

* New translations en-US.json (Serbian (Cyrillic))

* New translations en-US.json (Russian)

* New translations en-US.json (Portuguese)

* New translations en-US.json (Polish)

* New translations en-US.json (Norwegian)

* New translations en-US.json (Dutch)

* New translations en-US.json (Korean)

* New translations en-US.json (Italian)

* New translations en-US.json (French)

* New translations en-US.json (Hungarian)

* New translations en-US.json (Hebrew)

* New translations en-US.json (Finnish)

* New translations en-US.json (Greek)

* New translations en-US.json (Danish)

* New translations en-US.json (Czech)

* New translations en-US.json (Catalan)

* New translations en-US.json (Arabic)

* New translations en-US.json (Afrikaans)

* New translations en-US.json (Spanish)

* New translations en-US.json (Romanian)

* New translations en-US.json (Chinese Simplified)

* New translations en-US.json (Portuguese, Brazilian)

* New Crowdin updates (#528)

* New translations en-US.json (French)

* New translations en-US.json (Dutch)

* New translations en-US.json (Swedish)

* New translations en-US.json (Spanish)

* dev-feature/analyze-bundle (#529)

* add bundle analyzer

* use svg icons - closes #522

* fix recent recipes icon

Co-authored-by: hay-kot <hay-kot@pm.me>

* Docs/finale changelog (#530)

* bump version

* add data loss warning

* request correct image

Co-authored-by: hay-kot <hay-kot@pm.me>

Co-authored-by: hay-kot <hay-kot@pm.me>
Co-authored-by: Nat <nathanynath@yahoo.fr>
Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com>
Co-authored-by: Pedro Mata Rodrigues <pmmatarodrigues@gmail.com>
Co-authored-by: JonasSchubert <jonas.schubert.projects@web.de>
Co-authored-by: Jonas  Schubert <jonas.schubert.1990@web.de>
Co-authored-by: Chris Klann <cklann1@users.noreply.github.com>
Co-authored-by: CMBoii <66680498+CMBoii@users.noreply.github.com>
Co-authored-by: Florian Gareis <TheZoker@users.noreply.github.com>
Co-authored-by: Carey Metcalfe <carey@cmetcalfe.ca>
Co-authored-by: zierbeek <58994651+zierbeek@users.noreply.github.com>
Co-authored-by: wengtad <wengtad93@gmail.com>
Co-authored-by: Kevin Grossmann <mail@kevingrossmann.de>
2021-06-16 21:35:06 -08:00
tklingenberg8472
72e614b6e5 handle recipeInstructions that are given as json objects / name-value pairs (#509) 2021-06-13 10:36:38 -08:00
Wayward One
8abcf0ca4d Issue #337 - Update docs for user env (#338) 2021-04-21 20:08:14 -08:00
476 changed files with 33656 additions and 29017 deletions

View File

@@ -1,6 +1,6 @@
[flake8]
ignore = [
E501 # Line Length - See Black Config in pyproject.toml
E722 # Bare Exception | Temporary
E402 # Import Not at Top of File
]
exclude = _all_models.py

View File

@@ -0,0 +1,30 @@
name: Docker Build Dev Docs
on:
push:
branches:
- dev
jobs:
push_to_registry:
name: Push Docker image to GitHub Packages
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Check out the repo
uses: actions/checkout@v2
- name: Log in to GitHub Docker Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build container image
uses: docker/build-push-action@v2
with:
context: ./docs
push: true
tags: |
ghcr.io/${{ github.repository }}/dev-docs:latest

View File

@@ -44,6 +44,6 @@ jobs:
#
- name: build the image
run: |
docker build --push \
docker build --push --no-cache \
--tag hkotel/mealie:dev \
--platform linux/amd64,linux/arm/v7,linux/arm64 .
--platform linux/amd64,linux/arm64 .

View File

@@ -45,4 +45,4 @@ jobs:
run: |
docker build --push \
--tag hkotel/mealie:latest \
--platform linux/amd64,linux/arm/v7,linux/arm64 .
--platform linux/amd64,linux/arm64 .

View File

@@ -53,4 +53,4 @@ jobs:
run: |
docker build --push \
--tag hkotel/mealie:${{ steps.mealie_version.outputs.tag }} \
--platform linux/amd64,linux/arm/v7,linux/arm64 .
--platform linux/amd64,linux/arm64 .

View File

@@ -8,12 +8,23 @@ on:
branches:
- master
- dev
types: [synchronize, opened, reopened, ready_for_review]
jobs:
tests:
env:
PRODUCTION: false
runs-on: ubuntu-latest
services:
postgres:
image: postgres
env:
POSTGRES_USER: mealie
POSTGRES_PASSWORD: mealie
POSTGRES_DB: mealie
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
ports:
- 5432:5432
steps:
#----------------------------------------------
# check-out repo and set-up python
@@ -32,24 +43,35 @@ jobs:
with:
virtualenvs-create: true
virtualenvs-in-project: true
# #----------------------------------------------
# # load cached venv if cache exists #! This Breaks Stuff
# #----------------------------------------------
# - name: Load cached venv
# id: cached-poetry-dependencies
# uses: actions/cache@v2
# with:
# path: .venv
# key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
#----------------------------------------------
# load cached venv if cache exists
#----------------------------------------------
- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v2
with:
path: .venv
key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
#----------------------------------------------
# install dependencies if cache does not exist
#----------------------------------------------
- name: Install dependencies
run: poetry install
run: |
poetry install
poetry add "psycopg2-binary==2.8.6"
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
#----------------------------------------------
# run test suite
#----------------------------------------------
- name: Run tests
- name: Run Test Suite
run: |
poetry run pytest
make test-all
#----------------------------------------------
# run test suite
#----------------------------------------------
- name: Run Test Suite Postgres
env:
DB_ENGINE: postgres
POSTGRES_SERVER: localhost
run: |
make test-all

62
.gitignore vendored
View File

@@ -3,13 +3,12 @@
*__pycache__/
*.py[cod]
*$py.class
# frontend/.env.development
docs/site/
mealie/temp/*
mealie/temp/api.html
.temp/
*temp/*
.secret
frontend/dist/
dev/data/backups/*
dev/data/debug/*
@@ -17,14 +16,6 @@ dev/data/img/*
dev/data/migration/*
dev/data/users/*
#Exception to keep folders
!mealie/dist/.gitkeep
!dev/data/backups/.gitkeep
!dev/data/backups/dev_sample_data*
!dev/data/debug/.gitkeep
!dev/data/migration/.gitkeep
!dev/data/img/.gitkeep
.DS_Store
node_modules
@@ -148,48 +139,13 @@ ENV/
# mypy
.mypy_cache/
# IDE settings
# .vscode/
# Node Modules
node_modules/
mealie/data/debug/last_recipe.json
*.db
*.sqlite
dev/data/db/test.db
scratch.py
frontend/dist/favicon.ico
frontend/dist/index.html
frontend/dist/css/app.29fe0155.css
frontend/dist/css/chunk-vendors.db944396.css
frontend/dist/fonts/materialdesignicons-webfont.7a44ea19.woff2
frontend/dist/fonts/materialdesignicons-webfont.64d4cf64.eot
frontend/dist/fonts/materialdesignicons-webfont.147e3378.woff
frontend/dist/fonts/materialdesignicons-webfont.174c02fc.ttf
frontend/dist/fonts/roboto-latin-100.5cb7edfc.woff
frontend/dist/fonts/roboto-latin-100.7370c367.woff2
frontend/dist/fonts/roboto-latin-100italic.f8b1df51.woff2
frontend/dist/fonts/roboto-latin-100italic.f9e8e590.woff
frontend/dist/fonts/roboto-latin-300.b00849e0.woff
frontend/dist/fonts/roboto-latin-300.ef7c6637.woff2
frontend/dist/fonts/roboto-latin-300italic.4df32891.woff
frontend/dist/fonts/roboto-latin-300italic.14286f3b.woff2
frontend/dist/fonts/roboto-latin-400.60fa3c06.woff
frontend/dist/fonts/roboto-latin-400.479970ff.woff2
frontend/dist/fonts/roboto-latin-400italic.51521a2a.woff2
frontend/dist/fonts/roboto-latin-400italic.fe65b833.woff
frontend/dist/fonts/roboto-latin-500.020c97dc.woff2
frontend/dist/fonts/roboto-latin-500.87284894.woff
frontend/dist/fonts/roboto-latin-500italic.288ad9c6.woff
frontend/dist/fonts/roboto-latin-500italic.db4a2a23.woff2
frontend/dist/fonts/roboto-latin-700.2735a3a6.woff2
frontend/dist/fonts/roboto-latin-700.adcde98f.woff
frontend/dist/fonts/roboto-latin-700italic.81f57861.woff
frontend/dist/fonts/roboto-latin-700italic.da0e7178.woff2
frontend/dist/fonts/roboto-latin-900.9b3766ef.woff2
frontend/dist/fonts/roboto-latin-900.bb1e4dc6.woff
frontend/dist/fonts/roboto-latin-900italic.28f91510.woff
frontend/dist/fonts/roboto-latin-900italic.ebf6d164.woff2
frontend/dist/js/app.36f2760c.js
frontend/dist/js/app.36f2760c.js.map
frontend/dist/js/chunk-vendors.c93761e4.js
frontend/dist/js/chunk-vendors.c93761e4.js.map
dev/data/backups/dev_sample_data*.zip
!dev/data/backups/test*.zip
dev/data/recipes/*
dev/scripts/output/app_routes.py
dev/scripts/output/javascriptAPI/*

11
.vscode/settings.json vendored
View File

@@ -1,18 +1,19 @@
{
"python.formatting.provider": "black",
"python.pythonPath": ".venv/bin/python3.9",
"python.linting.pylintEnabled": true,
"python.linting.pylintEnabled": false,
"python.linting.enabled": true,
"python.testing.unittestEnabled": false,
"python.testing.nosetestsEnabled": false,
"python.testing.pytestEnabled": true,
"python.testing.autoTestDiscoverOnSaveEnabled": false,
"python.testing.pytestArgs": ["tests"],
"cSpell.enableFiletypes": ["!javascript", "!python"],
"cSpell.enableFiletypes": ["!javascript", "!python", "!yaml"],
"i18n-ally.localesPaths": "frontend/src/locales/messages",
"i18n-ally.sourceLanguage": "en",
"i18n-ally.sourceLanguage": "en-US",
"i18n-ally.enabledFrameworks": ["vue"],
"i18n-ally.keystyle": "nested",
"cSpell.words": ["performant"],
"search.mode": "reuseEditor"
"cSpell.words": ["compression", "hkotel", "performant", "postgres", "webp"],
"search.mode": "reuseEditor",
"python.linting.flake8Enabled": true
}

View File

@@ -6,17 +6,30 @@
:80 {
@proxied path /api/* /docs /openapi.json
root * /app/dist
encode gzip
uri strip_suffix /
@static {
file
path *.ico *.css *.js *.gif *.jpg *.jpeg *.png *.svg *.woff *.woff2 *.webp
}
encode gzip zstd
# Handles Recipe Images / Assets
handle_path /api/media/recipes/* {
header @static Cache-Control max-age=31536000
root * /app/data/recipes/
file_server
}
handle @proxied {
uri strip_suffix /
reverse_proxy http://127.0.0.1:9000
}
handle {
header @static Cache-Control max-age=31536000
root * /app/dist
try_files {path}.html {path} /
file_server
}
}

View File

@@ -1,3 +1,4 @@
# build
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY ./frontend/package*.json ./
@@ -5,50 +6,54 @@ RUN npm install
COPY ./frontend/ .
RUN npm run build
FROM python:3.9-alpine
RUN apk add --no-cache libxml2-dev \
libxslt-dev \
libxml2 caddy \
libffi-dev \
python3 \
python3-dev \
jpeg-dev \
lcms2-dev \
openjpeg-dev \
zlib-dev
FROM python:3.9-slim-buster
ENV PRODUCTION true
EXPOSE 80
WORKDIR /app/
ENV POETRY_VERSION 1.1.6
COPY ./pyproject.toml /app/
RUN apk add --update --no-cache --virtual .build-deps \
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc g++ \
curl \
g++ \
python3-dev \
musl-dev \
gcc \
build-base && \
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | POETRY_HOME=/opt/poetry python && \
cd /usr/local/bin && \
ln -s /opt/poetry/bin/poetry && \
poetry config virtualenvs.create false && \
cd /app/ && poetry install --no-root --no-dev && \
apk --purge del .build-deps
gnupg gnupg2 gnupg1 \
apt-transport-https \
debian-archive-keyring \
debian-keyring \
libpq-dev \
libwebp-dev \
&& curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | apt-key add - \
&& curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee -a /etc/apt/sources.list.d/caddy-stable.list \
&& apt-get update && apt-get install -y --no-install-recommends \
caddy \
&& apt autoremove \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get remove -y curl apt-transport-https debian-keyring g++ gnupg gnupg2 gnupg1
RUN pip install --no-cache-dir "poetry==$POETRY_VERSION"
# project dependencies
WORKDIR /app
COPY pyproject.toml poetry.lock /app/
RUN poetry config virtualenvs.create false
RUN poetry install -E pgsql --no-dev --no-interaction --no-ansi
COPY ./mealie /app/mealie
RUN poetry install --no-dev
RUN poetry config virtualenvs.create false \
&& poetry install -E pgsql --no-dev
#! Future
# COPY ./alembic /app
# COPY alembic.ini /app
COPY ./Caddyfile /app
COPY ./dev/data/templates /app/data/templates
# frontend build
COPY --from=build-stage /app/dist /app/dist
VOLUME [ "/app/data/" ]
RUN chmod +x /app/mealie/run.sh
CMD /app/mealie/run.sh
EXPOSE 80
CMD /app/mealie/run.sh

View File

@@ -1,24 +1,33 @@
FROM python:3
FROM python:3.9-slim-buster
ENV PRODUCTION false
ENV POETRY_VERSION 1.1.6
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc g++ \
curl \
gnupg gnupg2 gnupg1 \
apt-transport-https \
debian-archive-keyring \
debian-keyring \
libwebp-dev \
&& curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | apt-key add - \
&& curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee -a /etc/apt/sources.list.d/caddy-stable.list \
&& apt-get update && apt-get install -y --no-install-recommends \
&& apt autoremove \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get remove -y curl apt-transport-https debian-keyring g++ gnupg gnupg2 gnupg1
RUN pip install --no-cache-dir "poetry==$POETRY_VERSION"
WORKDIR /app/
ENV PRODUCTION false
RUN apt-get update -y && \
apt-get install -y python-pip python-dev
# Install Poetry
RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | POETRY_HOME=/opt/poetry python && \
cd /usr/local/bin && \
ln -s /opt/poetry/bin/poetry && \
poetry config virtualenvs.create false
# Copy poetry.lock* in case it doesn't exist in the repo
COPY ./pyproject.toml /app/
COPY ./mealie /app/mealie
RUN poetry install
RUN poetry config virtualenvs.create false \
&& poetry install
RUN chmod +x /app/mealie/run.sh
CMD ["/app/mealie/run.sh", "reload"]

View File

@@ -4,6 +4,11 @@
[![Issues][issues-shield]][issues-url]
[![MIT License][license-shield]][license-url]
[![Docker Pulls][docker-pull]][docker-pull]
[![CodeFactor](https://www.codefactor.io/repository/github/hay-kot/mealie/badge)](https://www.codefactor.io/repository/github/hay-kot/mealie)
[![Docker Build Production](https://github.com/hay-kot/mealie/actions/workflows/dockerbuild.release.yml/badge.svg)](https://github.com/hay-kot/mealie/actions/workflows/dockerbuild.release.yml)
[![Project Tests Production](https://github.com/hay-kot/mealie/actions/workflows/pytest.yml/badge.svg)](https://github.com/hay-kot/mealie/actions/workflows/pytest.yml)
[![Docker Build Dev](https://github.com/hay-kot/mealie/actions/workflows/dockerbuild.dev.yml/badge.svg?branch=dev)](https://github.com/hay-kot/mealie/actions/workflows/dockerbuild.dev.yml)
[![Project Tests Dev](https://github.com/hay-kot/mealie/actions/workflows/pytest.yml/badge.svg?branch=dev)](https://github.com/hay-kot/mealie/actions/workflows/pytest.yml)
<!-- PROJECT LOGO -->
<br />
@@ -27,7 +32,7 @@
·
<a href="https://github.com/hay-kot/mealie/issues">Report Bug</a>
·
<a href="https://hay-kot.github.io/mealie/api/docs/">API</a>
<a href="https://hay-kot.github.io/mealie/api/redoc/">API</a>
·
<a href="https://github.com/hay-kot/mealie/issues">
Request Feature
@@ -52,14 +57,16 @@ Mealie is a self hosted recipe manager and meal planner with a RestAPI backend a
## Key Features
- 🔍 Fuzzy search
- 🏷️ Tag recipes with categories or tags to flexible sorting
- 🏷️ Tag recipes with categories or tags for flexible sorting
- 🕸 Import recipes from around the web by URL
- 💪 Powerful bulk Category/Tag assignment
- 📱 Beautiful Mobile Views
- 📆 Create Meal Plans
- 🛒 Generate shopping lists
- 🐳 Easy setup with Docker
- 🎨 Customize your interface with color themes layouts
- 💾 Export all your data in any format with Jinja2 Templates, with easy data restoration from the user interface.
- 🎨 Customize your interface with color themes
- 💾 Export all your data in any format with Jinja2 Templates
- 🔒 Keep your data safe with automated backup and easy restore options
- 🌍 localized in many languages
- Plus tons more!
- Flexible API
@@ -89,7 +96,7 @@ As to why we need a database?
<!-- CONTRIBUTING -->
## Contributing
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. Especially test. Literally any tests. See the [Contributors Guide](https://hay-kot.github.io/mealie/contributors/developers-guide/code-contributions/) for help getting started.
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. Especially test. Literally any tests. See the [Contributors Guide](https://hay-kot.github.io/mealie/contributors/non-coders/) for help getting started.
If you are not a coder, you can still contribute financially. financial contributions help me prioritize working on this project over others and helps me know that there is a real demand for project development.

View File

@@ -1,48 +1,41 @@
import json
import re
from enum import Enum
from itertools import groupby
from pathlib import Path
from typing import Optional
import slugify
from fastapi import FastAPI
from humps import camelize
from jinja2 import Template
from mealie.app import app
from pydantic import BaseModel
CWD = Path(__file__).parent
OUT_FILE = CWD.joinpath("output", "app_routes.py")
OUT_DIR = CWD / "output"
OUT_FILE = OUT_DIR / "app_routes.py"
code_template = """
class AppRoutes:
def __init__(self) -> None:
self.prefix = '{{paths.prefix}}'
{% for path in paths.static_paths %}
self.{{ path.router_slug }} = "{{path.prefix}}{{ path.route }}"{% endfor %}
{% for path in paths.function_paths %}
def {{path.router_slug}}(self, {{path.var|join(", ")}}):
return f"{self.prefix}{{ path.route }}"
{% endfor %}
"""
JS_DIR = OUT_DIR / "javascriptAPI"
JS_OUT_FILE = JS_DIR / "apiRoutes.js"
TEMPLATES_DIR = CWD / "templates"
PYTEST_TEMPLATE = TEMPLATES_DIR / "pytest_routes.j2"
JS_REQUESTS = TEMPLATES_DIR / "js_requests.j2"
JS_ROUTES = TEMPLATES_DIR / "js_routes.j2"
JS_INDEX = TEMPLATES_DIR / "js_index.j2"
def get_variables(path):
path = path.replace("/", " ")
print(path)
var = re.findall(r" \{.*\}", path)
print(var)
if var:
return [v.replace("{", "").replace("}", "") for v in var]
else:
return None
JS_DIR.mkdir(exist_ok=True, parents=True)
class RouteObject:
def __init__(self, route_string) -> None:
self.prefix = "/" + route_string.split("/")[1]
self.route = route_string.replace(self.prefix, "")
self.route = "/" + route_string.split("/", 2)[2]
self.js_route = self.route.replace("{", "${")
self.parts = route_string.split("/")[1:]
self.var = re.findall(r"\{(.*?)\}", route_string)
self.is_function = "{" in self.route
self.router_slug = slugify.slugify("_".join(self.parts[1:]), separator="_")
self.router_camel = camelize(self.router_slug)
def __repr__(self) -> str:
return f"""Route: {self.route}
@@ -53,31 +46,96 @@ Slug: {self.router_slug}
"""
def get_paths(app):
class RequestType(str, Enum):
get = "get"
put = "put"
post = "post"
patch = "patch"
delete = "delete"
class HTTPRequest(BaseModel):
request_type: RequestType
description: str = ""
summary: str
tags: list[str]
@property
def summary_camel(self):
return camelize(self.summary)
@property
def js_docs(self):
return self.description.replace("\n", " \n * ")
class PathObject(BaseModel):
route_object: RouteObject
http_verbs: list[HTTPRequest]
class Config:
arbitrary_types_allowed = True
def get_path_objects(app: FastAPI):
paths = []
print(json.dumps(app.openapi()))
for key, value in app.openapi().items():
if key == "paths":
for key, value in value.items():
paths.append(key)
paths.append(
PathObject(
route_object=RouteObject(key),
http_verbs=[HTTPRequest(request_type=k, **v) for k, v in value.items()],
)
)
return paths
def read_template(file: Path):
with open(file, "r") as f:
return f.read()
def generate_template(app):
paths = get_paths(app)
new_paths = [RouteObject(path) for path in paths]
paths = get_path_objects(app)
static_paths = [p for p in new_paths if not p.is_function]
function_paths = [p for p in new_paths if p.is_function]
static_paths = [x.route_object for x in paths if not x.route_object.is_function]
function_paths = [x.route_object for x in paths if x.route_object.is_function]
template = Template(code_template)
static_paths.sort(key=lambda x: x.router_slug)
function_paths.sort(key=lambda x: x.router_slug)
template = Template(read_template(PYTEST_TEMPLATE))
content = template.render(paths={"prefix": "/api", "static_paths": static_paths, "function_paths": function_paths})
with open(OUT_FILE, "w") as f:
f.write(content)
template = Template(read_template(JS_ROUTES))
content = template.render(
paths={"prefix": "/api", "static_paths": static_paths, "function_paths": function_paths, "all_paths": paths}
)
with open(JS_OUT_FILE, "w") as f:
f.write(content)
all_tags = []
for k, g in groupby(paths, lambda x: x.http_verbs[0].tags[0]):
template = Template(read_template(JS_REQUESTS))
content = template.render(paths={"all_paths": list(g), "export_name": camelize(k)})
all_tags.append(camelize(k))
with open(JS_DIR.joinpath(camelize(k) + ".js"), "w") as f:
f.write(content)
template = Template(read_template(JS_INDEX))
content = template.render(files={"files": all_tags})
with open(JS_DIR.joinpath("index.js"), "w") as f:
f.write(content)
if __name__ == "__main__":
generate_template(app)

View File

@@ -1,79 +1,64 @@
# This Content is Auto Generated for Pytest
class AppRoutes:
def __init__(self) -> None:
self.prefix = "/api"
self.prefix = '/api'
self.users_sign_ups = "/api/users/sign-ups"
self.about_events = "/api/about/events"
self.about_events_notifications = "/api/about/events/notifications"
self.about_events_notifications_test = "/api/about/events/notifications/test"
self.auth_refresh = "/api/auth/refresh"
self.auth_token = "/api/auth/token"
self.auth_token_long = "/api/auth/token/long"
self.auth_refresh = "/api/auth/refresh"
self.users = "/api/users"
self.users_self = "/api/users/self"
self.backups_available = "/api/backups/available"
self.backups_export_database = "/api/backups/export/database"
self.backups_upload = "/api/backups/upload"
self.categories = "/api/categories"
self.categories_empty = "/api/categories/empty"
self.debug = "/api/debug"
self.debug_last_recipe_json = "/api/debug/last-recipe-json"
self.debug_log = "/api/debug/log"
self.debug_statistics = "/api/debug/statistics"
self.debug_version = "/api/debug/version"
self.groups = "/api/groups"
self.groups_self = "/api/groups/self"
self.recipes = "/api/recipes"
self.recipes_category = "/api/recipes/category"
self.recipes_tag = "/api/recipes/tag"
self.categories = "/api/categories"
self.recipes_tags = "/api/recipes/tags/"
self.recipes_create = "/api/recipes/create"
self.recipes_create_url = "/api/recipes/create-url"
self.meal_plans_all = "/api/meal-plans/all"
self.meal_plans_create = "/api/meal-plans/create"
self.meal_plans_this_week = "/api/meal-plans/this-week"
self.meal_plans_today = "/api/meal-plans/today"
self.site_settings_custom_pages = "/api/site-settings/custom-pages"
self.meal_plans_today_image = "/api/meal-plans/today/image"
self.migrations = "/api/migrations"
self.recipes_category = "/api/recipes/category"
self.recipes_create = "/api/recipes/create"
self.recipes_create_url = "/api/recipes/create-url"
self.recipes_summary = "/api/recipes/summary"
self.recipes_summary_uncategorized = "/api/recipes/summary/uncategorized"
self.recipes_summary_untagged = "/api/recipes/summary/untagged"
self.recipes_tag = "/api/recipes/tag"
self.recipes_test_scrape_url = "/api/recipes/test-scrape-url"
self.shopping_lists = "/api/shopping-lists"
self.site_settings = "/api/site-settings"
self.site_settings_custom_pages = "/api/site-settings/custom-pages"
self.site_settings_webhooks_test = "/api/site-settings/webhooks/test"
self.tags = "/api/tags"
self.tags_empty = "/api/tags/empty"
self.themes = "/api/themes"
self.themes_create = "/api/themes/create"
self.backups_available = "/api/backups/available"
self.backups_export_database = "/api/backups/export/database"
self.backups_upload = "/api/backups/upload"
self.migrations = "/api/migrations"
self.debug_version = "/api/debug/version"
self.debug_last_recipe_json = "/api/debug/last-recipe-json"
self.users = "/api/users"
self.users_api_tokens = "/api/users/api-tokens"
self.users_self = "/api/users/self"
self.users_sign_ups = "/api/users/sign-ups"
self.utils_download = "/api/utils/download"
def users_sign_ups_token(self, token):
return f"{self.prefix}/users/sign-ups/{token}"
def about_events_id(self, id):
return f"{self.prefix}/about/events/{id}"
def users_id(self, id):
return f"{self.prefix}/users/{id}"
def about_events_notifications_id(self, id):
return f"{self.prefix}/about/events/notifications/{id}"
def users_id_reset_password(self, id):
return f"{self.prefix}/users/{id}/reset-password"
def users_id_image(self, id):
return f"{self.prefix}/users/{id}/image"
def users_id_password(self, id):
return f"{self.prefix}/users/{id}/password"
def groups_id(self, id):
return f"{self.prefix}/groups/{id}"
def categories_category(self, category):
return f"{self.prefix}/categories/{category}"
def recipes_tags_tag(self, tag):
return f"{self.prefix}/recipes/tags/{tag}"
def recipes_recipe_slug(self, recipe_slug):
return f"{self.prefix}/recipes/{recipe_slug}"
def recipes_recipe_slug_image(self, recipe_slug):
return f"{self.prefix}/recipes/{recipe_slug}/image"
def meal_plans_plan_id(self, plan_id):
return f"{self.prefix}/meal-plans/{plan_id}"
def meal_plans_id_shopping_list(self, id):
return f"{self.prefix}/meal-plans/{id}/shopping-list"
def site_settings_custom_pages_id(self, id):
return f"{self.prefix}/site-settings/custom-pages/{id}"
def themes_theme_name(self, theme_name):
return f"{self.prefix}/themes/{theme_name}"
def backups_file_name_delete(self, file_name):
return f"{self.prefix}/backups/{file_name}/delete"
def backups_file_name_download(self, file_name):
return f"{self.prefix}/backups/{file_name}/download"
@@ -81,17 +66,86 @@ class AppRoutes:
def backups_file_name_import(self, file_name):
return f"{self.prefix}/backups/{file_name}/import"
def backups_file_name_delete(self, file_name):
return f"{self.prefix}/backups/{file_name}/delete"
def migrations_type_file_name_import(self, type, file_name):
return f"{self.prefix}/migrations/{type}/{file_name}/import"
def migrations_type_file_name_delete(self, type, file_name):
return f"{self.prefix}/migrations/{type}/{file_name}/delete"
def migrations_type_upload(self, type):
return f"{self.prefix}/migrations/{type}/upload"
def categories_category(self, category):
return f"{self.prefix}/categories/{category}"
def debug_log_num(self, num):
return f"{self.prefix}/debug/log/{num}"
def groups_id(self, id):
return f"{self.prefix}/groups/{id}"
def meal_plans_id(self, id):
return f"{self.prefix}/meal-plans/{id}"
def meal_plans_id_shopping_list(self, id):
return f"{self.prefix}/meal-plans/{id}/shopping-list"
def meal_plans_plan_id(self, plan_id):
return f"{self.prefix}/meal-plans/{plan_id}"
def media_recipes_recipe_slug_assets_file_name(self, recipe_slug, file_name):
return f"{self.prefix}/media/recipes/{recipe_slug}/assets/{file_name}"
def media_recipes_recipe_slug_images_file_name(self, recipe_slug, file_name):
return f"{self.prefix}/media/recipes/{recipe_slug}/images/{file_name}"
def migrations_import_type_file_name_delete(self, import_type, file_name):
return f"{self.prefix}/migrations/{import_type}/{file_name}/delete"
def migrations_import_type_file_name_import(self, import_type, file_name):
return f"{self.prefix}/migrations/{import_type}/{file_name}/import"
def migrations_import_type_upload(self, import_type):
return f"{self.prefix}/migrations/{import_type}/upload"
def recipes_recipe_slug(self, recipe_slug):
return f"{self.prefix}/recipes/{recipe_slug}"
def recipes_recipe_slug_assets(self, recipe_slug):
return f"{self.prefix}/recipes/{recipe_slug}/assets"
def recipes_recipe_slug_image(self, recipe_slug):
return f"{self.prefix}/recipes/{recipe_slug}/image"
def recipes_slug_comments(self, slug):
return f"{self.prefix}/recipes/{slug}/comments"
def recipes_slug_comments_id(self, slug, id):
return f"{self.prefix}/recipes/{slug}/comments/{id}"
def shopping_lists_id(self, id):
return f"{self.prefix}/shopping-lists/{id}"
def site_settings_custom_pages_id(self, id):
return f"{self.prefix}/site-settings/custom-pages/{id}"
def tags_tag(self, tag):
return f"{self.prefix}/tags/{tag}"
def themes_id(self, id):
return f"{self.prefix}/themes/{id}"
def users_api_tokens_token_id(self, token_id):
return f"{self.prefix}/users/api-tokens/{token_id}"
def users_id(self, id):
return f"{self.prefix}/users/{id}"
def users_id_favorites(self, id):
return f"{self.prefix}/users/{id}/favorites"
def users_id_favorites_slug(self, id, slug):
return f"{self.prefix}/users/{id}/favorites/{slug}"
def users_id_image(self, id):
return f"{self.prefix}/users/{id}/image"
def users_id_password(self, id):
return f"{self.prefix}/users/{id}/password"
def users_id_reset_password(self, id):
return f"{self.prefix}/users/{id}/reset-password"
def users_sign_ups_token(self, token):
return f"{self.prefix}/users/sign-ups/{token}"

View File

@@ -0,0 +1,11 @@
git checkout dev
git merge --strategy=ours master # keep the content of this branch, but record a merge
git checkout master
git merge dev # fast-forward master up to the merge
## TODOs
# Create New Branch v0.x.x
# Push Branch Version to Github
# Create Pull Request

View File

@@ -1,27 +0,0 @@
"""
Helper script to download raw recipe data from a URL and dump it to disk.
The resulting files can be used as test input data.
"""
import sys, json, pprint
import requests
import extruct
from scrape_schema_recipe import scrape_url
from w3lib.html import get_base_url
for url in sys.argv[1:]:
try:
data = scrape_url(url)[0]
slug = list(filter(None, url.split("/")))[-1]
filename = f"{slug}.json"
with open(filename, "w") as f:
json.dump(data, f, indent=4, default=str)
print(f"Saved {filename}")
except Exception as e:
print(f"Error for {url}: {e}")
print("Trying extruct instead")
pp = pprint.PrettyPrinter(indent=2)
r = requests.get(url)
base_url = get_base_url(r.text, r.url)
data = extruct.extract(r.text, base_url=base_url)
pp.pprint(data)

View File

@@ -0,0 +1,7 @@
{% for api in files.files %}
import { {{ api }}API } from "./{{api}}.js" {% endfor %}
export const api = {
{% for api in files.files %}
{{api}}: {{api}}API, {% endfor %}
}

View File

@@ -0,0 +1,19 @@
// This Content is Auto Generated
import { API_ROUTES } from "./apiRoutes"
export const {{paths.export_name}}API = { {% for path in paths.all_paths %} {% for verb in path.http_verbs %} {% if path.route_object.is_function %}
/** {{ verb.js_docs }} {% for v in path.route_object.var %}
* @param {{ v }} {% endfor %}
*/
{{ verb.summary_camel }}({{path.route_object.var|join(", ")}}) {
const response = await apiReq.{{ verb.request_type.value }}(API_ROUTES.{{ path.route_object.router_camel }}({{path.route_object.var|join(", ")}}))
return response.data
}, {% else %}
/** {{ verb.js_docs }} {% for v in path.route_object.var %}
* @param {{ v }} {% endfor %}
*/
{{ verb.summary_camel }}() {
const response = await apiReq.{{ verb.request_type.value }}(API_ROUTES.{{ path.route_object.router_camel }})
return response.data
},{% endif %} {% endfor %} {% endfor %}
}

View File

@@ -0,0 +1,7 @@
// This Content is Auto Generated
const prefix = '{{paths.prefix}}'
export const API_ROUTES = { {% for path in paths.static_paths %}
{{ path.router_camel }}: `${prefix}{{ path.route }}`,{% endfor %}
{% for path in paths.function_paths %}
{{path.router_camel}}: ({{path.var|join(", ")}}) => `${prefix}{{ path.js_route }}`,{% endfor %}
}

View File

@@ -0,0 +1,12 @@
# This Content is Auto Generated for Pytest
class AppRoutes:
def __init__(self) -> None:
self.prefix = '{{paths.prefix}}'
{% for path in paths.static_paths %}
self.{{ path.router_slug }} = "{{path.prefix}}{{ path.route }}"{% endfor %}
{% for path in paths.function_paths %}
def {{path.router_slug}}(self, {{path.var|join(", ")}}):
return f"{self.prefix}{{ path.route }}"
{% endfor %}

View File

@@ -3,6 +3,7 @@ version: "3.1"
services:
# Vue Frontend
mealie-frontend:
container_name: mealie-frontend
image: mealie-frontend:dev
build:
context: ./frontend
@@ -18,6 +19,7 @@ services:
# Fast API
mealie-api:
container_name: mealie-api
image: mealie-api:dev
build:
context: ./
@@ -26,7 +28,6 @@ services:
ports:
- 9921:9000
environment:
db_type: sqlite
TZ: America/Anchorage # Specify Correct Timezone for Date/Time to line up correctly.
volumes:
- ./dev/data:/app/dev/data
@@ -34,6 +35,7 @@ services:
# Mkdocs
mealie-docs:
container_name: mealie-docs
image: squidfunk/mkdocs-material
restart: always
ports:

View File

@@ -6,7 +6,21 @@ services:
dockerfile: Dockerfile
container_name: mealie
restart: always
depends_on:
- "postgres"
ports:
- 9090:80
environment:
db_type: sqlite
DB_ENGINE: postgres # Optional: 'sqlite', 'postgres'
POSTGRES_USER: mealie
POSTGRES_PASSWORD: mealie
POSTGRES_SERVER: postgres
POSTGRES_PORT: 5432
POSTGRES_DB: mealie
postgres:
container_name: postgres
image: postgres
restart: always
environment:
POSTGRES_PASSWORD: mealie
POSTGRES_USER: mealie

15
docs/Caddyfile Normal file
View File

@@ -0,0 +1,15 @@
{
auto_https off
}
:80 {
root * /srv
encode gzip
uri strip_suffix /
handle {
try_files {path} {path}/ /index.html
file_server
}
}

10
docs/Dockerfile Normal file
View File

@@ -0,0 +1,10 @@
FROM python:3.8-slim as build-stage
WORKDIR /app
RUN pip install --no-cache-dir mkdocs mkdocs-material
COPY . .
RUN mkdocs build
FROM caddy:alpine
WORKDIR /app
COPY ./Caddyfile /etc/caddy/Caddyfile
COPY --from=build-stage /app/site /srv

11
docs/docker-compose.yml Normal file
View File

@@ -0,0 +1,11 @@
version: "3"
services:
wiki:
container_name: mealie-docs
image: mealie-docs
ports:
- 8888:80
build:
context: .
dockerfile: Dockerfile
restart: always

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 MiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 MiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 MiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@@ -1,233 +0,0 @@
<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="672px" height="802px" viewBox="-0.5 -0.5 672 802" content="&lt;mxfile host=&quot;23d2e92c-1798-4628-b714-afc635cb8bb4&quot; modified=&quot;2021-02-25T18:35:08.654Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Code-Insiders/1.54.0-insider Chrome/87.0.4280.141 Electron/11.3.0 Safari/537.36&quot; etag=&quot;VkjSc3HAwyf7iAB2Toef&quot; version=&quot;14.2.4&quot; type=&quot;embed&quot;&gt;&lt;diagram id=&quot;3j9sfWdaUOHFNAte1u_k&quot; name=&quot;Page-1&quot;&gt;7VvbcuM2Ev0aVW0e7KJ4keRH3zK7VU6tKzOpPKYgEiKxJgkuCVlyvj7duJAgCVnyhJqZeMYPtgg0cenuc7rRkGfBbbH/UJMq+4UnNJ/5XrKfBXcz35/74RL+YMuLbvGuQtWS1izRbV3DR/YnNYK6dcsS2vQEBee5YFW/MeZlSWPRayN1zXd9sQ3P+7NWJKWjho8xycetv7NEZKp1FXld+78pSzMz89zTPWsSP6U135Z6vpkf/Cx/VHdBzFhavslIwndWU3A/C25rzoX6VOxvaY7KNWpT7/18oLddd01LccoLoX7jmeRbapYsFyZejDJwP5UWo7Wge5cJyNqIe+M1zNudgctQXlBRv4DIvm904yzBSj3vOs2HRiaztH6l24g2dtqO3G0YPug9u/cfeMf3X3FWClrfP8N+cKr5LLhp7ebBQ0KajCb6IRNFboREzZ/oLc95DS0lL2HAm5ysaf7IGyYYL6E5pjg4dKBuGbjgw0BgzYXghSVwnbMUOwSvoJXop3YcWFqFKy/2KaLzsmhiQi9hC9uSXm4bWv+hDBrcbFiem9WBo95Hq8CPoH1swNZNhvYfG9Wy2tJhtMUURls6jLbIBWp/3rPd4v9bRNLNhpfiopE0cw0C81W17zrhU4p/fwPdQOcH1E5jBoS14JhKwjRWg1dS/Qqs3OPYYM1MCpa/2JO10sBUFH9LEOU5gAgNDiNs4BcaCmVERkQn2jQ8ZkSAsyEhplRktL6Ez79pafAcXqasTGW/PdeOSRVm5FkOFMe0aYwQjMLq4fAFJXmVk1IutEyG3UiBDU79KWMoIn/F2xp9BveLg+JeSvmwoURs5Rbk5tSq4O0FKdARy3VTWeoFnVedygdoBP8TJ8DM9m3d1FQkRtUEd1H39AlBdHfhI3R3GRP0I7TjVDsAD7RxcPlNLqGesSShALUbye8t4A8y4xhABynQIMUCTxCeifJC/9uj/PH2nYw/9yfYv+9ij/NQPpBqsrxae94ZeJ9vRc5KmMpkQN4pwYBvNixWYaC5JEnBSgZLJgKX+5Z44B9wjq8TDxZniQfXqJ4TA8EvwJZMMqt+STN2s61khBjQuZOGidzUVoWUhAgMDP+i+zjfJorRK2DgHa+T5ick3kcgJl4XZk5lRybHFaR5wmFz9qTWpAfQq8AwVdOGCtE128MrCUxldX/V8jkua00aqkQKluKcUkgt+LaNFgUpiY5E4NJSF2pCGTWubdeToYOUUgUNt/UCqxQ1i1XIqWnMKjoKigWpn2S/5mcdgiHbSZjiKNhLF5Fws99V5PEniTyTUG8YfP3Q4/dDjx86Yo93rtPGCaetb/u0MUHUkWxzLNgcc+rgaLBZnCvYXJ3t8NG8QkuvxJ5rSbFlmht6Q5zUVCfqkvokuUrOtWOQPDGQhsWo3Zo955jTm2iE7DnrzgZVzcFimvfV6C3Va1GbnynOynclcv39uNui75ILm7v1UaPP7IbJXbz93fD4AZff9137i5wgouM0ZiggfgG+SGgdHNCOZYW1UsrDum1oi2n/VbRjzKXqhfPo79LImyJF4FCxi2RWU2j4PBntXZu9eb/SnCDlNxmrPpN3Psl8yhBIbQ3Y4hgYAGhNtcgKQcIIhIRCMRMFVCBB/AeB32S8Fl2OqilADTDTdYOOQtTwg0qKLjn0XsEyxoWsY+BMN2jehG7INpcM1GbcVolkrVNmXWRpx+3U2Q4wLOrIzeCspF2s2Xg7YAaCaaZldALN26y1340AkMn3LqOaLDuKp3vIn5uBku09QL7d30G3cRkKLt8xW76O7FV0FNnuJDiYANvmEsHC9q/aVYYcumMFeC7qMs5YnjyQF8i/oK8R4Bjm6QaAw/4E+JPOQKQW+lIl8HoSH/FNrchOrXNNIPqd+co867V0Vje3IT6+T5FvHo3WvbbpgTTiaOY6ShodHjSBqeeLPosvVmNbz100PsmBJxon/BcdRUmmzgHFs0jnfxEyOoSxOWrowsp8lOya85xiLteTMTjpSQxcyWg7pxvxdgg/yLfuwoGbLA4eE6Qf6EOacjVBhPUM9jMecpKNI89tZAPgE206RfIThSOTqluAH+CdHLxhH7uR77Czq6g4DXbHWe7FTBfbXoOjvl2zsC1vlMbYNtmMLaojQU/23YE5fDOYXUaeBMzjuwCs5D7mDgr9Aei/D+jI/6rReOVEtAXYD13x8R3hbfnNBM+FP7KAW+U/wDZB9PSPh0/fVeqeBGyLca3/oj1sn5D52t8/0JItNUd37w2jiwO3NIcx6rTcJBgd157QRJf6YkaVM7Aygeq0Ssyz7qszHl//D68HpqsljCAzNEsBhyCcxllU6BcQbAv700CtLfoZqEUOUnUZLJzAYMsTbtX6GjhSiB0qyGmkKQgq7CcD5h6/pzQHPU3h5K5bnIHOaJJSEwYamhawq/uu6YaWyTV+1RS9MicNVkEPatFEFVelevSVkUGPHXfUGnFhb1W5pdPIoVPTpqq4z/3hXYrWMzzibaVl0au+ReeDERq+rWOqX+qsNRpnPhho6Q1sDmE+pWI0EBiEvFhi8jK1OXm9ZprOidSAnUu1Gj0NmSdclHyTyPS9foUUPPKLQXN5wiX5xNB8TxCcr8KB6Vafh8Fw8CW9aBirJsJgW1EbLPjQukbyofdZ+5gM5K67un8CyEN/GH/DLwfyE753/wPkh+OW3w9c0dVnBtpoAI6zBVr/1Ug7XpfnXtdkoB0X/uQhp7thPnDMMVd1+ojTjLz23Z5xBtn60vGl7fMdccaVO3nWvDRVgsMG6+q536HJhug+o83gsfu3NYXI7p8Dg/u/AA==&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(255, 255, 255);">
<defs/>
<g>
<rect x="0" y="138" width="70" height="60" fill="none" stroke="none" pointer-events="all"/>
<path d="M 0 190.12 C 0.33 185.06 0.82 180.02 1.48 175 C 1.8 173.47 2.19 171.97 2.66 170.5 C 3.13 168.98 4 167.67 5.14 166.72 C 6.56 165.61 8.15 164.81 9.83 164.35 C 10.51 164.04 11.26 164.04 11.94 164.35 C 16.84 169.6 24.48 169.6 29.38 164.35 C 29.98 164.08 30.64 164.08 31.24 164.35 C 33.19 165.09 35.06 166.07 36.82 167.27 C 34.65 167.54 32.55 168.25 30.62 169.39 C 27.64 171.19 25.41 174.27 24.43 177.95 L 22.92 190.14 Z M 20.17 161.73 C 17.61 161.8 15.14 160.56 13.36 158.3 C 11.58 156.05 10.65 152.98 10.79 149.85 C 10.72 146.76 11.68 143.77 13.45 141.58 C 15.23 139.39 17.66 138.19 20.17 138.26 C 22.78 138 25.35 139.12 27.25 141.33 C 29.14 143.54 30.18 146.64 30.09 149.85 C 30.25 153.1 29.25 156.28 27.34 158.56 C 25.44 160.84 22.83 162 20.17 161.73 Z M 25.84 198 C 26.15 193.52 26.59 189.05 27.17 184.6 C 27.42 182.59 27.8 180.6 28.32 178.66 C 28.64 176.59 29.65 174.75 31.15 173.52 C 32.85 172.3 34.66 171.28 36.55 170.5 C 37.4 170.21 38.32 170.4 39.03 171 C 40.08 172.2 41.31 173.19 42.66 173.92 C 46.02 175.58 49.83 175.58 53.19 173.92 C 54.53 173.16 55.78 172.22 56.9 171.1 C 57.79 170.31 59.01 170.19 60 170.8 C 61.6 171.42 63.13 172.3 64.51 173.42 C 65.8 174.41 66.77 175.86 67.26 177.55 C 68.13 180.7 68.72 183.94 69.03 187.22 C 69.43 190.81 69.76 194.4 70 198 Z M 48.5 167.98 C 42.29 168.13 37.15 161.83 36.99 153.87 C 37.03 150.02 38.26 146.34 40.42 143.65 C 42.58 140.97 45.49 139.5 48.5 139.57 C 54.38 140.09 58.97 146.32 59.02 153.87 C 58.89 161.35 54.33 167.47 48.5 167.98 Z" fill="#e58325" stroke="none" pointer-events="all"/>
<rect x="70" y="138" width="340" height="90" fill="none" stroke="none" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 332px; height: 1px; padding-top: 128px; margin-left: 75px;">
<div style="box-sizing: border-box; font-size: 0; text-align: left; max-height: 100px; overflow: hidden; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
<h1 style="font-size: 18px">
User Groups
</h1>
<p>
User groups, or "family" groups are a collection of users that are associated together. Users belonging to groups will have access to their associated mealplans and associated pages. This is currently the only feature of groups.
</p>
</div>
</div>
</div>
</foreignObject>
<text x="75" y="140" fill="#000000" font-family="Helvetica" font-size="12px">
User Groups...
</text>
</switch>
</g>
<rect x="0" y="10" width="70" height="60" fill="none" stroke="none" pointer-events="all"/>
<path d="M 63.22 68.4 C 63.82 68.4 64.58 67.93 64.58 67.14 C 64.58 66.64 64.03 65.99 63.22 65.99 C 62.34 65.99 61.86 66.7 61.86 67.14 C 61.86 67.83 62.49 68.4 63.22 68.4 Z M 66.39 67.22 C 66.39 68.69 64.91 70 63.27 70 C 61.44 70 60.07 68.65 60.07 67.25 L 60.07 50.06 C 58.43 49.33 56.45 47.65 56.45 44.65 C 56.55 42.25 58.13 40.43 60.07 39.51 L 60.07 44.39 L 63.22 45.99 L 66.39 44.39 L 66.39 39.5 C 68.29 40.34 70 42.32 70 44.78 C 69.95 47.1 68.53 49.03 66.39 50.06 Z M 49.19 69.99 C 48.73 69.99 48.32 69.65 48.32 69.19 L 48.32 57.17 C 48.32 56.81 48.7 56.39 49.17 56.39 L 50.12 56.39 L 50.13 45.21 L 49.77 42.55 L 49.77 38.79 L 52.29 38.79 L 52.3 42.55 L 51.94 45.21 L 51.94 56.39 L 52.85 56.39 C 53.37 56.39 53.74 56.68 53.74 57.21 L 53.74 69.22 C 53.74 69.68 53.33 69.99 52.88 69.99 Z M 27.78 36.63 C 20.5 36.63 14 31.25 14 22.98 C 14 16.57 19.5 10 27.52 10 C 35.36 10 41.1 16.36 41.1 23.29 C 41.1 31.31 34.33 36.63 27.78 36.63 Z M 0 63.51 C 0.63 57.61 1.47 49.54 3.07 45.46 C 3.81 43.61 4.88 42.28 6.61 41.17 C 7.73 40.43 11.72 38.48 12.45 38.16 C 13.73 37.57 15.05 37.26 16.18 38.16 C 22.94 43.46 32.3 43.3 39.15 38.18 C 39.94 37.46 41.21 37.65 42.04 37.94 C 42.97 38.26 45.37 39.46 46.96 40.29 L 46.96 42.69 L 47.32 45.36 L 47.32 54.39 C 46.31 54.92 45.52 55.93 45.52 57.17 L 45.51 63.51 Z" fill="#e58325" stroke="#d79b00" stroke-miterlimit="10" pointer-events="all"/>
<rect x="70" y="10" width="340" height="120" fill="none" stroke="none" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 332px; height: 1px; padding-top: 0px; margin-left: 75px;">
<div style="box-sizing: border-box; font-size: 0; text-align: left; max-height: 130px; overflow: hidden; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
<h1 style="font-size: 18px">
Admins
</h1>
<p>
Mealie admins are super users that have access to all user data (excluding passwords). Perform administrative tasks like adding users, resetting user passwords, backing up the database, migrating data, and managing site settings. Administrators can also access restricted recipes that are marked hidden or uneditable by the user.
</p>
</div>
</div>
</div>
</foreignObject>
<text x="75" y="12" fill="#000000" font-family="Helvetica" font-size="12px">
Admins...
</text>
</switch>
</g>
<rect x="10" y="240" width="60" height="60" fill="none" stroke="none" pointer-events="all"/>
<path d="M 40.01 269.86 C 32.14 269.86 25.13 263.82 25.13 254.55 C 25.13 247.37 31.06 240 39.72 240 C 48.19 240 54.39 247.13 54.39 254.9 C 54.39 263.89 47.08 269.86 40.01 269.86 Z M 10 300 C 10.68 293.37 11.59 284.33 13.32 279.75 C 14.11 277.68 15.27 276.19 17.14 274.95 C 18.35 274.12 22.66 271.93 23.45 271.57 C 24.83 270.91 26.26 270.57 27.48 271.57 C 34.78 277.52 44.88 277.34 52.28 271.6 C 53.14 270.78 54.51 271 55.41 271.32 C 56.82 271.82 61.36 274.29 62.22 274.79 C 64.73 276.3 66.08 278.32 67.09 282.11 C 68.37 287.23 69.13 293.75 70 300 Z" fill="#e58325" stroke="none" pointer-events="all"/>
<rect x="70" y="240" width="340" height="90" fill="none" stroke="none" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 332px; height: 1px; padding-top: 230px; margin-left: 75px;">
<div style="box-sizing: border-box; font-size: 0; text-align: left; max-height: 100px; overflow: hidden; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
<h1 style="font-size: 18px">
Users
</h1>
<p>
A single user created by an Admin that has basic privlages to edit their profile, create and edit recipes they own. Edit recipes that are not hidden and are marked editable.
</p>
</div>
</div>
</div>
</foreignObject>
<text x="75" y="242" fill="#000000" font-family="Helvetica" font-size="12px">
Users...
</text>
</switch>
</g>
<path d="M 10 375 C 10 366.72 23.43 360 40 360 C 47.96 360 55.59 361.58 61.21 364.39 C 66.84 367.21 70 371.02 70 375 L 70 425 C 70 433.28 56.57 440 40 440 C 23.43 440 10 433.28 10 425 Z" fill="#e58325" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 70 375 C 70 383.28 56.57 390 40 390 C 23.43 390 10 383.28 10 375" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/>
<rect x="75" y="360" width="340" height="130" fill="none" stroke="none" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 332px; height: 1px; padding-top: 350px; margin-left: 80px;">
<div style="box-sizing: border-box; font-size: 0; text-align: left; max-height: 140px; overflow: hidden; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
<h1 style="font-size: 18px">
Database Relationships
</h1>
<p>
The basic relationship and ownership is diagramed below. In short users are owners of recipes and groups are the owners of meal-plans. By default all users will be added to the "default" group. If a recipe is added through a migration or through a backup where no user exists ownership will be set to the default Admin.
</p>
</div>
</div>
</div>
</foreignObject>
<text x="80" y="362" fill="#000000" font-family="Helvetica" font-size="12px">
Database Relationships...
</text>
</switch>
</g>
<path d="M 310 710 L 310 693.5 Q 310 680 296.5 680 L 163.5 680 Q 150 680 150 693.5 L 150 710" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 150 710 L 150 786.5 Q 150 800 163.5 800 L 296.5 800 Q 310 800 310 786.5 L 310 710" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<path d="M 150 710 L 310 710" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="18px">
<text x="229.5" y="702.5">
Recipe
</text>
</g>
<g fill="#000000" font-family="Helvetica" pointer-events="none" font-size="16px">
<text x="155.5" y="731.5">
- owners: list[Users]
</text>
<text x="155.5" y="750.5">
- editable: boolean
</text>
<text x="155.5" y="769.5">
- hidden: boolean
</text>
</g>
<path d="M 200 550 L 200 533.5 Q 200 520 186.5 520 L 43.5 520 Q 30 520 30 533.5 L 30 550" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<path d="M 30 550 L 30 626.5 Q 30 640 43.5 640 L 186.5 640 Q 200 640 200 626.5 L 200 550" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<path d="M 30 550 L 200 550" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="18px">
<text x="114.5" y="542.5">
User
</text>
</g>
<g fill="#000000" font-family="Helvetica" pointer-events="none" font-size="16px">
<text x="35.5" y="571.5">
- admin: boolean
</text>
<text x="35.5" y="590.5">
- group: list[Group]
</text>
<text x="35.5" y="609.5">
- recipes: list[Recipe]
</text>
</g>
<path d="M 670 710 L 670 693.5 Q 670 680 656.5 680 L 523.5 680 Q 510 680 510 693.5 L 510 710" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<path d="M 510 710 L 510 786.5 Q 510 800 523.5 800 L 656.5 800 Q 670 800 670 786.5 L 670 710" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<path d="M 510 710 L 670 710" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="18px">
<text x="589.5" y="702.5">
MealPlan
</text>
</g>
<g fill="#000000" font-family="Helvetica" pointer-events="none" font-size="16px">
<text x="515.5" y="731.5">
- group: Group
</text>
</g>
<path d="M 610 550 L 610 533.5 Q 610 520 596.5 520 L 423.5 520 Q 410 520 410 533.5 L 410 550" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<path d="M 410 550 L 410 626.5 Q 410 640 423.5 640 L 596.5 640 Q 610 640 610 626.5 L 610 550" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<path d="M 410 550 L 610 550" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="18px">
<text x="509.5" y="542.5">
Group
</text>
</g>
<g fill="#000000" font-family="Helvetica" pointer-events="none" font-size="16px">
<text x="415.5" y="571.5">
- users: list[Users]
</text>
<text x="415.5" y="590.5">
- mealplans list[MealPlan]
</text>
</g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 98px; height: 1px; padding-top: 570px; margin-left: 271px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; ">
User.group is backfilled by a Groups object
</div>
</div>
</div>
</foreignObject>
<text x="320" y="574" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
User.group is bac...
</text>
</switch>
</g>
<rect x="34" y="636" width="10" height="10" fill="#ffffff" stroke="none" pointer-events="none"/>
<path d="M 39 611 L 39 690 Q 39 700 49 700 L 130.76 700" fill="none" stroke="#e58325" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<path d="M 136.76 700 L 128.76 704 L 130.76 700 L 128.76 696 Z" fill="#e58325" stroke="#e58325" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<rect x="195" y="583" width="10" height="10" fill="#ffffff" stroke="none" pointer-events="none"/>
<path d="M 174 588 L 234 588 Q 244 588 244 578 L 244 550 Q 244 540 254 540 L 391.76 540" fill="none" stroke="#e58325" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<path d="M 397.76 540 L 389.76 544 L 391.76 540 L 389.76 536 Z" fill="#e58325" stroke="#e58325" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<rect x="414" y="634" width="10" height="10" fill="#ffffff" stroke="none" pointer-events="none"/>
<path d="M 419 591 L 419 690 Q 419 700 429 700 L 480 700 Q 490 700 490.88 700 L 491.76 700" fill="none" stroke="#e58325" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<path d="M 497.76 700 L 489.76 704 L 491.76 700 L 489.76 696 Z" fill="#e58325" stroke="#e58325" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 98px; height: 1px; padding-top: 730px; margin-left: 35px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; ">
User.recipes is backfilled by Recipe objects
</div>
</div>
</div>
</foreignObject>
<text x="84" y="734" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
User.recipes is b...
</text>
</switch>
</g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 98px; height: 1px; padding-top: 730px; margin-left: 401px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; ">
Group.mealplan is backfilled by MealPlan objects
</div>
</div>
</div>
</foreignObject>
<text x="450" y="734" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
Group.mealplan is...
</text>
</switch>
</g>
</g>
<switch>
<g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/>
<a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank">
<text text-anchor="middle" font-size="10px" x="50%" y="100%">
Viewer does not support full SVG 1.1
</text>
</a>
</switch>
</svg>

Before

Width:  |  Height:  |  Size: 24 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 482 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

View File

@@ -0,0 +1,30 @@
# vx.x.x COOL TITLE GOES HERE
**App Version: vx.x.x**
**Database Version: vx.x.x**
## Breaking Changes
!!! error "Breaking Changes"
#### Database
#### ENV Variables
## Bug Fixes
- Fixed ...
## Features and Improvements
### General
- New Thing 1
### UI Improvements
-
### Behind the Scenes
- Refactoring...

View File

@@ -0,0 +1,129 @@
# v0.5.0 Too Many Changes!
**App Version: v0.5.0**
**Database Version: v0.5.0**
## Breaking Changes
!!! error "Breaking Changes"
#### Database
Database version has been bumped from v0.4.x -> v0.5.0. You will need to export and import your data. Moving forward, we will be using database migrations (BETA) to do this automatically. Note that you still must backup your data. If you don't, it's entirely possible something may go wrong and you could lose your data on upgrade.
#### Image Directory
the /data/img directory has been depreciated. All images are now stored in the /recipes/{slug}/image directory. Images should be migrated automatically, but you may experience issues related to this change.
#### API Usage
If you have been using the API directly, many of the routes and status codes have changed. You may experience issues with directly consuming the API.
#### Arm/v7 Support
Mealie will no longer build in CI/CD due to a issue with the rust compiler on 32 bit devices. You can reference [this issue on the matrix-org/synapse](https://github.com/matrix-org/synapse/issues/9403){:target="_blank"} Github page that are facing a similar issue. You may still be able to build the docker image you-self.
!!! warning "Potential Data Loss"
With this release comes a major rework of how files are stored on disk and where things belong. Migration of files should be done automatically. We have tested extensively with many different backups and user bases and have found that no one experienced data-loss. HOWEVER, with all the major changes that have occurred, it is vital that to prevent any data-loss you must create a backup and store that backup outside of your mealie instance. If you do not do this, you may lose your data.
## Bug Fixes
- Fixed #25 - Allow changing rating without going into edit
- Fixed #475 - trim whitespace on login
- Fixes #435 - Better Email Regex
- Fixed #428 - Meal Planner now works on iOS devices
- Fixed #419 - Typos
- Fixed #418 - You can now "export" shopping lists
- Fixed #356 - Shopping List items are now grouped
- Fixed #329 - Fixed profile image not loading
- Fixed #461 - Proper JSON serialization on webhooks
- Fixed #332 - Language settings are saved for one browser
- Fixes #281 - Slow Handling of Large Sets of Recipes
- Fixed #356 - Shopping lists generate duplicate items
- Fixed #271 - Slow handling of larger data sets
- Fixed #472, #469, #458, #456 - Improve Recipe Parser
## Features and Improvements
### Highlights
- Recipe Parser
- Recipes can now be imported with a bookmarklet!
- Significant improvement in supported sites with the new [Recipe Scraper Library](https://github.com/hhursev/recipe-scrapers){:target="_blank"}
- UI Debugging now available at `/recipes/debugger`
- Better error messages on failure
- ⚠️ last_recipe.json is now depreciated
- Beta Support for Postgres! 🎉 See the getting started page for details
- Recipe Features
- New button bar for editors with improved accessibility and performance
- Step Sections now supported
- Recipe Assets
- Add Asset image to recipe step
- Additional View Settings.
- Better print support
- New Toolbox Page!
- Bulk assign categories and tags by keyword search
- Title case all Categories or Tags with 1 click
- Create/Rename/Delete Operations for Tags/Categories
- Remove Unused Categories or Tags with 1 click
- Recipe Cards now have a menu button for quick actions!
- Edit
- Delete
- Integrated Share with supported OS/Browsers
- Print
- New Profile Dashboard!
- Edit Your Profile
- Create/Edit Themes
- View other users in your Group
- See what's for dinner
- Manage Long Live API Tokens (New)
- New Admin Dashboard! 🎉
- Now you can get some insight on your application with application statics and events.
- See uncategorized/untagged recipes and organize them!
- Backup/Restore right from your dashboard
- See server side events. Now you can know who deleted your favorite recipe!
- New Event Notifications through the Apprise Library
- Get notified when specific server side events occur
### Meal Planner
- Multiple Recipes per day
- Supports meals without recipes (Enter title and description)
- Generate share-link from created meal-planners
- Shopping lists can be directly generated from the meal plan
### General
- User can now favorite recipes
- New 'Dark' Color Theme Packaged with Mealie
- Updated Recipe Card Sections Toolbar
- New Sort Options (They work this time!)
- Alphabetical
- Rating
- Created Date
- Updated Date
- Shuffle (Random Sort)
- New 'Random' Recipe button on recipe sections. Random recipes are selected from the filtered results below. For example, on the "Cakes" category page, you will only get recipes in the "Cakes" category.
- Rating can be updated without entering the editor - Closes #25
- Updated recipe editor styles and moved notes to below the steps.
- Redesigned search bar
- 'Dinner this week' shows a warning when no meal is planned yet
- 'Dinner today' shows a warning when no meal is planned yet
- More localization
- Start date for Week is now selectable
- Languages are now managed through Crowdin
- Application Bar was Rewritten
- Sidebar can now be toggled everywhere.
- New and improved mobile friendly bottom bar
- Improved styling for search bar in desktop
- Improved search layout on mobile
- Profile image now shown on all sidebars
- Switched from Flash Messages to Snackbar (Removed dependency)
### Performance
- Images are now served up by the Caddy increase performance and offloading some loads from the API server
- Requesting all recipes from the server has been rewritten to refresh less often and manage client side data better.
- All images are now converted to .webp for better compression
### Behind the Scenes
- The database layer has been added for future recipe scaling.
- Black and Flake8 now run as CI/CD checks
- New debian based docker image
- Unified Sidebar Components
- Refactor UI components to fit Vue best practices (WIP)
- The API returns more consistent status codes
- The API returns error code instead of error text when appropriate
- ⚠️ May cause side-effects if you were directly consuming the API

View File

@@ -1,25 +1,26 @@
# Contributing to Mealie
[Please Join the Discord](https://discord.gg/QuStdQGSGK). We are building a community of developers working on the project.
[Please Join the Discord](https://discord.gg/QuStdQGSGK){:target="_blank"}. We are building a community of developers working on the project.
## We Develop with Github
We use github to host code, to track issues and feature requests, as well as accept pull requests.
## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests
Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your pull requests:
## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html){:target="_blank"}, So All Code Changes Happen Through Pull Requests
Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html){:target="_blank"}). We actively welcome your pull requests:
1. Fork the repo and create your branch from `dev`.
2. Read the page in in [dev/dev-notes.md](https://github.com/hay-kot/mealie/blob/master/dev/dev-notes.md) to get an idea on where the project is at.
2. Checkout the Discord, the PRs page, or the Projects page to get an idea of what's already being worked on.
3. If you're interested on working on major changes please get in touch on discord and coordinate with other developers. No sense in doubling up on work if someones already on it.
4. If you've changed APIs, update the documentation.
5. Issue that pull request!
6. If you make changes to the dev branch reflect those changes in the dev/dev-notes.md to keep track of changes. Don't forget to add your name/handle/identifier!
4. Once you've got an idea of what changes you want to make, create a draft PR as soon as you can to let us know what you're working on and how we can help!
5. If you've changed APIs, update the documentation.
6. Issue that pull request!
7. If you make changes to the dev branch reflect those changes in the active changelog to keep track of changes. Don't forget to add your name/handle/identifier!
## Any contributions you make will be under the MIT Software License
In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern.
In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/){:target="_blank"} that covers the project. Feel free to contact the maintainers if that's a concern.
## Report bugs using Github's [issues](https://github.com/hay-kot/mealie/issues)
We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/hay-kot/mealie/issues/new); it's that easy!
## Report bugs using Github's [issues](https://github.com/hay-kot/mealie/issues){:target="_blank"}
We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/hay-kot/mealie/issues/new){:target="_blank"}; it's that easy!
## Write bug reports with detail, background, and sample code
**Great Bug Reports** tend to have:
@@ -27,7 +28,7 @@ We use GitHub issues to track public bugs. Report a bug by [opening a new issue]
- A quick summary and/or background
- Steps to reproduce
- Be specific!
- Give sample code if you can. [This stackoverflow question](http://stackoverflow.com/q/12488905/180626) includes sample code that *anyone* with a base R setup can run to reproduce what I was seeing
- Give sample code if you can. [This stackoverflow question](http://stackoverflow.com/q/12488905/180626){:target="_blank"} includes sample code that *anyone* with a base R setup can run to reproduce what I was seeing
- What you expected would happen
- What actually happens
- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)
@@ -39,4 +40,4 @@ People *love* thorough bug reports. I'm not even kidding.
By contributing, you agree that your contributions will be licensed under its MIT License.
## References
This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md)
This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md){:target="_blank"}

View File

@@ -1,3 +1,7 @@
# Guidelines
TODO
## Python
## Vue
[See The Style Guide](../developers-guide/style-guide.md)

View File

@@ -1,6 +1,6 @@
# Development: Getting Started
After reading through the [Code Contributions Guide](https://hay-kot.github.io/mealie/contributors/developers-guide/code-contributions/) and forking the repo you can start working. This project is developed with :whale: docker and as such you will be greatly aided by using docker for development. It's not necessary but it is helpful.
After reading through the [Code Contributions Guide](../developers-guide/code-contributions.md) and forking the repo you can start working. This project is developed with :whale: docker and as such you will be greatly aided by using docker for development. It's not necessary but it is helpful.
## With Docker
Prerequisites
@@ -8,7 +8,7 @@ Prerequisites
- Docker
- docker-compose
You can easily start the development stack by running `make docker-dev` in the root of the project directory. This will run and build the docker-compose.dev.yml file.
You can easily start the development stack by running `make docker-dev` in the root of the project directory. This will run and build the docker-compose.dev.yml file.
## Without Docker
Prerequisites
@@ -18,32 +18,34 @@ Prerequisites
- Nodejs
- npm
Once the prerequisites are installed you can cd into the project base directory and run `make setup` to install the python and node dependencies. Once that is complete you can run `make backend` and `make vue` to start the backend and frontend servers.
Once the prerequisites are installed you can cd into the project base directory and run `make setup` to install the python and node dependencies. Once that is complete you can run `make backend` and `make frontend` to start the backend and frontend servers.
## Make File Reference
`make setup` installs python and node dependencies
`make backend` Starts the backend server on port `9000`
Run `make help` for reference
`make vue` Starts the frontend server on port `8080`
```
clean-purge ⚠️ Removes All Developer Data for a fresh server start
clean 🧹 Remove all build, test, coverage and Python artifacts
clean-pyc 🧹 Remove Python file artifacts
clean-test 🧹 Remove test and coverage artifacts
test-all 🧪 Check Lint Format and Testing
test 🧪 Run tests quickly with the default Python
lint 🧺 Check style with flake8
coverage ☂️ Check code coverage quickly with the default Python
setup 🏗 Setup Development Instance
backend 🎬 Start Mealie Backend Development Server
frontend 🎬 Start Mealie Frontend Development Server
frontend-build 🏗 Build Frontend in frontend/dist
docs 📄 Start Mkdocs Development Server
docker-dev 🐳 Build and Start Docker Development Stack
docker-prod 🐳 Build and Start Docker Production Stack
code-gen 🤖 Run Code-Gen Scripts
`make mdocs` Starts the documentation server on port `8000`
```
`make docker-dev` Builds docker-compose.dev.yml
## Before you Commit!
`make docker-prod` Builds docker-compose.yml to test for production
Before you commit any changes on the backend/python side you'll want to run `make format` to format all the code with black. `make lint` to check with flake8, and `make test` to run pytests. You can also use `make test-all` to run both `lint` and `test`.
## Trouble Shooting
!!! Error "Symptom: Vue Development Server Wont Start"
**Error:** `TypeError: Cannot read property 'upgrade' of undefined`
**Solution:** You may be missing the `/frontend/.env.development.` The contents should be `VUE_APP_API_BASE_URL=http://127.0.0.1:9921`. This is a reference to proxy the the API requests from Vue to 127.0.0.1 at port 9921 where FastAPI should be running.
!!! Error "Symptom: FastAPI Development Server Wont Start"
**Error:** `RuntimeError: Directory '/app/dist' does not exist`
**Solution:** Create an empty /mealie/dist directory. This directory is served as static content by FastAPI. It is provided during the build process and may be missing in development.
Run into another issue? [Ask for help on discord](https://discord.gg/QuStdQGSGK)
Run into another issue? [Ask for help on discord](https://discord.gg/QuStdQGSGK){:target="_blank"}

View File

@@ -0,0 +1,33 @@
# Style Guide
!!! note
Unifying styles across the application is an ongoing process, we are working on making the site more consistent.
## Button Guidelines
1. Buttons should follow the general color/icon scheme as outlined.
2. All buttons should have an icon on the left side of the button and text on the right.
3. Primary action buttons should be the default Vuetify styling.
4. Primary action buttons should be right aligned
5. Secondary buttons should be `text` or `outlined`. Text is preferred
6. Other buttons should generally be "info" or "primary" color and can take any style type depending on context
### Button Colors and Icons
| Type | Color | Icon |
| ----------- | :------------------ | :------------------------------------------------- |
| Default | `info` or `primary` | None |
| Create/New | `success` | `mdi-plus` or `$globals.icons.create` |
| Update/Save | `success` | `mdi-save-content` or `$globals.icons.save` |
| Edit | `info` | `mdi-square-edit-outline` or `$globals.icons.edit` |
### Example
```html
<v-btn color="primary">
<v-icon left> mdi-plus </v-icon>
Primary Button
</v-btn>
```

View File

@@ -9,7 +9,7 @@ We love your input! We want to make contributing to this project as easy and tra
- Becoming a maintainer
- Help translate to a new language or improve current translations
[Remember to join the Discord and stay in touch with other developers working on the project](https://discord.gg/QuStdQGSGK)!
[Remember to join the Discord and stay in touch with other developers working on the project](https://discord.gg/QuStdQGSGK){:target="_blank"}!
Additionally, you can buy me a coffee and support the project. When I get financial support it helps me know that there's real interest in the project and that it's worth the time to keep developing.

View File

@@ -1,16 +1,21 @@
# Contributing with Translations
Translations can be a great way **for non-coders** to contribute to project.
We use **[Crowdin](https://crowdin.com/project/mealie){:target="_blank"}** to allow several contributors to work on translating Mealie.
You can simply help by voting for your preferred translations, or even by completely translating Mealie into a new language.
Mealie supports a framework for the community to contribute different translations. Translations can be a great way for non-coders to contribute to project.
Translations are regularly pulled from Crowdin and included in each new release.
## My Language Is Missing
If your language is missing, you can add it, by beginning to translate. We use a Vue-i18n in json files. Copy frontend/src/locales/en.json to get started.
Please use Crowdin as much as possible if you have any question/issue regarding a particular string. You can take a look at [Crowdin Knowledge base](https://support.crowdin.com/for-volunteer-translators/){:target="_blank"} if you want to know more about how to use this tool.
## Improving Translations
If your language is missing the translation for some strings, you can help out by adding a translation for that string. If you find a string you think could be improved, please feel free to do so.
## My language is missing in Mealie
Once your language is translated on Crowdin, we need to manually add it in Mealie. If you believe your language is ready for use, please create an issue on GitHub.
## Tooling
Currently we use Vue-i18n for translations. Translations are stored in json format located in [frontend/src/locales](https://github.com/hay-kot/mealie/tree/master/frontend/src/locales).
## I can't find a particular text in Crowdin
There can be several reasons:
- The text you're looking for is outdated: someone has already changed it or it will be removed/changed in the next release.
- It is possible some texts are not translatable (yet) for technical reasons. If you spot one, please reach out to us on [Discord](https://discord.gg/QuStdQGSGK){:target="_blank"} or raise an issue on GitHub.
If you have experience with a good Translation Management System, please feel free to chime in on the [Discord](https://discord.gg/QuStdQGSGK), as such a system could be helpful as the projects grow.
Until then, [i18n Ally for VScode](https://marketplace.visualstudio.com/items?itemName=antfu.i18n-ally) is recommended to aid in translating. It also has a nice feature, which shows translations in-place when editing code.
i18n Ally will also show which languages is missing translations.
## Technical information
We use vue-i18n package for internationalization. Translations are stored in json format located in [frontend/src/locales/messages](https://github.com/hay-kot/mealie/tree/master/frontend/src/locales/messages){:target="_blank"}.
[i18n Ally for VScode](https://marketplace.visualstudio.com/items?itemName=lokalise.i18n-ally){:target="_blank"} is helpful for generating new strings to translate. It also has a nice feature, which shows translations in-place when editing code.

View File

@@ -3,7 +3,7 @@
All recipe data can be imported and exported as necessary from the UI. Under the admin page you'll find the section for using Backups and Exports.
!!! danger
As this is still a **BETA** It is recommended that you backup your data often and store in more than one place. Ad-hear to backup best practices with the [3-2-1 Backup Rule](https://en.wikipedia.org/wiki/Backup). Prior to upgrading you **should** perform a backup to limit any data loss.
As this is still a **BETA** It is recommended that you backup your data often and store in more than one place. Ad-hear to backup best practices with the [3-2-1 Backup Rule](https://en.wikipedia.org/wiki/Backup){:target="_blank"}. Prior to upgrading you **should** perform a backup to limit any data loss.
!!! tip "Mealie data that is saved on backups"
- [x] Recipe Data
@@ -19,7 +19,7 @@ To import a backup it must be in your backups folder. If it is in the backup fol
## Demo
![](../assets/gifs/backup-demo-v1.gif)
![](../../assets/gifs/backup-demo-v1.gif)
## API Examples
You can use the API to create and retrieve backups remotely from any server that can access the Mealie instance. This is useful for easily managing off-site backups via cron-job or other scheduled tasks. You can find interactive documentation for your API at https://your-mealie-instance.com/docs
@@ -38,16 +38,24 @@ curl -X 'POST' \
"settings": true,
"themes": true
},
"template": [
"templates": [
"recipes.md"
]
}'
```
### wget Example
Download a backup with `wget`
First request a file token with curl:
```bash
wget http://localhost:9000/api/backups/{file_name}/download
curl -X 'GET' \
'http://localhost:9000/api/backups/{file_name}/download' \
-H 'accept: application/json' \
-H 'Content-Type: application/json'
```
Then download the file with wget:
```bash
wget http://localhost:9000/api/utils/download?token={fileToken}
```

View File

@@ -1,11 +1,13 @@
# Building Pages
!!! warning
The page building is still experimental and may change. You can provide feedback on any changes you'd like to see on [github](https://github.com/hay-kot/mealie/discussions/229)
The page building is still experimental and may change. You can provide feedback on any changes you'd like to see on [github](https://github.com/hay-kot/mealie/discussions/229){:target="_blank"}
Custom pages can be created to organize multiple categories into a single page. Links to your custom pages are displayed on the home page sidebar and accessible by all users, however only Administrators can create or update pages.
Custom pages can be created to organize multiple categories into a single page. Links to your custom pages are displayed on the home page sidebar and accessible by all users, however only Administrators can create or update pages.
![custom page](../../assets/img/custom-page.webp)
To create a new page. Navigate to the settings page at `/admin/settings` and scroll down to the custom pages section. Here you can create, view, and edit your custom pages. To reorder how they are displayed on the sidebar you can drag and drop the pages into the preferred order.
![create custom page](../../assets/gifs/create-custom-page-demo.gif)
!!! tip
To save the order of pages you must click the save button displayed on the bottom of the Custom Page section. This is not necessary for updating individual page data.

View File

@@ -0,0 +1,16 @@
#Dashboard
The dashboard gives you a quick overview of how your Mealie is doing. There is a 'Recipes' card, an overview of the users and groups, an 'Events' card and a 'Backups' card.
![dashboard](../../assets/img/dashboard.webp)
## Recipes
'Recipes' shows how many recipes you have in your catalogue but also checks if you have any untagged or uncategorized ones. If you click on one of these, you are redirected to the Toolbox where you can further organize these recipes.
## Users
This gives an overview of the total number of users for your Mealie instance. The 'manage users' and 'manage groups' button will redirect you to the [user-management page](../admin/user-management.md).
## Backups
Here you can choose to import an older backup from a previous instance. You could also create a custom backup with your own tag where you can choose for a full backup or only some parts like recipes, users,...
If you click 'create', an automatic backup is generated.

View File

@@ -0,0 +1,19 @@
# Site Settings
Your sites settings panel can only be accessed by administrators. This where you can customize your site for all users.
## Home Page Settings
| Option | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------- |
| Show Recent | To display the recent recipes section on the home page |
| Card Per Section | The amount of cards displayed in each section on the home page |
| Home Page Sections | Category sections to include on the home page |
| Language | The default site language |
| First day of the week | The default start day of the week used in Meal Plans |
| Custom Pages | Create a [custom page](../admin/building-pages.md) which appears in the sidebar with the categories you chose |
![Site Settings Image](../../assets/img/site-settings.webp)

View File

@@ -56,7 +56,7 @@ There are two ways to create users in Mealie.
### Manually Creating a User
In the Manage Users section you are able to create a user by providing the necessary information in the pop-up dialog.
![Create User Image](../assets/img/add-user.png){: align=right style="height:50%;width:50%"}
![Create User Image](../../assets/img/add-user.webp){: align=right style="height:50%;width:50%"}
- User Name
- Email
@@ -69,7 +69,7 @@ When creating users manually, their password will be set from the default assign
### Sign Up Links
You can generate sign-up links in the Manage Users section. Select the "create link" button and provide the name of the link and if the user will be an administrator. Once a link is created it will populate in the table where you'll be able to see all active links, delete a link, and copy the link as needed.
![Sign Up Links Image](../assets/img/sign-up-links.png)
![Sign Up Links Image](../../assets/img/sign-up-links.webp)
!!! tip
When a link is used it is automatically removed from the database.
@@ -77,10 +77,10 @@ You can generate sign-up links in the Manage Users section. Select the "create l
## Creating Groups
You can easily create and manage groups via the frontend in the admin panel under "Manage Users". Navigate to the groups tab and you'll find a "create group" button as well as a list of all groups in your database. To create a group, select the "create group" button and provide a name for the new group. Once created you can now assign users to the new group.
![Group Management Panel](../assets/img/group-manager.png)
![Group Management Panel](../../assets/img/group-manager.png)
!!! tip
User Groups can only be deleted if no users are apart of the group. If you want to delete a group, you must assign the users to another group before removing.
## Password Reset
If a user forgets their password an administrator is able to reset their password through the user management page. In the user table, select edit. In the popup windows click the "Reset Password" to reset a users password to the default. This is either 'MyPassword' or set through an environment variable. See the [Installation Page](/mealie/getting-started/install/) for more details on environmental variables
If a user forgets their password an administrator is able to reset their password through the user management page. In the user table, select edit. In the popup windows click the "Reset Password" to reset a user's password to the default. This is either 'MyPassword' or set through an environment variable. See the [Installation Page](../getting-started/install.md) for more details on environmental variables

View File

@@ -0,0 +1,2 @@
!!! info
This guide was submitted by a community member. Find something wrong? Submit a PR to get it fixed!

View File

@@ -1,5 +1,5 @@
!!! info
This example was submitted by a user. Have an Example? Submit a PR!
This guide was submitted by a community member. Find something wrong? Submit a PR to get it fixed!
Recipes can be imported in bulk from a file containing a list of URLs. This can be done using the following bash or python scripts with the `list` file containing one URL per line.

View File

@@ -1,3 +1,7 @@
!!! info
This guide was submitted by a community member. Find something wrong? Submit a PR to get it fixed!
In a lot of ways, Home Assistant is why this project exists! Since it Mealie has a robust API it makes it a great fit for interacting with Home Assistant and pulling information into your dashboard.
### Get Todays Meal in Lovelace
@@ -5,7 +9,7 @@ Starting in v0.4.1 you are now able to use the uri `/api/meal-plans/today
Here's an example where `sensor.mealie_todays_meal` is pulling in the meal-plan name and I'm using the url to get the image.
![api-extras-gif](../assets/img/home-assistant-card.png)
![api-extras-gif](../../assets/img/home-assistant-card.png)
```yaml
type: picture-entity
@@ -27,4 +31,4 @@ style:
!!! tip
Due to how Home Assistant works with images, I had to include the additional styling to get the images to not appear distorted. This includes and [additional installation](https://github.com/thomasloven/lovelace-card-mod) from HACS.
Due to how Home Assistant works with images, I had to include the additional styling to get the images to not appear distorted. This includes and [additional installation](https://github.com/thomasloven/lovelace-card-mod){:target="_blank"} from HACS.

View File

@@ -1,8 +1,13 @@
# Using iOS Shortcuts with Mealie
![](../assets/img/iphone-image.png){: align=right style="height:400px;width:400px"}
!!! info
This guide was submitted by a community member. Find something wrong? Submit a PR to get it fixed!
User [brasilikum](https://github.com/brasilikum) opened an issue on the main repo about how they had created an [iOS shortcut](https://github.com/hay-kot/mealie/issues/103) for interested users. This is a useful utility for iOS users who browse for recipes in their web browser from their devices.
![](../../assets/img/iphone-image.png){: align=right style="height:400px;width:400px"}
User [brasilikum](https://github.com/brasilikum){:target="_blank"} opened an issue on the main repo about how they had created an [iOS shortcut](https://github.com/hay-kot/mealie/issues/103){:target="_blank"} for interested users. This is a useful utility for iOS users who browse for recipes in their web browser from their devices.
Don't know what an iOS shortcut is? Neither did I! Experienced iOS users may already be familiar with this utility but for the uninitiated, here is the official Apple explanation:
@@ -10,10 +15,10 @@ Don't know what an iOS shortcut is? Neither did I! Experienced iOS users may alr
> A shortcut is a quick way to get one or more tasks done with your apps. The Shortcuts app lets you create your own shortcuts with multiple steps. For example, build a “Surf Time” shortcut that grabs the surf report, gives an ETA to the beach, and launches your surf music playlist.
Basically it is a visual scripting language that lets a user build an automation in a guided fashion. The automation can be [shared with anyone](https://www.icloud.com/shortcuts/6ae356d5fc644cfa8983a3c90f242fbb) but if it is a user creation, you'll have to jump through a few hoops to make an untrusted automation work on your device. In brasilikum's shortcut, you need to make changes for it to work. Recent updates to the project have changed some of the syntax and folder structure since its original creation.
Basically it is a visual scripting language that lets a user build an automation in a guided fashion. The automation can be [shared with anyone](https://www.icloud.com/shortcuts/6ae356d5fc644cfa8983a3c90f242fbb){:target="_blank"} but if it is a user creation, you'll have to jump through a few hoops to make an untrusted automation work on your device. In brasilikum's shortcut, you need to make changes for it to work. Recent updates to the project have changed some of the syntax and folder structure since its original creation.
![screenshot](../assets/img/ios-shortcut-image.jpg){: align=right style="height:500;width:400px"}
![screenshot](../../assets/img/ios-shortcut-image.jpg){: align=right style="height:500;width:400px"}

View File

@@ -0,0 +1,92 @@
# Using SWAG as Reverse Proxy
!!! info
This guide was submitted by a community member. Find something wrong? Submit a PR to get it fixed!
To make the setup of a Reverse Proxy much easier, Linuxserver.io developed [SWAG](https://github.com/linuxserver/docker-swag){:target="_blank"}
SWAG - Secure Web Application Gateway (formerly known as letsencrypt, no relation to Let's Encrypt™) sets up an Nginx web server and reverse proxy with PHP support and a built-in certbot client that automates free SSL server certificate generation and renewal processes (Let's Encrypt and ZeroSSL). It also contains fail2ban for intrusion prevention.
## Step 1: Get a domain
The first step is to grab a dynamic DNS if you don't have your own subdomain already. You can get this from for example [DuckDNS](https://www.duckdns.org){:target="_blank"}.
## Step 2: Set-up SWAG
Then you will need to set up SWAG, the variables of the docker-compose are explained on the Github page of [SWAG](https://github.com/linuxserver/docker-swag){:target="_blank"}.
This is an example of how to set it up using duckdns and docker-compose.
!!! example "docker-compose.yml"
```yaml
version: "2.1"
services:
swag:
image: ghcr.io/linuxserver/swag
container_name: swag
cap_add:
- NET_ADMIN
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Brussels
- URL=<mydomain.duckdns>
- SUBDOMAINS=wildcard
- VALIDATION=duckdns
- CERTPROVIDER= #optional
- DNSPLUGIN= #optional
- DUCKDNSTOKEN=<duckdnstoken>
- EMAIL=<e-mail> #optional
- ONLY_SUBDOMAINS=false #optional
- EXTRA_DOMAINS=<extradomains> #optional
- STAGING=false #optional
volumes:
- /etc/config/swag:/config
ports:
- 443:443
restart: unless-stopped
```
Don't forget to change the <code>mydomain.duckns</code> into your personal domain and the <code>duckdnstoken</code> into your token and remove the brackets.
## Step 3: Change the config files
Navigate to the config folder of SWAG and head to <code>proxy-confs</code>. If you used the example above, you should navigate to: <code>/etc/config/swag/nginx/proxy-confs/</code>.
There are a lot of preconfigured files to use for different apps such as radarr,sonarr,overseerr,...
To use the bundled configuration file, simply rename <code>mealie.subdomain.conf.sample</code> in the proxy-confs folder to <code>mealie.subdomain.conf</code>.
Alternatively, you can create a new file <code>mealie.subdomain.conf</code> in proxy-confs with the following configuration:
!!! example "mealie.subdomain.conf"
```yaml
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mealie.*;
include /config/nginx/ssl.conf;
client_max_body_size 0;
location / {
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app mealie;
set $upstream_port 80;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
}
```
## Step 4: Port-forward port 443
Since SWAG allows you to set up a secure connection, you will need to open port 443 on your router for encrypted traffic. This is way more secure than port 80 for http.
## Step 5: Restart SWAG
When you change anything in the config of Nginx, you will need to restart the container using <code>docker restart swag</code>.
If everything went well, you can now access mealie on the subdomain you configured: mealie.mydomain.duckdns.org

View File

@@ -2,38 +2,17 @@
## Getting a Token
Currently Mealie doesn't support creating a long-live token. You can however get a token from the API. This example was pulled from the automatic API documentation provided by Mealie.
Mealie supports long-live api tokens in the user frontend. See [user settings page](../users-groups/user-settings.md)
### Curl
```bash
curl -X 'POST' \
'https://mealie-demo.hay-kot.dev/api/auth/token' \
-H 'accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=&username=changeme%40email.com&password=demo&scope=&client_id=&client_secret='
```
#### Response
```json
{
"snackbar": {
"text": "User Successfully Logged In",
"type": "success"
},
"access_token": "your-long-token-string",
"token_type": "bearer"
}
```
## Key Components
### Exploring Your Local API
On your local installation you can access interactive API documentation that provides `curl` examples and expected results. This allows you to easily test and interact with your API to identify places to include your own functionality. You can visit the documentation at `http://mealie.yourdomain.com/docs or see the example at the [Demo Site](https://mealie-demo.hay-kot.dev/docs)
On your local installation you can access interactive API documentation that provides `curl` examples and expected results. This allows you to easily test and interact with your API to identify places to include your own functionality. You can visit the documentation at `http://mealie.yourdomain.com/docs` or see the example at the [Demo Site](https://mealie-demo.hay-kot.dev/docs){:target="_blank"}
### Recipe Extras
Recipes extras are a key feature of the Mealie API. They allow you to create custom json key/value pairs within a recipe to reference from 3rd part applications. You can use these keys to contain information to trigger automation or custom messages to relay to your desired device.
For example you could add `{"message": "Remember to thaw the chicken"}` to a recipe and use the webhooks built into mealie to send that message payload to a destination to be processed.
![api-extras-gif](../assets/gifs/api-extras.gif)
![api-extras-gif](../../assets/gifs/api-extras.gif)

View File

@@ -1,13 +1,12 @@
# Installation
To deploy docker on your local network it is highly recommended to use docker to deploy the image straight from dockerhub. Using the docker-compose below you should be able to get a stack up and running easily by changing a few default values and deploying. Currently only SQLite is supported. Postrgres support is planned, however for most loads you may find SQLite performant enough.
To deploy mealie on your local network it is highly recommended to use docker to deploy the image straight from dockerhub. Using the docker-compose below you should be able to get a stack up and running easily by changing a few default values and deploying. You can deploy with either SQLite (default) or Postgres. SQLite is sufficient for most use cases. Additionally, with mealies automated backup and restore functionality, you can easily move between SQLite and Postgres as you wish.
[Get Docker](https://docs.docker.com/get-docker/)
[Get Docker](https://docs.docker.com/get-docker/){:target="_blank"}
[Mealie on Dockerhub](https://hub.docker.com/r/hkotel/mealie)
[Mealie on Dockerhub](https://hub.docker.com/r/hkotel/mealie){:target="_blank"}
- linux/amd64
- linux/arm/v7
- linux/arm64
@@ -16,7 +15,6 @@ Deployment with the Docker CLI can be done with `docker run` and specify the dat
```shell
docker run \
-e DB_TYPE='sqlite' \
-p 9925:80 \
-v `pwd`:'/app/data/' \
hkotel/mealie:latest
@@ -41,27 +39,71 @@ services:
ports:
- 9925:80
environment:
DB_TYPE: sqlite
TZ: America/Anchorage
volumes:
- ./mealie/data/:/app/data
```
## Docker Compose with Postgres *(BETA)*
Postgres support was introduced in v0.5.0. At this point it should be used with caution and frequent backups.
```yaml
version: "3.1"
services:
mealie:
container_name: mealie
image: hkotel/mealie:latest
restart: always
ports:
- 9090:80
environment:
DB_ENGINE: postgres # Optional: 'sqlite', 'postgres'
POSTGRES_USER: mealie
POSTGRES_PASSWORD: mealie
POSTGRES_SERVER: postgres
POSTGRES_PORT: 5432
POSTGRES_DB: mealie
postgres:
container_name: postgres
image: postgres
restart: always
environment:
POSTGRES_PASSWORD: mealie
POSTGRES_USER: mealie
```
## Env Variables
| Variables | Default | Description |
| ---------------- | ------------------ | ----------------------------------------------------------------------------------- |
| DB_TYPE | sqlite | The database type to be used. Current Options 'sqlite' |
| DEFAULT_GROUP | Home | The default group for users |
| DEFAULT_USERNAME | changeme@email.com | The default username for the superuser |
| DEFAULT_PASSWORD | MyPassword | The default password for the superuser |
| TOKEN_TIME | 2 | The time in hours that a login/auth token is valid |
| API_PORT | 9000 | The port exposed by backend API. **do not change this if you're running in docker** |
| API_DOCS | True | Turns on/off access to the API documentation locally. |
| TZ | UTC | Must be set to get correct date/time on the server |
| Variables | Default | Description |
| ----------------- | --------------------- | ----------------------------------------------------------------------------------- |
| DEFAULT_GROUP | Home | The default group for users |
| DEFAULT_EMAIL | changeme@email.com | The default username for the superuser |
| BASE_URL | http://localhost:8080 | Used for Notifications |
| DB_ENGINE | sqlite | Optional: 'sqlite', 'postgres' |
| POSTGRES_USER | mealie | Postgres database user |
| POSTGRES_PASSWORD | mealie | Postgres database password |
| POSTGRES_SERVER | postgres | Postgres database server address |
| POSTGRES_PORT | 5432 | Postgres database port |
| POSTGRES_DB | mealie | Postgres database name |
| TOKEN_TIME | 2 | The time in hours that a login/auth token is valid |
| API_PORT | 9000 | The port exposed by backend API. **do not change this if you're running in docker** |
| API_DOCS | True | Turns on/off access to the API documentation locally. |
| TZ | UTC | Must be set to get correct date/time on the server |
## Raspberry Pi 4
!!! tip "Fatal Python error: init_interp_main: can't initialize time"
Some users experience an problem with running the linux/arm/v7 container on Raspberry Pi 4. This is not a problem with the Mealie container, but with a bug in the hosts Docker installation.
Update the host RP4 using [instructions](https://github.com/linuxserver/docker-papermerge/issues/4#issuecomment-735236388){:target="_blank"}, summarized here:
```shell
wget http://ftp.us.debian.org/debian/pool/main/libs/libseccomp/libseccomp2_2.5.1-1_armhf.deb
sudo dpkg -i libseccomp2_2.5.1-1_armhf.deb
```
## Advanced
@@ -73,17 +115,22 @@ The Docker image provided by Mealie contains both the API and the html bundle in
```
{
auto_https off
auto_https off
admin off
}
:80 {
@proxied path /api/* /docs /openapi.json
root * /app/dist
encode gzip
uri strip_suffix /
handle_path /api/recipes/image/* {
root * /app/data/img/
file_server
}
handle @proxied {
reverse_proxy http://127.0.0.1:9000
}
@@ -98,7 +145,7 @@ The Docker image provided by Mealie contains both the API and the html bundle in
## Deployed without Docker
!!! error "Unsupported Deployment"
If you are experiencing a problem with manual deployment, please do not submit a github issue unless it is related to an aspect of the application. For deployment help, the [discord server](https://discord.gg/QuStdQGSGK) is a better place to find support.
If you are experiencing a problem with manual deployment, please do not submit a github issue unless it is related to an aspect of the application. For deployment help, the [discord server](https://discord.gg/QuStdQGSGK){:target="_blank"} is a better place to find support.
Alternatively, this project is built on Python and SQLite so you may run it as a python application on your server. This is not a supported options for deployment and is only here as a reference for those who would like to do this on their own. To get started you can clone this repository into a directory of your choice and use the instructions below as a reference for how to get started.

View File

@@ -2,7 +2,7 @@
Mealie is a self hosted recipe manager and meal planner with a RestAPI backend and a reactive frontend application built in Vue for a pleasant user experience for the whole family. Easily add recipes into your database by providing the url and Mealie will automatically import the relevant data or add a family recipe with the UI editor. Mealie also provides an API for interactions from 3rd party applications.
[Remember to join the Discord](https://discord.gg/QuStdQGSGK)!
[Remember to join the Discord](https://discord.gg/QuStdQGSGK){:target="_blank"}!
!!! note
In some of the demo gifs the styling may be different than the finale application. demos were done during development prior to finale styling.
@@ -15,7 +15,7 @@ Mealie is a self hosted recipe manager and meal planner with a RestAPI backend a
- 🔍 Fuzzy search
- 🏷️ Tag recipes with categories or tags to flexible sorting
- 🕸 Import recipes from around the web by URL
- 📱 Beautiful Mobile Views
- 📱 Progressive Web App
- 📆 Create Meal Plans
- 🛒 Generate shopping lists
- 🐳 Easy setup with Docker
@@ -26,7 +26,7 @@ Mealie is a self hosted recipe manager and meal planner with a RestAPI backend a
- Flexible API
- Custom key/value pairs for recipes
- Webhook support
- Interactive API Documentation thanks to [FastAPI](https://fastapi.tiangolo.com/) and [Swagger](https://petstore.swagger.io/)
- Interactive API Documentation thanks to [FastAPI](https://fastapi.tiangolo.com/){:target="_blank"} and [Swagger](https://petstore.swagger.io/){:target="_blank"}
- Raw JSON Recipe Editor
- Migration from other platforms
- Chowdown
@@ -36,7 +36,7 @@ Mealie is a self hosted recipe manager and meal planner with a RestAPI backend a
## FAQ
### Why An API?
An API allows integration into applications like [Home Assistant](https://www.home-assistant.io/) that can act as notification engines to provide custom notifications based of Meal Plan data to remind you to defrost the chicken, marinade the steak, or start the CrockPot. Additionally, you can access nearly any backend service via the API giving you total control to extend the application. To explore the API spin up your server and navigate to http://yourserver.com/docs for interactive API documentation.
An API allows integration into applications like [Home Assistant](https://www.home-assistant.io/){:target="_blank"} that can act as notification engines to provide custom notifications based of Meal Plan data to remind you to defrost the chicken, marinade the steak, or start the CrockPot. Additionally, you can access nearly any backend service via the API giving you total control to extend the application. To explore the API spin up your server and navigate to http://yourserver.com/docs for interactive API documentation.
### Why a Database?
Some users of static-site generator applications like ChowDown have expressed concerns about their data being stuck in a database. Considering this is a new project it is a valid concern to be worried about your data. Mealie specifically addresses this concern by provided automatic daily backups that export your data in json, plain-text markdown files, and/or custom Jinja2 templates. **This puts you in controls of how your data is represented** when exported from Mealie, which means you can easily migrate to any other service provided Mealie doesn't work for you.
@@ -48,24 +48,23 @@ As to why we need a database?
## Built With
* [Vue.js](https://vuejs.org/)
* [Vuetify](https://vuetifyjs.com/en/)
* [FastAPI](https://fastapi.tiangolo.com/)
* [Docker](https://www.docker.com/)
* [Vue.js](https://vuejs.org/){:target="_blank"}
* [Vuetify](https://vuetifyjs.com/en/){:target="_blank"}
* [FastAPI](https://fastapi.tiangolo.com/){:target="_blank"}
* [Docker](https://www.docker.com/){:target="_blank"}
<!-- ROADMAP -->
## Road Map
[See Roadmap](/roadmap)
[See Roadmap](../../roadmap.md)
<!-- CONTRIBUTING -->
## Contributing
Contributions are what make the open source community such an amazing place to be learn, develop, and create. Any contributions you make are **greatly appreciated**. See the [Contributors Guide](https://hay-kot.github.io/mealie/contributors/developers-guide/code-contributions/) for help getting started.
Contributions are what make the open source community such an amazing place to be learn, develop, and create. Any contributions you make are **greatly appreciated**. See the [Contributors Guide](../../contributors/non-coders.md) for help getting started.
If you are not a coder, you can still contribute financially. financial contributions help me prioritize working on this project over others and helps me know that there is a real demand for project development.
<a href="https://www.buymeacoffee.com/haykot" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-green.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>

View File

@@ -11,7 +11,7 @@
## Backing Up Your Data
[See Backups and Restore Section](/mealie/site-administration/backups-and-exports/) for details on backing up your data
[See Backups and Restore Section](../admin/backups-and-exports.md) for details on backing up your data
## Docker
For all setups using Docker the updating process look something like this

View File

@@ -0,0 +1,23 @@
# Organizing Recipes
Below are some general guidelines that were considered when creating the organization structure for recipes.
## From The Community
> My categories are mostly based on the 'course' they belong to. Appetizers, Starters, Main course, but also sauces or beverages. When I'm looking for an idea for an every day dinner, I just browse "main course".
>
> My tags are for picking the exact type of meal I'm looking for, based on my mood or my guests' diet, like gluten-free, vegetarian, sweet-sour or casserole. They can also act as sub-categories, like "alcohol" for beverages or "hot meal" for a main course.
>
> User: [sephrat](https://github.com/sephrat){:target="_blank"}
## Structure
!!! tip
Below is a suggestion of guidelines my wife and I use for organizing our recipes within Mealie. Mealie is fairly flexible, so feel free to utilize how you'd like! 👍
In the diagram below you will see what we came up with using the new custom pages feature. The large circles indicate pages, and the rectangles indicate categories. We've grouped several 'like' categories with each other as a way to quickly find similar items.
![Mealie Diagram](../../assets/img/mealie-diagram.webp)

View File

@@ -0,0 +1,139 @@
# Recipes
## URL Import
Adding a recipe can be as easy as clicking in the bottom-right corner, copying the recipe URL into Mealie and letting the web scrapper organize information. Currently this scraper is implemented with [recipe-scrapers](https://github.com/hhursev/recipe-scrapers){:target="_blank"}. You may have mixed results on some websites, especially with blogs or non-specific recipe websites. See the bulk import Option below for another a convenient way to add blog style recipes into Mealie.
!!! tip
You can find a list of some of the supported sites in the recipe-scrapers repo. If you're site isn't supported, you can work with the recipe-scrapers team to implement it and we can down-stream those changes into Mealie.
![](../../assets/gifs/URL-import.gif)
## Using Bookmarklets
You can use bookmarklets to generate a bookmark that will take your current location, and open a new tab that will try to import that URL into Mealie.
You can use a [bookmarklet generator site](https://caiorss.github.io/bookmarklet-maker/){:target="_blank"} and the code below to generate a bookmark for your site. Just change the `http://localhost:8080` to your sites web address and follow the instructions. Note that there is no trailing `/`.
```js
var url = document.URL ;
var mealie = "http://localhost:8080"
var dest = mealie + "/?recipe_import_url=" + url
window.open(dest, '_blank')
```
## Recipe Editor
![edit-recipe](../../assets/img/edit-recipe.webp){: align=right style="height:225px;width:275px"}
Recipes can be edited and created via the UI. This is done with both a form based approach where you have a UI to work with as well as with a in browser JSON Editor. The JSON editor allows you to easily copy and paste data from other sources.
You can also add a custom recipe with the UI editor built into the web view. Using the `+` button on the site.
### Recipe Settings
Settings for a specific recipe can be adjusted in the settings menu inside the editor. Currently the settings supports
- Settings a Recipe to Public/Private
- Show Nutrition Values
- Show Assets
- Landscape Mode (Coming Soon)
!!! note
Recipes set to private will only be displayed when a user is logged in. Currently there is no way to generate a share-link for a private recipe, but it is on the roadmap.
### Recipe Assets
While in the editor you also have an opportunity to upload any asset to your recipe. There are several icons that you can choose from or you can choose an arbitrary file icon. Once uploaded you can view or download the asset when viewing the page.
!!! tip
You can get a link to an asset to embed in a recipe step by select the copy icon in editor mode.
### Bulk Import
Mealie also supports bulk import of recipe instructions and ingredients. Select "Bulk Add" in the editor and paste in your plain text data to be parsed. Each line is treated as one entry and will be appended to the existing ingredients or instructions if they exist. Empty lines will be stripped from the text.
![](../../assets/gifs/bulk-add-demo.gif)
## Schema
Recipes are stored in the json-like format in mongoDB and then sent and edited in json format on the frontend. Each recipes uses [Recipe Schema](https://schema.org/Recipe){:target="_blank"} as a general guide with some additional properties specific to Mealie.
### Example
```json
{
"id": 263,
"name": "Homemade Mac and Cheese Bites",
"slug": "homemade-mac-and-cheese-bites",
"image": "no image",
"description": "These are so simple and the perfect finger food ideal for serving kids and as an appetizer! These are DELICIOUS",
"recipeCategory": [],
"tags": [],
"rating": null,
"dateAdded": "2021-06-07",
"dateUpdated": "2021-06-07T16:23:10.254840",
"recipeYield": null,
"recipeIngredient": [
"½ pound elbow macaroni",
"2 Tablespoons butter",
"2 Tablespoons flour",
"1½ cups milk",
"2 cups shredded sharp cheddar cheese",
"2 ounces cream cheese",
"½ teaspoon salt",
"¼ teaspoon pepper",
"1 egg beaten"
],
"recipeInstructions": [
{
"title": "Preperation",
"text": "Preheat oven to 400 degrees F."
},
{
"title": "",
"text": "Spray mini muffin tins with cooking spray."
},
{
"title": "",
"text": "Cook pasta according to packaged directions and set aside."
},
{
"title": "Cooking",
"text": "In a medium size pan combine butter and flour over medium heat. Whisk until butter is melted and mixture is smooth. Slowly add milk and bring to a simmer. Add 1½ cups of the cheese, cream cheese, salt and pepper. Stir until smooth and creamy. Remove from heat."
},
{
"title": "",
"text": "In a large mixing bowl, carefully stir pasta, cheese sauce, and egg until evenly mixed and pasta is evenly coated."
},
{
"title": "",
"text": "Spoon mac and cheese into mini muffin tins and top each with a small pinch of remaining cheese. Bake at 400 degrees F for 15 minutes or until golden brown."
},
{
"title": "",
"text": "Allow to cool 5 minutes before gently removing the bites."
}
],
"nutrition": {
"calories": null,
"fatContent": null,
"proteinContent": null,
"carbohydrateContent": null,
"fiberContent": null,
"sodiumContent": null,
"sugarContent": null
},
"tools": [],
"totalTime": null,
"prepTime": null,
"performTime": null,
"settings": {
"public": true,
"showNutrition": true,
"showAssets": true,
"landscapeView": true
},
"assets": [],
"notes": [],
"orgURL": "https://www.chef-in-training.com/homemade-mac-and-cheese-bites/",
"extras": {},
"comments": []
}
```

View File

@@ -0,0 +1,59 @@
# External Notifications
## Apprise
Using the [Apprise](https://github.com/caronc/apprise/){:target="_blank"} library Mealie is able to provided notification services for nearly every popular service. Some of our favorites are...
- [Gotify](https://github.com/caronc/apprise/wiki/Notify_gotify){:target="_blank"}
- [Discord](https://github.com/caronc/apprise/wiki/Notify_discord){:target="_blank"}
- [Home Assistant](https://github.com/caronc/apprise/wiki/Notify_homeassistant){:target="_blank"}
- [Matrix](https://github.com/caronc/apprise/wiki/Notify_matrix){:target="_blank"}
- [Pushover](https://github.com/caronc/apprise/wiki/Notify_pushover){:target="_blank"}
But there are some many to choose from! Take a look at their wiki for information on how to create their URL formats and that you can use to create a notification integration in Mealie.
## Subscribe Events
There are several categories of events that mealie logs that can be broadcast with the notifications feature. You can also see a feed of your events in the Admin Dashboard
- General Events
- Application Startup
- Recipe Events
- Create Recipe
- Delete Recipe
- Database Events
- Export/Import
- Database Initialization
- Scheduled Events
- MealPlan Webhooks Sent
- Group Events
- Create/Delete Groups
- User Events
- User Creation
- User Sign-up
- Sign-up Token Creation
- Invalid login attempts
In most cases the events will also provide details on which user performed the action. Now you'll know when your grandma deletes your favorite recipe!
!!! info
This is a new feature and we are still working through all the possibilities of events. if you have an idea for an event let us know!
## Creating a New Notification
New events can be created and viewed in admin Toolbox `/admin/toolbox?tab=event-notifications`. Select the "+ Notification" button and you'll be provided with a dialog. Complete the form using the URL for the service you'd like to connect to. Before saving be sure to use the test feature.
!!! tip
The feedback provided from the test feature is only an indicated of if the URL you provided is valid, not if the message was successfully sent. Be sure to check the notification feed for the test message.
![Add Notification Image](../../assets/img/add-notification.webp)
### Examples
#### Discord
![Discord](../../assets/img/discord-notification-example.webp)
#### Gotify
![Gotify](../../assets/img/gotify-notification-example.webp)

View File

@@ -0,0 +1,17 @@
#Toolbox
The toolbox gives you multiple options to clean-up and organize your recipes. You can get notified through different channels.
You can access it through the 'Settings' menu or through the [dashboard](../admin/dashboard.md).
## Category and Tag Editor
The 'Categories' and 'Tags' tab give you the option to bulk assign categories and tags to multiple recipes. You could also remove the unused ones or title case them all.
![Toolbox-Categories](../../assets/img/Toolbox-Categories.webp)
## Bulk Organize
The 'Organize' tab can be used to show all of the items that do not have any category or tag assigned.
![Toolbox-Organize](../../assets/img/Toolbox-Organize.webp)

View File

@@ -1,13 +1,15 @@
# Meal Planner
## Working with Meal Plans
In Mealie you can create a meal plan based off the calendar inputs on the meal planner page. There is no limit to how long or how short a meal plan is. You may also create duplicate meal plans for the same date range. After selecting your date range, click on the card for each day and search through recipes to find your choice. After selecting a recipe for all meals save the plan. You can also randomly generate meal plans.
## Working with Planner
To edit the meal in a meal plan simply select the edit button on the card in the timeline. Similarly, to delete a meal plan click the delete button on the card in the timeline. Currently there is no support to change the date range in a meal plan.
In Mealie you can create a meal plan based off the calendar inputs on the meal planner page. There is no limit to how long or how short a meal plan is. You may also create duplicate meal plans for the same date range. After selecting your date range, click on the card for each day and search through recipes to find your choice. Add a side-dish if you prefer to. After selecting a recipe for all meals, save the plan. Selecting the 'No Recipe' button will allow you to add an entry without a recipe by providing a title and description
You can also randomly generate meal plans with the dice-button at the bottom.
To edit the meal in a meal plan simply select the edit button on the card in the timeline. Similarly, to delete a meal plan click the delete button on the card in the timeline. Currently, there is no support to change the date range in a meal plan.
## Shopping Lists
For any meal plan created you can view a breakdown of all the ingredients and use an experimental sort function to sort similarly ingredients. This is a very new feature and results of the auto sort may vary.
![](../assets/gifs/meal-plan-demo-v2.gif)
![](../../assets/gifs/meal-planner-demoV3.gif)

View File

@@ -0,0 +1,33 @@
# User Settings
## Profile Settings
In the users profile they are able to:
- Change Display Name
- Change Email
- Update Password
- View Their Group
- Update Profile Picture (Experimental)
- Create API Keys
## Themes
Color themes can be created and set from the UI in the Settings-Profile page. You can select an existing color theme or create a new one. On creation of a new color theme, the default colors will be used, then you can select and save as you'd like. By default, the "default" theme will be loaded for all new users visiting the site. All created color themes are available to all users of the site. Theme Colors will be set for both light and dark modes.
![](../../assets/gifs/theme-demo-v3.gif)
!!! tip
Theme data is stored in local storage in the browser. Calling "Save colors and apply theme will refresh the local storage with the selected theme as well save the theme to the database.
## Group & Meal Plan
In the meal planner section a user can select categories to be used as a part of the random recipe selector in the meal plan creator. If no categories are selected, all recipes will be used
Meal planner webhooks are post requests sent from Mealie to an external endpoint. The body of the message is the Recipe JSON of the scheduled meal. If no meal is schedule, no request is sent. The webhook functionality can be enabled or disabled as well as scheduled. Note that you must "Save" prior to any changes taking affect server side.
## API Key Generation
Users can quickly and easily generate API keys with the user interface. Provide a name for your token and then you are shown 1 time the generated API key. If you ever loose the API key you are not able to identify or retrieve it from the UI.
![API Key Image](../../assets/img/api-key-image-v1.webp)
!!! warning
API keys are stored in plain text in the database.

View File

@@ -1,14 +0,0 @@
# Usage
## Getting a Token
Bla Bla
## Key Components
### Recipe Extras
Recipes extras are a key feature of the Mealie API. They allow you to create custom json key/value pairs within a recipe to reference from 3rd part applications. You can use these keys to contain information to trigger automation or custom messages to relay to your desired device.
For example you could add `{"message": "Remember to thaw the chicken"}` to a recipe and use the webhooks built into mealie to send that message payload to a destination to be processed.
![api-extras-gif](../assets/gifs/api-extras.gif)
Have Ideas? Submit a PR!

View File

@@ -1,8 +0,0 @@
# Organizing Recipes
!!! tip
Below is a suggestion of guidelines my wife and I use for organizing our recipes within Mealie. Mealie is fairly flexible, so feel free to utilize how you'd like! 👍
In the diagram below you will see what we came up with using the new custom pages feature. The large circles indicate pages, and the rectangles indicate categories. We've grouped several 'like' categories with each other as a way to quickly find similar items.
![Mealie Diagram](../../assets/img/MealieDiagram.png)

View File

@@ -1,90 +0,0 @@
# Recipes
## URL Import
Adding a recipe can be as easy as copying the recipe URL into mealie and letting the web scrapper try to pull down the information. Currently this scraper is implemented with [scrape-schema-recipe package](https://pypi.org/project/scrape-schema-recipe/). You may have mixed results on some websites, especially with blogs or non specific recipe websites. See the bulk import Option below for another a convenient way to add blog style recipes into Mealie.
## Recipe Editor
Recipes can be edited and created via the UI. This is done with both a form based approach where you have a UI to work with as well as with a in browser JSON Editor. The JSON editor allows you to easily copy and paste data from other sources.
You can also add a custom recipe with the UI editor built into the web view.
## Bulk Import
Mealie also supports bulk import of recipe instructions and ingredients. Select "Bulk Add" in the editor and paste in your plain text data to be parsed. Each line is treated as one entry and will be appended to the existing ingredients or instructions if they exist. Empty lines will be stripped from the text.
![](../assets/gifs/bulk-add-demo.gif)
## Schema
Recipes are stored in the json-like format in mongoDB and then sent and edited in json format on the frontend. Each recipes uses [Recipe Schema](https://schema.org/Recipe) as a general guide with some additional properties specific to Mealie.
### Example
```json
{
_id: ObjectId('5fcdc3d715f131e8b191f642'),
name: 'Oat and Pecan Brittle Cookies',
description: 'A gorgeously textured cookie with crispy-edges, a chewy center, toasty pecans, and tiny crispy pecan brittle bits throughout.',
image: 'oat-and-pecan-brittle-cookies.jpg',
recipeYield: 'Makes about 18',
recipeIngredient: [
'1¼ cups (142 g) coarsely chopped pecans',
'¾ cup (150 g) granulated sugar',
'4 Tbsp. (½ stick) unsalted butter',
'½ tsp. baking soda',
'½ tsp. Diamond Crystal or ¼ tsp. Morton kosher salt',
'1 cup (2 sticks) unsalted butter, cut into 16 pieces, divided',
'1 cups (173 g) all-purpose flour',
'2 tsp. Diamond Crystal or 1 tsp. Morton kosher salt',
'1 tsp. baking soda',
'2 cups (200 g) old-fashioned oats, divided',
'¾ cup (packed; 150 g) dark brown sugar',
'½ cup (100 g) granulated sugar',
'2 large eggs',
'1 Tbsp. vanilla extract'
],
recipeInstructions: [
{
'@type': 'HowToStep',
text: 'Place a rack in middle of oven; preheat to 350°. Toast pecans on a small rimmed baking sheet, tossing halfway through, until slightly darkened and fragrant, 810 minutes. Let cool.'
},
{
'@type': 'HowToStep',
text: 'Line another small rimmed baking sheet with a Silpat baking mat. Cook granulated sugar, butter, and 2 Tbsp. water in a small saucepan over medium-low heat, stirring gently with a heatproof rubber spatula, until sugar is dissolved. Increase heat to medium and bring syrup to a rapid simmer. Cook, without stirring, swirling pan often, until syrup turns a deep amber color, 810 minutes. Immediately remove saucepan from heat and stir in pecans. Once pecans are well coated, add baking soda and salt and stir to incorporate (mixture will foam and sputter as baking soda aerates caramel). Working quickly (it will harden fast), scrape mixture onto prepared baking sheet and spread into a thin layer. Let cool completely, 510 minutes. Chop into pea-size pieces; set aside.'
},
{
'@type': 'HowToStep',
text: 'Place half of butter (½ cup) in the bowl of a stand mixer. Bring remaining butter to a boil in a small saucepan over medium-low heat, stirring often with a heatproof rubber spatula. Cook, scraping bottom and sides of pan constantly, until butter sputters, foams, and, eventually, you see browned bits floating on the surface, 57 minutes. Pour brown butter over butter in stand mixer bowl, making sure to scrape in all the browned bits. Let sit until butter begins to resolidify, about 30 minutes.'
},
{
'@type': 'HowToStep',
text: 'Pulse flour, salt, and baking soda in a food processor to combine. Add half of reserved pecan brittle and 1 cup oats; process in long pulses until oats and brittle are finely ground.'
},
{
'@type': 'HowToStep',
text: 'Add brown sugar and granulated sugar to butter and beat with paddle attachment on medium speed until light and smooth but not fluffy, about 2 minutes. Scrape down sides of bowl and add eggs and vanilla. Beat until very light and satiny, about 1 minute. Scrape down sides of bowl and add flour mixture; beat on low speed until no dry spots remain and you have a soft, evenly mixed dough. Add remaining half of brittle and remaining 1 cup oats; mix on low speed just to distribute. Fold batter several times with a spatula to ensure everything is evenly mixed.'
},
{
'@type': 'HowToStep',
text: 'Using a 2-oz. scoop or ¼-cup measuring cup, scoop level portions of dough to make 18 cookies. Place on a parchment-lined baking sheet, spacing as close together as possible (youll space them out before baking). Cover tightly with plastic wrap and chill at least 12 hours and up to 2 days. (If youre pressed for time, a couple hours will do; cookies just wont be as chewy.)'
},
{
'@type': 'HowToStep',
text: 'When ready to bake, place racks in upper and lower thirds of oven; preheat to 350°. Line 2 large rimmed baking sheets with parchment paper. Arrange 6 cookies on each prepared baking sheet, spacing at least 3" apart.'
},
{
'@type': 'HowToStep',
text: 'Bake cookies, rotating baking sheets top to bottom and front to back after 12 minutes, until dark golden brown around the edges, 1620 minutes. Let cookies cool 5 minutes on baking sheets, then transfer cookies to a wire rack with a spatula and let cool completely.'
},
{
'@type': 'HowToStep',
text: 'Carefully move a rack to middle of oven. Arrange remaining dough on one of the baking sheets (its okay if its still warm). Bake as before (this batch might go a bit faster).\nDo ahead: Dough can be formed 2 months ahead; chill dough balls at least 2 hours before transferring to freezer. Once frozen solid, store in resealable plastic freezer bags and keep frozen. No need to thaw before baking, but you may need to add a minute or two to the baking time. Cookies can be baked 5 days ahead; store airtight at room temperature.'
}
],
slug: 'oat-and-pecan-brittle-cookies',
tags: [],
categories: [],
dateAdded: ISODate('2020-12-07T05:55:35.434Z'),
notes: [],
orgURL: 'https://www.bonappetit.com/recipe/oat-and-pecan-brittle-cookies',
rating: 3
}
```

View File

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
{% extends "base.html" %} {% block analytics %}
<script
async
defer
data-domain="hay-kot.github.io/mealie"
src="https://plausible.io/js/plausible.js"
></script>
{% endblock %}

View File

@@ -1,7 +1,7 @@
# Development Road Map
## Feature Requests
See the [Github META issue for tracking feature requests](https://github.com/hay-kot/mealie/issues/122)
See the [Github META issue for tracking feature requests](https://github.com/hay-kot/mealie/issues/122){:target="_blank"}
## Progress
See the [Github Projects](https://github.com/hay-kot/mealie/projects) to see what is currently being worked on
See the [Github Projects](https://github.com/hay-kot/mealie/projects){:target="_blank"} to see what is currently being worked on

View File

@@ -1,18 +0,0 @@
# Site Settings
Your sites settings panel can only be accessed by administrators. This where you can customize your site for all users.
## Home Page Settings
| Option | Description |
| ------------------ | -------------------------------------------------------------- |
| Language | The default site language |
| Show Recent | To display the recent recipes section on the home page |
| Card Per Section | The amount of cards displayed in each section on the home page |
| Home Page Sections | Category sections to include on the home page |
![Site Settings Image](../assets/img/site-settings.png)

View File

@@ -1,25 +0,0 @@
# User Settings
A user will be able to access 3 sections in their admin panel. The user profile, themes, group/meal-plan settings section.
## Profile Settings
In as users profile they are able to
- Change Display Name
- Change Email
- Update Password
- View Their Group
- Upgrade Profile Picture (Experimental)
## Themes
Color themes can be created and set from the UI in the users settings page. You can select an existing color theme or create a new one. On creation of a new color theme, the default colors will be used, then you can select and save as you'd like. By default the "default" theme will be loaded for all new users visiting the site. All created color themes are available to all users of the site. Theme Colors will be set for both light and dark modes.
![](../assets/gifs/theme-demo-v2.gif)
!!! tip
Theme data is stored in local storage in the browser. Calling "Save colors and apply theme will refresh the local storage with the selected theme as well save the theme to the database.
## Group & Meal Plan
In the meal planner section a user can select categories to be used as apart of the random recipe selector in the meal plan creator. If no categories are selected, all recipes will be used
Meal planner webhooks are post requests sent from Mealie to an external endpoint. The body of the message is the Recipe JSON of the scheduled meal. If no meal is schedule, no request is sent. The webhook functionality can be enabled or disabled as well as scheduled. Note that you must "Save" prior to any changes taking affect server side.

View File

@@ -1,5 +1,7 @@
site_name: Mealie
demo_url: https://mealie-demo.hay-kot.dev/
site_url: https://hay-kot.github.io/mealie/
use_directory_urls: true
theme:
palette:
# Light mode
@@ -17,7 +19,7 @@ theme:
custom_dir: docs/overrides
features:
- navigation.top
- navigation.instant
# - navigation.instant
- navigation.expand
- navigation.sections
- navigation.tabs
@@ -49,24 +51,36 @@ repo_name: hay-kot/mealie
nav:
- Home: "index.md"
- Getting Started:
- Introduction: "getting-started/introduction.md"
- Installation: "getting-started/install.md"
- Updating: "getting-started/updating.md"
- Working With Recipes: "getting-started/recipes.md"
- Organizing Recipes: "getting-started/organizing-recipes.md"
- Planning Meals: "getting-started/meal-planner.md"
- iOS Shortcuts: "getting-started/ios.md"
- Site Administration:
- User Settings: "site-administration/user-settings.md"
- Site Settings: "site-administration/site-settings.md"
- Building Pages: "site-administration/building-pages.md"
- User Management: "site-administration/user-management.md"
- Backups and Restore: "site-administration/backups-and-exports.md"
- Recipe Migration: "site-administration/migration-imports.md"
- API Usage:
- Getting Started: "api-usage/getting-started.md"
- Home Assistant: "api-usage/home-assistant.md"
- Bulk Url Import: "api-usage/bulk-url-import.md"
- Introduction: "documentation/getting-started/introduction.md"
- Installation: "documentation/getting-started/install.md"
- Updating: "documentation/getting-started/updating.md"
- API: "documentation/getting-started/api-usage.md"
- Recipes:
- Working With Recipes: "documentation/recipes/recipes.md"
- Organizing Recipes: "documentation/recipes/organizing-recipes.md"
- Users & Groups:
- User Settings: "documentation/users-groups/user-settings.md"
- Planning Meals: "documentation/users-groups/meal-planner.md"
- Admin:
- Dashboard: "documentation/admin/dashboard.md"
- Site Settings: "documentation/admin/site-settings.md"
- Building Pages: "documentation/admin/building-pages.md"
- User Management: "documentation/admin/user-management.md"
- Backups and Restore: "documentation/admin/backups-and-exports.md"
- Recipe Migration: "documentation/admin/migration-imports.md"
- Toolbox:
- External Notifications: "documentation/toolbox/notifications.md"
- Organization Tools: "documentation/toolbox/organize-tools.md"
- Community Guides:
- iOS Shortcuts: "documentation/community-guide/ios.md"
- Reverse Proxy (SWAG): "documentation/community-guide/swag.md"
- Home Assistant: "documentation/community-guide/home-assistant.md"
- Bulk Url Import: "documentation/community-guide/bulk-url-import.md"
- API Reference: "api/redoc.md"
- Contributors Guide:
- Non-Code: "contributors/non-coders.md"
@@ -75,8 +89,10 @@ nav:
- Code Contributions: "contributors/developers-guide/code-contributions.md"
- Dev Getting Started: "contributors/developers-guide/starting-dev-server.md"
- Guidelines: "contributors/developers-guide/general-guidelines.md"
- Style Guide: "contributors/developers-guide/style-guide.md"
- Development Road Map: "roadmap.md"
- Change Log:
- v0.5.0 General Upgrades: "changelog/v0.5.0.md"
- v0.4.3 Hot Fix: "changelog/v0.4.3.md"
- v0.4.2 Backend/Migrations: "changelog/v0.4.2.md"
- v0.4.1 Frontend/UI: "changelog/v0.4.1.md"

View File

@@ -1 +1,2 @@
VUE_APP_API_BASE_URL=http://localhost:9000
VUE_APP_API_BASE_URL=http://localhost:9000
PREVIEW_BUNDLE=true

View File

@@ -1,5 +1,3 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
presets: ["@vue/cli-plugin-babel/preset"],
};

20090
frontend/package-lock.json generated
View File

File diff suppressed because it is too large Load Diff

View File

@@ -10,36 +10,37 @@
},
"dependencies": {
"@adapttive/vue-markdown": "^4.0.1",
"@smartweb/vue-flash-message": "^0.6.10",
"axios": "^0.21.1",
"core-js": "^3.9.1",
"fast-levenshtein": "^3.0.0",
"core-js": "^3.14.0",
"fuse.js": "^6.4.6",
"qs": "^6.9.6",
"register-service-worker": "^1.7.1",
"typeface-roboto": "^1.1.13",
"v-jsoneditor": "^1.4.2",
"vue": "^2.6.11",
"v-jsoneditor": "^1.4.4",
"vue": "^2.6.14",
"vue-i18n": "^8.24.1",
"vue-router": "^3.5.1",
"vuedraggable": "^2.24.3",
"vuetify": "^2.4.6",
"vuetify": "^2.5.3",
"vuex": "^3.6.2",
"vuex-persistedstate": "^4.0.0-beta.3"
},
"devDependencies": {
"@intlify/vue-i18n-loader": "^1.1.0",
"@mdi/font": "^5.9.55",
"@vue/cli-plugin-babel": "^4.5.11",
"@vue/cli-plugin-eslint": "^4.5.11",
"@vue/cli-service": "^4.5.11",
"@mdi/js": "^5.9.55",
"@vue/cli-plugin-babel": "^4.5.13",
"@vue/cli-plugin-eslint": "^4.5.13",
"@vue/cli-plugin-pwa": "~4.5.0",
"@vue/cli-service": "^4.5.13",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"sass": "^1.32.8",
"sass": "^1.34.1",
"sass-loader": "^8.0.2",
"vue-cli-plugin-i18n": "~1.0.1",
"vue-cli-plugin-vuetify": "^2.2.2",
"vue-template-compiler": "^2.6.11",
"vue-cli-plugin-vuetify": "^2.4.1",
"vue-cli-plugin-webpack-bundle-analyzer": "^4.0.0",
"vue-template-compiler": "^2.6.14",
"vuetify-loader": "^1.7.2"
},
"eslintConfig": {
@@ -56,15 +57,16 @@
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
],
"prettier": {
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": false
}
"singleQuote": false,
"printWidth": 120
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

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