From ea7c4771ee5691c88f88626ec29abdf4d7a58ada Mon Sep 17 00:00:00 2001
From: Hayden <64056131+hay-kot@users.noreply.github.com>
Date: Sat, 18 Dec 2021 19:04:36 -0900
Subject: [PATCH] Feature/user photo storage (#877)
* add default assets for user profile
* add recipe avatar
* change user_id to UUID
* add profile image upload
* setup image cache keys
* cleanup tests and add image tests
* purge user data on delete
* new user repository tests
* add user_id validator for int -> UUID conversion
* delete depreciated route
* force set content type
* refactor tests to use temp directory
* validate parent exists before createing
* set user_id to correct type
* update instruction id
* reset primary key on migration
---
Caddyfile | 7 +++
.../Domain/Recipe/RecipeComments.vue | 13 ++---
.../components/Domain/User/UserAvatar.vue | 46 ++++++++++++++++
frontend/components/Layout/AppSidebar.vue | 8 +--
frontend/pages/user/group/members.vue | 10 ++--
frontend/pages/user/profile/edit.vue | 17 +++++-
frontend/pages/user/profile/index.vue | 8 +--
frontend/static/fallback-profile.webp | Bin 0 -> 18088 bytes
.../assets/__init__.py | 0
mealie/assets/templates/__init__.py | 5 ++
.../assets}/templates/recipes.md | 0
mealie/assets/users/__init__.py | 7 +++
mealie/assets/users/random_1.webp | Bin 0 -> 21184 bytes
mealie/assets/users/random_2.webp | Bin 0 -> 18088 bytes
mealie/assets/users/random_3.webp | Bin 0 -> 12448 bytes
mealie/core/config.py | 10 ++--
mealie/core/dependencies/dependencies.py | 21 +++++++-
mealie/core/security.py | 2 +-
mealie/core/settings/db_providers.py | 6 +--
mealie/core/settings/directories.py | 9 ++++
mealie/core/settings/settings.py | 1 +
mealie/core/settings/static.py | 3 --
mealie/db/data_access_layer/_access_model.py | 3 +-
.../db/data_access_layer/user_access_model.py | 27 +++++++++-
mealie/db/init_db.py | 4 +-
mealie/db/models/_model_utils/guid.py | 4 ++
mealie/db/models/group/exports.py | 4 +-
mealie/db/models/group/report.py | 5 +-
mealie/db/models/recipe/comment.py | 6 +--
mealie/db/models/recipe/instruction.py | 6 +--
mealie/db/models/recipe/recipe.py | 2 +-
mealie/db/models/users/password_reset.py | 5 +-
mealie/db/models/users/user_to_favorite.py | 3 +-
mealie/db/models/users/users.py | 10 ++--
mealie/routes/media/__init__.py | 5 +-
.../media/{recipe.py => media_recipe.py} | 0
mealie/routes/media/media_user.py | 24 +++++++++
mealie/routes/users/api_tokens.py | 4 +-
mealie/routes/users/crud.py | 9 ++--
mealie/routes/users/images.py | 44 ++++++++-------
mealie/schema/group/group_permissions.py | 3 +-
mealie/schema/recipe/recipe.py | 14 +++--
mealie/schema/recipe/recipe_comments.py | 5 +-
mealie/schema/user/user.py | 14 ++++-
mealie/schema/user/user_passwords.py | 3 +-
mealie/services/image/minify.py | 16 ++++++
mealie/services/migrations/_migration_base.py | 4 +-
mealie/services/migrations/mealie_alpha.py | 3 ++
.../migrations/utils/database_helpers.py | 4 +-
mealie/services/recipe/recipe_service.py | 6 +--
mealie/services/user_services/user_service.py | 5 ++
mealie/utils/__init__.py | 1 +
mealie/utils/cache_key.py | 9 ++++
tests/conftest.py | 25 ++++++++-
tests/fixtures/__init__.py | 1 +
tests/fixtures/fixture_database.py | 14 +++++
.../admin_tests/test_admin_user_actions.py | 50 ++++++++++++------
tests/integration_tests/test_import_routes.py | 27 ----------
.../user_tests/test_user_images.py | 43 ++++++++-------
tests/pre_test.py | 15 ------
.../repository_tests/test_user_repository.py | 10 ++++
.../test_email_service.py | 0
tests/unit_tests/test_config.py | 2 +-
tests/utils/fixture_schemas.py | 2 +-
64 files changed, 433 insertions(+), 181 deletions(-)
create mode 100644 frontend/components/Domain/User/UserAvatar.vue
create mode 100644 frontend/static/fallback-profile.webp
rename tests/integration_tests/test_tags_categories.py => mealie/assets/__init__.py (100%)
create mode 100644 mealie/assets/templates/__init__.py
rename {dev/data => mealie/assets}/templates/recipes.md (100%)
create mode 100644 mealie/assets/users/__init__.py
create mode 100644 mealie/assets/users/random_1.webp
create mode 100644 mealie/assets/users/random_2.webp
create mode 100644 mealie/assets/users/random_3.webp
rename mealie/routes/media/{recipe.py => media_recipe.py} (100%)
create mode 100644 mealie/routes/media/media_user.py
create mode 100644 mealie/utils/cache_key.py
create mode 100644 tests/fixtures/fixture_database.py
delete mode 100644 tests/integration_tests/test_import_routes.py
delete mode 100644 tests/pre_test.py
create mode 100644 tests/unit_tests/repository_tests/test_user_repository.py
rename tests/unit_tests/{services => services_tests}/test_email_service.py (100%)
diff --git a/Caddyfile b/Caddyfile
index c39e00ea2b7e..f22327c8f9ac 100644
--- a/Caddyfile
+++ b/Caddyfile
@@ -20,6 +20,13 @@
file_server
}
+ # Handles User Images
+ handle_path /api/media/users/* {
+ header @static Cache-Control max-age=31536000
+ root * /app/data/users/
+ file_server
+ }
+
handle @proxied {
uri strip_suffix /
reverse_proxy http://127.0.0.1:9000
diff --git a/frontend/components/Domain/Recipe/RecipeComments.vue b/frontend/components/Domain/Recipe/RecipeComments.vue
index 2791acb3fd8e..58711ccccb5d 100644
--- a/frontend/components/Domain/Recipe/RecipeComments.vue
+++ b/frontend/components/Domain/Recipe/RecipeComments.vue
@@ -9,9 +9,8 @@
{{ comment.user.username }} • {{ $d(Date.parse(comment.createdAt), "medium") }}
@@ -60,8 +57,12 @@ import { defineComponent, ref, toRefs, onMounted, reactive } from "@nuxtjs/composition-api"; import { useUserApi } from "~/composables/api"; import { RecipeComment } from "~/api/class-interfaces/recipes/types"; +import UserAvatar from "~/components/Domain/User/UserAvatar.vue"; export default defineComponent({ + components: { + UserAvatar, + }, props: { slug: { type: String, diff --git a/frontend/components/Domain/User/UserAvatar.vue b/frontend/components/Domain/User/UserAvatar.vue new file mode 100644 index 000000000000..c0a7f6f9b2c1 --- /dev/null +++ b/frontend/components/Domain/User/UserAvatar.vue @@ -0,0 +1,46 @@ + +