v0.3.0 Release Candidate (#176)
* Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog * Dropping Mongo From Dev Branch (#89) * Fix link to Docker Hub Found an extra s. DESTROYED it. * initial pass * second pass cleanup * backup card framework * backup card functionality * translation * upload button vile creation * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * dev bug: change data location to prevent reloads * api docs * api docs bug * workflow update Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * Add French Translation (#93) * New tests (#94) * dev-bug: fixed vscode freezes * test: refactor database init to support tests Co-authored-by: Hayden <hay-kot@pm.me> * Mealplan CRUD Tests (#95) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing Co-authored-by: Hayden <hay-kot@pm.me> * Fix typos (#96) * Settings, Themes and Migration Route Tests (#100) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing Co-authored-by: Hayden <hay-kot@pm.me> * Refactor + New Docker File (#105) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding Co-authored-by: Hayden <hay-kot@pm.me> * Meal planner improvements (#107) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding * mealplan redesign Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#108) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#113) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript * UI updates + name validation * docs: changelog + sp * fixed route links * changelog Co-authored-by: Hayden <hay-kot@pm.me> * fixed menu links * fixed poetry install on docker.dev build * Migration redesign (#119) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes Co-authored-by: Hayden <hay-kot@pm.me> * Fix link to dev-notes.md (#110) * translation: add swedish (#128) * language: da is Danish * translations: add swedish * scraper: unescape html in instructions (#129) Some urls erroneously deliver escaped html their instructions, sometimes they are even escaped on multiple levels like here: https://www.ica.se/recept/kladdig-kladdkaka-722982/ ``` >>> normalize_instruction("S&auml;tt ugnen p&aring; 200&deg;C.") 'Sätt ugnen på 200°C.' ``` * v0.2.0 Updates (#130) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes * test todos * bug/added docker volume * chowdow test data * partial image recipe image testing * added card section card * settings form * homepage cetegory ui * frontend category placeholder * fixed broken scheduler * remove old files * removed temp test Co-authored-by: Hayden <hay-kot@pm.me> * Fix missing translations key (#133) * translation: add simplified & traditional chinese * Fix missing translations * fix chinese translations * v0.2.0 Release Candidate (#141) * Fix link to Docker Hub Found an extra s. DESTROYED it. * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * notes hot fix * bug: mongo updates fail #99 * Fix error message (#101) * gh funding * Create Issue Templates (#125) * Create bug_report.md * Create config.yml Included a link to feature requests. * Update config.yml Fixed link I had for testing to the actual link * Update bug_report.md fix capitalization * Update .github/ISSUE_TEMPLATE/bug_report.md Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * merge kentors changes * refactor/recipe routers * category/tag database relationship and endpoints * frontend category management * update branch todos * bug/normalize recipe steps html * remove console.log + refactor categories * fix categories database errors * refactor/ router endpoint * refactor/ remove old code * drag and drop ingredients * general cleanup * route refactoring * changelog * api refactoring + random cleanup * fixed backwards sort * Update mkdocs.yml (#137) Fix warning from Deploy Docs github action * fixed navigate on enter in search * refactor/create global css * added category scroll * cleanup todos * debug routes * docs/new gifs & general updates * cleanup * fix list test Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * fix build * fix duplicate editor * fixed docker mount problem * python 3.9 * added tasks for non-docker development * remove old scripts * dev updates * fixed no image upload option * get version from backend * final docs pass * .gitignore * feature/markdown support for description and steps * package-lock * rename production task * category import errors on import (#150) Co-authored-by: hay-kot <hay-kot@pm.me> * Feature/improved notifications (#152) * category import errors on import * Import Error Hotfix (#148) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog * Dropping Mongo From Dev Branch (#89) * Fix link to Docker Hub Found an extra s. DESTROYED it. * initial pass * second pass cleanup * backup card framework * backup card functionality * translation * upload button vile creation * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * dev bug: change data location to prevent reloads * api docs * api docs bug * workflow update Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * Add French Translation (#93) * New tests (#94) * dev-bug: fixed vscode freezes * test: refactor database init to support tests Co-authored-by: Hayden <hay-kot@pm.me> * Mealplan CRUD Tests (#95) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing Co-authored-by: Hayden <hay-kot@pm.me> * Fix typos (#96) * Settings, Themes and Migration Route Tests (#100) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing Co-authored-by: Hayden <hay-kot@pm.me> * Refactor + New Docker File (#105) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding Co-authored-by: Hayden <hay-kot@pm.me> * Meal planner improvements (#107) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding * mealplan redesign Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#108) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#113) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript * UI updates + name validation * docs: changelog + sp * fixed route links * changelog Co-authored-by: Hayden <hay-kot@pm.me> * fixed menu links * fixed poetry install on docker.dev build * Migration redesign (#119) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes Co-authored-by: Hayden <hay-kot@pm.me> * Fix link to dev-notes.md (#110) * translation: add swedish (#128) * language: da is Danish * translations: add swedish * scraper: unescape html in instructions (#129) Some urls erroneously deliver escaped html their instructions, sometimes they are even escaped on multiple levels like here: https://www.ica.se/recept/kladdig-kladdkaka-722982/ ``` >>> normalize_instruction("S&auml;tt ugnen p&aring; 200&deg;C.") 'Sätt ugnen på 200°C.' ``` * v0.2.0 Updates (#130) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes * test todos * bug/added docker volume * chowdow test data * partial image recipe image testing * added card section card * settings form * homepage cetegory ui * frontend category placeholder * fixed broken scheduler * remove old files * removed temp test Co-authored-by: Hayden <hay-kot@pm.me> * Fix missing translations key (#133) * translation: add simplified & traditional chinese * Fix missing translations * fix chinese translations * v0.2.0 Release Candidate (#141) * Fix link to Docker Hub Found an extra s. DESTROYED it. * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * notes hot fix * bug: mongo updates fail #99 * Fix error message (#101) * gh funding * Create Issue Templates (#125) * Create bug_report.md * Create config.yml Included a link to feature requests. * Update config.yml Fixed link I had for testing to the actual link * Update bug_report.md fix capitalization * Update .github/ISSUE_TEMPLATE/bug_report.md Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * merge kentors changes * refactor/recipe routers * category/tag database relationship and endpoints * frontend category management * update branch todos * bug/normalize recipe steps html * remove console.log + refactor categories * fix categories database errors * refactor/ router endpoint * refactor/ remove old code * drag and drop ingredients * general cleanup * route refactoring * changelog * api refactoring + random cleanup * fixed backwards sort * Update mkdocs.yml (#137) Fix warning from Deploy Docs github action * fixed navigate on enter in search * refactor/create global css * added category scroll * cleanup todos * debug routes * docs/new gifs & general updates * cleanup * fix list test Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * fix build * fix duplicate editor * fixed docker mount problem * python 3.9 * added tasks for non-docker development * remove old scripts * dev updates * fixed no image upload option * get version from backend * final docs pass * .gitignore * feature/markdown support for description and steps * package-lock * rename production task * category import errors on import Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <wengtad93@gmail.com> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * test notifications * unified notifications * docs/changelog Co-authored-by: hay-kot <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <wengtad93@gmail.com> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * Refactor/response models (#156) - First Pass * cleanup * split app/db versioning * async file response * refactor/recipe viewer + minor ui improvements * auto grow size * added async file responses * docs/changelog * "/" to open search bar * docs/changelog * change imports to use @/ for imports * cleanup * cleanup * db to session * theme + settings refactor * bug/image save fix * fixed failing tests * fix last json bug - #155 * fix settings import * fixed router link for site title Co-authored-by: hay-kot <hay-kot@pm.me> * version update * Refactor/response models (#161) * cleanup * split app/db versioning * async file response * refactor/recipe viewer + minor ui improvements * auto grow size * added async file responses * docs/changelog * "/" to open search bar * docs/changelog * change imports to use @/ for imports * cleanup * cleanup * db to session * theme + settings refactor * bug/image save fix * fixed failing tests * fix last json bug - #155 * fix settings import * fixed router link for site title * add version tag * v0.2.1 (#157) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog * Dropping Mongo From Dev Branch (#89) * Fix link to Docker Hub Found an extra s. DESTROYED it. * initial pass * second pass cleanup * backup card framework * backup card functionality * translation * upload button vile creation * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * dev bug: change data location to prevent reloads * api docs * api docs bug * workflow update Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * Add French Translation (#93) * New tests (#94) * dev-bug: fixed vscode freezes * test: refactor database init to support tests Co-authored-by: Hayden <hay-kot@pm.me> * Mealplan CRUD Tests (#95) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing Co-authored-by: Hayden <hay-kot@pm.me> * Fix typos (#96) * Settings, Themes and Migration Route Tests (#100) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing Co-authored-by: Hayden <hay-kot@pm.me> * Refactor + New Docker File (#105) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding Co-authored-by: Hayden <hay-kot@pm.me> * Meal planner improvements (#107) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding * mealplan redesign Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#108) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#113) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript * UI updates + name validation * docs: changelog + sp * fixed route links * changelog Co-authored-by: Hayden <hay-kot@pm.me> * fixed menu links * fixed poetry install on docker.dev build * Migration redesign (#119) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes Co-authored-by: Hayden <hay-kot@pm.me> * Fix link to dev-notes.md (#110) * translation: add swedish (#128) * language: da is Danish * translations: add swedish * scraper: unescape html in instructions (#129) Some urls erroneously deliver escaped html their instructions, sometimes they are even escaped on multiple levels like here: https://www.ica.se/recept/kladdig-kladdkaka-722982/ ``` >>> normalize_instruction("S&auml;tt ugnen p&aring; 200&deg;C.") 'Sätt ugnen på 200°C.' ``` * v0.2.0 Updates (#130) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes * test todos * bug/added docker volume * chowdow test data * partial image recipe image testing * added card section card * settings form * homepage cetegory ui * frontend category placeholder * fixed broken scheduler * remove old files * removed temp test Co-authored-by: Hayden <hay-kot@pm.me> * Fix missing translations key (#133) * translation: add simplified & traditional chinese * Fix missing translations * fix chinese translations * v0.2.0 Release Candidate (#141) * Fix link to Docker Hub Found an extra s. DESTROYED it. * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * notes hot fix * bug: mongo updates fail #99 * Fix error message (#101) * gh funding * Create Issue Templates (#125) * Create bug_report.md * Create config.yml Included a link to feature requests. * Update config.yml Fixed link I had for testing to the actual link * Update bug_report.md fix capitalization * Update .github/ISSUE_TEMPLATE/bug_report.md Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * merge kentors changes * refactor/recipe routers * category/tag database relationship and endpoints * frontend category management * update branch todos * bug/normalize recipe steps html * remove console.log + refactor categories * fix categories database errors * refactor/ router endpoint * refactor/ remove old code * drag and drop ingredients * general cleanup * route refactoring * changelog * api refactoring + random cleanup * fixed backwards sort * Update mkdocs.yml (#137) Fix warning from Deploy Docs github action * fixed navigate on enter in search * refactor/create global css * added category scroll * cleanup todos * debug routes * docs/new gifs & general updates * cleanup * fix list test Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * fix build * fix duplicate editor * fixed docker mount problem * python 3.9 * added tasks for non-docker development * remove old scripts * dev updates * fixed no image upload option * get version from backend * final docs pass * .gitignore * feature/markdown support for description and steps * package-lock * rename production task * category import errors on import (#150) Co-authored-by: hay-kot <hay-kot@pm.me> * Feature/improved notifications (#152) * category import errors on import * Import Error Hotfix (#148) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog * Dropping Mongo From Dev Branch (#89) * Fix link to Docker Hub Found an extra s. DESTROYED it. * initial pass * second pass cleanup * backup card framework * backup card functionality * translation * upload button vile creation * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * dev bug: change data location to prevent reloads * api docs * api docs bug * workflow update Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * Add French Translation (#93) * New tests (#94) * dev-bug: fixed vscode freezes * test: refactor database init to support tests Co-authored-by: Hayden <hay-kot@pm.me> * Mealplan CRUD Tests (#95) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing Co-authored-by: Hayden <hay-kot@pm.me> * Fix typos (#96) * Settings, Themes and Migration Route Tests (#100) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing Co-authored-by: Hayden <hay-kot@pm.me> * Refactor + New Docker File (#105) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding Co-authored-by: Hayden <hay-kot@pm.me> * Meal planner improvements (#107) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding * mealplan redesign Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#108) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#113) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript * UI updates + name validation * docs: changelog + sp * fixed route links * changelog Co-authored-by: Hayden <hay-kot@pm.me> * fixed menu links * fixed poetry install on docker.dev build * Migration redesign (#119) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes Co-authored-by: Hayden <hay-kot@pm.me> * Fix link to dev-notes.md (#110) * translation: add swedish (#128) * language: da is Danish * translations: add swedish * scraper: unescape html in instructions (#129) Some urls erroneously deliver escaped html their instructions, sometimes they are even escaped on multiple levels like here: https://www.ica.se/recept/kladdig-kladdkaka-722982/ ``` >>> normalize_instruction("S&auml;tt ugnen p&aring; 200&deg;C.") 'Sätt ugnen på 200°C.' ``` * v0.2.0 Updates (#130) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes * test todos * bug/added docker volume * chowdow test data * partial image recipe image testing * added card section card * settings form * homepage cetegory ui * frontend category placeholder * fixed broken scheduler * remove old files * removed temp test Co-authored-by: Hayden <hay-kot@pm.me> * Fix missing translations key (#133) * translation: add simplified & traditional chinese * Fix missing translations * fix chinese translations * v0.2.0 Release Candidate (#141) * Fix link to Docker Hub Found an extra s. DESTROYED it. * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * notes hot fix * bug: mongo updates fail #99 * Fix error message (#101) * gh funding * Create Issue Templates (#125) * Create bug_report.md * Create config.yml Included a link to feature requests. * Update config.yml Fixed link I had for testing to the actual link * Update bug_report.md fix capitalization * Update .github/ISSUE_TEMPLATE/bug_report.md Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * merge kentors changes * refactor/recipe routers * category/tag database relationship and endpoints * frontend category management * update branch todos * bug/normalize recipe steps html * remove console.log + refactor categories * fix categories database errors * refactor/ router endpoint * refactor/ remove old code * drag and drop ingredients * general cleanup * route refactoring * changelog * api refactoring + random cleanup * fixed backwards sort * Update mkdocs.yml (#137) Fix warning from Deploy Docs github action * fixed navigate on enter in search * refactor/create global css * added category scroll * cleanup todos * debug routes * docs/new gifs & general updates * cleanup * fix list test Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * fix build * fix duplicate editor * fixed docker mount problem * python 3.9 * added tasks for non-docker development * remove old scripts * dev updates * fixed no image upload option * get version from backend * final docs pass * .gitignore * feature/markdown support for description and steps * package-lock * rename production task * category import errors on import Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <wengtad93@gmail.com> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * test notifications * unified notifications * docs/changelog Co-authored-by: hay-kot <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <wengtad93@gmail.com> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * Refactor/response models (#156) - First Pass * cleanup * split app/db versioning * async file response * refactor/recipe viewer + minor ui improvements * auto grow size * added async file responses * docs/changelog * "/" to open search bar * docs/changelog * change imports to use @/ for imports * cleanup * cleanup * db to session * theme + settings refactor * bug/image save fix * fixed failing tests * fix last json bug - #155 * fix settings import * fixed router link for site title Co-authored-by: hay-kot <hay-kot@pm.me> Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <wengtad93@gmail.com> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * Revert "v0.2.1 (#157)" (#158) This reverts commita899f46464
. * v0.2.1 (#159) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog * Dropping Mongo From Dev Branch (#89) * Fix link to Docker Hub Found an extra s. DESTROYED it. * initial pass * second pass cleanup * backup card framework * backup card functionality * translation * upload button vile creation * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * dev bug: change data location to prevent reloads * api docs * api docs bug * workflow update Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * Add French Translation (#93) * New tests (#94) * dev-bug: fixed vscode freezes * test: refactor database init to support tests Co-authored-by: Hayden <hay-kot@pm.me> * Mealplan CRUD Tests (#95) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing Co-authored-by: Hayden <hay-kot@pm.me> * Fix typos (#96) * Settings, Themes and Migration Route Tests (#100) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing Co-authored-by: Hayden <hay-kot@pm.me> * Refactor + New Docker File (#105) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding Co-authored-by: Hayden <hay-kot@pm.me> * Meal planner improvements (#107) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding * mealplan redesign Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#108) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#113) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript * UI updates + name validation * docs: changelog + sp * fixed route links * changelog Co-authored-by: Hayden <hay-kot@pm.me> * fixed menu links * fixed poetry install on docker.dev build * Migration redesign (#119) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes Co-authored-by: Hayden <hay-kot@pm.me> * Fix link to dev-notes.md (#110) * translation: add swedish (#128) * language: da is Danish * translations: add swedish * scraper: unescape html in instructions (#129) Some urls erroneously deliver escaped html their instructions, sometimes they are even escaped on multiple levels like here: https://www.ica.se/recept/kladdig-kladdkaka-722982/ ``` >>> normalize_instruction("S&auml;tt ugnen p&aring; 200&deg;C.") 'Sätt ugnen på 200°C.' ``` * v0.2.0 Updates (#130) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes * test todos * bug/added docker volume * chowdow test data * partial image recipe image testing * added card section card * settings form * homepage cetegory ui * frontend category placeholder * fixed broken scheduler * remove old files * removed temp test Co-authored-by: Hayden <hay-kot@pm.me> * Fix missing translations key (#133) * translation: add simplified & traditional chinese * Fix missing translations * fix chinese translations * v0.2.0 Release Candidate (#141) * Fix link to Docker Hub Found an extra s. DESTROYED it. * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * notes hot fix * bug: mongo updates fail #99 * Fix error message (#101) * gh funding * Create Issue Templates (#125) * Create bug_report.md * Create config.yml Included a link to feature requests. * Update config.yml Fixed link I had for testing to the actual link * Update bug_report.md fix capitalization * Update .github/ISSUE_TEMPLATE/bug_report.md Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * merge kentors changes * refactor/recipe routers * category/tag database relationship and endpoints * frontend category management * update branch todos * bug/normalize recipe steps html * remove console.log + refactor categories * fix categories database errors * refactor/ router endpoint * refactor/ remove old code * drag and drop ingredients * general cleanup * route refactoring * changelog * api refactoring + random cleanup * fixed backwards sort * Update mkdocs.yml (#137) Fix warning from Deploy Docs github action * fixed navigate on enter in search * refactor/create global css * added category scroll * cleanup todos * debug routes * docs/new gifs & general updates * cleanup * fix list test Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * fix build * fix duplicate editor * fixed docker mount problem * python 3.9 * added tasks for non-docker development * remove old scripts * dev updates * fixed no image upload option * get version from backend * final docs pass * .gitignore * feature/markdown support for description and steps * package-lock * rename production task * category import errors on import (#150) Co-authored-by: hay-kot <hay-kot@pm.me> * Feature/improved notifications (#152) * category import errors on import * Import Error Hotfix (#148) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog * Dropping Mongo From Dev Branch (#89) * Fix link to Docker Hub Found an extra s. DESTROYED it. * initial pass * second pass cleanup * backup card framework * backup card functionality * translation * upload button vile creation * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * dev bug: change data location to prevent reloads * api docs * api docs bug * workflow update Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * Add French Translation (#93) * New tests (#94) * dev-bug: fixed vscode freezes * test: refactor database init to support tests Co-authored-by: Hayden <hay-kot@pm.me> * Mealplan CRUD Tests (#95) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing Co-authored-by: Hayden <hay-kot@pm.me> * Fix typos (#96) * Settings, Themes and Migration Route Tests (#100) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing Co-authored-by: Hayden <hay-kot@pm.me> * Refactor + New Docker File (#105) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding Co-authored-by: Hayden <hay-kot@pm.me> * Meal planner improvements (#107) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding * mealplan redesign Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#108) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#113) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript * UI updates + name validation * docs: changelog + sp * fixed route links * changelog Co-authored-by: Hayden <hay-kot@pm.me> * fixed menu links * fixed poetry install on docker.dev build * Migration redesign (#119) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes Co-authored-by: Hayden <hay-kot@pm.me> * Fix link to dev-notes.md (#110) * translation: add swedish (#128) * language: da is Danish * translations: add swedish * scraper: unescape html in instructions (#129) Some urls erroneously deliver escaped html their instructions, sometimes they are even escaped on multiple levels like here: https://www.ica.se/recept/kladdig-kladdkaka-722982/ ``` >>> normalize_instruction("S&auml;tt ugnen p&aring; 200&deg;C.") 'Sätt ugnen på 200°C.' ``` * v0.2.0 Updates (#130) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes * test todos * bug/added docker volume * chowdow test data * partial image recipe image testing * added card section card * settings form * homepage cetegory ui * frontend category placeholder * fixed broken scheduler * remove old files * removed temp test Co-authored-by: Hayden <hay-kot@pm.me> * Fix missing translations key (#133) * translation: add simplified & traditional chinese * Fix missing translations * fix chinese translations * v0.2.0 Release Candidate (#141) * Fix link to Docker Hub Found an extra s. DESTROYED it. * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * notes hot fix * bug: mongo updates fail #99 * Fix error message (#101) * gh funding * Create Issue Templates (#125) * Create bug_report.md * Create config.yml Included a link to feature requests. * Update config.yml Fixed link I had for testing to the actual link * Update bug_report.md fix capitalization * Update .github/ISSUE_TEMPLATE/bug_report.md Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * merge kentors changes * refactor/recipe routers * category/tag database relationship and endpoints * frontend category management * update branch todos * bug/normalize recipe steps html * remove console.log + refactor categories * fix categories database errors * refactor/ router endpoint * refactor/ remove old code * drag and drop ingredients * general cleanup * route refactoring * changelog * api refactoring + random cleanup * fixed backwards sort * Update mkdocs.yml (#137) Fix warning from Deploy Docs github action * fixed navigate on enter in search * refactor/create global css * added category scroll * cleanup todos * debug routes * docs/new gifs & general updates * cleanup * fix list test Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * fix build * fix duplicate editor * fixed docker mount problem * python 3.9 * added tasks for non-docker development * remove old scripts * dev updates * fixed no image upload option * get version from backend * final docs pass * .gitignore * feature/markdown support for description and steps * package-lock * rename production task * category import errors on import Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <wengtad93@gmail.com> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * test notifications * unified notifications * docs/changelog Co-authored-by: hay-kot <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <wengtad93@gmail.com> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * Refactor/response models (#156) - First Pass * cleanup * split app/db versioning * async file response * refactor/recipe viewer + minor ui improvements * auto grow size * added async file responses * docs/changelog * "/" to open search bar * docs/changelog * change imports to use @/ for imports * cleanup * cleanup * db to session * theme + settings refactor * bug/image save fix * fixed failing tests * fix last json bug - #155 * fix settings import * fixed router link for site title Co-authored-by: hay-kot <hay-kot@pm.me> * version update Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <… * Consider any .json file from Nextcloud (#164) * Allow empty instructions (#165) * fix scrape recipe error (#166) - fixes #138 - fixes #145 * Add polish translation (#154) * add polish translation * add missing allLangs value for polish translation in language.js * Create de.json (#167) Add German Translation * Refactor/response models (#169) * cleanup * split app/db versioning * async file response * refactor/recipe viewer + minor ui improvements * auto grow size * added async file responses * docs/changelog * "/" to open search bar * docs/changelog * change imports to use @/ for imports * cleanup * cleanup * db to session * theme + settings refactor * bug/image save fix * fixed failing tests * fix last json bug - #155 * fix settings import * fixed router link for site title * add version tag * v0.2.1 (#157) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog * Dropping Mongo From Dev Branch (#89) * Fix link to Docker Hub Found an extra s. DESTROYED it. * initial pass * second pass cleanup * backup card framework * backup card functionality * translation * upload button vile creation * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * dev bug: change data location to prevent reloads * api docs * api docs bug * workflow update Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * Add French Translation (#93) * New tests (#94) * dev-bug: fixed vscode freezes * test: refactor database init to support tests Co-authored-by: Hayden <hay-kot@pm.me> * Mealplan CRUD Tests (#95) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing Co-authored-by: Hayden <hay-kot@pm.me> * Fix typos (#96) * Settings, Themes and Migration Route Tests (#100) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing Co-authored-by: Hayden <hay-kot@pm.me> * Refactor + New Docker File (#105) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding Co-authored-by: Hayden <hay-kot@pm.me> * Meal planner improvements (#107) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding * mealplan redesign Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#108) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#113) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript * UI updates + name validation * docs: changelog + sp * fixed route links * changelog Co-authored-by: Hayden <hay-kot@pm.me> * fixed menu links * fixed poetry install on docker.dev build * Migration redesign (#119) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes Co-authored-by: Hayden <hay-kot@pm.me> * Fix link to dev-notes.md (#110) * translation: add swedish (#128) * language: da is Danish * translations: add swedish * scraper: unescape html in instructions (#129) Some urls erroneously deliver escaped html their instructions, sometimes they are even escaped on multiple levels like here: https://www.ica.se/recept/kladdig-kladdkaka-722982/ ``` >>> normalize_instruction("S&auml;tt ugnen p&aring; 200&deg;C.") 'Sätt ugnen på 200°C.' ``` * v0.2.0 Updates (#130) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes * test todos * bug/added docker volume * chowdow test data * partial image recipe image testing * added card section card * settings form * homepage cetegory ui * frontend category placeholder * fixed broken scheduler * remove old files * removed temp test Co-authored-by: Hayden <hay-kot@pm.me> * Fix missing translations key (#133) * translation: add simplified & traditional chinese * Fix missing translations * fix chinese translations * v0.2.0 Release Candidate (#141) * Fix link to Docker Hub Found an extra s. DESTROYED it. * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * notes hot fix * bug: mongo updates fail #99 * Fix error message (#101) * gh funding * Create Issue Templates (#125) * Create bug_report.md * Create config.yml Included a link to feature requests. * Update config.yml Fixed link I had for testing to the actual link * Update bug_report.md fix capitalization * Update .github/ISSUE_TEMPLATE/bug_report.md Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * merge kentors changes * refactor/recipe routers * category/tag database relationship and endpoints * frontend category management * update branch todos * bug/normalize recipe steps html * remove console.log + refactor categories * fix categories database errors * refactor/ router endpoint * refactor/ remove old code * drag and drop ingredients * general cleanup * route refactoring * changelog * api refactoring + random cleanup * fixed backwards sort * Update mkdocs.yml (#137) Fix warning from Deploy Docs github action * fixed navigate on enter in search * refactor/create global css * added category scroll * cleanup todos * debug routes * docs/new gifs & general updates * cleanup * fix list test Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * fix build * fix duplicate editor * fixed docker mount problem * python 3.9 * added tasks for non-docker development * remove old scripts * dev updates * fixed no image upload option * get version from backend * final docs pass * .gitignore * feature/markdown support for description and steps * package-lock * rename production task * category import errors on import (#150) Co-authored-by: hay-kot <hay-kot@pm.me> * Feature/improved notifications (#152) * category import errors on import * Import Error Hotfix (#148) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog * Dropping Mongo From Dev Branch (#89) * Fix link to Docker Hub Found an extra s. DESTROYED it. * initial pass * second pass cleanup * backup card framework * backup card functionality * translation * upload button vile creation * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * dev bug: change data location to prevent reloads * api docs * api docs bug * workflow update Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * Add French Translation (#93) * New tests (#94) * dev-bug: fixed vscode freezes * test: refactor database init to support tests Co-authored-by: Hayden <hay-kot@pm.me> * Mealplan CRUD Tests (#95) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing Co-authored-by: Hayden <hay-kot@pm.me> * Fix typos (#96) * Settings, Themes and Migration Route Tests (#100) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing Co-authored-by: Hayden <hay-kot@pm.me> * Refactor + New Docker File (#105) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding Co-authored-by: Hayden <hay-kot@pm.me> * Meal planner improvements (#107) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding * mealplan redesign Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#108) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#113) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript * UI updates + name validation * docs: changelog + sp * fixed route links * changelog Co-authored-by: Hayden <hay-kot@pm.me> * fixed menu links * fixed poetry install on docker.dev build * Migration redesign (#119) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes Co-authored-by: Hayden <hay-kot@pm.me> * Fix link to dev-notes.md (#110) * translation: add swedish (#128) * language: da is Danish * translations: add swedish * scraper: unescape html in instructions (#129) Some urls erroneously deliver escaped html their instructions, sometimes they are even escaped on multiple levels like here: https://www.ica.se/recept/kladdig-kladdkaka-722982/ ``` >>> normalize_instruction("S&auml;tt ugnen p&aring; 200&deg;C.") 'Sätt ugnen på 200°C.' ``` * v0.2.0 Updates (#130) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes * test todos * bug/added docker volume * chowdow test data * partial image recipe image testing * added card section card * settings form * homepage cetegory ui * frontend category placeholder * fixed broken scheduler * remove old files * removed temp test Co-authored-by: Hayden <hay-kot@pm.me> * Fix missing translations key (#133) * translation: add simplified & traditional chinese * Fix missing translations * fix chinese translations * v0.2.0 Release Candidate (#141) * Fix link to Docker Hub Found an extra s. DESTROYED it. * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * notes hot fix * bug: mongo updates fail #99 * Fix error message (#101) * gh funding * Create Issue Templates (#125) * Create bug_report.md * Create config.yml Included a link to feature requests. * Update config.yml Fixed link I had for testing to the actual link * Update bug_report.md fix capitalization * Update .github/ISSUE_TEMPLATE/bug_report.md Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * merge kentors changes * refactor/recipe routers * category/tag database relationship and endpoints * frontend category management * update branch todos * bug/normalize recipe steps html * remove console.log + refactor categories * fix categories database errors * refactor/ router endpoint * refactor/ remove old code * drag and drop ingredients * general cleanup * route refactoring * changelog * api refactoring + random cleanup * fixed backwards sort * Update mkdocs.yml (#137) Fix warning from Deploy Docs github action * fixed navigate on enter in search * refactor/create global css * added category scroll * cleanup todos * debug routes * docs/new gifs & general updates * cleanup * fix list test Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * fix build * fix duplicate editor * fixed docker mount problem * python 3.9 * added tasks for non-docker development * remove old scripts * dev updates * fixed no image upload option * get version from backend * final docs pass * .gitignore * feature/markdown support for description and steps * package-lock * rename production task * category import errors on import Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <wengtad93@gmail.com> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * test notifications * unified notifications * docs/changelog Co-authored-by: hay-kot <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <wengtad93@gmail.com> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * Refactor/response models (#156) - First Pass * cleanup * split app/db versioning * async file response * refactor/recipe viewer + minor ui improvements * auto grow size * added async file responses * docs/changelog * "/" to open search bar * docs/changelog * change imports to use @/ for imports * cleanup * cleanup * db to session * theme + settings refactor * bug/image save fix * fixed failing tests * fix last json bug - #155 * fix settings import * fixed router link for site title Co-authored-by: hay-kot <hay-kot@pm.me> Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <wengtad93@gmail.com> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * Revert "v0.2.1 (#157)" (#158) This reverts commita899f46464
. * v0.2.1 (#159) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog * Dropping Mongo From Dev Branch (#89) * Fix link to Docker Hub Found an extra s. DESTROYED it. * initial pass * second pass cleanup * backup card framework * backup card functionality * translation * upload button vile creation * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * dev bug: change data location to prevent reloads * api docs * api docs bug * workflow update Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * Add French Translation (#93) * New tests (#94) * dev-bug: fixed vscode freezes * test: refactor database init to support tests Co-authored-by: Hayden <hay-kot@pm.me> * Mealplan CRUD Tests (#95) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing Co-authored-by: Hayden <hay-kot@pm.me> * Fix typos (#96) * Settings, Themes and Migration Route Tests (#100) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing Co-authored-by: Hayden <hay-kot@pm.me> * Refactor + New Docker File (#105) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding Co-authored-by: Hayden <hay-kot@pm.me> * Meal planner improvements (#107) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding * mealplan redesign Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#108) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#113) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript * UI updates + name validation * docs: changelog + sp * fixed route links * changelog Co-authored-by: Hayden <hay-kot@pm.me> * fixed menu links * fixed poetry install on docker.dev build * Migration redesign (#119) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes Co-authored-by: Hayden <hay-kot@pm.me> * Fix link to dev-notes.md (#110) * translation: add swedish (#128) * language: da is Danish * translations: add swedish * scraper: unescape html in instructions (#129) Some urls erroneously deliver escaped html their instructions, sometimes they are even escaped on multiple levels like here: https://www.ica.se/recept/kladdig-kladdkaka-722982/ ``` >>> normalize_instruction("S&auml;tt ugnen p&aring; 200&deg;C.") 'Sätt ugnen på 200°C.' ``` * v0.2.0 Updates (#130) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes * test todos * bug/added docker volume * chowdow test data * partial image recipe image testing * added card section card * settings form * homepage cetegory ui * frontend category placeholder * fixed broken scheduler * remove old files * removed temp test Co-authored-by: Hayden <hay-kot@pm.me> * Fix missing translations key (#133) * translation: add simplified & traditional chinese * Fix missing translations * fix chinese translations * v0.2.0 Release Candidate (#141) * Fix link to Docker Hub Found an extra s. DESTROYED it. * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * notes hot fix * bug: mongo updates fail #99 * Fix error message (#101) * gh funding * Create Issue Templates (#125) * Create bug_report.md * Create config.yml Included a link to feature requests. * Update config.yml Fixed link I had for testing to the actual link * Update bug_report.md fix capitalization * Update .github/ISSUE_TEMPLATE/bug_report.md Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * merge kentors changes * refactor/recipe routers * category/tag database relationship and endpoints * frontend category management * update branch todos * bug/normalize recipe steps html * remove console.log + refactor categories * fix categories database errors * refactor/ router endpoint * refactor/ remove old code * drag and drop ingredients * general cleanup * route refactoring * changelog * api refactoring + random cleanup * fixed backwards sort * Update mkdocs.yml (#137) Fix warning from Deploy Docs github action * fixed navigate on enter in search * refactor/create global css * added category scroll * cleanup todos * debug routes * docs/new gifs & general updates * cleanup * fix list test Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * fix build * fix duplicate editor * fixed docker mount problem * python 3.9 * added tasks for non-docker development * remove old scripts * dev updates * fixed no image upload option * get version from backend * final docs pass * .gitignore * feature/markdown support for description and steps * package-lock * rename production task * category import errors on import (#150) Co-authored-by: hay-kot <hay-kot@pm.me> * Feature/improved notifications (#152) * category import errors on import * Import Error Hotfix (#148) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog * Dropping Mongo From Dev Branch (#89) * Fix link to Docker Hub Found an extra s. DESTROYED it. * initial pass * second pass cleanup * backup card framework * backup card functionality * translation * upload button vile creation * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * dev bug: change data location to prevent reloads * api docs * api docs bug * workflow update Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * Add French Translation (#93) * New tests (#94) * dev-bug: fixed vscode freezes * test: refactor database init to support tests Co-authored-by: Hayden <hay-kot@pm.me> * Mealplan CRUD Tests (#95) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing Co-authored-by: Hayden <hay-kot@pm.me> * Fix typos (#96) * Settings, Themes and Migration Route Tests (#100) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing Co-authored-by: Hayden <hay-kot@pm.me> * Refactor + New Docker File (#105) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding Co-authored-by: Hayden <hay-kot@pm.me> * Meal planner improvements (#107) * dev-bug: fixed vscode freezes * test: refactor database init to support tests * mealplan CRUD testing * restructure test folder * git attributes * tests: migration, settings, theme routes testing * docker-file shrink * rebuild * refactor: moving directories around * adding funding * mealplan redesign Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#108) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript Co-authored-by: Hayden <hay-kot@pm.me> * Upload component (#113) * unified upload button + download backups * javascript toolings * fix vuetur config * fixed type check error * refactor: clean up bag javascript * UI updates + name validation * docs: changelog + sp * fixed route links * changelog Co-authored-by: Hayden <hay-kot@pm.me> * fixed menu links * fixed poetry install on docker.dev build * Migration redesign (#119) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes Co-authored-by: Hayden <hay-kot@pm.me> * Fix link to dev-notes.md (#110) * translation: add swedish (#128) * language: da is Danish * translations: add swedish * scraper: unescape html in instructions (#129) Some urls erroneously deliver escaped html their instructions, sometimes they are even escaped on multiple levels like here: https://www.ica.se/recept/kladdig-kladdkaka-722982/ ``` >>> normalize_instruction("S&auml;tt ugnen p&aring; 200&deg;C.") 'Sätt ugnen på 200°C.' ``` * v0.2.0 Updates (#130) * migration redesign init * new color picker * changelog * added UI language selection * fix layout issue on recipe editor * remove git as dependency * added UI editor for original URL * CI/CD Tests * test: fixed migration routes * test todos * bug/added docker volume * chowdow test data * partial image recipe image testing * added card section card * settings form * homepage cetegory ui * frontend category placeholder * fixed broken scheduler * remove old files * removed temp test Co-authored-by: Hayden <hay-kot@pm.me> * Fix missing translations key (#133) * translation: add simplified & traditional chinese * Fix missing translations * fix chinese translations * v0.2.0 Release Candidate (#141) * Fix link to Docker Hub Found an extra s. DESTROYED it. * Release v0.1.0 Candidate (#85) * Changed uvicorn port to 80 * Changed port in docker-compose to match dockerfile * Readded environment variables in docker-compose * production image rework * Use opengraph metadata to make basic recipe cards when full recipe metadata is not available * fixed instrucitons on parse * add last_recipe * automated testing * roadmap update * Sqlite (#75) * file structure * auto-test * take 2 * refactor ap scheduler and startup process * fixed scraper error * database abstraction * database abstraction * port recipes over to new schema * meal migration * start settings migration * finale mongo port * backup improvements * migration imports to new DB structure * unused import cleanup * docs strings * settings and theme import logic * cleanup * fixed tinydb error * requirements * fuzzy search * remove scratch file * sqlalchemy models * improved search ui * recipe models almost done * sql modal population * del scratch * rewrite database model mixins * mostly grabage * recipe updates * working sqllite * remove old files and reorganize * final cleanup Co-authored-by: Hayden <hay-kot@pm.me> * Backup card (#78) * backup / import dialog * upgrade to new tag method * New import card * rename settings.py to app_config.py * migrate to poetry for development * fix failing test Co-authored-by: Hayden <hay-kot@pm.me> * added mkdocs to docker-compose * Translations (#72) * Translations + danish * changed back proxy target to use ENV * Resolved more merge conflicts * Removed test in translation * Documentation of translations * Updated translations * removed old packages Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> * fail to start bug fixes * feature: prep/cook/total time slots (#80) Co-authored-by: Hayden <hay-kot@pm.me> * missing bind attributes * Bug fixes (#81) * fix: url remains after succesful import * docs: changelog + update todos * arm image * arm compose * compose updates * update poetry * arm support Co-authored-by: Hayden <hay-kot@pm.me> * dockerfile hotfix * dockerfile hotfix * Version Release Final Touches (#84) * Remove slim * bug: opacity issues * bug: startup failure with no database * ci/cd on dev branch * formatting * v0.1.0 documentation Co-authored-by: Hayden <hay-kot@pm.me> * db init hotfix * bug: fix crash in mongo * fix mongo bug * fixed version notifier * finale changelog Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> * build container * webscraper hotfix * notes hot fix * bug: mongo updates fail #99 * Fix error message (#101) * gh funding * Create Issue Templates (#125) * Create bug_report.md * Create config.yml Included a link to feature requests. * Update config.yml Fixed link I had for testing to the actual link * Update bug_report.md fix capitalization * Update .github/ISSUE_TEMPLATE/bug_report.md Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * merge kentors changes * refactor/recipe routers * category/tag database relationship and endpoints * frontend category management * update branch todos * bug/normalize recipe steps html * remove console.log + refactor categories * fix categories database errors * refactor/ router endpoint * refactor/ remove old code * drag and drop ingredients * general cleanup * route refactoring * changelog * api refactoring + random cleanup * fixed backwards sort * Update mkdocs.yml (#137) Fix warning from Deploy Docs github action * fixed navigate on enter in search * refactor/create global css * added category scroll * cleanup todos * debug routes * docs/new gifs & general updates * cleanup * fix list test Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * fix build * fix duplicate editor * fixed docker mount problem * python 3.9 * added tasks for non-docker development * remove old scripts * dev updates * fixed no image upload option * get version from backend * final docs pass * .gitignore * feature/markdown support for description and steps * package-lock * rename production task * category import errors on import Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <wengtad93@gmail.com> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * test notifications * unified notifications * docs/changelog Co-authored-by: hay-kot <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <wengtad93@gmail.com> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> * Refactor/response models (#156) - First Pass * cleanup * split app/db versioning * async file response * refactor/recipe viewer + minor ui improvements * auto grow size * added async file responses * docs/changelog * "/" to open search bar * docs/changelog * change imports to use @/ for imports * cleanup * cleanup * db to session * theme + settings refactor * bug/image save fix * fixed failing tests * fix last json bug - #155 * fix settings import * fixed router link for site title Co-authored-by: hay-kot <hay-kot@pm.me> * version update Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <… * Enhance mobile view (#171) * Fixed navbar on mobile * Feature/shopping list (#172) * API Endpoint * shopping list added to the UI * fixed category sidebar on mobile Co-authored-by: hay-kot <hay-kot@pm.me> * Feature/shopping list (#173) * API Endpoint * shopping list added to the UI * fixed category sidebar on mobile * fix category sidebar hidden all the time * adjust mobile view on times * remove console.logs * actually remove console.logs * Fixed varying card height on smaller screens * change style of meal planner categories Co-authored-by: hay-kot <hay-kot@pm.me> * refactor/scrapper (#175) * API Endpoint * shopping list added to the UI * fixed category sidebar on mobile * fix category sidebar hidden all the time * adjust mobile view on times * remove console.logs * actually remove console.logs * Fixed varying card height on smaller screens * change style of meal planner categories * bug/fixed open search on '/' when on input * Improved import summary dialog * url validation * refactor/split reciper scraper into seperate fiels Co-authored-by: hay-kot <hay-kot@pm.me> * auto focus on add from url * docs/update v0.3.0 * remove print * docs/v0.3.0 Co-authored-by: kentora <=> Co-authored-by: Hayden <hay-kot@pm.me> Co-authored-by: Richard Mitic <richard.h.mitic@gmail.com> Co-authored-by: kentora <kentora@kentora.dk> Co-authored-by: David Young <davidy@funkypenguin.co.nz> Co-authored-by: Bastien <43323819+Batgame@users.noreply.github.com> Co-authored-by: sephrat <34862846+sephrat@users.noreply.github.com> Co-authored-by: Nick CJ <17556895+nickcj931@users.noreply.github.com> Co-authored-by: dekvall <dkvldev@gmail.com> Co-authored-by: wengtad <wengtad93@gmail.com> Co-authored-by: Alexei Pesic <pesic.alexei@gmail.com> Co-authored-by: Andrew <dpieski@gmail.com> Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com> Co-authored-by: retmas-gh <58191209+retmas-gh@users.noreply.github.com> Co-authored-by: mindesbunister <32161838+mindesbunister@users.noreply.github.com> Co-authored-by: Raghnarok05 <77641728+Raghnarok05@users.noreply.github.com>
This commit is contained in:
parent
717d7ca0fb
commit
38e20ba321
91 changed files with 1805 additions and 518 deletions
|
@ -1,3 +1,5 @@
|
|||
*/node_modules
|
||||
*/dist
|
||||
*/data/db
|
||||
*/data/db
|
||||
*/mealie/test
|
||||
*/mealie/.temp
|
56
.github/workflows/dockerbuild.release.yml
vendored
Normal file
56
.github/workflows/dockerbuild.release.yml
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
name: Docker Build Production
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
#
|
||||
# Get Release Version
|
||||
#
|
||||
- uses: oprypin/find-latest-tag@v1
|
||||
with:
|
||||
repository: hay-kot/mealie # The repository to scan.
|
||||
releases-only: true # We know that all relevant tags have a GitHub release for them.
|
||||
id: mealie_version # The step ID to refer to later.
|
||||
#
|
||||
# Checkout
|
||||
#
|
||||
- name: checkout code
|
||||
uses: actions/checkout@v2
|
||||
#
|
||||
# Setup QEMU
|
||||
#
|
||||
- name: Set up QEMU
|
||||
id: qemu
|
||||
uses: docker/setup-qemu-action@v1
|
||||
with:
|
||||
image: tonistiigi/binfmt:latest
|
||||
platforms: all
|
||||
#
|
||||
# Setup Buildx
|
||||
#
|
||||
- name: install buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
with:
|
||||
install: true
|
||||
#
|
||||
# Login to Docker Hub
|
||||
#
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
#
|
||||
# Build
|
||||
#
|
||||
- name: build the image
|
||||
run: |
|
||||
docker build --push \
|
||||
--tag hkotel/mealie:${{ steps.mealie_version.outputs.tag }} \
|
||||
--platform linux/amd64,linux/arm/v7,linux/arm64 .
|
2
.github/workflows/pytest.yml
vendored
2
.github/workflows/pytest.yml
vendored
|
@ -21,7 +21,7 @@ jobs:
|
|||
- name: Set up python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.8
|
||||
python-version: 3.9
|
||||
#----------------------------------------------
|
||||
# ----- install & configure poetry -----
|
||||
#----------------------------------------------
|
||||
|
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -17,5 +17,6 @@
|
|||
"i18n-ally.keystyle": "nested",
|
||||
"cSpell.words": [
|
||||
"performant"
|
||||
]
|
||||
],
|
||||
"search.mode": "reuseEditor"
|
||||
}
|
||||
|
|
21
Caddyfile
Normal file
21
Caddyfile
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
auto_https off
|
||||
}
|
||||
|
||||
:80 {
|
||||
@proxied path /api/* /docs /openapi.json
|
||||
|
||||
root * /app/dist
|
||||
encode gzip
|
||||
uri strip_suffix /
|
||||
|
||||
handle @proxied {
|
||||
reverse_proxy http://127.0.0.1:9000
|
||||
}
|
||||
|
||||
handle {
|
||||
try_files {path}.html {path} /
|
||||
file_server
|
||||
}
|
||||
|
||||
}
|
10
Dockerfile
10
Dockerfile
|
@ -7,7 +7,7 @@ RUN npm run build
|
|||
|
||||
FROM python:3.9-alpine
|
||||
|
||||
RUN apk add --no-cache libxml2-dev libxslt-dev libxml2
|
||||
RUN apk add --no-cache libxml2-dev libxslt-dev libxml2 caddy
|
||||
ENV ENV prod
|
||||
EXPOSE 80
|
||||
WORKDIR /app
|
||||
|
@ -30,9 +30,11 @@ RUN apk add --update --no-cache --virtual .build-deps \
|
|||
|
||||
|
||||
COPY ./mealie /app
|
||||
COPY ./Caddyfile /app
|
||||
COPY ./app_data/templates /app/data/templates
|
||||
RUN rm -rf /app/tests /app/.temp
|
||||
COPY --from=build-stage /app/dist /app/dist
|
||||
RUN rm -rf /app/test /app/.temp
|
||||
|
||||
|
||||
VOLUME [ "/app/data/" ]
|
||||
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80"]
|
||||
RUN chmod +x /app/run.sh
|
||||
CMD /app/run.sh
|
|
@ -63,6 +63,7 @@ Mealie also provides a secure API for interactions from 3rd party applications.
|
|||
#### Meal Planner
|
||||
- Random Meal plan generation based off categories
|
||||
- Expose notes in the API to allow external applications to access relevant information for meal plans
|
||||
- Shopping Lists
|
||||
#### Database Import / Export
|
||||
- Easily Import / Export your recipes from the UI
|
||||
- Export recipes in into custom files using Jinja2 templates
|
||||
|
@ -82,7 +83,7 @@ Contributions are what make the open source community such an amazing place to b
|
|||
|
||||
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>
|
||||
<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: 30px !important;width: 107px !important;" ></a>
|
||||
|
||||
<!-- LICENSE -->
|
||||
## License
|
||||
|
|
Binary file not shown.
|
@ -1,15 +1,45 @@
|
|||
# Release Notes
|
||||
|
||||
## v0.3.0 - Draft!
|
||||
## v0.3.0
|
||||
|
||||
### Bug Fixes
|
||||
- Fixed open search on `/` when in input. - Closes #174
|
||||
- Error when importing recipe: KeyError: '@type' - Closes #145
|
||||
- Fixed Import Issue - bhg.com - Closes #138
|
||||
- Scraper not working with recipe containing HowToSection - Closes #73
|
||||
|
||||
### Features and Improvements
|
||||
- Improved Nextcloud Imports
|
||||
- Improved Recipe Parser!
|
||||
- Open search with `/` hotkey!
|
||||
- Database and App version are now split
|
||||
- Unified and improved snackbar notifications
|
||||
- Recipe Viewer
|
||||
- Categories, Tags, and Notes will not be displayed below the steps on smaller screens
|
||||
- Recipe Editor
|
||||
- New Category/Tag endpoints to filter all recipes by Category or Tag
|
||||
- Category sidebar now has show/hide behavior on mobile
|
||||
- Settings menu on mobile is improved
|
||||
- **Meal Planner**
|
||||
- You can now restrict recipe categories used for random meal-plan creation in the settings menu
|
||||
- Recipe picker dialog will now display recipes when the search bar is empty
|
||||
- Minor UI improvements
|
||||
- **Shopping lists!** Shopping list can now be generated from a meal plan. Currently ingredients are split by recipes or there is a beta feature that attempts to sort them by similarity.
|
||||
- **Recipe Viewer**
|
||||
- Categories, Tags, and Notes will now be displayed below the steps on smaller screens
|
||||
- **Recipe Editor**
|
||||
- Text areas now auto grow to fit content
|
||||
- Description, Steps, and Notes support Markdown! This includes inline html in Markdown.
|
||||
- **Imports**
|
||||
- A revamped dialog has been created to provide more information on restoring backups. Exceptions on the backend are now sent to the frontend and are easily viewable to see what went wrong when you restored a backup. This functionality will be ported over to the migrations in a future release.
|
||||
|
||||
## v0.2.1 - Hot Fixes!
|
||||
|
||||
### Features and Improvements
|
||||
- Fixes upload image error when no photo was scrapped
|
||||
- Fixes no last_recipe.json not updating
|
||||
- Added markdown rendering for notes
|
||||
- New notifications
|
||||
- Minor UI improvements
|
||||
- Recipe editor refactor
|
||||
- Settings/Theme models refactor
|
||||
|
||||
### Development / Misc
|
||||
- Added async file response for images, downloading files.
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
# Meal Planner
|
||||
|
||||
## Working with Meal Plans
|
||||
In Mealie you can create a mealplan 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.
|
||||
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.
|
||||
|
||||
To edit the meal in a meal plan simply select the edit button on the card in the timeline. Similarly, to delete a mealplan click the delete button on the card in the timeline. Currently there is no support to change the date range in a meal plan.
|
||||
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.
|
||||
|
||||
!!! warning
|
||||
In coming a future release recipes for meals will be restricted to specific categories.
|
||||
|
||||
## 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.
|
||||
|
||||
![](../gifs/meal-plan-demo-v2.gif)
|
||||
|
||||
|
|
|
@ -19,7 +19,9 @@ Color themes can be created and set from the UI in the settings page. You can se
|
|||
## Backups
|
||||
Site backups can easily be taken and download from the UI. To import, simply select the backup you'd like to restore and check which items you'd like to import.
|
||||
|
||||
## Meal Planner Webhooks
|
||||
## Meal Planner
|
||||
In the meal planner section you can select categories to be used as apart of the random recipe selector in the meal plan creator.
|
||||
|
||||
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 Webhooks" prior to any changes taking affect server side.
|
||||
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
23
frontend/package-lock.json
generated
23
frontend/package-lock.json
generated
|
@ -5585,10 +5585,17 @@
|
|||
"integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM="
|
||||
},
|
||||
"fast-levenshtein": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npm.taobao.org/fast-levenshtein/download/fast-levenshtein-2.0.6.tgz",
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||
"dev": true
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz",
|
||||
"integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==",
|
||||
"requires": {
|
||||
"fastest-levenshtein": "^1.0.7"
|
||||
}
|
||||
},
|
||||
"fastest-levenshtein": {
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
|
||||
"integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow=="
|
||||
},
|
||||
"faye-websocket": {
|
||||
"version": "0.11.3",
|
||||
|
@ -8334,6 +8341,14 @@
|
|||
"prelude-ls": "~1.1.2",
|
||||
"type-check": "~0.3.2",
|
||||
"word-wrap": "~1.2.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"fast-levenshtein": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"ora": {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
"@smartweb/vue-flash-message": "^0.6.10",
|
||||
"axios": "^0.21.1",
|
||||
"core-js": "^3.8.2",
|
||||
"fast-levenshtein": "^3.0.0",
|
||||
"fuse.js": "^6.4.6",
|
||||
"qs": "^6.9.6",
|
||||
"v-jsoneditor": "^1.4.2",
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<title> Mealie </title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
|
||||
<link rel="stylesheet" href="./styles/global.css">
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
*::-webkit-scrollbar {
|
||||
width: 0.25rem;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track {
|
||||
background: lightgray;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background: grey;
|
||||
}
|
|
@ -63,7 +63,7 @@ export default {
|
|||
},
|
||||
created() {
|
||||
window.addEventListener("keyup", e => {
|
||||
if (e.key == "/") {
|
||||
if (e.key == "/" && !document.activeElement.id.startsWith('input') ) {
|
||||
this.search = !this.search;
|
||||
}
|
||||
});
|
||||
|
@ -132,6 +132,25 @@ export default {
|
|||
background-color: var(--v-success-base) !important;
|
||||
}
|
||||
|
||||
.notify-base {
|
||||
color: white !important;
|
||||
margin-right: 60px;
|
||||
margin-bottom: -5px;
|
||||
opacity: 0.9 !important;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
width: 0.25rem;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track {
|
||||
background: lightgray;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background: grey;
|
||||
}
|
||||
|
||||
.notify-base {
|
||||
color: white !important;
|
||||
margin-right: 60px;
|
||||
|
|
|
@ -8,9 +8,9 @@ const backupURLs = {
|
|||
// Backup
|
||||
available: `${backupBase}available`,
|
||||
createBackup: `${backupBase}export/database`,
|
||||
importBackup: (fileName) => `${backupBase}${fileName}/import`,
|
||||
deleteBackup: (fileName) => `${backupBase}${fileName}/delete`,
|
||||
downloadBackup: (fileName) => `${backupBase}${fileName}/download`,
|
||||
importBackup: fileName => `${backupBase}${fileName}/import`,
|
||||
deleteBackup: fileName => `${backupBase}${fileName}/delete`,
|
||||
downloadBackup: fileName => `${backupBase}${fileName}/download`,
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
|
@ -8,9 +8,10 @@ const mealPlanURLs = {
|
|||
all: `${prefix}all`,
|
||||
create: `${prefix}create`,
|
||||
thisWeek: `${prefix}this-week`,
|
||||
update: (planID) => `${prefix}${planID}`,
|
||||
delete: (planID) => `${prefix}${planID}`,
|
||||
update: planID => `${prefix}${planID}`,
|
||||
delete: planID => `${prefix}${planID}`,
|
||||
today: `${prefix}today`,
|
||||
shopping: planID => `${prefix}${planID}/shopping-list`,
|
||||
};
|
||||
|
||||
export default {
|
||||
|
@ -43,4 +44,9 @@ export default {
|
|||
let response = await apiReq.put(mealPlanURLs.update(id), body);
|
||||
return response;
|
||||
},
|
||||
|
||||
async shoppingList(id) {
|
||||
let response = await apiReq.get(mealPlanURLs.shopping(id));
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@ const prefix = baseURL + "debug";
|
|||
|
||||
const debugURLs = {
|
||||
version: `${prefix}/version`,
|
||||
lastRecipe: `${prefix}/last-recipe-json`,
|
||||
};
|
||||
|
||||
export default {
|
||||
|
@ -12,4 +13,8 @@ export default {
|
|||
let response = await apiReq.get(debugURLs.version);
|
||||
return response.data;
|
||||
},
|
||||
async getLastJson() {
|
||||
let response = await apiReq.get(debugURLs.lastRecipe);
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -8,13 +8,14 @@ const prefix = baseURL + "recipes/";
|
|||
|
||||
const recipeURLs = {
|
||||
allRecipes: baseURL + "recipes",
|
||||
allRecipesByCategory: prefix + "category",
|
||||
create: prefix + "create",
|
||||
createByURL: prefix + "create-url",
|
||||
recipe: (slug) => prefix + slug,
|
||||
update: (slug) => prefix + slug,
|
||||
delete: (slug) => prefix + slug,
|
||||
recipeImage: (slug) => `${prefix}${slug}/image`,
|
||||
updateImage: (slug) => `${prefix}${slug}/image`,
|
||||
recipe: slug => prefix + slug,
|
||||
update: slug => prefix + slug,
|
||||
delete: slug => prefix + slug,
|
||||
recipeImage: slug => `${prefix}${slug}/image`,
|
||||
updateImage: slug => `${prefix}${slug}/image`,
|
||||
};
|
||||
|
||||
export default {
|
||||
|
@ -27,6 +28,14 @@ export default {
|
|||
return response;
|
||||
},
|
||||
|
||||
async getAllByCategory(categories) {
|
||||
let response = await apiReq.post(
|
||||
recipeURLs.allRecipesByCategory,
|
||||
categories
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async create(recipeData) {
|
||||
let response = await apiReq.post(recipeURLs.create, recipeData);
|
||||
return response.data;
|
||||
|
@ -67,7 +76,7 @@ export default {
|
|||
keys: recipeKeys,
|
||||
num: num,
|
||||
},
|
||||
paramsSerializer: (params) => {
|
||||
paramsSerializer: params => {
|
||||
return qs.stringify(params, { arrayFormat: "repeat" });
|
||||
},
|
||||
});
|
||||
|
|
38
frontend/src/components/Debug/LastRecipe.vue
Normal file
38
frontend/src/components/Debug/LastRecipe.vue
Normal file
|
@ -0,0 +1,38 @@
|
|||
<template>
|
||||
<v-card>
|
||||
<v-card-title>Last Scrapped JSON Data</v-card-title>
|
||||
<v-card-text>
|
||||
<VJsoneditor
|
||||
@error="logError()"
|
||||
v-model="lastRecipeJson"
|
||||
height="1500px"
|
||||
:options="jsonEditorOptions"
|
||||
/>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VJsoneditor from "v-jsoneditor";
|
||||
import api from "@/api";
|
||||
export default {
|
||||
components: { VJsoneditor },
|
||||
data() {
|
||||
return {
|
||||
lastRecipeJson: {},
|
||||
jsonEditorOptions: {
|
||||
mode: "code",
|
||||
search: false,
|
||||
mainMenuBar: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
async mounted() {
|
||||
this.lastRecipeJson = await api.meta.getLastJson();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
37
frontend/src/components/Debug/LogFile.vue
Normal file
37
frontend/src/components/Debug/LogFile.vue
Normal file
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<v-card>
|
||||
<v-card-title>Last Scrapped JSON Data</v-card-title>
|
||||
<v-card-text>
|
||||
<VJsoneditor
|
||||
@error="logError()"
|
||||
v-model="lastRecipeJson"
|
||||
height="1500px"
|
||||
:options="jsonEditorOptions"
|
||||
/>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VJsoneditor from "v-jsoneditor";
|
||||
export default {
|
||||
components: { VJsoneditor },
|
||||
data() {
|
||||
return {
|
||||
lastRecipeJson: "",
|
||||
jsonEditorOptions: {
|
||||
mode: "code",
|
||||
search: false,
|
||||
mainMenuBar: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
async mounted() {
|
||||
this.lastRecipeJson = "Hello \n 123 \n 567"
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -96,6 +96,7 @@ export default {
|
|||
return {
|
||||
isLoading: false,
|
||||
meals: [],
|
||||
items: [],
|
||||
|
||||
// Dates
|
||||
startDate: null,
|
||||
|
@ -117,11 +118,12 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
let settings = await api.settings.requestAll();
|
||||
this.items = await api.recipes.getAllByCategory(settings.planCategories);
|
||||
},
|
||||
|
||||
computed: {
|
||||
items() {
|
||||
return this.$store.getters.getRecentRecipes;
|
||||
},
|
||||
actualStartDate() {
|
||||
return Date.parse(this.startDate);
|
||||
},
|
||||
|
|
110
frontend/src/components/MealPlan/ShoppingListDialog.vue
Normal file
110
frontend/src/components/MealPlan/ShoppingListDialog.vue
Normal file
|
@ -0,0 +1,110 @@
|
|||
<template>
|
||||
<div class="text-center">
|
||||
<v-dialog v-model="dialog" width="650">
|
||||
<v-card>
|
||||
<v-card-title class="headline">
|
||||
Shopping List
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn text color="accent" @click="group = !group">
|
||||
Group (Beta)
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
<v-divider></v-divider>
|
||||
|
||||
<v-card-text v-if="group == false">
|
||||
<v-list
|
||||
dense
|
||||
v-for="(recipe, index) in ingredients"
|
||||
:key="`${index}-recipe`"
|
||||
>
|
||||
<v-subheader>{{ recipe.name }} </v-subheader>
|
||||
<v-divider></v-divider>
|
||||
|
||||
<v-list-item-group color="primary">
|
||||
<v-list-item
|
||||
v-for="(item, i) in recipe.recipeIngredient"
|
||||
:key="i"
|
||||
>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title v-text="item"></v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list-item-group>
|
||||
</v-list>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-text v-else>
|
||||
<v-list dense>
|
||||
<v-list-item-group color="primary">
|
||||
<v-list-item v-for="(item, i) in rawIngredients" :key="i">
|
||||
<v-list-item-content>
|
||||
<v-list-item-title v-text="item"></v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list-item-group>
|
||||
</v-list>
|
||||
</v-card-text>
|
||||
|
||||
<v-divider></v-divider>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from "@/api";
|
||||
const levenshtein = require("fast-levenshtein");
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialog: false,
|
||||
planID: 0,
|
||||
ingredients: [],
|
||||
rawIngredients: [],
|
||||
group: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
openDialog: function(id) {
|
||||
this.dialog = true;
|
||||
this.planID = id;
|
||||
this.getIngredients();
|
||||
},
|
||||
async getIngredients() {
|
||||
this.ingredients = await api.mealPlans.shoppingList(this.planID);
|
||||
this.getRawIngredients();
|
||||
},
|
||||
getRawIngredients() {
|
||||
this.ingredients.forEach(element => {
|
||||
this.rawIngredients.push(element.recipeIngredient);
|
||||
});
|
||||
|
||||
this.rawIngredients = this.rawIngredients.flat();
|
||||
this.rawIngredients = this.levenshteinFilter(this.rawIngredients);
|
||||
},
|
||||
levenshteinFilter(source, maximum = 5) {
|
||||
let _source, matches, x, y;
|
||||
_source = source.slice();
|
||||
matches = [];
|
||||
for (x = _source.length - 1; x >= 0; x--) {
|
||||
let output = _source.splice(x, 1);
|
||||
for (y = _source.length - 1; y >= 0; y--) {
|
||||
if (levenshtein.get(output[0], _source[y]) <= maximum) {
|
||||
output.push(_source[y]);
|
||||
_source.splice(y, 1);
|
||||
x--;
|
||||
}
|
||||
}
|
||||
matches.push(output);
|
||||
}
|
||||
return matches.flat();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -1,50 +1,58 @@
|
|||
<template>
|
||||
<v-card
|
||||
color="accent"
|
||||
class="custom-transparent"
|
||||
class="custom-transparent d-flex justify-start align-center text-center "
|
||||
tile
|
||||
:width="`${timeCardWidth}`"
|
||||
v-if="totalTime || prepTime || performTime"
|
||||
>
|
||||
<v-card-text
|
||||
class="text-caption white--text"
|
||||
v-if="totalTime || prepTime || performTime"
|
||||
<v-card flat color="rgb(255, 0, 0, 0.0)">
|
||||
<v-icon large color="white" class="mx-2"> mdi-clock-outline </v-icon>
|
||||
</v-card>
|
||||
|
||||
<v-divider vertical color="white" class="py-1" v-if="totalTime">
|
||||
</v-divider>
|
||||
<v-card flat color="rgb(255, 0, 0, 0.0)" class=" my-2 " v-if="totalTime">
|
||||
<v-card-text class="white--text">
|
||||
<div>
|
||||
<strong> {{ $t("recipe.total-time") }} </strong>
|
||||
</div>
|
||||
<div>{{ totalTime }}</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<v-divider vertical color="white" class="py-1" v-if="prepTime"> </v-divider>
|
||||
|
||||
<v-card
|
||||
flat
|
||||
color="rgb(255, 0, 0, 0.0)"
|
||||
class="white--text my-2 "
|
||||
v-if="prepTime"
|
||||
>
|
||||
<v-row align="center" dense>
|
||||
<v-col :cols="iconColumn">
|
||||
<v-icon large color="white"> mdi-clock-outline </v-icon>
|
||||
</v-col>
|
||||
<v-divider
|
||||
vertical
|
||||
color="white"
|
||||
class="my-1"
|
||||
v-if="totalTime"
|
||||
></v-divider>
|
||||
<v-col v-if="totalTime">
|
||||
<div><strong> {{ $t("recipe.total-time") }} </strong></div>
|
||||
<div>{{ totalTime }}</div>
|
||||
</v-col>
|
||||
<v-divider
|
||||
vertical
|
||||
color="white"
|
||||
class="my-1"
|
||||
v-if="prepTime"
|
||||
></v-divider>
|
||||
<v-col v-if="prepTime">
|
||||
<div><strong> {{ $t("recipe.prep-time") }} </strong></div>
|
||||
<div>{{ prepTime }}</div>
|
||||
</v-col>
|
||||
<v-divider
|
||||
vertical
|
||||
color="white"
|
||||
class="my-1"
|
||||
v-if="performTime"
|
||||
></v-divider>
|
||||
<v-col v-if="performTime">
|
||||
<div><strong> {{ $t("recipe.perform-time") }} </strong></div>
|
||||
<div>{{ performTime }}</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
<v-card-text class="white--text">
|
||||
<div>
|
||||
<strong> {{ $t("recipe.prep-time") }} </strong>
|
||||
</div>
|
||||
<div>{{ prepTime }}</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<v-divider vertical color="white" class="my-1" v-if="performTime">
|
||||
</v-divider>
|
||||
|
||||
<v-card
|
||||
flat
|
||||
color="rgb(255, 0, 0, 0.0)"
|
||||
class="white--text py-2 "
|
||||
v-if="performTime"
|
||||
>
|
||||
<v-card-text class="white--text">
|
||||
<div>
|
||||
<strong> {{ $t("recipe.perform-time") }} </strong>
|
||||
</div>
|
||||
<div>{{ performTime }}</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
|
@ -59,7 +67,7 @@ export default {
|
|||
timeLength() {
|
||||
let times = [];
|
||||
let timeArray = [this.totalTime, this.prepTime, this.performTime];
|
||||
timeArray.forEach((element) => {
|
||||
timeArray.forEach(element => {
|
||||
if (element) {
|
||||
times.push(element);
|
||||
}
|
||||
|
@ -83,10 +91,10 @@ export default {
|
|||
},
|
||||
timeCardWidth() {
|
||||
let timeArray = [this.totalTime, this.prepTime, this.performTime];
|
||||
let width = 120;
|
||||
timeArray.forEach((element) => {
|
||||
let width = 80;
|
||||
timeArray.forEach(element => {
|
||||
if (element) {
|
||||
width += 70;
|
||||
width += 95;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
/>
|
||||
<v-row>
|
||||
<v-col
|
||||
:cols="12"
|
||||
:sm="6"
|
||||
:md="6"
|
||||
:lg="4"
|
||||
|
@ -19,14 +20,14 @@
|
|||
<v-card hover outlined @click="openDialog(backup)">
|
||||
<v-card-text>
|
||||
<v-row align="center">
|
||||
<v-col cols="12" sm="2">
|
||||
<v-icon large color="primary"> mdi-backup-restore </v-icon>
|
||||
<v-col cols="2">
|
||||
<v-icon large color="primary">mdi-backup-restore</v-icon>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="10">
|
||||
<div>
|
||||
<v-col cols="10">
|
||||
<div class="text-truncate">
|
||||
<strong>{{ backup.name }}</strong>
|
||||
</div>
|
||||
<div>{{ readableTime(backup.date) }}</div>
|
||||
<div class="text-truncate">{{ readableTime(backup.date) }}</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
|
@ -68,10 +69,9 @@ export default {
|
|||
this.$emit("loading");
|
||||
let response = await api.backups.import(data.name, data);
|
||||
|
||||
let failed = response.data.failed;
|
||||
let succesful = response.data.successful;
|
||||
let importData = response.data;
|
||||
|
||||
this.$emit("finished", succesful, failed);
|
||||
this.$emit("finished", importData);
|
||||
},
|
||||
deleteBackup(data) {
|
||||
this.$emit("loading");
|
||||
|
|
|
@ -1,7 +1,23 @@
|
|||
<template>
|
||||
<div class="text-center">
|
||||
<v-dialog v-model="dialog" width="500">
|
||||
<v-dialog
|
||||
v-model="dialog"
|
||||
width="500"
|
||||
:fullscreen="$vuetify.breakpoint.xsOnly"
|
||||
>
|
||||
<v-card>
|
||||
<v-toolbar dark color="primary" v-show="$vuetify.breakpoint.xsOnly">
|
||||
<v-btn icon dark @click="dialog = false">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
<v-toolbar-title></v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-toolbar-items>
|
||||
<v-btn dark text @click="raiseEvent('import')">
|
||||
{{ $t("general.import") }}
|
||||
</v-btn>
|
||||
</v-toolbar-items>
|
||||
</v-toolbar>
|
||||
<v-card-title> {{ name }} </v-card-title>
|
||||
<v-card-subtitle class="mb-n3"> {{ date }} </v-card-subtitle>
|
||||
<v-divider></v-divider>
|
||||
|
@ -72,7 +88,12 @@
|
|||
<v-btn color="error" text @click="raiseEvent('delete')">
|
||||
{{ $t("general.delete") }}
|
||||
</v-btn>
|
||||
<v-btn color="success" outlined @click="raiseEvent('import')">
|
||||
<v-btn
|
||||
color="success"
|
||||
outlined
|
||||
@click="raiseEvent('import')"
|
||||
v-show="$vuetify.breakpoint.smAndUp"
|
||||
>
|
||||
{{ $t("general.import") }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<template>
|
||||
<div>
|
||||
<v-data-table
|
||||
dense
|
||||
:headers="dataHeaders"
|
||||
:items="dataSet"
|
||||
item-key="name"
|
||||
class="elevation-1 mt-2"
|
||||
show-expand
|
||||
:expanded.sync="expanded"
|
||||
:footer-props="{
|
||||
'items-per-page-options': [100, 200, 300, 400, -1],
|
||||
}"
|
||||
:items-per-page="100"
|
||||
>
|
||||
<template v-slot:item.status="{ item }">
|
||||
<div :class="item.status ? 'success--text' : 'error--text'">
|
||||
{{ item.status ? "Imported" : "Failed" }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:expanded-item="{ headers, item }">
|
||||
<td :colspan="headers.length">
|
||||
<div class="ma-2">
|
||||
{{ item.exception }}
|
||||
</div>
|
||||
</td>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
dataSet: Array,
|
||||
dataHeaders: Array,
|
||||
},
|
||||
data: () => ({
|
||||
singleExpand: false,
|
||||
expanded: [],
|
||||
}),
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -0,0 +1,152 @@
|
|||
<template>
|
||||
<div class="text-center">
|
||||
<v-dialog v-model="dialog" width="70%">
|
||||
<v-card>
|
||||
<v-card-title> Import Summary </v-card-title>
|
||||
<v-card-text>
|
||||
<v-row class="mb-n9">
|
||||
<v-card flat>
|
||||
<v-card-text>
|
||||
<div>
|
||||
<h3>Recipes</h3>
|
||||
</div>
|
||||
<div class="success--text">
|
||||
Success: {{ recipeNumbers.success }}
|
||||
</div>
|
||||
<div class="error--text">
|
||||
Failed: {{ recipeNumbers.failure }}
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
<v-card flat>
|
||||
<v-card-text>
|
||||
<div>
|
||||
<h3>Themes</h3>
|
||||
</div>
|
||||
<div class="success--text">
|
||||
Success: {{ themeNumbers.success }}
|
||||
</div>
|
||||
<div class="error--text">
|
||||
Failed: {{ themeNumbers.failure }}
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
<v-card flat>
|
||||
<v-card-text>
|
||||
<div>
|
||||
<h3>Settings</h3>
|
||||
</div>
|
||||
<div class="success--text">
|
||||
Success: {{ settingsNumbers.success }}
|
||||
</div>
|
||||
<div class="error--text">
|
||||
Failed: {{ settingsNumbers.failure }}
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
<v-tabs v-model="tab">
|
||||
<v-tab>Recipes</v-tab>
|
||||
<v-tab>Themes</v-tab>
|
||||
<v-tab>Settings</v-tab>
|
||||
</v-tabs>
|
||||
<v-tabs-items v-model="tab">
|
||||
<v-tab-item>
|
||||
<v-card flat>
|
||||
<DataTable :data-headers="recipeHeaders" :data-set="recipeData" />
|
||||
</v-card>
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<v-card>
|
||||
<DataTable
|
||||
:data-headers="recipeHeaders"
|
||||
:data-set="themeData"
|
||||
/> </v-card
|
||||
></v-tab-item>
|
||||
<v-tab-item>
|
||||
<v-card
|
||||
><DataTable
|
||||
:data-headers="recipeHeaders"
|
||||
:data-set="settingsData"
|
||||
/>
|
||||
</v-card>
|
||||
</v-tab-item>
|
||||
</v-tabs-items>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DataTable from "./DataTable";
|
||||
export default {
|
||||
components: {
|
||||
DataTable,
|
||||
},
|
||||
data: () => ({
|
||||
tab: null,
|
||||
dialog: false,
|
||||
recipeData: [],
|
||||
themeData: [],
|
||||
settingsData: [],
|
||||
recipeHeaders: [
|
||||
{
|
||||
text: "Status",
|
||||
value: "status",
|
||||
},
|
||||
{
|
||||
text: "Name",
|
||||
align: "start",
|
||||
sortable: true,
|
||||
value: "name",
|
||||
},
|
||||
|
||||
{ text: "Exception", value: "data-table-expand", align: "center" },
|
||||
],
|
||||
allDataTables: [],
|
||||
}),
|
||||
|
||||
computed: {
|
||||
recipeNumbers() {
|
||||
let numbers = { success: 0, failure: 0 };
|
||||
this.recipeData.forEach(element => {
|
||||
if (element.status) {
|
||||
numbers.success++;
|
||||
} else numbers.failure++;
|
||||
});
|
||||
return numbers;
|
||||
},
|
||||
settingsNumbers() {
|
||||
let numbers = { success: 0, failure: 0 };
|
||||
this.settingsData.forEach(element => {
|
||||
if (element.status) {
|
||||
numbers.success++;
|
||||
} else numbers.failure++;
|
||||
});
|
||||
return numbers;
|
||||
},
|
||||
themeNumbers() {
|
||||
let numbers = { success: 0, failure: 0 };
|
||||
this.themeData.forEach(element => {
|
||||
if (element.status) {
|
||||
numbers.success++;
|
||||
} else numbers.failure++;
|
||||
});
|
||||
return numbers;
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
open(importData) {
|
||||
this.recipeData = importData.recipeImports;
|
||||
this.themeData = importData.themeReport;
|
||||
this.settingsData = importData.settingsReport;
|
||||
this.dialog = true;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -8,7 +8,7 @@
|
|||
v-model="tag"
|
||||
></v-text-field>
|
||||
</v-card-text>
|
||||
<v-card-actions class="mt-n9">
|
||||
<v-card-actions class="mt-n9 flex-wrap">
|
||||
<v-switch v-model="fullBackup" :label="switchLabel"></v-switch>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="success" text @click="createBackup()">
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<v-col cols="12" md="6" ss="12">
|
||||
<v-col cols="12" md="6" sm="12">
|
||||
<NewBackupCard @created="processFinished" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="6" sm="12">
|
||||
|
@ -41,6 +41,7 @@
|
|||
:failed-header="$t('settings.backup.failed-imports')"
|
||||
:failed="failedImports"
|
||||
/>
|
||||
<ImportSummaryDialog ref="report" :import-data="importData" />
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</template>
|
||||
|
@ -48,6 +49,7 @@
|
|||
<script>
|
||||
import api from "@/api";
|
||||
import SuccessFailureAlert from "../../UI/SuccessFailureAlert";
|
||||
import ImportSummaryDialog from "./ImportSummaryDialog";
|
||||
import UploadBtn from "../../UI/UploadBtn";
|
||||
import AvailableBackupCard from "./AvailableBackupCard";
|
||||
import NewBackupCard from "./NewBackupCard";
|
||||
|
@ -58,6 +60,7 @@ export default {
|
|||
UploadBtn,
|
||||
AvailableBackupCard,
|
||||
NewBackupCard,
|
||||
ImportSummaryDialog,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -65,6 +68,7 @@ export default {
|
|||
successfulImports: [],
|
||||
backupLoading: false,
|
||||
availableBackups: [],
|
||||
importData: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
@ -87,12 +91,10 @@ export default {
|
|||
this.backupLoading = false;
|
||||
}
|
||||
},
|
||||
processFinished(successful = null, failed = null) {
|
||||
processFinished(data) {
|
||||
this.getAvailableBackups();
|
||||
this.backupLoading = false;
|
||||
this.successfulImports = successful;
|
||||
this.failedImports = failed;
|
||||
this.$refs.report.open();
|
||||
this.$refs.report.open(data);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
<v-card-text>
|
||||
<h2 class="mt-1 mb-1">Home Page</h2>
|
||||
<v-row align="center" justify="center" dense class="mb-n7 pb-n5">
|
||||
<v-col sm="2">
|
||||
<v-col cols="12" sm="3" md="2">
|
||||
<v-switch v-model="showRecent" label="Show Recent"></v-switch>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-col cols="12" sm="5" md="5">
|
||||
<v-slider
|
||||
class="pt-4"
|
||||
class="pt-sm-4"
|
||||
label="Card Per Section"
|
||||
v-model="showLimit"
|
||||
max="30"
|
||||
|
@ -24,7 +24,7 @@
|
|||
</v-card-text>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-col cols="12" sm="6">
|
||||
<v-card outlined min-height="250">
|
||||
<v-card-text class="pt-2 pb-1">
|
||||
<h3>Homepage Categories</h3>
|
||||
|
@ -64,7 +64,7 @@
|
|||
</v-list>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-col cols="12" sm="6">
|
||||
<v-card outlined min-height="250px">
|
||||
<v-card-text class="pt-2 pb-1">
|
||||
<h3>
|
||||
|
|
|
@ -11,12 +11,10 @@
|
|||
</span>
|
||||
</v-card-title>
|
||||
<v-divider></v-divider>
|
||||
<HomePageSettings />
|
||||
<v-divider></v-divider>
|
||||
<v-card-text>
|
||||
<h2 class="mt-1 mb-4">{{ $t("settings.language") }}</h2>
|
||||
<v-row>
|
||||
<v-col cols="3">
|
||||
<v-col sm="3">
|
||||
<v-select
|
||||
dense
|
||||
v-model="selectedLang"
|
||||
|
@ -30,6 +28,8 @@
|
|||
</v-row>
|
||||
</v-card-text>
|
||||
<v-divider></v-divider>
|
||||
<HomePageSettings />
|
||||
<v-divider></v-divider>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
|
@ -59,6 +59,9 @@ export default {
|
|||
this.langOptions = this.$store.getters.getAllLangs;
|
||||
this.selectedLang = this.$store.getters.getActiveLang;
|
||||
},
|
||||
removeCategory(index) {
|
||||
this.value.categories.splice(index, 1);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,9 +1,49 @@
|
|||
<template>
|
||||
<v-card>
|
||||
<v-card-title class="headline">
|
||||
{{ $t("settings.webhooks.meal-planner-webhooks") }}
|
||||
{{ $t("meal-plan.meal-planner") }}
|
||||
</v-card-title>
|
||||
<v-divider></v-divider>
|
||||
<v-card-text>
|
||||
<h2 class="mt-1">{{ $t("recipe.categories") }}</h2>
|
||||
|
||||
<v-row>
|
||||
<v-col sm="12" md="6">
|
||||
<v-select
|
||||
outlined
|
||||
:flat="isFlat"
|
||||
elavation="0"
|
||||
v-model="planCategories"
|
||||
:items="categories"
|
||||
item-text="name"
|
||||
item-value="name"
|
||||
multiple
|
||||
chips
|
||||
hint="Only recipes with these categories will be used in Meal Plans"
|
||||
class="mt-2"
|
||||
persistent-hint
|
||||
>
|
||||
<template v-slot:selection="data">
|
||||
<v-chip
|
||||
outlined
|
||||
:input-value="data.selected"
|
||||
close
|
||||
@click:close="removeCategory(data.index)"
|
||||
color="secondary"
|
||||
dark
|
||||
>
|
||||
{{ data.item.name }}
|
||||
</v-chip>
|
||||
</template>
|
||||
</v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
<v-divider> </v-divider>
|
||||
<v-card-text>
|
||||
<h2 class="mt-1 mb-4">
|
||||
{{ $t("settings.webhooks.meal-planner-webhooks") }}
|
||||
</h2>
|
||||
<p>
|
||||
{{
|
||||
$t(
|
||||
|
@ -68,11 +108,20 @@ export default {
|
|||
webhooks: [],
|
||||
enabled: false,
|
||||
time: "",
|
||||
planCategories: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getSiteSettings();
|
||||
},
|
||||
computed: {
|
||||
categories() {
|
||||
return this.$store.getters.getCategories;
|
||||
},
|
||||
isFlat() {
|
||||
return this.planCategories ? true : false;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
saveTime(value) {
|
||||
this.time = value;
|
||||
|
@ -83,6 +132,7 @@ export default {
|
|||
this.name = settings.name;
|
||||
this.time = settings.webhooks.webhookTime;
|
||||
this.enabled = settings.webhooks.enabled;
|
||||
this.planCategories = settings.planCategories;
|
||||
},
|
||||
addWebhook() {
|
||||
this.webhooks.push(" ");
|
||||
|
@ -93,6 +143,7 @@ export default {
|
|||
saveWebhooks() {
|
||||
const body = {
|
||||
name: this.name,
|
||||
planCategories: this.planCategories,
|
||||
webhooks: {
|
||||
webhookURLs: this.webhooks,
|
||||
webhookTime: this.time,
|
||||
|
@ -104,6 +155,9 @@ export default {
|
|||
testWebhooks() {
|
||||
api.settings.testWebhooks();
|
||||
},
|
||||
removeCategory(index) {
|
||||
this.planCategories.splice(index, 1);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -21,14 +21,16 @@
|
|||
>
|
||||
<v-card-text>
|
||||
<v-row align="center">
|
||||
<v-col cols="12" sm="2">
|
||||
<v-icon large color="primary"> mdi-import </v-icon>
|
||||
<v-col cols="2">
|
||||
<v-icon large color="primary">mdi-import</v-icon>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="10">
|
||||
<div>
|
||||
<v-col cols="10">
|
||||
<div class="text-truncate">
|
||||
<strong>{{ migration.name }}</strong>
|
||||
</div>
|
||||
<div>{{ readableTime(migration.date) }}</div>
|
||||
<div class="text-truncate">
|
||||
{{ readableTime(migration.date) }}
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
|
||||
<v-row dense>
|
||||
<v-col
|
||||
:sm="12"
|
||||
:cols="12"
|
||||
:sm="6"
|
||||
:md="6"
|
||||
:lg="4"
|
||||
:xl="3"
|
||||
|
|
|
@ -3,7 +3,13 @@
|
|||
<div class="text-center">
|
||||
<h3>{{ buttonText }}</h3>
|
||||
</div>
|
||||
<v-text-field v-model="color" hide-details class="ma-0 pa-0" solo>
|
||||
<v-text-field
|
||||
v-model="color"
|
||||
hide-details
|
||||
class="ma-0 pa-0"
|
||||
solo
|
||||
v-show="$vuetify.breakpoint.mdAndUp"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<v-menu
|
||||
v-model="menu"
|
||||
|
@ -17,12 +23,27 @@
|
|||
</template>
|
||||
<v-card>
|
||||
<v-card-text class="pa-0">
|
||||
<v-color-picker v-model="color" flat show-swatches />
|
||||
<v-color-picker v-model="color" flat mode="hexa" show-swatches />
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
</template>
|
||||
</v-text-field>
|
||||
<div class="text-center" v-show="$vuetify.breakpoint.smAndDown">
|
||||
<v-menu
|
||||
v-model="menu"
|
||||
top
|
||||
nudge-bottom="105"
|
||||
nudge-left="16"
|
||||
:close-on-content-click="false"
|
||||
>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-chip label :color="`${color}`" dark v-bind="attrs" v-on="on">
|
||||
{{ color }}
|
||||
</v-chip>
|
||||
</template>
|
||||
</v-menu>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -36,7 +57,7 @@ export default {
|
|||
return {
|
||||
dialog: false,
|
||||
swatches: false,
|
||||
color: "#1976D2",
|
||||
color: this.value || "#1976D2",
|
||||
mask: "!#XXXXXXXX",
|
||||
menu: false,
|
||||
};
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
}}
|
||||
</p>
|
||||
<v-row dense align="center">
|
||||
<v-col cols="12">
|
||||
<v-col cols="6">
|
||||
<v-btn-toggle
|
||||
v-model="selectedDarkMode"
|
||||
color="primary "
|
||||
|
@ -22,12 +22,25 @@
|
|||
@change="setStoresDarkMode"
|
||||
>
|
||||
<v-btn value="system">
|
||||
{{ $t("settings.theme.default-to-system") }}
|
||||
<v-icon>mdi-desktop-tower-monitor</v-icon>
|
||||
<span class="ml-1" v-show="$vuetify.breakpoint.smAndUp">
|
||||
{{ $t("settings.theme.default-to-system") }}
|
||||
</span>
|
||||
</v-btn>
|
||||
|
||||
<v-btn value="light"> {{ $t("settings.theme.light") }} </v-btn>
|
||||
<v-btn value="light">
|
||||
<v-icon>mdi-white-balance-sunny</v-icon>
|
||||
<span class="ml-1" v-show="$vuetify.breakpoint.smAndUp">
|
||||
{{ $t("settings.theme.light") }}
|
||||
</span>
|
||||
</v-btn>
|
||||
|
||||
<v-btn value="dark"> {{ $t("settings.theme.dark") }} </v-btn>
|
||||
<v-btn value="dark">
|
||||
<v-icon>mdi-weather-night</v-icon>
|
||||
<span class="ml-1" v-show="$vuetify.breakpoint.smAndUp">
|
||||
{{ $t("settings.theme.dark") }}
|
||||
</span>
|
||||
</v-btn>
|
||||
</v-btn-toggle>
|
||||
</v-col>
|
||||
</v-row></v-card-text
|
||||
|
@ -45,7 +58,7 @@
|
|||
|
||||
<v-form ref="form" lazy-validation>
|
||||
<v-row dense align="center">
|
||||
<v-col md="4" sm="3">
|
||||
<v-col cols="12" md="4" sm="3">
|
||||
<v-select
|
||||
:label="$t('settings.theme.saved-color-theme')"
|
||||
:items="availableThemes"
|
||||
|
|
|
@ -7,10 +7,14 @@
|
|||
</v-card-title>
|
||||
|
||||
<v-card-text>
|
||||
<v-form>
|
||||
<v-form ref="urlForm">
|
||||
<v-text-field
|
||||
v-model="recipeURL"
|
||||
:label="$t('new-recipe.recipe-url')"
|
||||
required
|
||||
validate-on-blur
|
||||
autofocus
|
||||
:rules="[isValidWebUrl]"
|
||||
></v-text-field>
|
||||
</v-form>
|
||||
|
||||
|
@ -64,18 +68,20 @@ export default {
|
|||
|
||||
methods: {
|
||||
async createRecipe() {
|
||||
this.processing = true;
|
||||
let response = await api.recipes.createByURL(this.recipeURL);
|
||||
if (response.status !== 201) {
|
||||
this.error = true;
|
||||
this.processing = false;
|
||||
return;
|
||||
}
|
||||
if (this.$refs.urlForm.validate()) {
|
||||
this.processing = true;
|
||||
let response = await api.recipes.createByURL(this.recipeURL);
|
||||
if (response.status !== 201) {
|
||||
this.error = true;
|
||||
this.processing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.addRecipe = false;
|
||||
this.processing = false;
|
||||
this.recipeURL = "";
|
||||
this.$router.push(`/recipe/${response.data}`);
|
||||
this.addRecipe = false;
|
||||
this.processing = false;
|
||||
this.recipeURL = "";
|
||||
this.$router.push(`/recipe/${response.data}`);
|
||||
}
|
||||
},
|
||||
|
||||
navCreate() {
|
||||
|
@ -89,6 +95,10 @@ export default {
|
|||
this.recipeURL = "";
|
||||
this.processing = false;
|
||||
},
|
||||
isValidWebUrl(url) {
|
||||
let regEx = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)$/gm;
|
||||
return regEx.test(url) ? true : "Must be a Valid URL";
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,20 +1,43 @@
|
|||
<template>
|
||||
<v-navigation-drawer width="175px" clipped app permanent expand-on-hover>
|
||||
<v-list nav dense>
|
||||
<v-list-item v-for="nav in links" :key="nav.title" link :to="nav.to">
|
||||
<v-list-item-icon>
|
||||
<v-icon>{{ nav.icon }}</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>{{ nav.title | titleCase }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-navigation-drawer>
|
||||
<div>
|
||||
<v-btn
|
||||
class="mt-9 ml-n1"
|
||||
fixed
|
||||
left
|
||||
bottom
|
||||
fab
|
||||
small
|
||||
color="primary"
|
||||
@click="showSidebar = !showSidebar"
|
||||
>
|
||||
<v-icon>mdi-tag</v-icon></v-btn
|
||||
>
|
||||
|
||||
<v-navigation-drawer
|
||||
:value="mobile ? showSidebar : true"
|
||||
v-model="showSidebar"
|
||||
width="175px"
|
||||
clipped
|
||||
app
|
||||
>
|
||||
<v-list nav dense>
|
||||
<v-list-item v-for="nav in links" :key="nav.title" link :to="nav.to">
|
||||
<v-list-item-icon>
|
||||
<v-icon>{{ nav.icon }}</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>{{ nav.title | titleCase }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-navigation-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showSidebar: false,
|
||||
mobile: false,
|
||||
links: [],
|
||||
baseLinks: [
|
||||
{
|
||||
|
@ -39,16 +62,20 @@ export default {
|
|||
allCategories() {
|
||||
this.buildSidebar();
|
||||
},
|
||||
showSidebar() {
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.buildSidebar();
|
||||
this.mobile = this.viewScale();
|
||||
this.showSidebar = !this.viewScale();
|
||||
},
|
||||
|
||||
methods: {
|
||||
async buildSidebar() {
|
||||
this.links = [];
|
||||
this.links.push(...this.baseLinks);
|
||||
this.allCategories.forEach(async (element) => {
|
||||
this.allCategories.forEach(async element => {
|
||||
this.links.push({
|
||||
title: element.name,
|
||||
to: `/recipes/${element.slug}`,
|
||||
|
@ -56,6 +83,16 @@ export default {
|
|||
});
|
||||
});
|
||||
},
|
||||
viewScale() {
|
||||
switch (this.$vuetify.breakpoint.name) {
|
||||
case "xs":
|
||||
return true;
|
||||
case "sm":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -6,8 +6,24 @@
|
|||
:to="route ? `/recipe/${slug}` : ''"
|
||||
@click="$emit('click')"
|
||||
>
|
||||
<v-img height="200" :src="getImage(image)"></v-img>
|
||||
<v-card-title class="my-n3 mb-n6">{{ name | truncate(30) }}</v-card-title>
|
||||
<v-img height="200" :src="getImage(image)">
|
||||
<v-expand-transition v-if="description">
|
||||
<div
|
||||
v-if="hover"
|
||||
class="d-flex transition-fast-in-fast-out secondary v-card--reveal "
|
||||
style="height: 100%;"
|
||||
>
|
||||
<v-card-text class="v-card--text-show white--text">
|
||||
{{ description | truncate(300) }}
|
||||
</v-card-text>
|
||||
</div>
|
||||
</v-expand-transition>
|
||||
</v-img>
|
||||
<v-card-title class="my-n3 mb-n6 ">
|
||||
<div class="headerClass">
|
||||
{{ name }}
|
||||
</div>
|
||||
</v-card-title>
|
||||
|
||||
<v-card-actions class="">
|
||||
<v-row dense align="center">
|
||||
|
@ -23,16 +39,7 @@
|
|||
></v-rating>
|
||||
</v-col>
|
||||
<v-col></v-col>
|
||||
<v-col align="end">
|
||||
<v-tooltip top color="secondary" max-width="400" open-delay="50">
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn color="secondary" v-on="on" v-bind="attrs" text>{{
|
||||
$t("recipe.description")
|
||||
}}</v-btn>
|
||||
</template>
|
||||
<span>{{ description }}</span>
|
||||
</v-tooltip>
|
||||
</v-col>
|
||||
<v-col align="end"> </v-col>
|
||||
</v-row>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
|
@ -61,4 +68,21 @@ export default {
|
|||
</script>
|
||||
|
||||
<style>
|
||||
.v-card--reveal {
|
||||
align-items: center;
|
||||
bottom: 0;
|
||||
justify-content: center;
|
||||
opacity: 0.8;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
.v-card--text-show {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.headerClass {
|
||||
white-space: nowrap;
|
||||
word-break: normal;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
|
@ -57,6 +57,7 @@ export default {
|
|||
return {
|
||||
searchSlug: "",
|
||||
search: " ",
|
||||
data: [],
|
||||
result: [],
|
||||
autoResults: [],
|
||||
isDark: false,
|
||||
|
@ -67,27 +68,30 @@ export default {
|
|||
distance: 100,
|
||||
maxPatternLength: 32,
|
||||
minMatchCharLength: 1,
|
||||
keys: ["name", "slug"],
|
||||
keys: ["name", "slug", "description"],
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.isDark = this.$store.getters.getIsDark;
|
||||
this.data = this.$store.getters.getRecentRecipes;
|
||||
},
|
||||
computed: {
|
||||
data() {
|
||||
return this.$store.getters.getRecentRecipes;
|
||||
},
|
||||
fuse() {
|
||||
return new Fuse(this.data, this.options);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
search() {
|
||||
if (this.search.trim() === "") this.result = this.list;
|
||||
else this.result = this.fuse.search(this.search.trim());
|
||||
|
||||
try {
|
||||
this.result = this.fuse.search(this.search.trim());
|
||||
} catch {
|
||||
this.result = this.data
|
||||
.map(x => ({ item: x }))
|
||||
.sort((a, b) => (a.name > b.name ? 1 : -1));
|
||||
}
|
||||
this.$emit("results", this.result);
|
||||
|
||||
if (this.showResults === true) {
|
||||
this.autoResults = this.result;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="text-center">
|
||||
<v-dialog v-model="dialog" min-height="700" max-width="1000">
|
||||
<v-dialog v-model="dialog" height="100%" max-width="1200">
|
||||
<v-card min-height="725" height="100%">
|
||||
<v-card-text>
|
||||
<v-card-title></v-card-title>
|
||||
|
@ -22,7 +22,7 @@
|
|||
:md="6"
|
||||
:lg="4"
|
||||
:xl="3"
|
||||
v-for="item in searchResults.slice(0, 10)"
|
||||
v-for="item in searchResults.slice(0, 24)"
|
||||
:key="item.item.name"
|
||||
>
|
||||
<RecipeCard
|
||||
|
|
|
@ -1,7 +1,21 @@
|
|||
<template>
|
||||
<v-dialog v-model="dialog" max-width="900px">
|
||||
<v-dialog
|
||||
v-model="dialog"
|
||||
max-width="900px"
|
||||
:fullscreen="$vuetify.breakpoint.xsOnly"
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title> {{ title }} </v-card-title>
|
||||
<v-toolbar dark color="primary" v-show="$vuetify.breakpoint.xsOnly">
|
||||
<v-btn icon dark @click="dialog = false">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
<v-toolbar-title>{{ title }}</v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-toolbar-items></v-toolbar-items>
|
||||
</v-toolbar>
|
||||
<v-card-title v-show="$vuetify.breakpoint.smAndUp">
|
||||
{{ title }}
|
||||
</v-card-title>
|
||||
<v-card-text class="mt-3">
|
||||
<v-row>
|
||||
<v-col>
|
||||
|
|
158
frontend/src/locales/de.json
Normal file
158
frontend/src/locales/de.json
Normal file
|
@ -0,0 +1,158 @@
|
|||
{
|
||||
"404": {
|
||||
"page-not-found": "404 Seite nicht gefunden",
|
||||
"take-me-home": "Zurück"
|
||||
},
|
||||
"new-recipe": {
|
||||
"from-url": "Von URL",
|
||||
"recipe-url": "Rezept URL",
|
||||
"error-message": "Ein Fehler ist beim import der URL aufgetreten. Überprüfe das Log sowie debug/last_recipe.json um zu sehen was schief gelaufen ist.",
|
||||
"bulk-add": "Massenimport",
|
||||
"paste-in-your-recipe-data-each-line-will-be-treated-as-an-item-in-a-list": "Füge deine Rezeptdaten ein. Jede Zeile wird als Eintrag in einer Liste dargestellt"
|
||||
},
|
||||
"general": {
|
||||
"upload": "Hochladen",
|
||||
"submit": "Einfügen",
|
||||
"name": "Name",
|
||||
"settings": "Einstellungen",
|
||||
"close": "Schließen",
|
||||
"save": "Speichern",
|
||||
"image-file": "Bilddatei",
|
||||
"update": "Aktualisieren",
|
||||
"edit": "Bearbeiten",
|
||||
"delete": "Löschen",
|
||||
"select": "Auswählen",
|
||||
"random": "Zufall",
|
||||
"new": "Neu",
|
||||
"create": "Erstellen",
|
||||
"cancel": "Abbrechen",
|
||||
"ok": "OK",
|
||||
"enabled": "Aktiviert",
|
||||
"download": "Herunterladen",
|
||||
"import": "Importieren",
|
||||
"options": "Optionen",
|
||||
"templates": "Vorlagen",
|
||||
"recipes": "Rezepte",
|
||||
"themes": "Themen",
|
||||
"confirm": "Besstätigen"
|
||||
},
|
||||
"login": {
|
||||
"stay-logged-in": "Eingeloggt bleiben?",
|
||||
"email": "Email",
|
||||
"password": "Passwort",
|
||||
"sign-in": "Einloggen",
|
||||
"sign-up": "Registrieren"
|
||||
},
|
||||
"meal-plan": {
|
||||
"dinner-this-week": "Essen diese Woche",
|
||||
"dinner-today": "Heutiges Essen",
|
||||
"planner": "Planer",
|
||||
"edit-meal-plan": "Essensplan bearbeiten",
|
||||
"meal-plans": "Essenspläne",
|
||||
"create-a-new-meal-plan": "Neuen Essensplan erstellen",
|
||||
"start-date": "Start-Datum",
|
||||
"end-date": "End-Datum"
|
||||
},
|
||||
"recipe": {
|
||||
"description": "Beschreibung",
|
||||
"ingredients": "Zutaten",
|
||||
"categories": "Kategorien",
|
||||
"tags": "Markierungen",
|
||||
"instructions": "Anweisungen",
|
||||
"step-index": "Schritt: {step}",
|
||||
"recipe-name": "Rezeptname",
|
||||
"servings": "Portionen",
|
||||
"ingredient": "Zutat",
|
||||
"notes": "Notizen",
|
||||
"note": "Notiz",
|
||||
"original-url": "Original URL",
|
||||
"view-recipe": "Rezept anschauen",
|
||||
"title": "Titel",
|
||||
"total-time": "Gesamtzeit",
|
||||
"prep-time": "Vorbereitungszeit",
|
||||
"perform-time": "Kochzeit",
|
||||
"api-extras": "API Extras",
|
||||
"object-key": "Objektschlüssel",
|
||||
"object-value": "Objektwert",
|
||||
"new-key-name": "Neuer Schlüsselname",
|
||||
"add-key": "Schlüssel hinzufügen",
|
||||
"key-name-required": "Schlüsselname benötigt",
|
||||
"no-white-space-allowed": "Keine Leerschritte erlaubt",
|
||||
"delete-recipe": "Rezept löschen",
|
||||
"delete-confirmation": "Bist du sicher das du dieses Rezept löschen möchtest?"
|
||||
},
|
||||
"search": {
|
||||
"search-mealie": "Suche Mealie"
|
||||
},
|
||||
"settings": {
|
||||
"general-settings": "Einstellungen",
|
||||
"local-api": "Lokale API",
|
||||
"language": "Sprache",
|
||||
"add-a-new-theme": "Neues Thema hinzufügen",
|
||||
"set-new-time": "Neue Zeit einstellen",
|
||||
"current": "Version:",
|
||||
"latest": "Neuste",
|
||||
"explore-the-docs": "Stöbern",
|
||||
"contribute": "Beitragen",
|
||||
"backup-and-exports": "Sicherungen",
|
||||
"backup-info": "Sicherungen werden im standard JSON Format in das Dateisystem exportiert mitsamt sämtlicher Bilder. In deinem Sicherungsorder findest du eine ZIP Datei welche sämtliche JSON's deiner Rezepte und die Bilder aus der Datenbank enthält. Solltest du eine Markdown Datei auswählen werden diese ebenfalls im ZIP gespeichert. Um eine Sicherung zurückzuspielen muss die entsprechende ZIP Datei im Sicherungsorder liegen. Automatische Sicherungen finden jeden Tag um 3 Uhr früh statt.",
|
||||
"available-backups": "Verfügbare Sicherungen",
|
||||
"theme": {
|
||||
"theme-name": "Themenname",
|
||||
"theme-settings": "Themeneinstellungen",
|
||||
"select-a-theme-from-the-dropdown-or-create-a-new-theme-note-that-the-default-theme-will-be-served-to-all-users-who-have-not-set-a-theme-preference": "Wähle ein Thema aus der Dropdown-Liste oder erstelle ein neues. Beachte das das Standard Thema auf alle Benutzer angewandt wird die keine Einstellung für ein Thema getroffen haben.",
|
||||
"dark-mode": "Dunkler Modus",
|
||||
"theme-is-required": "Thema wird benötigt",
|
||||
"primary": "primär",
|
||||
"secondary": "sekundär",
|
||||
"accent": "betonen",
|
||||
"success": "Erfolg",
|
||||
"info": "Information",
|
||||
"warning": "Warnung",
|
||||
"error": "Fehler",
|
||||
"default-to-system": "Standardeinstellung",
|
||||
"light": "Hell",
|
||||
"dark": "Dunkel",
|
||||
"theme": "Thema",
|
||||
"saved-color-theme": "Buntes Thema gespeichert",
|
||||
"delete-theme": "Thema löschen",
|
||||
"are-you-sure-you-want-to-delete-this-theme": "Bist du sicher das du dieses Thema löschen möchtest?",
|
||||
"choose-how-mealie-looks-to-you-set-your-theme-preference-to-follow-your-system-settings-or-choose-to-use-the-light-or-dark-theme": "Entscheide wie Mealie für dich aussehen soll. Wähle Systemthema oder ob es Hell oder Dunkel dargestellt werden soll",
|
||||
"theme-name-is-required": "Theme Name is required."
|
||||
},
|
||||
"webhooks": {
|
||||
"meal-planner-webhooks": "Meal Planner Webhooks",
|
||||
"the-urls-listed-below-will-recieve-webhooks-containing-the-recipe-data-for-the-meal-plan-on-its-scheduled-day-currently-webhooks-will-execute-at": "Die unten stehenden URL's erhalten webhooks die die Rezeptdaten enthalten für den Menüplan am geplanten Tag. Derzeit werden die webhooks ausgeführt um",
|
||||
"test-webhooks": "Teste Webhooks",
|
||||
"webhook-url": "Webhook URL"
|
||||
},
|
||||
"new-version-available": "Eine neue Version von Mealie steht zur verfügung, <a {aContents}> Schau ins Repository </a>",
|
||||
"backup": {
|
||||
"import-recipes": "Rezepte importieren",
|
||||
"import-themes": "Themen importieren",
|
||||
"import-settings": "Einstellungen importieren",
|
||||
"create-heading": "Sicherung erstellen",
|
||||
"backup-tag": "Sicherungsmarkierung",
|
||||
"full-backup": "Komplettsicherungen",
|
||||
"partial-backup": "Teilsicherungen",
|
||||
"backup-restore-report": "Sicherungs/Widerherstellungsbericht",
|
||||
"successfully-imported": "Erfolgreich importiert",
|
||||
"failed-imports": "Import fehlgeschlagen"
|
||||
}
|
||||
},
|
||||
"migration": {
|
||||
"recipe-migration": "Rezepte übertragen",
|
||||
"failed-imports": "Fehlgeschlagene Importe",
|
||||
"migration-report": "Übertragungsbericht",
|
||||
"successful-imports": "Erfolgreiche Importe",
|
||||
"no-migration-data-available": "Keine Übertragungsdaten verfügbar",
|
||||
"nextcloud": {
|
||||
"title": "Nextcloud Cookbook",
|
||||
"description": "Übertrage Daten aus einer Nextcloud Cookbook Instanz"
|
||||
},
|
||||
"chowdown": {
|
||||
"title": "Chowdown",
|
||||
"description": "Übertrage Daten aus Chowdown"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -44,7 +44,9 @@
|
|||
"sign-up": "Sign up"
|
||||
},
|
||||
"meal-plan": {
|
||||
"shopping-list": "Shopping List",
|
||||
"dinner-this-week": "Dinner This Week",
|
||||
"meal-planner": "Meal Planner",
|
||||
"dinner-today": "Dinner Today",
|
||||
"planner": "Planner",
|
||||
"edit-meal-plan": "Edit Meal Plan",
|
||||
|
|
158
frontend/src/locales/pl.json
Normal file
158
frontend/src/locales/pl.json
Normal file
|
@ -0,0 +1,158 @@
|
|||
{
|
||||
"404": {
|
||||
"page-not-found": "404 Strony nie odnaleziono",
|
||||
"take-me-home": "Powrót na stronę główną"
|
||||
},
|
||||
"new-recipe": {
|
||||
"from-url": "Z odnośnika",
|
||||
"recipe-url": "Odnośnik przepisu",
|
||||
"error-message": "Wygląda na to, że wystąpił błąd. Sprawdź log i debug/last_recipe.json aby zasięgnąć po więcej informacji.",
|
||||
"bulk-add": "Dodanie zbiorcze",
|
||||
"paste-in-your-recipe-data-each-line-will-be-treated-as-an-item-in-a-list": "Przeklej zawartość przepisu. Każda indywidualna linia traktowana będzie jako pozycja na liście"
|
||||
},
|
||||
"general": {
|
||||
"upload": "Wrzuć",
|
||||
"submit": "Zatwierdź",
|
||||
"name": "Nazwa",
|
||||
"settings": "Ustawienia",
|
||||
"close": "Zamknij",
|
||||
"save": "Zapisz",
|
||||
"image-file": "Plik obrazu",
|
||||
"update": "Uaktualnij",
|
||||
"edit": "Edytuj",
|
||||
"delete": "Usuń",
|
||||
"select": "Zaznacz",
|
||||
"random": "Losowa",
|
||||
"new": "Nowa",
|
||||
"create": "Utwórz",
|
||||
"cancel": "Anuluj",
|
||||
"ok": "OK",
|
||||
"enabled": "Włączone",
|
||||
"download": "Pobierz",
|
||||
"import": "Importuj",
|
||||
"options": "Opcje",
|
||||
"templates": "Szablony",
|
||||
"recipes": "Przepisy",
|
||||
"themes": "Motywy",
|
||||
"confirm": "Potwierdź"
|
||||
},
|
||||
"login": {
|
||||
"stay-logged-in": "Pozostań zalogowany",
|
||||
"email": "Email",
|
||||
"password": "Hasło",
|
||||
"sign-in": "Zaloguj się",
|
||||
"sign-up": "Zarejestruj się"
|
||||
},
|
||||
"meal-plan": {
|
||||
"dinner-this-week": "Obiad w tym tygodniu",
|
||||
"dinner-today": "Obiad dziś",
|
||||
"planner": "Planer",
|
||||
"edit-meal-plan": "Edytuj plan posiłku",
|
||||
"meal-plans": "Plany posiłku",
|
||||
"create-a-new-meal-plan": "Utwórz nowy plan posiłku",
|
||||
"start-date": "Data rozpoczęcia",
|
||||
"end-date": "Data zakończenia"
|
||||
},
|
||||
"recipe": {
|
||||
"description": "Opis",
|
||||
"ingredients": "Składniki",
|
||||
"categories": "Kategorie",
|
||||
"tags": "Etykiety",
|
||||
"instructions": "Instrukcje",
|
||||
"step-index": "Krok: {step}",
|
||||
"recipe-name": "Nazwa przepisu",
|
||||
"servings": "Porcje",
|
||||
"ingredient": "Składnik",
|
||||
"notes": "Notatki",
|
||||
"note": "Notatka",
|
||||
"original-url": "Oryginalny odnośnik",
|
||||
"view-recipe": "Wyświetl przepis",
|
||||
"title": "Tytuł",
|
||||
"total-time": "Czas całkowity",
|
||||
"prep-time": "Czas przyrządzania",
|
||||
"perform-time": "Czas gotowania",
|
||||
"api-extras": "Dodatki API",
|
||||
"object-key": "Klucz obiektu",
|
||||
"object-value": "Wartość obiektu",
|
||||
"new-key-name": "Nazwa nowego klucza",
|
||||
"add-key": "Dodaj klucz",
|
||||
"key-name-required": "Nazwa klucza jest wymagana",
|
||||
"no-white-space-allowed": "Znaki niedrukowalne są niedozwolone",
|
||||
"delete-recipe": "Usuń przepis",
|
||||
"delete-confirmation": "Czy jesteś pewien, że chcesz usunąć ten przepis?"
|
||||
},
|
||||
"search": {
|
||||
"search-mealie": "Przeszukaj Mealie"
|
||||
},
|
||||
"settings": {
|
||||
"general-settings": "Ustawienia główne",
|
||||
"local-api": "Lokalne API",
|
||||
"language": "Język",
|
||||
"add-a-new-theme": "Dodaj nowy motyw",
|
||||
"set-new-time": "Ustaw nowy czas",
|
||||
"current": "Wersja:",
|
||||
"latest": "Najnowsza",
|
||||
"explore-the-docs": "Zobacz dokumentację",
|
||||
"contribute": "Wspomóż",
|
||||
"backup-and-exports": "Kopie zapasowe",
|
||||
"backup-info": "Kopie zapasowe zapisywane są w standardowym formacie JSON wraz ze zdjęciami w systemie plików. W katalogu kopii zapasowej znajdziesz plik z rozszerzeniem .zip zawierający wszystkie przepisy i zdjęcia z bazy danych. Jeśli oznaczone zostały pliki markdown, one także znajdą się w pliku .zip. Aby zaimportować kopię, musi ona znajdować się w folderze kopii zapasowych. Kopie automatyczne tworzone są codziennie o godzinie 03:00.",
|
||||
"available-backups": "Dostępne kopie zapsowe",
|
||||
"theme": {
|
||||
"theme-name": "Nazwa motywu",
|
||||
"theme-settings": "Ustawienia motywu",
|
||||
"select-a-theme-from-the-dropdown-or-create-a-new-theme-note-that-the-default-theme-will-be-served-to-all-users-who-have-not-set-a-theme-preference": "Wybierz motyw z rozwijanej listy bądź stwórz nowy. Domyślny motyw zostanie użyty dla wszystkich użytkowników którzy nie wybrali własnej preferencji.",
|
||||
"dark-mode": "Ciemny motyw",
|
||||
"theme-is-required": "Motyw jest wymagany",
|
||||
"primary": "Pierwszorzędny",
|
||||
"secondary": "Drugorzędny",
|
||||
"accent": "Akcent",
|
||||
"success": "Powodzenie",
|
||||
"info": "Informacja",
|
||||
"warning": "Ostrzeżenie",
|
||||
"error": "Błąd",
|
||||
"default-to-system": "Domyślny dla systemu",
|
||||
"light": "Jasny",
|
||||
"dark": "Ciemny",
|
||||
"theme": "Motyw",
|
||||
"saved-color-theme": "Zapisany kolor motywu",
|
||||
"delete-theme": "Usuń motyw",
|
||||
"are-you-sure-you-want-to-delete-this-theme": "Czy jesteś pewien, że chcesz usunąć ten motyw?",
|
||||
"choose-how-mealie-looks-to-you-set-your-theme-preference-to-follow-your-system-settings-or-choose-to-use-the-light-or-dark-theme": "Wybierz jak Mealie ma dla Ciebie wyglądać. Dostępne opcje to podążanie za odcieniem systemowym, bądź motyw jasny lub ciemny.",
|
||||
"theme-name-is-required": "Nazwa motywu jest wymagana."
|
||||
},
|
||||
"webhooks": {
|
||||
"meal-planner-webhooks": "Webhooki planera posiłków",
|
||||
"the-urls-listed-below-will-recieve-webhooks-containing-the-recipe-data-for-the-meal-plan-on-its-scheduled-day-currently-webhooks-will-execute-at": "Odnośniki poniżej otrzymają webhook zawierający dane o przepisie dla danego dnia. Aktualnie webhooki zostanę wykonane o",
|
||||
"test-webhooks": "Testuj webhooki",
|
||||
"webhook-url": "Odnośnik webhooka"
|
||||
},
|
||||
"new-version-available": "Dostępna jest nowa wersja Mealie, <a {aContents}> sprawdź repozytorium </a>",
|
||||
"backup": {
|
||||
"import-recipes": "Wgraj przepisy",
|
||||
"import-themes": "Wgraj motywy",
|
||||
"import-settings": "Wgraj ustawienia",
|
||||
"create-heading": "Utwórz kopię zapasową",
|
||||
"backup-tag": "Etykieta kopii zapasowej",
|
||||
"full-backup": "Pełna kopia zapasowa",
|
||||
"partial-backup": "Częściowa kopia zapasowa",
|
||||
"backup-restore-report": "Raport przywrócenia kopii zapasowej",
|
||||
"successfully-imported": "Import zakończony suckesem",
|
||||
"failed-imports": "Importy nieudane"
|
||||
}
|
||||
},
|
||||
"migration": {
|
||||
"recipe-migration": "Przenoszenie przepisów",
|
||||
"failed-imports": "Importy udane",
|
||||
"migration-report": "Raport przenosin",
|
||||
"successful-imports": "Importy nieudane",
|
||||
"no-migration-data-available": "Brak danych do przeniesienia",
|
||||
"nextcloud": {
|
||||
"title": "Nextcloud Cookbook",
|
||||
"description": "Przenieś dane z Nextcloud Cookbook"
|
||||
},
|
||||
"chowdown": {
|
||||
"title": "Chowdown",
|
||||
"description": "Przenieś dane z Chowdown"
|
||||
}
|
||||
}
|
||||
}
|
20
frontend/src/pages/Debug.vue
Normal file
20
frontend/src/pages/Debug.vue
Normal file
|
@ -0,0 +1,20 @@
|
|||
<template>
|
||||
<div>
|
||||
<LastRecipe />
|
||||
<LogFile class="mt-2" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LastRecipe from "@/components/Debug/LastRecipe";
|
||||
import LogFile from "@/components/Debug/LogFile";
|
||||
export default {
|
||||
components: {
|
||||
LastRecipe,
|
||||
LogFile,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -6,6 +6,7 @@
|
|||
@updated="planUpdated"
|
||||
/>
|
||||
<NewMeal v-else @created="requestMeals" class="mb-5" />
|
||||
<ShoppingListDialog ref="shoppingList" />
|
||||
|
||||
<v-card class="my-2">
|
||||
<v-card-title class="headline">
|
||||
|
@ -49,6 +50,14 @@
|
|||
</v-list-item-group>
|
||||
</v-list>
|
||||
<v-card-actions class="mt-n5">
|
||||
<v-btn
|
||||
color="accent lighten-2"
|
||||
class="mx-0"
|
||||
text
|
||||
@click="openShoppingList(mealplan.uid)"
|
||||
>
|
||||
{{ $t("meal-plan.shopping-list") }}
|
||||
</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn
|
||||
color="accent lighten-2"
|
||||
|
@ -78,11 +87,13 @@ import api from "@/api";
|
|||
import utils from "@/utils";
|
||||
import NewMeal from "../components/MealPlan/MealPlanNew";
|
||||
import EditPlan from "../components/MealPlan/MealPlanEditor";
|
||||
import ShoppingListDialog from "../components/MealPlan/ShoppingListDialog";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
NewMeal,
|
||||
EditPlan,
|
||||
ShoppingListDialog,
|
||||
},
|
||||
data: () => ({
|
||||
plannedMeals: [],
|
||||
|
@ -122,6 +133,9 @@ export default {
|
|||
api.mealPlans.delete(id);
|
||||
this.requestMeals();
|
||||
},
|
||||
openShoppingList(id) {
|
||||
this.$refs.shoppingList.openDialog(id);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<General />
|
||||
<Theme class="mt-2" />
|
||||
<Backup class="mt-2" />
|
||||
<Webhooks class="mt-2" />
|
||||
<MealPlanner class="mt-2" />
|
||||
<Migration class="mt-2" />
|
||||
<p class="text-center my-2">
|
||||
{{ $t("settings.current") }}
|
||||
|
@ -41,7 +41,7 @@
|
|||
<script>
|
||||
import Backup from "../components/Settings/Backup";
|
||||
import General from "../components/Settings/General";
|
||||
import Webhooks from "../components/Settings/Webhook";
|
||||
import MealPlanner from "../components/Settings/MealPlanner";
|
||||
import Theme from "../components/Settings/Theme";
|
||||
import Migration from "../components/Settings/Migration";
|
||||
import api from "@/api";
|
||||
|
@ -50,7 +50,7 @@ import axios from "axios";
|
|||
export default {
|
||||
components: {
|
||||
Backup,
|
||||
Webhooks,
|
||||
MealPlanner,
|
||||
Theme,
|
||||
Migration,
|
||||
General,
|
||||
|
|
|
@ -7,12 +7,14 @@ import SettingsPage from "./pages/SettingsPage";
|
|||
import AllRecipesPage from "./pages/AllRecipesPage";
|
||||
import CategoryPage from "./pages/CategoryPage";
|
||||
import MeaplPlanPage from "./pages/MealPlanPage";
|
||||
import Debug from "./pages/Debug";
|
||||
import MealPlanThisWeekPage from "./pages/MealPlanThisWeekPage";
|
||||
import api from "@/api";
|
||||
|
||||
export const routes = [
|
||||
{ path: "/", component: HomePage },
|
||||
{ path: "/mealie", component: HomePage },
|
||||
{ path: "/debug", component: Debug },
|
||||
{ path: "/search", component: SearchPage },
|
||||
{ path: "/recipes/all", component: AllRecipesPage },
|
||||
{ path: "/recipes/:category", component: CategoryPage },
|
||||
|
|
|
@ -15,7 +15,7 @@ const mutations = {
|
|||
state.showLimit = payload;
|
||||
},
|
||||
setCategories(state, payload) {
|
||||
state.categories = payload;
|
||||
state.categories = payload.sort((a, b) => (a.name > b.name ? 1 : -1));
|
||||
},
|
||||
setHomeCategories(state, payload) {
|
||||
state.homeCategories = payload;
|
||||
|
|
|
@ -15,6 +15,10 @@ const state = {
|
|||
name: "French",
|
||||
value: "fr",
|
||||
},
|
||||
{
|
||||
name: "Polish",
|
||||
value: "pl",
|
||||
},
|
||||
{
|
||||
name: "Swedish",
|
||||
value: "sv",
|
||||
|
|
|
@ -29,6 +29,7 @@ const store = new Vuex.Store({
|
|||
// All Recipe Data Store
|
||||
recentRecipes: [],
|
||||
allRecipes: [],
|
||||
mealPlanCategories: [],
|
||||
},
|
||||
|
||||
mutations: {
|
||||
|
@ -44,6 +45,10 @@ const store = new Vuex.Store({
|
|||
setRecentRecipes(state, payload) {
|
||||
state.recentRecipes = payload;
|
||||
},
|
||||
|
||||
setMealPlanCategories(state, payload) {
|
||||
state.mealPlanCategories = payload;
|
||||
},
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
@ -69,6 +74,7 @@ const store = new Vuex.Store({
|
|||
getSnackType: state => state.snackType,
|
||||
|
||||
getRecentRecipes: state => state.recentRecipes,
|
||||
getMealPlanCategories: state => state.mealPlanCategories,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module.exports = {
|
||||
transpileDependencies: ["vuetify"],
|
||||
publicPath: process.env.NODE_ENV === "production" ? "/static/" : "/",
|
||||
publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
|
||||
outputDir: process.env.NODE_ENV === "production" ? "./dist" : "../mealie/web",
|
||||
devServer: {
|
||||
proxy: {
|
||||
|
@ -12,10 +12,10 @@ module.exports = {
|
|||
},
|
||||
pluginOptions: {
|
||||
i18n: {
|
||||
locale: 'en',
|
||||
fallbackLocale: 'en',
|
||||
localeDir: 'locales',
|
||||
enableInSFC: true
|
||||
}
|
||||
}
|
||||
locale: "en",
|
||||
fallbackLocale: "en",
|
||||
localeDir: "locales",
|
||||
enableInSFC: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
import uvicorn
|
||||
from fastapi import FastAPI
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
# import utils.startup as startup
|
||||
from app_config import APP_VERSION, PORT, PRODUCTION, WEB_PATH, docs_url, redoc_url
|
||||
from app_config import APP_VERSION, PORT, PRODUCTION, docs_url, redoc_url
|
||||
from routes import (
|
||||
backup_routes,
|
||||
debug_routes,
|
||||
meal_routes,
|
||||
migration_routes,
|
||||
setting_routes,
|
||||
static_routes,
|
||||
theme_routes,
|
||||
)
|
||||
from routes.recipe import (
|
||||
|
@ -31,10 +29,6 @@ app = FastAPI(
|
|||
)
|
||||
|
||||
|
||||
def mount_static_files():
|
||||
app.mount("/static", StaticFiles(directory=WEB_PATH, html=True))
|
||||
|
||||
|
||||
def start_scheduler():
|
||||
import services.scheduler.scheduled_jobs
|
||||
|
||||
|
@ -62,24 +56,8 @@ def api_routers():
|
|||
app.include_router(debug_routes.router)
|
||||
|
||||
|
||||
if PRODUCTION:
|
||||
mount_static_files()
|
||||
|
||||
api_routers()
|
||||
|
||||
# API 404 Catch all CALL AFTER ROUTERS
|
||||
@app.get("/api/{full_path:path}", status_code=404, include_in_schema=False)
|
||||
def invalid_api():
|
||||
return None
|
||||
|
||||
|
||||
app.include_router(static_routes.router)
|
||||
|
||||
|
||||
# Generate API Documentation
|
||||
# if not PRODUCTION:
|
||||
# generate_api_docs(app)
|
||||
|
||||
start_scheduler()
|
||||
init_settings()
|
||||
|
||||
|
@ -92,6 +70,7 @@ if __name__ == "__main__":
|
|||
port=PORT,
|
||||
reload=True,
|
||||
debug=True,
|
||||
log_level="info",
|
||||
workers=1,
|
||||
forwarded_allow_ips="*",
|
||||
)
|
||||
|
|
|
@ -16,8 +16,8 @@ ENV = CWD.joinpath(".env")
|
|||
dotenv.load_dotenv(ENV)
|
||||
|
||||
# General
|
||||
APP_VERSION = "v0.2.1"
|
||||
DB_VERSION = "v0.2.0"
|
||||
APP_VERSION = "v0.3.0"
|
||||
DB_VERSION = "v0.2.1"
|
||||
PRODUCTION = os.environ.get("ENV")
|
||||
PORT = int(os.getenv("mealie_port", 9000))
|
||||
API = os.getenv("api_docs", True)
|
||||
|
|
|
@ -15,7 +15,7 @@ from db.sql.theme_models import SiteThemeModel
|
|||
class _Recipes(BaseDocument):
|
||||
def __init__(self) -> None:
|
||||
self.primary_key = "slug"
|
||||
self.sql_model = RecipeModel
|
||||
self.sql_model: RecipeModel = RecipeModel
|
||||
|
||||
def update_image(self, session: Session, slug: str, extension: str = None) -> str:
|
||||
entry: RecipeModel = self._query_one(session, match_value=slug)
|
||||
|
@ -48,15 +48,6 @@ class _Settings(BaseDocument):
|
|||
self.primary_key = "name"
|
||||
self.sql_model = SiteSettingsModel
|
||||
|
||||
def create(self, session: Session, main: dict, webhooks: dict) -> str:
|
||||
new_settings = self.sql_model(main.get("name"), webhooks)
|
||||
|
||||
session.add(new_settings)
|
||||
return_data = new_settings.dict()
|
||||
session.commit()
|
||||
|
||||
return return_data
|
||||
|
||||
|
||||
class _Themes(BaseDocument):
|
||||
def __init__(self) -> None:
|
||||
|
|
|
@ -100,11 +100,17 @@ class BaseDocument:
|
|||
match_key = self.primary_key
|
||||
|
||||
result = (
|
||||
session.query(self.sql_model).filter_by(**{match_key: match_value}).one()
|
||||
session.query(self.sql_model)
|
||||
.filter_by(**{match_key: match_value})
|
||||
.limit(limit)
|
||||
.all()
|
||||
)
|
||||
db_entry = result.dict()
|
||||
db_entries = [x.dict() for x in result]
|
||||
|
||||
return db_entry
|
||||
if limit == 1:
|
||||
return db_entries[0]
|
||||
|
||||
return db_entries
|
||||
|
||||
def create(self, session: Session, document: dict) -> dict:
|
||||
"""Creates a new database entry for the given SQL Alchemy Model.
|
||||
|
|
|
@ -85,6 +85,13 @@ class Category(SqlAlchemyBase):
|
|||
"recipes": [x.dict() for x in self.recipes],
|
||||
}
|
||||
|
||||
def dict_no_recipes(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"slug": self.slug,
|
||||
"name": self.name,
|
||||
}
|
||||
|
||||
|
||||
class Tag(SqlAlchemyBase):
|
||||
__tablename__ = "tags"
|
||||
|
|
|
@ -1,27 +1,54 @@
|
|||
import sqlalchemy as sa
|
||||
import sqlalchemy.orm as orm
|
||||
from db.sql.model_base import BaseMixins, SqlAlchemyBase
|
||||
from db.sql.recipe_models import Category
|
||||
|
||||
|
||||
class SiteSettingsModel(SqlAlchemyBase):
|
||||
class SiteSettingsModel(SqlAlchemyBase, BaseMixins):
|
||||
__tablename__ = "site_settings"
|
||||
name = sa.Column(sa.String, primary_key=True)
|
||||
planCategories = orm.relationship(
|
||||
"MealCategory", uselist=True, cascade="all, delete"
|
||||
)
|
||||
webhooks = orm.relationship("WebHookModel", uselist=False, cascade="all, delete")
|
||||
|
||||
def __init__(self, name: str = None, webhooks: dict = None, session=None) -> None:
|
||||
def __init__(
|
||||
self, name: str = None, webhooks: dict = None, planCategories=[], session=None
|
||||
) -> None:
|
||||
self.name = name
|
||||
self.planCategories = [MealCategory(cat) for cat in planCategories]
|
||||
self.webhooks = WebHookModel(**webhooks)
|
||||
|
||||
def update(self, session, name, webhooks: dict) -> dict:
|
||||
def update(self, session, name, webhooks: dict, planCategories=[]) -> dict:
|
||||
|
||||
self._sql_remove_list(session, [MealCategory], self.name)
|
||||
self.name = name
|
||||
self.planCategories = [MealCategory(x) for x in planCategories]
|
||||
self.webhooks.update(session=session, **webhooks)
|
||||
return
|
||||
|
||||
def dict(self):
|
||||
data = {"name": self.name, "webhooks": self.webhooks.dict()}
|
||||
data = {
|
||||
"name": self.name,
|
||||
"planCategories": [cat.to_str() for cat in self.planCategories],
|
||||
"webhooks": self.webhooks.dict(),
|
||||
}
|
||||
return data
|
||||
|
||||
|
||||
class MealCategory(SqlAlchemyBase):
|
||||
__tablename__ = "meal_plan_categories"
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
name = sa.Column(sa.String)
|
||||
parent_id = sa.Column(sa.Integer, sa.ForeignKey("site_settings.name"))
|
||||
|
||||
def __init__(self, name) -> None:
|
||||
self.name = name
|
||||
|
||||
def to_str(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class WebHookModel(SqlAlchemyBase, BaseMixins):
|
||||
__tablename__ = "webhook_settings"
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
|
|
0
mealie/dist/.gitkeep
vendored
0
mealie/dist/.gitkeep
vendored
|
@ -1,4 +1,4 @@
|
|||
from typing import List
|
||||
from typing import List, Optional
|
||||
|
||||
from pydantic.main import BaseModel
|
||||
from services.recipe_services import Recipe
|
||||
|
@ -8,7 +8,7 @@ class RecipeCategoryResponse(BaseModel):
|
|||
id: int
|
||||
name: str
|
||||
slug: str
|
||||
recipes: List[Recipe]
|
||||
recipes: Optional[List[Recipe]]
|
||||
|
||||
class Config:
|
||||
schema_extra = {"example": {"id": 1, "name": "dinner", "recipes": [{}]}}
|
||||
|
|
20
mealie/models/import_models.py
Normal file
20
mealie/models/import_models.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic.main import BaseModel
|
||||
|
||||
|
||||
class RecipeImport(BaseModel):
|
||||
name: Optional[str]
|
||||
slug: str
|
||||
status: bool
|
||||
exception: Optional[str]
|
||||
|
||||
class ThemeImport(BaseModel):
|
||||
name: str
|
||||
status: bool
|
||||
exception: Optional[str]
|
||||
|
||||
class SettingsImport(BaseModel):
|
||||
name: str
|
||||
status: bool
|
||||
exception: Optional[str]
|
|
@ -11,12 +11,14 @@ class Webhooks(BaseModel):
|
|||
|
||||
class SiteSettings(BaseModel):
|
||||
name: str = "main"
|
||||
planCategories: list[str] = []
|
||||
webhooks: Webhooks
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": {
|
||||
"name": "main",
|
||||
"planCategories": ["dinner", "lunch"],
|
||||
"webhooks": {
|
||||
"webhookTime": "00:00",
|
||||
"webhookURLs": ["https://mywebhookurl.com/webhook"],
|
||||
|
|
|
@ -22,7 +22,7 @@ async def get_last_recipe_json():
|
|||
return json.loads(f.read())
|
||||
|
||||
|
||||
@router.get("/log/{num}", response_class=HTMLResponse)
|
||||
@router.get("/log/{num}")
|
||||
async def get_log(num: int):
|
||||
""" Doc Str """
|
||||
with open(LOGGER_FILE, "rb") as f:
|
||||
|
@ -53,4 +53,4 @@ def tail(f, lines=20):
|
|||
block_end_byte -= BLOCK_SIZE
|
||||
block_number -= 1
|
||||
all_read_text = b"".join(reversed(blocks))
|
||||
return b"<br/>".join(all_read_text.splitlines()[-total_lines_wanted:])
|
||||
return b"/n".join(all_read_text.splitlines()[-total_lines_wanted:])
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from typing import List
|
||||
|
||||
from db.database import db
|
||||
from db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from services.meal_services import MealPlan
|
||||
|
@ -16,6 +17,21 @@ def get_all_meals(session: Session = Depends(generate_session)):
|
|||
return MealPlan.get_all(session)
|
||||
|
||||
|
||||
@router.get("/{id}/shopping-list")
|
||||
def get_shopping_list(id: str, session: Session = Depends(generate_session)):
|
||||
|
||||
#! Refactor into Single Database Call
|
||||
mealplan = db.meals.get(session, id)
|
||||
slugs = [x.get("slug") for x in mealplan.get("meals")]
|
||||
recipes = [db.recipes.get(session, x) for x in slugs]
|
||||
ingredients = [
|
||||
{"name": x.get("name"), "recipeIngredient": x.get("recipeIngredient")}
|
||||
for x in recipes
|
||||
]
|
||||
|
||||
return ingredients
|
||||
|
||||
|
||||
@router.post("/create")
|
||||
def set_meal_plan(data: MealPlan, session: Session = Depends(generate_session)):
|
||||
""" Creates a meal plan database entry """
|
||||
|
|
|
@ -4,6 +4,7 @@ from db.database import db
|
|||
from db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from models.recipe_models import AllRecipeRequest
|
||||
from slugify import slugify
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
router = APIRouter(tags=["Query All Recipes"])
|
||||
|
@ -69,3 +70,25 @@ def get_all_recipes_post(
|
|||
"""
|
||||
|
||||
return db.recipes.get_all_limit_columns(session, body.properties, body.limit)
|
||||
|
||||
|
||||
@router.post("/api/recipes/category")
|
||||
def filter_by_category(categories: list, session: Session = Depends(generate_session)):
|
||||
""" pass a list of categories and get a list of recipes associated with those categories """
|
||||
#! This should be refactored into a single database call, but I couldn't figure it out
|
||||
in_category = [
|
||||
db.categories.get(session, slugify(cat), limit=1) for cat in categories
|
||||
]
|
||||
in_category = [cat.get("recipes") for cat in in_category]
|
||||
in_category = [item for sublist in in_category for item in sublist]
|
||||
return in_category
|
||||
|
||||
|
||||
@router.post("/api/recipes/tag")
|
||||
async def filter_by_tags(tags: list, session: Session = Depends(generate_session)):
|
||||
""" pass a list of tags and get a list of recipes associated with those tags"""
|
||||
#! This should be refactored into a single database call, but I couldn't figure it out
|
||||
in_tags = [db.tags.get(session, slugify(tag), limit=1) for tag in tags]
|
||||
in_tags = [tag.get("recipes") for tag in in_tags]
|
||||
in_tags = [item for sublist in in_tags for item in sublist]
|
||||
return in_tags
|
||||
|
|
|
@ -3,6 +3,7 @@ from db.db_setup import generate_session
|
|||
from fastapi import APIRouter, Depends
|
||||
from models.category_models import RecipeCategoryResponse
|
||||
from sqlalchemy.orm.session import Session
|
||||
from utils.snackbar import SnackResponse
|
||||
|
||||
from utils.snackbar import SnackResponse
|
||||
|
||||
|
@ -26,14 +27,15 @@ def get_all_recipes_by_category(
|
|||
return db.categories.get(session, category)
|
||||
|
||||
|
||||
|
||||
@router.delete("/{category}")
|
||||
async def delete_recipe_category(
|
||||
category: str, session: Session = Depends(generate_session)
|
||||
):
|
||||
""" Removes a recipe category from the database. Deleting a
|
||||
"""Removes a recipe category from the database. Deleting a
|
||||
category does not impact a recipe. The category will be removed
|
||||
from any recipes that contain it """
|
||||
from any recipes that contain it"""
|
||||
|
||||
db.categories.delete(session, category)
|
||||
|
||||
return SnackResponse(f"Category Deleted: {category}")
|
||||
return SnackResponse.error(f"Category Deleted: {category}")
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
from db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends, File, Form, HTTPException, Query
|
||||
from fastapi import APIRouter, Depends, File, Form, HTTPException
|
||||
from fastapi.logger import logger
|
||||
from fastapi.responses import FileResponse
|
||||
from models.recipe_models import RecipeURLIn
|
||||
from services.image_services import read_image, write_image
|
||||
from services.recipe_services import Recipe
|
||||
from services.scrape_services import create_from_url
|
||||
from services.scraper.scraper import create_from_url
|
||||
from sqlalchemy.orm.session import Session
|
||||
from utils.snackbar import SnackResponse
|
||||
|
||||
|
@ -27,6 +28,7 @@ def parse_recipe_url(url: RecipeURLIn, db: Session = Depends(generate_session)):
|
|||
""" Takes in a URL and attempts to scrape data and load it into the database """
|
||||
|
||||
recipe = create_from_url(url.url)
|
||||
|
||||
recipe.save_to_db(db)
|
||||
|
||||
return recipe.slug
|
||||
|
@ -69,8 +71,10 @@ def delete_recipe(recipe_slug: str, db: Session = Depends(generate_session)):
|
|||
async def get_recipe_img(recipe_slug: str):
|
||||
""" Takes in a recipe slug, returns the static image """
|
||||
recipe_image = read_image(recipe_slug)
|
||||
|
||||
return FileResponse(recipe_image)
|
||||
if recipe_image:
|
||||
return FileResponse(recipe_image)
|
||||
else:
|
||||
return
|
||||
|
||||
|
||||
@router.put("/{recipe_slug}/image")
|
||||
|
|
|
@ -2,6 +2,7 @@ from db.database import db
|
|||
from db.db_setup import generate_session
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy.orm.session import Session
|
||||
from utils.snackbar import SnackResponse
|
||||
|
||||
from utils.snackbar import SnackResponse
|
||||
|
||||
|
@ -13,7 +14,7 @@ router = APIRouter(
|
|||
)
|
||||
|
||||
|
||||
@router.get("/all")
|
||||
@router.get("/")
|
||||
async def get_all_recipe_tags(session: Session = Depends(generate_session)):
|
||||
""" Returns a list of available tags in the database """
|
||||
return db.tags.get_all_primary_keys(session)
|
||||
|
|
|
@ -19,7 +19,6 @@ def get_main_settings(session: Session = Depends(generate_session)):
|
|||
except:
|
||||
default_settings_init(session)
|
||||
data = db.settings.get(session, "main")
|
||||
|
||||
return data
|
||||
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
from pathlib import Path
|
||||
|
||||
from fastapi import APIRouter, responses
|
||||
from fastapi.responses import FileResponse
|
||||
|
||||
CWD = Path(__file__).parent
|
||||
WEB_PATH = CWD.parent.joinpath("dist")
|
||||
BASE_HTML = WEB_PATH.joinpath("index.html")
|
||||
router = APIRouter(include_in_schema=False)
|
||||
|
||||
|
||||
@router.get("/favicon.ico")
|
||||
def facivon():
|
||||
return responses.RedirectResponse(url="/mealie/favicon.ico")
|
||||
|
||||
|
||||
@router.get("/")
|
||||
async def root():
|
||||
return FileResponse(BASE_HTML)
|
||||
|
||||
|
||||
@router.get("/{full_path:path}")
|
||||
async def root_plus(full_path):
|
||||
return FileResponse(BASE_HTML)
|
10
mealie/run.sh
Normal file
10
mealie/run.sh
Normal file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
|
||||
## Migrations
|
||||
# TODO
|
||||
|
||||
## Web Server
|
||||
caddy start --config ./Caddyfile
|
||||
|
||||
## Start API
|
||||
uvicorn app:app --host 0.0.0.0 --port 9000
|
|
@ -1,15 +1,14 @@
|
|||
import json
|
||||
import shutil
|
||||
import zipfile
|
||||
from logging import error
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
from app_config import BACKUP_DIR, IMG_DIR, TEMP_DIR
|
||||
from db.database import db
|
||||
from models.import_models import RecipeImport, SettingsImport, ThemeImport
|
||||
from models.theme_models import SiteTheme
|
||||
from services.recipe_services import Recipe
|
||||
from services.settings_services import SiteSettings
|
||||
from sqlalchemy.orm.session import Session
|
||||
from utils.logger import logger
|
||||
|
||||
|
@ -57,23 +56,29 @@ class ImportDatabase:
|
|||
raise Exception("Import file does not exist")
|
||||
|
||||
def run(self):
|
||||
report = {}
|
||||
recipe_report = []
|
||||
settings_report = []
|
||||
theme_report = []
|
||||
if self.imp_recipes:
|
||||
report = self.import_recipes()
|
||||
recipe_report = self.import_recipes()
|
||||
if self.imp_settings:
|
||||
self.import_settings()
|
||||
settings_report = self.import_settings()
|
||||
if self.imp_themes:
|
||||
self.import_themes()
|
||||
theme_report = self.import_themes()
|
||||
|
||||
self.clean_up()
|
||||
|
||||
return report if report else None
|
||||
return {
|
||||
"recipeImports": recipe_report,
|
||||
"settingsReport": settings_report,
|
||||
"themeReport": theme_report,
|
||||
}
|
||||
|
||||
def import_recipes(self):
|
||||
recipe_dir: Path = self.import_dir.joinpath("recipes")
|
||||
|
||||
imports = []
|
||||
successful_imports = []
|
||||
failed_imports = []
|
||||
|
||||
for recipe in recipe_dir.glob("*.json"):
|
||||
with open(recipe, "r") as f:
|
||||
|
@ -82,16 +87,27 @@ class ImportDatabase:
|
|||
try:
|
||||
recipe_obj = Recipe(**recipe_dict)
|
||||
recipe_obj.save_to_db(self.session)
|
||||
import_status = RecipeImport(
|
||||
name=recipe_obj.name, slug=recipe_obj.slug, status=True
|
||||
)
|
||||
imports.append(import_status)
|
||||
successful_imports.append(recipe.stem)
|
||||
logger.info(f"Imported: {recipe.stem}")
|
||||
|
||||
except Exception as inst:
|
||||
logger.error(inst)
|
||||
logger.info(f"Failed Import: {recipe.stem}")
|
||||
failed_imports.append(recipe.stem)
|
||||
import_status = RecipeImport(
|
||||
name=recipe.stem,
|
||||
slug=recipe.stem,
|
||||
status=False,
|
||||
exception=str(inst),
|
||||
)
|
||||
imports.append(import_status)
|
||||
|
||||
self._import_images(successful_imports)
|
||||
|
||||
return {"successful": successful_imports, "failed": failed_imports}
|
||||
return imports
|
||||
|
||||
@staticmethod
|
||||
def _recipe_migration(recipe_dict: dict) -> dict:
|
||||
|
@ -130,7 +146,7 @@ class ImportDatabase:
|
|||
|
||||
def import_themes(self):
|
||||
themes_file = self.import_dir.joinpath("themes", "themes.json")
|
||||
|
||||
theme_imports = []
|
||||
with open(themes_file, "r") as f:
|
||||
themes: list[dict] = json.loads(f.read())
|
||||
for theme in themes:
|
||||
|
@ -138,17 +154,38 @@ class ImportDatabase:
|
|||
continue
|
||||
new_theme = SiteTheme(**theme)
|
||||
try:
|
||||
|
||||
db.themes.create(self.session, new_theme.dict())
|
||||
except:
|
||||
theme_imports.append(ThemeImport(name=new_theme.name, status=True))
|
||||
except Exception as inst:
|
||||
logger.info(f"Unable Import Theme {new_theme.name}")
|
||||
theme_imports.append(
|
||||
ThemeImport(name=new_theme.name, status=False, exception=str(inst))
|
||||
)
|
||||
|
||||
return theme_imports
|
||||
|
||||
def import_settings(self):
|
||||
settings_file = self.import_dir.joinpath("settings", "settings.json")
|
||||
settings_imports = []
|
||||
|
||||
with open(settings_file, "r") as f:
|
||||
settings: dict = json.loads(f.read())
|
||||
|
||||
db.settings.update(self.session, settings.get("name"), settings)
|
||||
name = settings.get("name")
|
||||
|
||||
try:
|
||||
db.settings.update(self.session, name, settings)
|
||||
import_status = SettingsImport(name=name, status=True)
|
||||
|
||||
except Exception as inst:
|
||||
import_status = SettingsImport(
|
||||
name=name, status=False, exception=str(inst)
|
||||
)
|
||||
|
||||
settings_imports.append(import_status)
|
||||
|
||||
return settings_imports
|
||||
|
||||
def clean_up(self):
|
||||
shutil.rmtree(TEMP_DIR)
|
||||
|
|
|
@ -3,6 +3,7 @@ from pathlib import Path
|
|||
|
||||
import requests
|
||||
from app_config import IMG_DIR
|
||||
from utils.logger import logger
|
||||
|
||||
|
||||
def read_image(recipe_slug: str) -> Path:
|
||||
|
@ -48,6 +49,7 @@ def scrape_image(image_url: str, slug: str) -> Path:
|
|||
try:
|
||||
r = requests.get(image_url, stream=True)
|
||||
except:
|
||||
logger.exception("Fatal Image Request Exception")
|
||||
return None
|
||||
|
||||
if r.status_code == 200:
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
from datetime import date, timedelta
|
||||
from pathlib import Path
|
||||
from typing import List, Optional
|
||||
|
||||
from db.database import db
|
||||
|
|
|
@ -6,7 +6,7 @@ from pathlib import Path
|
|||
|
||||
from app_config import IMG_DIR, MIGRATION_DIR, TEMP_DIR
|
||||
from services.recipe_services import Recipe
|
||||
from services.scrape_services import normalize_data, process_recipe_data
|
||||
from services.scraper.cleaner import Cleaner
|
||||
from app_config import IMG_DIR, TEMP_DIR
|
||||
|
||||
|
||||
|
@ -28,13 +28,13 @@ def import_recipes(recipe_dir: Path) -> Recipe:
|
|||
for file in recipe_dir.glob("full.*"):
|
||||
image = file
|
||||
|
||||
recipe_file = recipe_dir.joinpath("recipe.json")
|
||||
for file in recipe_dir.glob("*.json"):
|
||||
recipe_file = file
|
||||
|
||||
with open(recipe_file, "r") as f:
|
||||
recipe_dict = json.loads(f.read())
|
||||
|
||||
recipe_dict = process_recipe_data(recipe_dict)
|
||||
recipe_data = normalize_data(recipe_dict)
|
||||
recipe_data = Cleaner.clean(recipe_dict)
|
||||
|
||||
image_name = None
|
||||
if image:
|
||||
|
@ -81,6 +81,7 @@ def migrate(session, selection: str):
|
|||
successful_imports.append(recipe.name)
|
||||
except:
|
||||
logging.error(f"Failed Nextcloud Import: {dir.name}")
|
||||
logging.exception('')
|
||||
failed_imports.append(dir.name)
|
||||
|
||||
cleanup()
|
||||
|
|
|
@ -38,8 +38,8 @@ class Recipe(BaseModel):
|
|||
tags: Optional[List[str]] = []
|
||||
dateAdded: Optional[datetime.date]
|
||||
notes: Optional[List[RecipeNote]] = []
|
||||
rating: Optional[int]
|
||||
orgURL: Optional[str]
|
||||
rating: Optional[int] = 0
|
||||
orgURL: Optional[str] = ""
|
||||
extras: Optional[dict] = {}
|
||||
|
||||
class Config:
|
||||
|
|
|
@ -1,211 +0,0 @@
|
|||
import html
|
||||
import json
|
||||
import re
|
||||
from typing import List, Tuple
|
||||
|
||||
import extruct
|
||||
import requests
|
||||
import scrape_schema_recipe
|
||||
from app_config import DEBUG_DIR
|
||||
from slugify import slugify
|
||||
from utils.logger import logger
|
||||
from w3lib.html import get_base_url
|
||||
|
||||
from services.image_services import scrape_image
|
||||
from services.recipe_services import Recipe
|
||||
|
||||
LAST_JSON = DEBUG_DIR.joinpath("last_recipe.json")
|
||||
|
||||
|
||||
def cleanhtml(raw_html):
|
||||
cleanr = re.compile("<.*?>")
|
||||
cleantext = re.sub(cleanr, "", raw_html)
|
||||
return cleantext
|
||||
|
||||
|
||||
def normalize_image_url(image) -> str:
|
||||
if type(image) == list:
|
||||
return image[0]
|
||||
elif type(image) == dict:
|
||||
return image["url"]
|
||||
elif type(image) == str:
|
||||
return image
|
||||
else:
|
||||
raise Exception(f"Unrecognised image URL format: {image}")
|
||||
|
||||
|
||||
def normalize_instructions(instructions) -> List[dict]:
|
||||
# One long string split by (possibly multiple) new lines
|
||||
if type(instructions) == str:
|
||||
return [
|
||||
{"text": normalize_instruction(line)}
|
||||
for line in instructions.splitlines()
|
||||
if line
|
||||
]
|
||||
|
||||
# Plain strings in a list
|
||||
elif type(instructions) == list and type(instructions[0]) == str:
|
||||
return [{"text": normalize_instruction(step)} for step in instructions]
|
||||
|
||||
# Dictionaries (let's assume it's a HowToStep) in a list
|
||||
elif type(instructions) == list and type(instructions[0]) == dict:
|
||||
return [
|
||||
{"text": normalize_instruction(step["text"])}
|
||||
for step in instructions
|
||||
if step["@type"] == "HowToStep"
|
||||
]
|
||||
|
||||
else:
|
||||
raise Exception(f"Unrecognised instruction format: {instructions}")
|
||||
|
||||
|
||||
def normalize_instruction(line) -> str:
|
||||
l = cleanhtml(line.strip())
|
||||
# Some sites erroneously escape their strings on multiple levels
|
||||
while not l == (l := html.unescape(l)):
|
||||
pass
|
||||
return l
|
||||
|
||||
|
||||
def normalize_ingredient(ingredients: list) -> str:
|
||||
|
||||
return [cleanhtml(html.unescape(ing)) for ing in ingredients]
|
||||
|
||||
|
||||
def normalize_yield(yld) -> str:
|
||||
if type(yld) == list:
|
||||
return yld[-1]
|
||||
else:
|
||||
return yld
|
||||
|
||||
|
||||
def normalize_time(time_entry) -> str:
|
||||
if type(time_entry) == type(None):
|
||||
return None
|
||||
elif type(time_entry) != str:
|
||||
return str(time_entry)
|
||||
|
||||
|
||||
def normalize_data(recipe_data: dict) -> dict:
|
||||
recipe_data["totalTime"] = normalize_time(recipe_data.get("totalTime"))
|
||||
recipe_data["description"] = cleanhtml(recipe_data.get("description", ""))
|
||||
recipe_data["prepTime"] = normalize_time(recipe_data.get("prepTime"))
|
||||
recipe_data["performTime"] = normalize_time(recipe_data.get("performTime"))
|
||||
recipe_data["recipeYield"] = normalize_yield(recipe_data.get("recipeYield"))
|
||||
recipe_data["recipeIngredient"] = normalize_ingredient(
|
||||
recipe_data.get("recipeIngredient")
|
||||
)
|
||||
recipe_data["recipeInstructions"] = normalize_instructions(
|
||||
recipe_data["recipeInstructions"]
|
||||
)
|
||||
recipe_data["image"] = normalize_image_url(recipe_data["image"])
|
||||
return recipe_data
|
||||
|
||||
|
||||
def process_recipe_data(new_recipe: dict, url=None) -> dict:
|
||||
slug = slugify(new_recipe["name"])
|
||||
mealie_tags = {
|
||||
"slug": slug,
|
||||
"orgURL": url,
|
||||
"categories": [],
|
||||
"tags": [],
|
||||
"dateAdded": None,
|
||||
"notes": [],
|
||||
"extras": [],
|
||||
}
|
||||
|
||||
new_recipe.update(mealie_tags)
|
||||
|
||||
return new_recipe
|
||||
|
||||
|
||||
def extract_recipe_from_html(html: str, url: str) -> dict:
|
||||
scraped_recipes: List[dict] = scrape_schema_recipe.loads(html, python_objects=True)
|
||||
dump_last_json(scraped_recipes)
|
||||
|
||||
if not scraped_recipes:
|
||||
scraped_recipes: List[dict] = scrape_schema_recipe.scrape_url(
|
||||
url, python_objects=True
|
||||
)
|
||||
|
||||
if scraped_recipes:
|
||||
new_recipe: dict = scraped_recipes[0]
|
||||
logger.info(f"Recipe Scraped From Web: {new_recipe}")
|
||||
|
||||
if not new_recipe:
|
||||
return "fail" # TODO: Return Better Error Here
|
||||
|
||||
new_recipe = process_recipe_data(new_recipe, url=url)
|
||||
new_recipe = normalize_data(new_recipe)
|
||||
else:
|
||||
new_recipe = basic_recipe_from_opengraph(html, url)
|
||||
logger.info(f"Recipe Scraped from opengraph metadata: {new_recipe}")
|
||||
|
||||
return new_recipe
|
||||
|
||||
|
||||
def download_image_for_recipe(recipe: dict) -> dict:
|
||||
try:
|
||||
img_path = scrape_image(recipe.get("image"), recipe.get("slug"))
|
||||
recipe["image"] = img_path.name
|
||||
except:
|
||||
recipe["image"] = None
|
||||
|
||||
return recipe
|
||||
|
||||
|
||||
def og_field(properties: dict, field_name: str) -> str:
|
||||
return next((val for name, val in properties if name == field_name), None)
|
||||
|
||||
|
||||
def og_fields(properties: List[Tuple[str, str]], field_name: str) -> List[str]:
|
||||
return list({val for name, val in properties if name == field_name})
|
||||
|
||||
|
||||
def basic_recipe_from_opengraph(html: str, url: str) -> dict:
|
||||
base_url = get_base_url(html, url)
|
||||
data = extruct.extract(html, base_url=base_url)
|
||||
try:
|
||||
properties = data["opengraph"][0]["properties"]
|
||||
except:
|
||||
return
|
||||
|
||||
return {
|
||||
"name": og_field(properties, "og:title"),
|
||||
"description": og_field(properties, "og:description"),
|
||||
"image": og_field(properties, "og:image"),
|
||||
"recipeYield": "",
|
||||
# FIXME: If recipeIngredient is an empty list, mongodb's data verification fails.
|
||||
"recipeIngredient": ["Could not detect ingredients"],
|
||||
# FIXME: recipeInstructions is allowed to be empty but message this is added for user sanity.
|
||||
"recipeInstructions": [{"text": "Could not detect instructions"}],
|
||||
"slug": slugify(og_field(properties, "og:title")),
|
||||
"orgURL": og_field(properties, "og:url"),
|
||||
"categories": [],
|
||||
"tags": og_fields(properties, "og:article:tag"),
|
||||
"dateAdded": None,
|
||||
"notes": [],
|
||||
"extras": [],
|
||||
}
|
||||
|
||||
|
||||
def dump_last_json(recipe_data: dict):
|
||||
with open(LAST_JSON, "w") as f:
|
||||
f.write(json.dumps(recipe_data, indent=4, default=str))
|
||||
|
||||
return
|
||||
|
||||
|
||||
def process_recipe_url(url: str) -> dict:
|
||||
r = requests.get(url)
|
||||
new_recipe = extract_recipe_from_html(r.text, url)
|
||||
new_recipe = download_image_for_recipe(new_recipe)
|
||||
return new_recipe
|
||||
|
||||
|
||||
def create_from_url(url: str) -> Recipe:
|
||||
recipe_data = process_recipe_url(url)
|
||||
|
||||
recipe = Recipe(**recipe_data)
|
||||
|
||||
return recipe
|
149
mealie/services/scraper/cleaner.py
Normal file
149
mealie/services/scraper/cleaner.py
Normal file
|
@ -0,0 +1,149 @@
|
|||
import html
|
||||
import re
|
||||
from typing import List
|
||||
|
||||
from slugify import slugify
|
||||
|
||||
|
||||
class Cleaner:
|
||||
"""A Namespace for utility function to clean recipe data extracted
|
||||
from a url and returns a dictionary that is ready for import into
|
||||
the database. Cleaner.clean is the main entrypoint
|
||||
|
||||
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def clean(recipe_data: dict, url=None) -> dict:
|
||||
"""Main entrypoint to clean a recipe extracted from the web
|
||||
and format the data into an accectable format for the database
|
||||
|
||||
Args:
|
||||
recipe_data (dict): raw recipe dicitonary
|
||||
|
||||
Returns:
|
||||
dict: cleaned recipe dictionary
|
||||
"""
|
||||
recipe_data["totalTime"] = Cleaner.time(recipe_data.get("totalTime"))
|
||||
recipe_data["description"] = Cleaner.html(recipe_data.get("description", ""))
|
||||
recipe_data["prepTime"] = Cleaner.time(recipe_data.get("prepTime"))
|
||||
recipe_data["performTime"] = Cleaner.time(recipe_data.get("performTime"))
|
||||
recipe_data["recipeYield"] = Cleaner.yield_amount(
|
||||
recipe_data.get("recipeYield")
|
||||
)
|
||||
recipe_data["recipeIngredient"] = Cleaner.ingredient(
|
||||
recipe_data.get("recipeIngredient")
|
||||
)
|
||||
recipe_data["recipeInstructions"] = Cleaner.instructions(
|
||||
recipe_data["recipeInstructions"]
|
||||
)
|
||||
recipe_data["image"] = Cleaner.image(recipe_data["image"])
|
||||
recipe_data["slug"] = slugify(recipe_data["name"])
|
||||
recipe_data["orgURL"] = url
|
||||
|
||||
return recipe_data
|
||||
|
||||
@staticmethod
|
||||
def html(raw_html):
|
||||
cleanr = re.compile("<.*?>")
|
||||
cleantext = re.sub(cleanr, "", raw_html)
|
||||
return cleantext
|
||||
|
||||
@staticmethod
|
||||
def image(image) -> str:
|
||||
if type(image) == list:
|
||||
return image[0]
|
||||
elif type(image) == dict:
|
||||
return image["url"]
|
||||
elif type(image) == str:
|
||||
return image
|
||||
else:
|
||||
raise Exception(f"Unrecognised image URL format: {image}")
|
||||
|
||||
@staticmethod
|
||||
def instructions(instructions) -> List[dict]:
|
||||
if not instructions:
|
||||
return []
|
||||
|
||||
# One long string split by (possibly multiple) new lines
|
||||
if type(instructions) == str:
|
||||
return [
|
||||
{"text": Cleaner._instruction(line)}
|
||||
for line in instructions.splitlines()
|
||||
if line
|
||||
]
|
||||
|
||||
# Plain strings in a list
|
||||
elif type(instructions) == list and type(instructions[0]) == str:
|
||||
return [{"text": Cleaner._instruction(step)} for step in instructions]
|
||||
|
||||
# Dictionaries (let's assume it's a HowToStep) in a list
|
||||
elif type(instructions) == list and type(instructions[0]) == dict:
|
||||
# Try List of Dictionary without "@type" or "type"
|
||||
if not instructions[0].get("@type", False) and not instructions[0].get(
|
||||
"type", False
|
||||
):
|
||||
return [
|
||||
{"text": Cleaner._instruction(step["text"])}
|
||||
for step in instructions
|
||||
]
|
||||
|
||||
try:
|
||||
# If HowToStep is under HowToSection
|
||||
sectionSteps = []
|
||||
for step in instructions:
|
||||
if step["@type"] == "HowToSection":
|
||||
[sectionSteps.append(item) for item in step["itemListELement"]]
|
||||
|
||||
if len(sectionSteps) > 0:
|
||||
return [
|
||||
{"text": Cleaner._instruction(step["text"])}
|
||||
for step in sectionSteps
|
||||
if step["@type"] == "HowToStep"
|
||||
]
|
||||
|
||||
return [
|
||||
{"text": Cleaner._instruction(step["text"])}
|
||||
for step in instructions
|
||||
if step["@type"] == "HowToStep"
|
||||
]
|
||||
except Exception as e:
|
||||
# Not "@type", try "type"
|
||||
try:
|
||||
return [
|
||||
{"text": Cleaner._instruction(step["properties"]["text"])}
|
||||
for step in instructions
|
||||
if step["type"].find("HowToStep") > -1
|
||||
]
|
||||
except:
|
||||
pass
|
||||
|
||||
else:
|
||||
raise Exception(f"Unrecognised instruction format: {instructions}")
|
||||
|
||||
@staticmethod
|
||||
def _instruction(line) -> str:
|
||||
l = Cleaner.html(line.strip())
|
||||
# Some sites erroneously escape their strings on multiple levels
|
||||
while not l == (l := html.unescape(l)):
|
||||
pass
|
||||
return l
|
||||
|
||||
@staticmethod
|
||||
def ingredient(ingredients: list) -> str:
|
||||
|
||||
return [Cleaner.html(html.unescape(ing)) for ing in ingredients]
|
||||
|
||||
@staticmethod
|
||||
def yield_amount(yld) -> str:
|
||||
if type(yld) == list:
|
||||
return yld[-1]
|
||||
else:
|
||||
return yld
|
||||
|
||||
@staticmethod
|
||||
def time(time_entry) -> str:
|
||||
if type(time_entry) == type(None):
|
||||
return None
|
||||
elif type(time_entry) != str:
|
||||
return str(time_entry)
|
43
mealie/services/scraper/open_graph.py
Normal file
43
mealie/services/scraper/open_graph.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
from typing import Tuple
|
||||
|
||||
import extruct
|
||||
from app_config import DEBUG_DIR
|
||||
from slugify import slugify
|
||||
from w3lib.html import get_base_url
|
||||
|
||||
LAST_JSON = DEBUG_DIR.joinpath("last_recipe.json")
|
||||
|
||||
|
||||
def og_field(properties: dict, field_name: str) -> str:
|
||||
return next((val for name, val in properties if name == field_name), None)
|
||||
|
||||
|
||||
def og_fields(properties: list[Tuple[str, str]], field_name: str) -> list[str]:
|
||||
return list({val for name, val in properties if name == field_name})
|
||||
|
||||
|
||||
def basic_recipe_from_opengraph(html: str, url: str) -> dict:
|
||||
base_url = get_base_url(html, url)
|
||||
data = extruct.extract(html, base_url=base_url)
|
||||
try:
|
||||
properties = data["opengraph"][0]["properties"]
|
||||
except:
|
||||
return
|
||||
|
||||
return {
|
||||
"name": og_field(properties, "og:title"),
|
||||
"description": og_field(properties, "og:description"),
|
||||
"image": og_field(properties, "og:image"),
|
||||
"recipeYield": "",
|
||||
# FIXME: If recipeIngredient is an empty list, mongodb's data verification fails.
|
||||
"recipeIngredient": ["Could not detect ingredients"],
|
||||
# FIXME: recipeInstructions is allowed to be empty but message this is added for user sanity.
|
||||
"recipeInstructions": [{"text": "Could not detect instructions"}],
|
||||
"slug": slugify(og_field(properties, "og:title")),
|
||||
"orgURL": og_field(properties, "og:url"),
|
||||
"categories": [],
|
||||
"tags": og_fields(properties, "og:article:tag"),
|
||||
"dateAdded": None,
|
||||
"notes": [],
|
||||
"extras": [],
|
||||
}
|
84
mealie/services/scraper/scraper.py
Normal file
84
mealie/services/scraper/scraper.py
Normal file
|
@ -0,0 +1,84 @@
|
|||
import json
|
||||
from typing import List
|
||||
|
||||
import requests
|
||||
import scrape_schema_recipe
|
||||
from app_config import DEBUG_DIR
|
||||
from services.image_services import scrape_image
|
||||
from services.recipe_services import Recipe
|
||||
from services.scraper import open_graph
|
||||
from services.scraper.cleaner import Cleaner
|
||||
from utils.logger import logger
|
||||
|
||||
LAST_JSON = DEBUG_DIR.joinpath("last_recipe.json")
|
||||
|
||||
|
||||
def create_from_url(url: str) -> Recipe:
|
||||
"""Main entry point for generating a recipe from a URL. Pass in a URL and
|
||||
a Recipe object will be returned if successful.
|
||||
|
||||
Args:
|
||||
url (str): a valid string representing a URL
|
||||
|
||||
Returns:
|
||||
Recipe: Recipe Object
|
||||
"""
|
||||
r = requests.get(url)
|
||||
new_recipe = extract_recipe_from_html(r.text, url)
|
||||
new_recipe = Cleaner.clean(new_recipe)
|
||||
new_recipe = download_image_for_recipe(new_recipe)
|
||||
|
||||
recipe = Recipe(**new_recipe)
|
||||
|
||||
return recipe
|
||||
|
||||
|
||||
def extract_recipe_from_html(html: str, url: str) -> dict:
|
||||
try:
|
||||
scraped_recipes: List[dict] = scrape_schema_recipe.loads(
|
||||
html, python_objects=True
|
||||
)
|
||||
dump_last_json(scraped_recipes)
|
||||
|
||||
if not scraped_recipes:
|
||||
scraped_recipes: List[dict] = scrape_schema_recipe.scrape_url(
|
||||
url, python_objects=True
|
||||
)
|
||||
except Exception as e:
|
||||
# trying without python_objects
|
||||
scraped_recipes: List[dict] = scrape_schema_recipe.loads(html)
|
||||
dump_last_json(scraped_recipes)
|
||||
|
||||
if not scraped_recipes:
|
||||
scraped_recipes: List[dict] = scrape_schema_recipe.scrape_url(url)
|
||||
|
||||
if scraped_recipes:
|
||||
new_recipe: dict = scraped_recipes[0]
|
||||
logger.info(f"Recipe Scraped From Web: {new_recipe}")
|
||||
|
||||
if not new_recipe:
|
||||
return "fail" # TODO: Return Better Error Here
|
||||
|
||||
new_recipe = Cleaner.clean(new_recipe, url)
|
||||
else:
|
||||
new_recipe = open_graph.basic_recipe_from_opengraph(html, url)
|
||||
logger.info(f"Recipe Scraped from opengraph metadata: {new_recipe}")
|
||||
|
||||
return new_recipe
|
||||
|
||||
|
||||
def download_image_for_recipe(recipe: dict) -> dict:
|
||||
try:
|
||||
img_path = scrape_image(recipe.get("image"), recipe.get("slug"))
|
||||
recipe["image"] = img_path.name
|
||||
except:
|
||||
recipe["image"] = "no image"
|
||||
|
||||
return recipe
|
||||
|
||||
|
||||
def dump_last_json(recipe_data: dict):
|
||||
with open(LAST_JSON, "w") as f:
|
||||
f.write(json.dumps(recipe_data, indent=4, default=str))
|
||||
|
||||
return
|
|
@ -1,7 +1,8 @@
|
|||
from db.database import db
|
||||
from db.db_setup import create_session, sql_exists
|
||||
from db.db_setup import create_session
|
||||
from models.settings_models import SiteSettings, Webhooks
|
||||
from sqlalchemy.orm.session import Session
|
||||
from utils.logger import logger
|
||||
|
||||
|
||||
def default_settings_init(session: Session = None):
|
||||
|
@ -10,7 +11,7 @@ def default_settings_init(session: Session = None):
|
|||
try:
|
||||
webhooks = Webhooks()
|
||||
default_entry = SiteSettings(name="main", webhooks=webhooks)
|
||||
document = db.settings.create(session, default_entry.dict(), webhooks.dict())
|
||||
document = db.settings.create(session, default_entry.dict())
|
||||
logger.info(f"Created Site Settings: \n {document}")
|
||||
except:
|
||||
pass
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ from tests.utils.routes import (
|
|||
def default_settings():
|
||||
return {
|
||||
"name": "main",
|
||||
"planCategories": [],
|
||||
"webhooks": {"webhookTime": "00:00", "webhookURLs": [], "enabled": False},
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,8 @@ import json
|
|||
import re
|
||||
|
||||
import pytest
|
||||
from services.scrape_services import (
|
||||
extract_recipe_from_html,
|
||||
normalize_data,
|
||||
normalize_instructions,
|
||||
)
|
||||
from services.scraper.cleaner import Cleaner
|
||||
from services.scraper.scraper import extract_recipe_from_html
|
||||
from tests.test_config import TEST_RAW_HTML, TEST_RAW_RECIPES
|
||||
|
||||
# https://github.com/django/django/blob/stable/1.3.x/django/core/validators.py#L45
|
||||
|
@ -42,7 +39,7 @@ url_validation_regex = re.compile(
|
|||
],
|
||||
)
|
||||
def test_normalize_data(json_file, num_steps):
|
||||
recipe_data = normalize_data(json.load(open(TEST_RAW_RECIPES.joinpath(json_file))))
|
||||
recipe_data = Cleaner.clean(json.load(open(TEST_RAW_RECIPES.joinpath(json_file))))
|
||||
assert len(recipe_data["recipeInstructions"]) == num_steps
|
||||
|
||||
|
||||
|
@ -58,7 +55,7 @@ def test_normalize_data(json_file, num_steps):
|
|||
],
|
||||
)
|
||||
def test_normalize_instructions(instructions):
|
||||
assert normalize_instructions(instructions) == [
|
||||
assert Cleaner.instructions(instructions) == [
|
||||
{"text": "A"},
|
||||
{"text": "B"},
|
||||
{"text": "C"},
|
||||
|
|
|
@ -31,11 +31,12 @@ HTML_TEMPLATE = """<!DOCTYPE html>
|
|||
</html>
|
||||
"""
|
||||
|
||||
HTML_PATH = DATA_DIR.parent.joinpath("docs/docs/html/api.html")
|
||||
|
||||
|
||||
def generate_api_docs(app):
|
||||
out_dir = DATA_DIR.joinpath(".temp")
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
out_path = out_dir.joinpath("index.html")
|
||||
with open(out_path, "w") as fd:
|
||||
out_path.parent.mkdir(exist_ok=True)
|
||||
with open(HTML_PATH, "w") as fd:
|
||||
print(HTML_TEMPLATE % json.dumps(app.openapi()), file=fd)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from pathlib import Path
|
||||
|
||||
from app_config import REQUIRED_DIRS
|
||||
from services.settings_services import default_theme_init
|
||||
|
||||
CWD = Path(__file__).parent
|
||||
|
@ -10,8 +9,5 @@ def post_start():
|
|||
default_theme_init()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
|
|
Loading…
Reference in a new issue