diff --git a/frontend.old/.env.development b/frontend.old/.env.development deleted file mode 100644 index 4afc44f70ac8..000000000000 --- a/frontend.old/.env.development +++ /dev/null @@ -1,2 +0,0 @@ -VUE_APP_API_BASE_URL=http://localhost:9000 -PREVIEW_BUNDLE=true \ No newline at end of file diff --git a/frontend.old/README.md b/frontend.old/README.md deleted file mode 100644 index 576b98091161..000000000000 --- a/frontend.old/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# frontend - -## Project setup -``` -npm install -``` - -### Compiles and hot-reloads for development -``` -npm run serve -``` - -### Compiles and minifies for production -``` -npm run build -``` - -### Lints and fixes files -``` -npm run lint -``` - -### Customize configuration -See [Configuration Reference](https://cli.vuejs.org/config/). diff --git a/frontend.old/babel.config.js b/frontend.old/babel.config.js deleted file mode 100644 index 162a3ea97c29..000000000000 --- a/frontend.old/babel.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - presets: ["@vue/cli-plugin-babel/preset"], -}; diff --git a/frontend.old/component-stagin/Domain/MealPlan/MealPlanCard.vue b/frontend.old/component-stagin/Domain/MealPlan/MealPlanCard.vue deleted file mode 100644 index 140e9872cb39..000000000000 --- a/frontend.old/component-stagin/Domain/MealPlan/MealPlanCard.vue +++ /dev/null @@ -1,173 +0,0 @@ - - - - - diff --git a/frontend.old/component-stagin/Domain/MealPlan/MealPlanEditor.vue b/frontend.old/component-stagin/Domain/MealPlan/MealPlanEditor.vue deleted file mode 100644 index 7f790b483491..000000000000 --- a/frontend.old/component-stagin/Domain/MealPlan/MealPlanEditor.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - - diff --git a/frontend.old/component-stagin/Domain/MealPlan/MealPlanNew.vue b/frontend.old/component-stagin/Domain/MealPlan/MealPlanNew.vue deleted file mode 100644 index fd8fbe347ec2..000000000000 --- a/frontend.old/component-stagin/Domain/MealPlan/MealPlanNew.vue +++ /dev/null @@ -1,227 +0,0 @@ - - - diff --git a/frontend.old/component-stagin/Domain/User/UserAvatar.vue b/frontend.old/component-stagin/Domain/User/UserAvatar.vue deleted file mode 100644 index a2f119084b25..000000000000 --- a/frontend.old/component-stagin/Domain/User/UserAvatar.vue +++ /dev/null @@ -1,61 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend.old/component-stagin/Page/Recipe/RecipeEditor.vue b/frontend.old/component-stagin/Page/Recipe/RecipeEditor.vue deleted file mode 100644 index 65ab9152a3ef..000000000000 --- a/frontend.old/component-stagin/Page/Recipe/RecipeEditor.vue +++ /dev/null @@ -1,153 +0,0 @@ - - - - - diff --git a/frontend.old/component-stagin/Page/Recipe/RecipeViewer.vue b/frontend.old/component-stagin/Page/Recipe/RecipeViewer.vue deleted file mode 100644 index c06b9a0cca14..000000000000 --- a/frontend.old/component-stagin/Page/Recipe/RecipeViewer.vue +++ /dev/null @@ -1,142 +0,0 @@ - - - - - diff --git a/frontend.old/frontend.Dockerfile b/frontend.old/frontend.Dockerfile deleted file mode 100644 index 2cdab5876dc9..000000000000 --- a/frontend.old/frontend.Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM node:lts-alpine - -# # install simple http server for serving static content -# RUN npm install -g http-server - -# make the 'app' folder the current working directory -WORKDIR /app - -# copy both 'package.json' and 'package-lock.json' (if available) -COPY package*.json ./ - -# install project dependencies -RUN npm install - -# copy project files and folders to the current working directory (i.e. 'app' folder) -# COPY . . - -# build app for production with minification -# RUN npm run build - -EXPOSE 8080 -CMD [ "npm", "run", "serve" ] \ No newline at end of file diff --git a/frontend.old/jsconfig.json b/frontend.old/jsconfig.json deleted file mode 100644 index 0486e3bb36a6..000000000000 --- a/frontend.old/jsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "baseUrl": ".", - "paths": { - "@/*": ["./src/*"] - } - }, - "exclude": ["node_modules", "dist"] -} diff --git a/frontend.old/package.json b/frontend.old/package.json deleted file mode 100644 index 1384c5140725..000000000000 --- a/frontend.old/package.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "frontend", - "version": "0.1.0", - "private": true, - "scripts": { - "serve": "vue-cli-service serve", - "build": "vue-cli-service build", - "lint": "vue-cli-service lint", - "i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'" - }, - "dependencies": { - "@adapttive/vue-markdown": "^4.0.1", - "axios": "^0.21.1", - "core-js": "^3.14.0", - "fuse.js": "^6.4.6", - "register-service-worker": "^1.7.1", - "v-jsoneditor": "^1.4.4", - "vue": "^2.6.14", - "vue-i18n": "^8.24.1", - "vue-router": "^3.5.1", - "vuedraggable": "^2.24.3", - "vuetify": "^2.5.3", - "vuex": "^3.6.2", - "vuex-persistedstate": "^4.0.0-beta.3" - }, - "devDependencies": { - "@intlify/vue-i18n-loader": "^1.1.0", - "@mdi/font": "^5.9.55", - "@mdi/js": "^5.9.55", - "@vue/cli-plugin-babel": "^4.5.13", - "@vue/cli-plugin-eslint": "^4.5.13", - "@vue/cli-plugin-pwa": "~4.5.0", - "@vue/cli-service": "^4.5.13", - "@vue/preload-webpack-plugin": "^2.0.0", - "babel-eslint": "^10.1.0", - "eslint": "^6.7.2", - "eslint-plugin-vue": "^6.2.2", - "html-webpack-plugin": "^5.3.1", - "preload-webpack-plugin": "^2.3.0", - "sass": "^1.34.1", - "sass-loader": "^8.0.2", - "typeface-roboto": "^1.1.13", - "vue-cli-plugin-i18n": "~1.0.1", - "vue-cli-plugin-vuetify": "^2.4.1", - "vue-cli-plugin-webpack-bundle-analyzer": "^4.0.0", - "vue-template-compiler": "^2.6.14", - "vuetify-loader": "^1.7.2" - }, - "eslintConfig": { - "root": true, - "env": { - "node": true - }, - "extends": [ - "plugin:vue/essential", - "eslint:recommended" - ], - "parserOptions": { - "parser": "babel-eslint" - }, - "rules": {} - }, - "prettier": { - "trailingComma": "es5", - "tabWidth": 2, - "semi": true, - "singleQuote": false, - "printWidth": 120 - }, - "browserslist": [ - "> 1%", - "last 2 versions", - "not dead" - ] -} \ No newline at end of file diff --git a/frontend.old/public/img/icons/android-chrome-192x192.png b/frontend.old/public/img/icons/android-chrome-192x192.png deleted file mode 100644 index 0569b776e427..000000000000 Binary files a/frontend.old/public/img/icons/android-chrome-192x192.png and /dev/null differ diff --git a/frontend.old/public/img/icons/android-chrome-maskable-192x192.png b/frontend.old/public/img/icons/android-chrome-maskable-192x192.png deleted file mode 100644 index 0569b776e427..000000000000 Binary files a/frontend.old/public/img/icons/android-chrome-maskable-192x192.png and /dev/null differ diff --git a/frontend.old/public/img/icons/android-chrome-maskable-512x512.png b/frontend.old/public/img/icons/android-chrome-maskable-512x512.png deleted file mode 100644 index cb0380533224..000000000000 Binary files a/frontend.old/public/img/icons/android-chrome-maskable-512x512.png and /dev/null differ diff --git a/frontend.old/public/img/icons/apple-touch-icon-120x120.png b/frontend.old/public/img/icons/apple-touch-icon-120x120.png deleted file mode 100644 index 0bb475552c3c..000000000000 Binary files a/frontend.old/public/img/icons/apple-touch-icon-120x120.png and /dev/null differ diff --git a/frontend.old/public/img/icons/apple-touch-icon-152x152.png b/frontend.old/public/img/icons/apple-touch-icon-152x152.png deleted file mode 100644 index 53d2b9201a40..000000000000 Binary files a/frontend.old/public/img/icons/apple-touch-icon-152x152.png and /dev/null differ diff --git a/frontend.old/public/img/icons/apple-touch-icon-180x180.png b/frontend.old/public/img/icons/apple-touch-icon-180x180.png deleted file mode 100644 index 12ee3c053603..000000000000 Binary files a/frontend.old/public/img/icons/apple-touch-icon-180x180.png and /dev/null differ diff --git a/frontend.old/public/img/icons/apple-touch-icon-60x60.png b/frontend.old/public/img/icons/apple-touch-icon-60x60.png deleted file mode 100644 index 772375179bb6..000000000000 Binary files a/frontend.old/public/img/icons/apple-touch-icon-60x60.png and /dev/null differ diff --git a/frontend.old/public/img/icons/apple-touch-icon-76x76.png b/frontend.old/public/img/icons/apple-touch-icon-76x76.png deleted file mode 100644 index 919cbdeb6985..000000000000 Binary files a/frontend.old/public/img/icons/apple-touch-icon-76x76.png and /dev/null differ diff --git a/frontend.old/public/img/icons/apple-touch-icon.png b/frontend.old/public/img/icons/apple-touch-icon.png deleted file mode 100644 index 12ee3c053603..000000000000 Binary files a/frontend.old/public/img/icons/apple-touch-icon.png and /dev/null differ diff --git a/frontend.old/public/img/icons/favicon-16x16.png b/frontend.old/public/img/icons/favicon-16x16.png deleted file mode 100644 index 05e2e7625d46..000000000000 Binary files a/frontend.old/public/img/icons/favicon-16x16.png and /dev/null differ diff --git a/frontend.old/public/img/icons/favicon-32x32.png b/frontend.old/public/img/icons/favicon-32x32.png deleted file mode 100644 index 9263cc67c9c4..000000000000 Binary files a/frontend.old/public/img/icons/favicon-32x32.png and /dev/null differ diff --git a/frontend.old/public/img/icons/msapplication-icon-144x144.png b/frontend.old/public/img/icons/msapplication-icon-144x144.png deleted file mode 100644 index c4a5fcb71b59..000000000000 Binary files a/frontend.old/public/img/icons/msapplication-icon-144x144.png and /dev/null differ diff --git a/frontend.old/public/img/icons/mstile-150x150.png b/frontend.old/public/img/icons/mstile-150x150.png deleted file mode 100644 index c6dfc5414f9b..000000000000 Binary files a/frontend.old/public/img/icons/mstile-150x150.png and /dev/null differ diff --git a/frontend.old/public/img/icons/safari-pinned-tab.svg b/frontend.old/public/img/icons/safari-pinned-tab.svg deleted file mode 100644 index 802178d07502..000000000000 --- a/frontend.old/public/img/icons/safari-pinned-tab.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/frontend.old/public/index.html b/frontend.old/public/index.html deleted file mode 100644 index fa926f2b96ea..000000000000 --- a/frontend.old/public/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - Mealie - - - - -
- - - - \ No newline at end of file diff --git a/frontend.old/src/App.vue b/frontend.old/src/App.vue deleted file mode 100644 index 63d1c45e1549..000000000000 --- a/frontend.old/src/App.vue +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - diff --git a/frontend.old/src/api/about.js b/frontend.old/src/api/about.js deleted file mode 100644 index 92434fad1311..000000000000 --- a/frontend.old/src/api/about.js +++ /dev/null @@ -1,80 +0,0 @@ -import { apiReq } from "./api-utils"; -import i18n from "@/i18n.js"; -import { API_ROUTES } from "./apiRoutes"; - -export const aboutAPI = { - async getEvents() { - const resposne = await apiReq.get(API_ROUTES.aboutEvents); - return resposne.data; - }, - async deleteEvent(id) { - const resposne = await apiReq.delete(API_ROUTES.aboutEventsId(id)); - return resposne.data; - }, - async deleteAllEvents() { - const resposne = await apiReq.delete(API_ROUTES.aboutEvents); - return resposne.data; - }, - - async allEventNotifications() { - const response = await apiReq.get(API_ROUTES.aboutEventsNotifications); - return response.data; - }, - - async createNotification(data) { - const response = await apiReq.post(API_ROUTES.aboutEventsNotifications, data); - return response.data; - }, - - async deleteNotification(id) { - const response = await apiReq.delete(API_ROUTES.aboutEventsNotificationsId(id)); - return response.data; - }, - async testNotificationByID(id) { - const response = await apiReq.post( - API_ROUTES.aboutEventsNotificationsTest, - { id: id }, - () => i18n.t("events.something-went-wrong"), - () => i18n.t("events.test-message-sent") - ); - return response.data; - }, - async testNotificationByURL(url) { - const response = await apiReq.post( - API_ROUTES.aboutEventsNotificationsTest, - { test_url: url }, - () => i18n.t("events.something-went-wrong"), - () => i18n.t("events.test-message-sent") - ); - return response.data; - }, - // async getAppInfo() { - // const response = await apiReq.get(aboutURLs.version); - // return response.data; - // }, - - // async getDebugInfo() { - // const response = await apiReq.get(aboutURLs.debug); - // return response.data; - // }, - - // async getLogText(num) { - // const response = await apiReq.get(aboutURLs.log(num)); - // return response.data; - // }, - - // async getLastJson() { - // const response = await apiReq.get(aboutURLs.lastRecipe); - // return response.data; - // }, - - // async getIsDemo() { - // const response = await apiReq.get(aboutURLs.demo); - // return response.data; - // }, - - // async getStatistics() { - // const response = await apiReq.get(aboutURLs.statistics); - // return response.data; - // }, -}; diff --git a/frontend.old/src/api/api-utils.js b/frontend.old/src/api/api-utils.js deleted file mode 100644 index 2a9b0acb4a85..000000000000 --- a/frontend.old/src/api/api-utils.js +++ /dev/null @@ -1,121 +0,0 @@ -import { prefix } from "./apiRoutes"; -import axios from "axios"; -import { store } from "../store"; -import { utils } from "@/utils"; - -axios.defaults.headers.common["Authorization"] = `Bearer ${store.getters.getToken}`; - -function handleError(error, getText) { - if (getText) { - utils.notify.error(getText(error.response)); - } - return false; -} -function handleResponse(response, getText) { - if (response && getText) { - const successText = getText(response); - utils.notify.success(successText); - } - return response; -} - -function defaultErrorText(response) { - return response.statusText; -} - -function defaultSuccessText(response) { - return response.statusText; -} - -const requests = { - /** - * - * @param {*} funcCall Callable Axios Function - * @param {*} url Destination url - * @param {*} data Request Data - * @param {*} getErrorText Error Text Function - * @param {*} getSuccessText Success Text Function - * @returns Object response - */ - unsafe: async function(funcCall, url, data, getErrorText = defaultErrorText, getSuccessText) { - const response = await funcCall(url, data).catch(function(error) { - handleError(error, getErrorText); - }); - return handleResponse(response, getSuccessText); - }, - /** - * - * @param {*} funcCall Callable Axios Function - * @param {*} url Destination url - * @param {*} data Request Data - * @param {*} getErrorText Error Text Function - * @param {*} getSuccessText Success Text Function - * @returns Array [response, error] - */ - safe: async function(funcCall, url, data, getErrorText = defaultErrorText, getSuccessText) { - const response = await funcCall(url, data).catch(function(error) { - handleError(error, getErrorText); - return [null, error]; - }); - return [handleResponse(response, getSuccessText), null]; - }, -}; - -const apiReq = { - get: async function(url, getErrorText = defaultErrorText) { - return axios.get(url).catch(function(error) { - handleError(error, getErrorText); - }); - }, - - getSafe: async function(url) { - let error = null; - const response = await axios.get(url).catch(e => { - error = e; - }); - return [response, error]; - }, - - post: async function(url, data, getErrorText = defaultErrorText, getSuccessText) { - return await requests.unsafe(axios.post, url, data, getErrorText, getSuccessText); - }, - - postSafe: async function(url, data, getErrorText = defaultErrorText, getSuccessText) { - return await requests.safe(axios.post, url, data, getErrorText, getSuccessText); - }, - - put: async function(url, data, getErrorText = defaultErrorText, getSuccessText) { - return await requests.unsafe(axios.put, url, data, getErrorText, getSuccessText); - }, - - putSafe: async function(url, data, getErrorText = defaultErrorText, getSuccessText) { - return await requests.safe(axios.put, url, data, getErrorText, getSuccessText); - }, - - patch: async function(url, data, getErrorText = defaultErrorText, getSuccessText) { - return await requests.unsafe(axios.patch, url, data, getErrorText, getSuccessText); - }, - - patchSafe: async function(url, data, getErrorText = defaultErrorText, getSuccessText) { - return await requests.safe(axios.patch, url, data, getErrorText, getSuccessText); - }, - - delete: async function(url, data, getErrorText = defaultErrorText, getSuccessText = defaultSuccessText) { - return await requests.unsafe(axios.delete, url, data, getErrorText, getSuccessText); - }, - - deleteSafe: async function(url, data, getErrorText = defaultErrorText, getSuccessText = defaultSuccessText) { - return await requests.unsafe(axios.delete, url, data, getErrorText, getSuccessText); - }, - - download: async function(url) { - const response = await this.get(url); - const token = response.data.fileToken; - - const tokenURL = prefix + "/utils/download?token=" + token; - window.open(tokenURL, "_blank"); - return response.data; - }, -}; - -export { apiReq }; diff --git a/frontend.old/src/api/apiRoutes.js b/frontend.old/src/api/apiRoutes.js deleted file mode 100644 index 5d726267743f..000000000000 --- a/frontend.old/src/api/apiRoutes.js +++ /dev/null @@ -1,90 +0,0 @@ -// This Content is Auto Generated -export const prefix = "/api"; -export const API_ROUTES = { - aboutEvents: `${prefix}/about/events`, - aboutEventsNotifications: `${prefix}/about/events/notifications`, - aboutEventsNotificationsTest: `${prefix}/about/events/notifications/test`, - aboutRecipesDefaults: `${prefix}/about/recipes/defaults`, - authRefresh: `${prefix}/auth/refresh`, - authToken: `${prefix}/auth/token`, - authTokenLong: `${prefix}/auth/token/long`, - backupsAvailable: `${prefix}/backups/available`, - backupsExportDatabase: `${prefix}/backups/export/database`, - backupsUpload: `${prefix}/backups/upload`, - categories: `${prefix}/categories`, - categoriesEmpty: `${prefix}/categories/empty`, - debug: `${prefix}/debug`, - debugLastRecipeJson: `${prefix}/debug/last-recipe-json`, - debugLog: `${prefix}/debug/log`, - debugStatistics: `${prefix}/debug/statistics`, - debugVersion: `${prefix}/debug/version`, - groups: `${prefix}/groups`, - groupsSelf: `${prefix}/groups/self`, - mealPlansAll: `${prefix}/meal-plans/all`, - mealPlansCreate: `${prefix}/meal-plans/create`, - mealPlansThisWeek: `${prefix}/meal-plans/this-week`, - mealPlansToday: `${prefix}/meal-plans/today`, - mealPlansTodayImage: `${prefix}/meal-plans/today/image`, - migrations: `${prefix}/migrations`, - recipesCategory: `${prefix}/recipes/category`, - recipesCreate: `${prefix}/recipes/create`, - recipesCreateFromZip: `${prefix}/recipes/create-from-zip`, - recipesCreateUrl: `${prefix}/recipes/create-url`, - recipesSummary: `${prefix}/recipes/summary`, - recipesSummaryUncategorized: `${prefix}/recipes/summary/uncategorized`, - recipesSummaryUntagged: `${prefix}/recipes/summary/untagged`, - recipesTag: `${prefix}/recipes/tag`, - recipesTestScrapeUrl: `${prefix}/recipes/test-scrape-url`, - shoppingLists: `${prefix}/shopping-lists`, - siteSettings: `${prefix}/site-settings`, - siteSettingsCustomPages: `${prefix}/site-settings/custom-pages`, - siteSettingsWebhooksTest: `${prefix}/site-settings/webhooks/test`, - tags: `${prefix}/tags`, - tagsEmpty: `${prefix}/tags/empty`, - themes: `${prefix}/themes`, - themesCreate: `${prefix}/themes/create`, - users: `${prefix}/users`, - usersApiTokens: `${prefix}/users/api-tokens`, - usersSelf: `${prefix}/users/self`, - usersSignUps: `${prefix}/users/sign-ups`, - utilsDownload: `${prefix}/utils/download`, - - aboutEventsId: id => `${prefix}/about/events/${id}`, - aboutEventsNotificationsId: id => `${prefix}/about/events/notifications/${id}`, - backupsFileNameDelete: file_name => `${prefix}/backups/${file_name}/delete`, - backupsFileNameDownload: file_name => `${prefix}/backups/${file_name}/download`, - backupsFileNameImport: file_name => `${prefix}/backups/${file_name}/import`, - categoriesCategory: category => `${prefix}/categories/${category}`, - debugLogNum: num => `${prefix}/debug/log/${num}`, - groupsId: id => `${prefix}/groups/${id}`, - mealPlansId: id => `${prefix}/meal-plans/${id}`, - mealPlansIdShoppingList: id => `${prefix}/meal-plans/${id}/shopping-list`, - mealPlansPlanId: plan_id => `${prefix}/meal-plans/${plan_id}`, - mediaRecipesRecipeSlugAssetsFileName: (recipe_slug, file_name) => - `${prefix}/media/recipes/${recipe_slug}/assets/${file_name}`, - mediaRecipesRecipeSlugImagesFileName: (recipe_slug, file_name) => - `${prefix}/media/recipes/${recipe_slug}/images/${file_name}`, - migrationsImportTypeFileNameDelete: (import_type, file_name) => - `${prefix}/migrations/${import_type}/${file_name}/delete`, - migrationsImportTypeFileNameImport: (import_type, file_name) => - `${prefix}/migrations/${import_type}/${file_name}/import`, - migrationsImportTypeUpload: import_type => `${prefix}/migrations/${import_type}/upload`, - recipesRecipeSlug: recipe_slug => `${prefix}/recipes/${recipe_slug}`, - recipesRecipeSlugAssets: recipe_slug => `${prefix}/recipes/${recipe_slug}/assets`, - recipesRecipeSlugImage: recipe_slug => `${prefix}/recipes/${recipe_slug}/image`, - recipesRecipeSlugZip: recipe_slug => `${prefix}/recipes/${recipe_slug}/zip`, - recipesSlugComments: slug => `${prefix}/recipes/${slug}/comments`, - recipesSlugCommentsId: (slug, id) => `${prefix}/recipes/${slug}/comments/${id}`, - shoppingListsId: id => `${prefix}/shopping-lists/${id}`, - siteSettingsCustomPagesId: id => `${prefix}/site-settings/custom-pages/${id}`, - tagsTag: tag => `${prefix}/tags/${tag}`, - themesId: id => `${prefix}/themes/${id}`, - usersApiTokensTokenId: token_id => `${prefix}/users/api-tokens/${token_id}`, - usersId: id => `${prefix}/users/${id}`, - usersIdFavorites: id => `${prefix}/users/${id}/favorites`, - usersIdFavoritesSlug: (id, slug) => `${prefix}/users/${id}/favorites/${slug}`, - usersIdImage: id => `${prefix}/users/${id}/image`, - usersIdPassword: id => `${prefix}/users/${id}/password`, - usersIdResetPassword: id => `${prefix}/users/${id}/reset-password`, - usersSignUpsToken: token => `${prefix}/users/sign-ups/${token}`, -}; diff --git a/frontend.old/src/api/backup.js b/frontend.old/src/api/backup.js deleted file mode 100644 index 31c354c07e9d..000000000000 --- a/frontend.old/src/api/backup.js +++ /dev/null @@ -1,62 +0,0 @@ -import { apiReq } from "./api-utils"; -import { store } from "@/store"; -import i18n from "@/i18n.js"; -import { API_ROUTES } from "./apiRoutes"; - -export const backupAPI = { - /** - * Request all backups available on the server - * @returns {Array} List of Available Backups - */ - async requestAvailable() { - let response = await apiReq.get(API_ROUTES.backupsAvailable); - return response.data; - }, - /** - * Calls for importing a file on the server - * @param {string} fileName - * @param {object} data - * @returns A report containing status of imported items - */ - async import(fileName, data) { - let response = await apiReq.post(API_ROUTES.backupsFileNameImport(fileName), data); - store.dispatch("requestRecentRecipes"); - return response; - }, - /** - * Removes a file from the server - * @param {string} fileName - */ - async delete(fileName) { - return apiReq.delete( - API_ROUTES.backupsFileNameDelete(fileName), - null, - () => i18n.t("settings.backup.unable-to-delete-backup"), - () => i18n.t("settings.backup.backup-deleted") - ); - }, - /** - * Creates a backup on the serve given a set of options - * @param {object} data - * @returns - */ - async create(options) { - return apiReq.post( - API_ROUTES.backupsExportDatabase, - options, - () => i18n.t("settings.backup.error-creating-backup-see-log-file"), - response => { - return i18n.t("settings.backup.backup-created-at-response-export_path", { path: response.data.export_path }); - } - ); - }, - /** - * Downloads a file from the server. I don't actually think this is used? - * @param {string} fileName - * @returns Download URL - */ - async download(fileName) { - const url = API_ROUTES.backupsFileNameDownload(fileName); - apiReq.download(url); - }, -}; diff --git a/frontend.old/src/api/category.js b/frontend.old/src/api/category.js deleted file mode 100644 index d06d4b5b3932..000000000000 --- a/frontend.old/src/api/category.js +++ /dev/null @@ -1,111 +0,0 @@ -import { apiReq } from "./api-utils"; -import { store } from "@/store"; -import i18n from "@/i18n.js"; -import { API_ROUTES } from "./apiRoutes"; - -export const categoryAPI = { - async getAll() { - let response = await apiReq.get(API_ROUTES.categories); - return response.data; - }, - async getEmpty() { - let response = await apiReq.get(API_ROUTES.categoriesEmpty); - return response.data; - }, - async create(name) { - const response = await apiReq.post( - API_ROUTES.categories, - { name: name }, - () => i18n.t("category.category-creation-failed"), - () => i18n.t("category.category-created") - ); - if (response) { - store.dispatch("requestCategories"); - return response.data; - } - }, - async getRecipesInCategory(category) { - let response = await apiReq.get(API_ROUTES.categoriesCategory(category)); - return response.data; - }, - async update(name, newName, overrideRequest = false) { - const response = await apiReq.put( - API_ROUTES.categoriesCategory(name), - { name: newName }, - () => i18n.t("category.category-update-failed"), - () => i18n.t("category.category-updated") - ); - if (response && !overrideRequest) { - store.dispatch("requestCategories"); - return response.data; - } - }, - async delete(category, overrideRequest = false) { - const response = await apiReq.delete( - API_ROUTES.categoriesCategory(category), - null, - () => i18n.t("category.category-deletion-failed"), - () => i18n.t("category.category-deleted") - ); - if (response && !overrideRequest) { - store.dispatch("requestCategories"); - } - return response; - }, -}; - -export const tagAPI = { - async getAll() { - let response = await apiReq.get(API_ROUTES.tags); - return response.data; - }, - async getEmpty() { - let response = await apiReq.get(API_ROUTES.tagsEmpty); - return response.data; - }, - async create(name) { - const response = await apiReq.post( - API_ROUTES.tags, - { name: name }, - () => i18n.t("tag.tag-creation-failed"), - () => i18n.t("tag.tag-created") - ); - if (response) { - store.dispatch("requestTags"); - return response.data; - } - }, - async getRecipesInTag(tag) { - let response = await apiReq.get(API_ROUTES.tagsTag(tag)); - return response.data; - }, - async update(name, newName, overrideRequest = false) { - const response = await apiReq.put( - API_ROUTES.tagsTag(name), - { name: newName }, - () => i18n.t("tag.tag-update-failed"), - () => i18n.t("tag.tag-updated") - ); - - if (response) { - if (!overrideRequest) { - store.dispatch("requestTags"); - } - return response.data; - } - }, - async delete(tag, overrideRequest = false) { - const response = await apiReq.delete( - API_ROUTES.tagsTag(tag), - null, - () => i18n.t("tag.tag-deletion-failed"), - () => i18n.t("tag.tag-deleted") - ); - if (response) { - if (!overrideRequest) { - store.dispatch("requestTags"); - } - return response.data; - } - }, -}; diff --git a/frontend.old/src/api/groups.js b/frontend.old/src/api/groups.js deleted file mode 100644 index 62ad406b3b43..000000000000 --- a/frontend.old/src/api/groups.js +++ /dev/null @@ -1,53 +0,0 @@ -import { apiReq } from "./api-utils"; -import i18n from "@/i18n.js"; -import { API_ROUTES } from "./apiRoutes"; - -function deleteErrorText(response) { - switch (response.data.detail) { - case "GROUP_WITH_USERS": - return i18n.t("group.cannot-delete-group-with-users"); - - case "GROUP_NOT_FOUND": - return i18n.t("group.group-not-found"); - - case "DEFAULT_GROUP": - return i18n.t("group.cannot-delete-default-group"); - - default: - return i18n.t("group.group-deletion-failed"); - } -} - -export const groupAPI = { - async allGroups() { - let response = await apiReq.get(API_ROUTES.groups); - return response.data; - }, - create(name) { - return apiReq.post( - API_ROUTES.groups, - { name: name }, - () => i18n.t("group.user-group-creation-failed"), - () => i18n.t("group.user-group-created") - ); - }, - delete(id) { - return apiReq.delete(API_ROUTES.groupsId(id), null, deleteErrorText, function() { - return i18n.t("group.group-deleted"); - }); - }, - async current() { - const response = await apiReq.get(API_ROUTES.groupsSelf, null, null); - if (response) { - return response.data; - } - }, - update(data) { - return apiReq.put( - API_ROUTES.groupsId(data.id), - data, - () => i18n.t("group.error-updating-group"), - () => i18n.t("settings.group-settings-updated") - ); - }, -}; diff --git a/frontend.old/src/api/index.js b/frontend.old/src/api/index.js deleted file mode 100644 index dbc633212f33..000000000000 --- a/frontend.old/src/api/index.js +++ /dev/null @@ -1,37 +0,0 @@ -import { backupAPI } from "./backup"; -import { recipeAPI } from "./recipe"; -import { mealplanAPI } from "./mealplan"; -import { settingsAPI } from "./settings"; -import { themeAPI } from "./themes"; -import { migrationAPI } from "./migration"; -import { utilsAPI } from "./upload"; -import { categoryAPI, tagAPI } from "./category"; -import { metaAPI } from "./meta"; -import { userAPI } from "./users"; -import { signupAPI } from "./signUps"; -import { groupAPI } from "./groups"; -import { siteSettingsAPI } from "./siteSettings"; -import { aboutAPI } from "./about"; -import { shoppingListsAPI } from "./shoppingLists"; - -/** - * The main object namespace for interacting with the backend database - */ -export const api = { - recipes: recipeAPI, - siteSettings: siteSettingsAPI, - backups: backupAPI, - mealPlans: mealplanAPI, - settings: settingsAPI, - themes: themeAPI, - migrations: migrationAPI, - utils: utilsAPI, - categories: categoryAPI, - tags: tagAPI, - meta: metaAPI, - users: userAPI, - signUps: signupAPI, - groups: groupAPI, - about: aboutAPI, - shoppingLists: shoppingListsAPI, -}; diff --git a/frontend.old/src/api/mealplan.js b/frontend.old/src/api/mealplan.js deleted file mode 100644 index f1e3dc8d219e..000000000000 --- a/frontend.old/src/api/mealplan.js +++ /dev/null @@ -1,57 +0,0 @@ -import { apiReq } from "./api-utils"; -import i18n from "@/i18n.js"; -import { API_ROUTES } from "./apiRoutes"; - -export const mealplanAPI = { - create(postBody) { - return apiReq.post( - API_ROUTES.mealPlansCreate, - postBody, - () => i18n.t("meal-plan.mealplan-creation-failed"), - () => i18n.t("meal-plan.mealplan-created") - ); - }, - - async all() { - let response = await apiReq.get(API_ROUTES.mealPlansAll); - return response; - }, - - async thisWeek() { - let response = await apiReq.get(API_ROUTES.mealPlansThisWeek); - return response.data; - }, - - async today() { - let response = await apiReq.get(API_ROUTES.mealPlansToday); - return response; - }, - - async getById(id) { - let response = await apiReq.get(API_ROUTES.mealPlansId(id)); - return response.data; - }, - - delete(id) { - return apiReq.delete( - API_ROUTES.mealPlansId(id), - null, - () => i18n.t("meal-plan.mealplan-deletion-failed"), - () => i18n.t("meal-plan.mealplan-deleted") - ); - }, - - update(id, body) { - return apiReq.put( - API_ROUTES.mealPlansId(id), - body, - () => i18n.t("meal-plan.mealplan-update-failed"), - () => i18n.t("meal-plan.mealplan-updated") - ); - }, - - async shoppingList(id) { - let response = await apiReq.get(API_ROUTES.mealPlansIdShoppingList(id)); - return response.data; - }, -}; diff --git a/frontend.old/src/api/meta.js b/frontend.old/src/api/meta.js deleted file mode 100644 index b460c961c17a..000000000000 --- a/frontend.old/src/api/meta.js +++ /dev/null @@ -1,29 +0,0 @@ -import { apiReq } from "./api-utils"; -import { API_ROUTES } from "./apiRoutes"; - -export const metaAPI = { - async getAppInfo() { - const response = await apiReq.get(API_ROUTES.debugVersion); - return response.data; - }, - - async getDebugInfo() { - const response = await apiReq.get(API_ROUTES.debug); - return response.data; - }, - - async getLogText(num) { - const response = await apiReq.get(API_ROUTES.debugLogNum(num)); - return response.data; - }, - - async getLastJson() { - const response = await apiReq.get(API_ROUTES.debugLastRecipeJson); - return response.data; - }, - - async getStatistics() { - const response = await apiReq.get(API_ROUTES.debugStatistics); - return response.data; - }, -}; diff --git a/frontend.old/src/api/migration.js b/frontend.old/src/api/migration.js deleted file mode 100644 index 96d148a88e64..000000000000 --- a/frontend.old/src/api/migration.js +++ /dev/null @@ -1,25 +0,0 @@ -import { apiReq } from "./api-utils"; -import { store } from "../store"; -import i18n from "@/i18n.js"; -import { API_ROUTES } from "./apiRoutes"; - -export const migrationAPI = { - async getMigrations() { - let response = await apiReq.get(API_ROUTES.migrations); - return response.data; - }, - async delete(folder, file) { - const response = await apiReq.delete( - API_ROUTES.migrationsImportTypeFileNameDelete(folder, file), - null, - () => i18n.t("general.file-folder-not-found"), - () => i18n.t("migration.migration-data-removed") - ); - return response; - }, - async import(folder, file) { - let response = await apiReq.post(API_ROUTES.migrationsImportTypeFileNameImport(folder, file)); - store.dispatch("requestRecentRecipes"); - return response.data; - }, -}; diff --git a/frontend.old/src/api/recipe.js b/frontend.old/src/api/recipe.js deleted file mode 100644 index 6a4445c7fd31..000000000000 --- a/frontend.old/src/api/recipe.js +++ /dev/null @@ -1,181 +0,0 @@ -import { API_ROUTES } from "./apiRoutes"; -import { apiReq } from "./api-utils"; -import { store } from "../store"; -import i18n from "@/i18n.js"; - -export const recipeAPI = { - /** - * Returns the Default Recipe Settings for the Site - * @returns {AxoisResponse} Axois Response Object - */ - async getDefaultSettings() { - const response = await apiReq.get(API_ROUTES.aboutRecipesDefaults); - return response; - }, - - /** - * Create a Recipe by URL - * @param {string} recipeURL - * @returns {string} Recipe Slug - */ - async createByURL(recipeURL) { - const response = await apiReq.post(API_ROUTES.recipesCreateUrl, { url: recipeURL }, false, () => - i18n.t("recipe.recipe-created") - ); - - store.dispatch("requestRecentRecipes"); - return response; - }, - - async getAllByCategory(categories) { - let response = await apiReq.post(API_ROUTES.recipesCategory, categories); - return response.data; - }, - - async create(recipeData) { - const response = await apiReq.post( - API_ROUTES.recipesCreate, - recipeData, - () => i18n.t("recipe.recipe-creation-failed"), - () => i18n.t("recipe.recipe-created") - ); - store.dispatch("requestRecentRecipes"); - return response.data; - }, - - async requestDetails(recipeSlug) { - const response = await apiReq.getSafe(API_ROUTES.recipesRecipeSlug(recipeSlug)); - return response; - }, - - updateImage(recipeSlug, fileObject, overrideSuccessMsg = false) { - const formData = new FormData(); - formData.append("image", fileObject); - formData.append("extension", fileObject.name.split(".").pop()); - - let successMessage = null; - if (!overrideSuccessMsg) { - successMessage = function() { - return overrideSuccessMsg ? null : i18n.t("recipe.recipe-image-updated"); - }; - } - - return apiReq.put( - API_ROUTES.recipesRecipeSlugImage(recipeSlug), - formData, - () => i18n.t("general.image-upload-failed"), - successMessage - ); - }, - - async createAsset(recipeSlug, fileObject, name, icon) { - const fd = new FormData(); - fd.append("file", fileObject); - fd.append("extension", fileObject.name.split(".").pop()); - fd.append("name", name); - fd.append("icon", icon); - const response = apiReq.post(API_ROUTES.recipesRecipeSlugAssets(recipeSlug), fd); - return response; - }, - - updateImagebyURL(slug, url) { - return apiReq.post( - API_ROUTES.recipesRecipeSlugImage(slug), - { url: url }, - () => i18n.t("general.image-upload-failed"), - () => i18n.t("recipe.recipe-image-updated") - ); - }, - - async update(data) { - let response = await apiReq.put( - API_ROUTES.recipesRecipeSlug(data.slug), - data, - () => i18n.t("recipe.recipe-update-failed"), - () => i18n.t("recipe.recipe-updated") - ); - if (response) { - store.dispatch("patchRecipe", response.data); - return response.data.slug; // ! Temporary until I rewrite to refresh page without additional request - } - }, - - async patch(data) { - let response = await apiReq.patch(API_ROUTES.recipesRecipeSlug(data.slug), data); - store.dispatch("patchRecipe", response.data); - return response.data; - }, - - async delete(recipeSlug) { - const response = await apiReq.delete( - API_ROUTES.recipesRecipeSlug(recipeSlug), - null, - () => i18n.t("recipe.unable-to-delete-recipe"), - () => i18n.t("recipe.recipe-deleted") - ); - store.dispatch("dropRecipe", response.data); - return response; - }, - - async allSummary(start = 0, limit = 9999) { - const response = await apiReq.get(API_ROUTES.recipesSummary, { - params: { start: start, limit: limit }, - }); - return response.data; - }, - - async allUntagged() { - const response = await apiReq.get(API_ROUTES.recipesSummaryUntagged); - return response.data; - }, - - async allUnategorized() { - const response = await apiReq.get(API_ROUTES.recipesSummaryUncategorized); - return response.data; - }, - - recipeImage(recipeSlug, version = null, key = null) { - return `/api/media/recipes/${recipeSlug}/images/original.webp?&rnd=${key}&version=${version}`; - }, - - recipeSmallImage(recipeSlug, version = null, key = null) { - return `/api/media/recipes/${recipeSlug}/images/min-original.webp?&rnd=${key}&version=${version}`; - }, - - recipeTinyImage(recipeSlug, version = null, key = null) { - return `/api/media/recipes/${recipeSlug}/images/tiny-original.webp?&rnd=${key}&version=${version}`; - }, - - recipeAssetPath(recipeSlug, assetName) { - return `/api/media/recipes/${recipeSlug}/assets/${assetName}`; - }, - - /** Create comment in the Database - * @param slug - */ - async createComment(slug, data) { - const response = await apiReq.post(API_ROUTES.recipesSlugComments(slug), data); - return response.data; - }, - /** Update comment in the Database - * @param slug - * @param id - */ - async updateComment(slug, id, data) { - const response = await apiReq.put(API_ROUTES.recipesSlugCommentsId(slug, id), data); - return response.data; - }, - /** Delete comment from the Database - * @param slug - * @param id - */ - async deleteComment(slug, id) { - const response = await apiReq.delete(API_ROUTES.recipesSlugCommentsId(slug, id)); - return response.data; - }, - - async testScrapeURL(url) { - const response = await apiReq.post(API_ROUTES.recipesTestScrapeUrl, { url: url }); - return response.data; - }, -}; diff --git a/frontend.old/src/api/settings.js b/frontend.old/src/api/settings.js deleted file mode 100644 index ffb2af344bbc..000000000000 --- a/frontend.old/src/api/settings.js +++ /dev/null @@ -1,19 +0,0 @@ -import { apiReq } from "./api-utils"; -import { API_ROUTES } from "./apiRoutes"; - -export const settingsAPI = { - async requestAll() { - let response = await apiReq.get(API_ROUTES.siteSettings); - return response.data; - }, - - async testWebhooks() { - let response = await apiReq.post(API_ROUTES.siteSettingsWebhooksTest); - return response.data; - }, - - async update(body) { - let response = await apiReq.put(API_ROUTES.siteSettings, body); - return response.data; - }, -}; diff --git a/frontend.old/src/api/shoppingLists.js b/frontend.old/src/api/shoppingLists.js deleted file mode 100644 index 74a7c9e2cd1c..000000000000 --- a/frontend.old/src/api/shoppingLists.js +++ /dev/null @@ -1,33 +0,0 @@ -// This Content is Auto Generated -import { API_ROUTES } from "./apiRoutes"; -import { apiReq } from "./api-utils"; - -export const shoppingListsAPI = { - /** Create Shopping List in the Database - */ - async createShoppingList(data) { - const response = await apiReq.post(API_ROUTES.shoppingLists, data); - return response.data; - }, - /** Get Shopping List from the Database - * @param id - */ - async getShoppingList(id) { - const response = await apiReq.get(API_ROUTES.shoppingListsId(id)); - return response.data; - }, - /** Update Shopping List in the Database - * @param id - */ - async updateShoppingList(id, data) { - const response = await apiReq.put(API_ROUTES.shoppingListsId(id), data); - return response.data; - }, - /** Delete Shopping List from the Database - * @param id - */ - async deleteShoppingList(id) { - const response = await apiReq.delete(API_ROUTES.shoppingListsId(id)); - return response.data; - }, -}; diff --git a/frontend.old/src/api/signUps.js b/frontend.old/src/api/signUps.js deleted file mode 100644 index 946a8ea71063..000000000000 --- a/frontend.old/src/api/signUps.js +++ /dev/null @@ -1,35 +0,0 @@ -import { apiReq } from "./api-utils"; -import i18n from "@/i18n.js"; -import { API_ROUTES } from "./apiRoutes"; - -export const signupAPI = { - async getAll() { - let response = await apiReq.get(API_ROUTES.usersSignUps); - return response.data; - }, - async createToken(data) { - let response = await apiReq.post( - API_ROUTES.usersSignUps, - data, - () => i18n.t("signup.sign-up-link-creation-failed"), - () => i18n.t("signup.sign-up-link-created") - ); - return response.data; - }, - async deleteToken(token) { - return await apiReq.delete( - API_ROUTES.usersSignUpsToken(token), - null, - () => i18n.t("signup.sign-up-token-deletion-failed"), - () => i18n.t("signup.sign-up-token-deleted") - ); - }, - async createUser(token, data) { - return apiReq.post( - API_ROUTES.usersSignUpsToken(token), - data, - () => i18n.t("user.you-are-not-allowed-to-create-a-user"), - () => i18n.t("user.user-created") - ); - }, -}; diff --git a/frontend.old/src/api/siteSettings.js b/frontend.old/src/api/siteSettings.js deleted file mode 100644 index 0d25479df24c..000000000000 --- a/frontend.old/src/api/siteSettings.js +++ /dev/null @@ -1,71 +0,0 @@ -import { apiReq } from "./api-utils"; -import { store } from "@/store"; -import i18n from "@/i18n.js"; -import { API_ROUTES } from "./apiRoutes"; - -export const siteSettingsAPI = { - async get() { - let response = await apiReq.get(API_ROUTES.siteSettings); - return response.data; - }, - - async update(body) { - const response = await apiReq.put( - API_ROUTES.siteSettings, - body, - () => i18n.t("settings.settings-update-failed"), - () => i18n.t("settings.settings-updated") - ); - if (response) { - store.dispatch("requestSiteSettings"); - } - return response; - }, - - async getPages() { - let response = await apiReq.get(API_ROUTES.siteSettingsCustomPages); - return response.data; - }, - - async getPage(id) { - let response = await apiReq.get(API_ROUTES.siteSettingsCustomPagesId(id)); - return response.data; - }, - - createPage(body) { - return apiReq.post( - API_ROUTES.siteSettingsCustomPages, - body, - () => i18n.t("page.page-creation-failed"), - () => i18n.t("page.new-page-created") - ); - }, - - async deletePage(id) { - return await apiReq.delete( - API_ROUTES.siteSettingsCustomPagesId(id), - null, - () => i18n.t("page.page-deletion-failed"), - () => i18n.t("page.page-deleted") - ); - }, - - updatePage(body) { - return apiReq.put( - API_ROUTES.siteSettingsCustomPagesId(body.id), - body, - () => i18n.t("page.page-update-failed"), - () => i18n.t("page.page-updated") - ); - }, - - async updateAllPages(allPages) { - let response = await apiReq.put( - API_ROUTES.siteSettingsCustomPages, - allPages, - () => i18n.t("page.pages-update-failed"), - () => i18n.t("page.pages-updated") - ); - return response; - }, -}; diff --git a/frontend.old/src/api/themes.js b/frontend.old/src/api/themes.js deleted file mode 100644 index ba19e0083c64..000000000000 --- a/frontend.old/src/api/themes.js +++ /dev/null @@ -1,42 +0,0 @@ -import { apiReq } from "./api-utils"; -import i18n from "@/i18n.js"; -import { API_ROUTES } from "./apiRoutes"; - -export const themeAPI = { - async requestAll() { - let response = await apiReq.get(API_ROUTES.themes); - return response.data; - }, - - async requestByName(name) { - let response = await apiReq.get(API_ROUTES.themesId(name)); - return response.data; - }, - - async create(postBody) { - return await apiReq.post( - API_ROUTES.themesCreate, - postBody, - () => i18n.t("settings.theme.error-creating-theme-see-log-file"), - () => i18n.t("settings.theme.theme-saved") - ); - }, - - update(data) { - return apiReq.put( - API_ROUTES.themesId(data.id), - data, - () => i18n.t("settings.theme.error-updating-theme"), - () => i18n.t("settings.theme.theme-updated") - ); - }, - - delete(id) { - return apiReq.delete( - API_ROUTES.themesId(id), - null, - () => i18n.t("settings.theme.error-deleting-theme"), - () => i18n.t("settings.theme.theme-deleted") - ); - }, -}; diff --git a/frontend.old/src/api/upload.js b/frontend.old/src/api/upload.js deleted file mode 100644 index efd9ada3e1fc..000000000000 --- a/frontend.old/src/api/upload.js +++ /dev/null @@ -1,14 +0,0 @@ -import { apiReq } from "./api-utils"; -import i18n from "@/i18n.js"; - -export const utilsAPI = { - // import { api } from "@/api"; - uploadFile(url, fileObject) { - return apiReq.post( - url, - fileObject, - () => i18n.t("general.failure-uploading-file"), - () => i18n.t("general.file-uploaded") - ); - }, -}; diff --git a/frontend.old/src/api/users.js b/frontend.old/src/api/users.js deleted file mode 100644 index d354a6e6614b..000000000000 --- a/frontend.old/src/api/users.js +++ /dev/null @@ -1,107 +0,0 @@ -import { API_ROUTES } from "./apiRoutes"; -import { apiReq } from "./api-utils"; -import i18n from "@/i18n.js"; - -export const userAPI = { - async login(formData) { - let response = await apiReq.post(API_ROUTES.authToken, formData, null, () => { - return i18n.t("user.user-successfully-logged-in"); - }); - return response; - }, - async refresh() { - return apiReq.getSafe(API_ROUTES.authRefresh); - }, - async allUsers() { - let response = await apiReq.get(API_ROUTES.users); - return response.data; - }, - create(user) { - return apiReq.post( - API_ROUTES.users, - user, - () => i18n.t("user.user-creation-failed"), - () => i18n.t("user.user-created") - ); - }, - async self() { - return apiReq.getSafe(API_ROUTES.usersSelf); - }, - async byID(id) { - let response = await apiReq.get(API_ROUTES.usersId(id)); - return response.data; - }, - update(user) { - return apiReq.put( - API_ROUTES.usersId(user.id), - user, - () => i18n.t("user.user-update-failed"), - () => i18n.t("user.user-updated") - ); - }, - changePassword(id, password) { - return apiReq.put( - API_ROUTES.usersIdPassword(id), - password, - () => i18n.t("user.existing-password-does-not-match"), - () => i18n.t("user.password-updated") - ); - }, - - delete(id) { - return apiReq.delete(API_ROUTES.usersId(id), null, deleteErrorText, () => { - return i18n.t("user.user-deleted"); - }); - }, - resetPassword(id) { - return apiReq.put( - API_ROUTES.usersIdResetPassword(id), - null, - () => i18n.t("user.password-reset-failed"), - () => i18n.t("user.password-has-been-reset-to-the-default-password") - ); - }, - async createAPIToken(name) { - const response = await apiReq.post(API_ROUTES.usersApiTokens, { name }); - return response.data; - }, - async deleteAPIToken(id) { - const response = await apiReq.delete(API_ROUTES.usersApiTokensTokenId(id)); - return response.data; - }, - /** Adds a Recipe to the users favorites - * @param id - */ - async getFavorites(id) { - const response = await apiReq.get(API_ROUTES.usersIdFavorites(id)); - return response.data; - }, - /** Adds a Recipe to the users favorites - * @param id - */ - async addFavorite(id, slug) { - const response = await apiReq.post(API_ROUTES.usersIdFavoritesSlug(id, slug)); - return response.data; - }, - /** Adds a Recipe to the users favorites - * @param id - */ - async removeFavorite(id, slug) { - const response = await apiReq.delete(API_ROUTES.usersIdFavoritesSlug(id, slug)); - return response.data; - }, - - userProfileImage(id) { - if (!id || id === undefined) return; - return `/api/users/${id}/image`; - }, -}; - -const deleteErrorText = response => { - switch (response.data.detail) { - case "SUPER_USER": - return i18n.t("user.error-cannot-delete-super-user"); - default: - return i18n.t("user.you-are-not-allowed-to-delete-this-user"); - } -}; diff --git a/frontend.old/src/components/Fallbacks/NoRecipe.vue b/frontend.old/src/components/Fallbacks/NoRecipe.vue deleted file mode 100644 index d196b487c05b..000000000000 --- a/frontend.old/src/components/Fallbacks/NoRecipe.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - diff --git a/frontend.old/src/components/Fallbacks/The404.vue b/frontend.old/src/components/Fallbacks/The404.vue deleted file mode 100644 index 60f8d5ba19cd..000000000000 --- a/frontend.old/src/components/Fallbacks/The404.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend.old/src/components/FormHelpers/CategoryTagSelector.vue b/frontend.old/src/components/FormHelpers/CategoryTagSelector.vue deleted file mode 100644 index e02b988b48ef..000000000000 --- a/frontend.old/src/components/FormHelpers/CategoryTagSelector.vue +++ /dev/null @@ -1,134 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/FormHelpers/ColorPickerDialog.vue b/frontend.old/src/components/FormHelpers/ColorPickerDialog.vue deleted file mode 100644 index 13ba003ec499..000000000000 --- a/frontend.old/src/components/FormHelpers/ColorPickerDialog.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/FormHelpers/DatePicker.vue b/frontend.old/src/components/FormHelpers/DatePicker.vue deleted file mode 100644 index 610ec00a8970..000000000000 --- a/frontend.old/src/components/FormHelpers/DatePicker.vue +++ /dev/null @@ -1,27 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/FormHelpers/ImportOptions.vue b/frontend.old/src/components/FormHelpers/ImportOptions.vue deleted file mode 100644 index 519037a46e53..000000000000 --- a/frontend.old/src/components/FormHelpers/ImportOptions.vue +++ /dev/null @@ -1,69 +0,0 @@ - - - \ No newline at end of file diff --git a/frontend.old/src/components/FormHelpers/LanguageSelector.vue b/frontend.old/src/components/FormHelpers/LanguageSelector.vue deleted file mode 100644 index c480fad998d5..000000000000 --- a/frontend.old/src/components/FormHelpers/LanguageSelector.vue +++ /dev/null @@ -1,48 +0,0 @@ - - - diff --git a/frontend.old/src/components/FormHelpers/TimePickerDialog.vue b/frontend.old/src/components/FormHelpers/TimePickerDialog.vue deleted file mode 100644 index 8a7c9e851a22..000000000000 --- a/frontend.old/src/components/FormHelpers/TimePickerDialog.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/ImportSummaryDialog/DataTable.vue b/frontend.old/src/components/ImportSummaryDialog/DataTable.vue deleted file mode 100644 index 8391bc95eedf..000000000000 --- a/frontend.old/src/components/ImportSummaryDialog/DataTable.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/ImportSummaryDialog/index.vue b/frontend.old/src/components/ImportSummaryDialog/index.vue deleted file mode 100644 index d754451fd0f7..000000000000 --- a/frontend.old/src/components/ImportSummaryDialog/index.vue +++ /dev/null @@ -1,142 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/Login/LoginDialog.vue b/frontend.old/src/components/Login/LoginDialog.vue deleted file mode 100644 index fae060b1d075..000000000000 --- a/frontend.old/src/components/Login/LoginDialog.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/Login/LoginForm.vue b/frontend.old/src/components/Login/LoginForm.vue deleted file mode 100644 index d3bda238cce9..000000000000 --- a/frontend.old/src/components/Login/LoginForm.vue +++ /dev/null @@ -1,94 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/Login/SignUpForm.vue b/frontend.old/src/components/Login/SignUpForm.vue deleted file mode 100644 index 4aa118f8f30a..000000000000 --- a/frontend.old/src/components/Login/SignUpForm.vue +++ /dev/null @@ -1,141 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/MealPlan/ShoppingListDialog.vue b/frontend.old/src/components/MealPlan/ShoppingListDialog.vue deleted file mode 100644 index d66d27219a89..000000000000 --- a/frontend.old/src/components/MealPlan/ShoppingListDialog.vue +++ /dev/null @@ -1,100 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/UI/Buttons/TheButton.vue b/frontend.old/src/components/UI/Buttons/TheButton.vue deleted file mode 100644 index a3973429b90d..000000000000 --- a/frontend.old/src/components/UI/Buttons/TheButton.vue +++ /dev/null @@ -1,163 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend.old/src/components/UI/Buttons/TheCopyButton.vue b/frontend.old/src/components/UI/Buttons/TheCopyButton.vue deleted file mode 100644 index adfa5a11ddd2..000000000000 --- a/frontend.old/src/components/UI/Buttons/TheCopyButton.vue +++ /dev/null @@ -1,71 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend.old/src/components/UI/Buttons/TheDownloadBtn.vue b/frontend.old/src/components/UI/Buttons/TheDownloadBtn.vue deleted file mode 100644 index 02e7a21a30e8..000000000000 --- a/frontend.old/src/components/UI/Buttons/TheDownloadBtn.vue +++ /dev/null @@ -1,54 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/UI/Buttons/TheUploadBtn.vue b/frontend.old/src/components/UI/Buttons/TheUploadBtn.vue deleted file mode 100644 index 95b4a8ce5262..000000000000 --- a/frontend.old/src/components/UI/Buttons/TheUploadBtn.vue +++ /dev/null @@ -1,89 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/UI/Dialogs/BackupDialog.vue b/frontend.old/src/components/UI/Dialogs/BackupDialog.vue deleted file mode 100644 index d9edb45efc53..000000000000 --- a/frontend.old/src/components/UI/Dialogs/BackupDialog.vue +++ /dev/null @@ -1,146 +0,0 @@ - - - diff --git a/frontend.old/src/components/UI/Dialogs/ImportDialog.vue b/frontend.old/src/components/UI/Dialogs/ImportDialog.vue deleted file mode 100644 index af7002f4cd3b..000000000000 --- a/frontend.old/src/components/UI/Dialogs/ImportDialog.vue +++ /dev/null @@ -1,119 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/UI/Dialogs/SearchDialog.vue b/frontend.old/src/components/UI/Dialogs/SearchDialog.vue deleted file mode 100644 index c45dbf9ae276..000000000000 --- a/frontend.old/src/components/UI/Dialogs/SearchDialog.vue +++ /dev/null @@ -1,172 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend.old/src/components/UI/GlobalSnackbar.vue b/frontend.old/src/components/UI/GlobalSnackbar.vue deleted file mode 100644 index 39b9cfab127c..000000000000 --- a/frontend.old/src/components/UI/GlobalSnackbar.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - \ No newline at end of file diff --git a/frontend.old/src/components/UI/LogCard.vue b/frontend.old/src/components/UI/LogCard.vue deleted file mode 100644 index 9fbc9a906cda..000000000000 --- a/frontend.old/src/components/UI/LogCard.vue +++ /dev/null @@ -1,81 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend.old/src/components/UI/Search/FuseSearchBar.vue b/frontend.old/src/components/UI/Search/FuseSearchBar.vue deleted file mode 100644 index fa109197e945..000000000000 --- a/frontend.old/src/components/UI/Search/FuseSearchBar.vue +++ /dev/null @@ -1,80 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/UI/Search/SearchBar.vue b/frontend.old/src/components/UI/Search/SearchBar.vue deleted file mode 100644 index bf2b145aec01..000000000000 --- a/frontend.old/src/components/UI/Search/SearchBar.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - - diff --git a/frontend.old/src/components/UI/Search/SearchDialog.vue b/frontend.old/src/components/UI/Search/SearchDialog.vue deleted file mode 100644 index ea4a6f1918f8..000000000000 --- a/frontend.old/src/components/UI/Search/SearchDialog.vue +++ /dev/null @@ -1,103 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/UI/StatCard.vue b/frontend.old/src/components/UI/StatCard.vue deleted file mode 100644 index a9f11c9451f3..000000000000 --- a/frontend.old/src/components/UI/StatCard.vue +++ /dev/null @@ -1,103 +0,0 @@ -w - - - - diff --git a/frontend.old/src/components/UI/TheAppBar.vue b/frontend.old/src/components/UI/TheAppBar.vue deleted file mode 100644 index e54393d7301d..000000000000 --- a/frontend.old/src/components/UI/TheAppBar.vue +++ /dev/null @@ -1,102 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/UI/TheRecipeFab.vue b/frontend.old/src/components/UI/TheRecipeFab.vue deleted file mode 100644 index 8136527ff534..000000000000 --- a/frontend.old/src/components/UI/TheRecipeFab.vue +++ /dev/null @@ -1,247 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/UI/TheSidebar.vue b/frontend.old/src/components/UI/TheSidebar.vue deleted file mode 100644 index 5d64acde2db6..000000000000 --- a/frontend.old/src/components/UI/TheSidebar.vue +++ /dev/null @@ -1,253 +0,0 @@ - - - - - diff --git a/frontend.old/src/components/UI/TheSiteMenu.vue b/frontend.old/src/components/UI/TheSiteMenu.vue deleted file mode 100644 index b9de04a1086b..000000000000 --- a/frontend.old/src/components/UI/TheSiteMenu.vue +++ /dev/null @@ -1,109 +0,0 @@ - - - - diff --git a/frontend.old/src/i18n.js b/frontend.old/src/i18n.js deleted file mode 100644 index 7433c36a8b24..000000000000 --- a/frontend.old/src/i18n.js +++ /dev/null @@ -1,38 +0,0 @@ -import Vue from "vue"; -import VueI18n from "vue-i18n"; -import Vuetify from "@/plugins/vuetify"; -import axios from 'axios'; - -Vue.use(VueI18n); - -const i18n = new VueI18n(); - -export default i18n; - -const loadedLanguages = []; - -function setI18nLanguage (lang) { - i18n.locale = lang; - Vuetify.framework.lang.current = lang; - axios.defaults.headers.common['Accept-Language'] = lang - document.querySelector('html').setAttribute('lang', lang) - return lang -} - -export function loadLanguageAsync(lang) { - - if ( ! loadedLanguages.includes(lang)) { - const messages = import(`./locales/messages/${lang}.json`); - const dateTimeFormats = import(`./locales/dateTimeFormats/${lang}.json`); - - return Promise.all([messages, dateTimeFormats]).then( - values => { - i18n.setLocaleMessage(lang, values[0].default) - i18n.setDateTimeFormat(lang, values[1].default) - loadedLanguages.push(lang) - return setI18nLanguage(lang) - } - ) - } - return Promise.resolve(setI18nLanguage(lang)) -} \ No newline at end of file diff --git a/frontend.old/src/installCompAPI.js b/frontend.old/src/installCompAPI.js deleted file mode 100644 index c1a45139dba5..000000000000 --- a/frontend.old/src/installCompAPI.js +++ /dev/null @@ -1,3 +0,0 @@ -import Vue from "vue"; -import VueCompositionAPI from "@vue/composition-api"; -Vue.use(VueCompositionAPI); diff --git a/frontend.old/src/main.js b/frontend.old/src/main.js deleted file mode 100644 index d7ad28f64372..000000000000 --- a/frontend.old/src/main.js +++ /dev/null @@ -1,44 +0,0 @@ -import "./installCompAPI"; // Must Be First - -import Vue from "vue"; -import App from "./App.vue"; -import vuetify from "./plugins/vuetify"; -import store from "./store"; -import VueRouter from "vue-router"; -import { router } from "./routes"; -import { globals } from "@/utils/globals"; -import i18n from "./i18n"; -import "typeface-roboto/index.css"; -import "./registerServiceWorker"; - -Vue.config.productionTip = false; -Vue.use(VueRouter); -Vue.component("TheButton", () => import("@/components/UI/Buttons/TheButton.vue")); - -Vue.prototype.$globals = globals; - -const vueApp = new Vue({ - vuetify, - store, - router, - i18n, - render: h => h(App), -}).$mount("#app"); - -// Truncate -const truncate = function(text, length, clamp) { - clamp = clamp || "..."; - let node = document.createElement("div"); - node.innerHTML = text; - let content = node.textContent; - return content.length > length ? content.slice(0, length) + clamp : content; -}; - -const titleCase = function(value) { - return value.replace(/(?:^|\s|-)\S/g, x => x.toUpperCase()); -}; - -Vue.filter("truncate", truncate); -Vue.filter("titleCase", titleCase); - -export { router, vueApp }; diff --git a/frontend.old/src/mixins/initials.js b/frontend.old/src/mixins/initials.js deleted file mode 100644 index 60448d1be521..000000000000 --- a/frontend.old/src/mixins/initials.js +++ /dev/null @@ -1,18 +0,0 @@ -export const initials = { - computed: { - initials() { - if (!this.user.fullName) return "00" - const allNames = this.user.fullName.trim().split(" "); - const initials = allNames.reduce( - (acc, curr, index) => { - if (index === 0 || index === allNames.length - 1) { - acc = `${acc}${curr.charAt(0).toUpperCase()}`; - } - return acc; - }, - [""] - ); - return initials; - }, - }, -}; diff --git a/frontend.old/src/mixins/user.js b/frontend.old/src/mixins/user.js deleted file mode 100644 index 2d500bea42d9..000000000000 --- a/frontend.old/src/mixins/user.js +++ /dev/null @@ -1,24 +0,0 @@ -import { store } from "@/store"; -export const user = { - computed: { - user() { - return store.getters.getUserData; - }, - loggedIn() { - return store.getters.getIsLoggedIn; - }, - initials() { - const allNames = this.user.fullName.trim().split(" "); - const initials = allNames.reduce( - (acc, curr, index) => { - if (index === 0 || index === allNames.length - 1) { - acc = `${acc}${curr.charAt(0).toUpperCase()}`; - } - return acc; - }, - [""] - ); - return initials; - }, - }, -}; diff --git a/frontend.old/src/mixins/utilMixins.js b/frontend.old/src/mixins/utilMixins.js deleted file mode 100644 index 2b9bf8504264..000000000000 --- a/frontend.old/src/mixins/utilMixins.js +++ /dev/null @@ -1,7 +0,0 @@ -export const utilMixins = { - commputed: { - isMobile() { - return this.$vuetify.breakpoint.name === "xs"; - }, - }, -}; diff --git a/frontend.old/src/mixins/validators.js b/frontend.old/src/mixins/validators.js deleted file mode 100644 index ba795b3effc8..000000000000 --- a/frontend.old/src/mixins/validators.js +++ /dev/null @@ -1,15 +0,0 @@ -const EMAIL_REGEX = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@(([[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - -export const validators = { - data() { - return { - emailRule: v => !v || EMAIL_REGEX.test(v) || this.$t("user.e-mail-must-be-valid"), - - existsRule: value => !!value || this.$t("general.field-required"), - - minRule: v => v.length >= 8 || this.$t("user.use-8-characters-or-more-for-your-password"), - - whiteSpace: v => !v || v.split(" ").length <= 1 || this.$t("recipe.no-white-space-allowed"), - }; - }, -}; diff --git a/frontend.old/src/pages/404Page.vue b/frontend.old/src/pages/404Page.vue deleted file mode 100644 index e98fab51ceee..000000000000 --- a/frontend.old/src/pages/404Page.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - - diff --git a/frontend.old/src/pages/Admin/About/index.vue b/frontend.old/src/pages/Admin/About/index.vue deleted file mode 100644 index fae2ee76d1db..000000000000 --- a/frontend.old/src/pages/Admin/About/index.vue +++ /dev/null @@ -1,130 +0,0 @@ - - - diff --git a/frontend.old/src/pages/Admin/Dashboard/BackupViewer.vue b/frontend.old/src/pages/Admin/Dashboard/BackupViewer.vue deleted file mode 100644 index e65d29622457..000000000000 --- a/frontend.old/src/pages/Admin/Dashboard/BackupViewer.vue +++ /dev/null @@ -1,162 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend.old/src/pages/Admin/Dashboard/EventViewer.vue b/frontend.old/src/pages/Admin/Dashboard/EventViewer.vue deleted file mode 100644 index 5dcd44ec397b..000000000000 --- a/frontend.old/src/pages/Admin/Dashboard/EventViewer.vue +++ /dev/null @@ -1,135 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend.old/src/pages/Admin/Dashboard/index.vue b/frontend.old/src/pages/Admin/Dashboard/index.vue deleted file mode 100644 index f217e700551c..000000000000 --- a/frontend.old/src/pages/Admin/Dashboard/index.vue +++ /dev/null @@ -1,126 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend.old/src/pages/Admin/ManageUsers/GroupCard.vue b/frontend.old/src/pages/Admin/ManageUsers/GroupCard.vue deleted file mode 100644 index 3ab26d3f2860..000000000000 --- a/frontend.old/src/pages/Admin/ManageUsers/GroupCard.vue +++ /dev/null @@ -1,122 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/ManageUsers/GroupDashboard.vue b/frontend.old/src/pages/Admin/ManageUsers/GroupDashboard.vue deleted file mode 100644 index 1b83f80100b1..000000000000 --- a/frontend.old/src/pages/Admin/ManageUsers/GroupDashboard.vue +++ /dev/null @@ -1,100 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/ManageUsers/TheSignUpTable.vue b/frontend.old/src/pages/Admin/ManageUsers/TheSignUpTable.vue deleted file mode 100644 index 95a442535eb4..000000000000 --- a/frontend.old/src/pages/Admin/ManageUsers/TheSignUpTable.vue +++ /dev/null @@ -1,230 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/ManageUsers/TheUserTable.vue b/frontend.old/src/pages/Admin/ManageUsers/TheUserTable.vue deleted file mode 100644 index 45f0350057ed..000000000000 --- a/frontend.old/src/pages/Admin/ManageUsers/TheUserTable.vue +++ /dev/null @@ -1,284 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/ManageUsers/index.vue b/frontend.old/src/pages/Admin/ManageUsers/index.vue deleted file mode 100644 index 15e1888877ef..000000000000 --- a/frontend.old/src/pages/Admin/ManageUsers/index.vue +++ /dev/null @@ -1,68 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/Migration/MigrationCard.vue b/frontend.old/src/pages/Admin/Migration/MigrationCard.vue deleted file mode 100644 index 54492f0486eb..000000000000 --- a/frontend.old/src/pages/Admin/Migration/MigrationCard.vue +++ /dev/null @@ -1,94 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/Migration/MigrationDialog.vue b/frontend.old/src/pages/Admin/Migration/MigrationDialog.vue deleted file mode 100644 index 5b5b3ab7bf54..000000000000 --- a/frontend.old/src/pages/Admin/Migration/MigrationDialog.vue +++ /dev/null @@ -1,106 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/Migration/index.vue b/frontend.old/src/pages/Admin/Migration/index.vue deleted file mode 100644 index c345bde2996f..000000000000 --- a/frontend.old/src/pages/Admin/Migration/index.vue +++ /dev/null @@ -1,82 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/Profile/APITokenCard.vue b/frontend.old/src/pages/Admin/Profile/APITokenCard.vue deleted file mode 100644 index 6977229a5fc7..000000000000 --- a/frontend.old/src/pages/Admin/Profile/APITokenCard.vue +++ /dev/null @@ -1,150 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/Profile/ProfileGroupCard.vue b/frontend.old/src/pages/Admin/Profile/ProfileGroupCard.vue deleted file mode 100644 index 27c4f5fb8187..000000000000 --- a/frontend.old/src/pages/Admin/Profile/ProfileGroupCard.vue +++ /dev/null @@ -1,211 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/Profile/ProfileThemeCard.vue b/frontend.old/src/pages/Admin/Profile/ProfileThemeCard.vue deleted file mode 100644 index 6a2559eead38..000000000000 --- a/frontend.old/src/pages/Admin/Profile/ProfileThemeCard.vue +++ /dev/null @@ -1,225 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend.old/src/pages/Admin/Profile/UserCard.vue b/frontend.old/src/pages/Admin/Profile/UserCard.vue deleted file mode 100644 index 11519ce55d35..000000000000 --- a/frontend.old/src/pages/Admin/Profile/UserCard.vue +++ /dev/null @@ -1,198 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/Profile/index.vue b/frontend.old/src/pages/Admin/Profile/index.vue deleted file mode 100644 index e6cfa1a38301..000000000000 --- a/frontend.old/src/pages/Admin/Profile/index.vue +++ /dev/null @@ -1,35 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/Settings/CreatePageDialog.vue b/frontend.old/src/pages/Admin/Settings/CreatePageDialog.vue deleted file mode 100644 index 355e5a060bce..000000000000 --- a/frontend.old/src/pages/Admin/Settings/CreatePageDialog.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/Settings/CustomPageCreator.vue b/frontend.old/src/pages/Admin/Settings/CustomPageCreator.vue deleted file mode 100644 index 2da1ce91f97e..000000000000 --- a/frontend.old/src/pages/Admin/Settings/CustomPageCreator.vue +++ /dev/null @@ -1,126 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/Settings/HomePageSettings.vue b/frontend.old/src/pages/Admin/Settings/HomePageSettings.vue deleted file mode 100644 index 14c0c8ec8966..000000000000 --- a/frontend.old/src/pages/Admin/Settings/HomePageSettings.vue +++ /dev/null @@ -1,220 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/Settings/index.vue b/frontend.old/src/pages/Admin/Settings/index.vue deleted file mode 100644 index c94954efcdbd..000000000000 --- a/frontend.old/src/pages/Admin/Settings/index.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/BulkAssign.vue b/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/BulkAssign.vue deleted file mode 100644 index 19c0aec4cfec..000000000000 --- a/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/BulkAssign.vue +++ /dev/null @@ -1,149 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/RemoveUnused.vue b/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/RemoveUnused.vue deleted file mode 100644 index c5df2b71a451..000000000000 --- a/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/RemoveUnused.vue +++ /dev/null @@ -1,89 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/index.vue b/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/index.vue deleted file mode 100644 index d3fe0715b182..000000000000 --- a/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/index.vue +++ /dev/null @@ -1,237 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/ToolBox/EventNotification.vue b/frontend.old/src/pages/Admin/ToolBox/EventNotification.vue deleted file mode 100644 index c022dbb3c1e5..000000000000 --- a/frontend.old/src/pages/Admin/ToolBox/EventNotification.vue +++ /dev/null @@ -1,213 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/ToolBox/RecipeOrganizer.vue b/frontend.old/src/pages/Admin/ToolBox/RecipeOrganizer.vue deleted file mode 100644 index 9e08cfb536be..000000000000 --- a/frontend.old/src/pages/Admin/ToolBox/RecipeOrganizer.vue +++ /dev/null @@ -1,91 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend.old/src/pages/Admin/ToolBox/index.vue b/frontend.old/src/pages/Admin/ToolBox/index.vue deleted file mode 100644 index c80cce98db44..000000000000 --- a/frontend.old/src/pages/Admin/ToolBox/index.vue +++ /dev/null @@ -1,62 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Admin/index.vue b/frontend.old/src/pages/Admin/index.vue deleted file mode 100644 index 55456e5b9030..000000000000 --- a/frontend.old/src/pages/Admin/index.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Debug.vue b/frontend.old/src/pages/Debug.vue deleted file mode 100644 index d4b8db4ee2a2..000000000000 --- a/frontend.old/src/pages/Debug.vue +++ /dev/null @@ -1,19 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/HomePage.vue b/frontend.old/src/pages/HomePage.vue deleted file mode 100644 index 74b8449e824d..000000000000 --- a/frontend.old/src/pages/HomePage.vue +++ /dev/null @@ -1,75 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/LoginPage.vue b/frontend.old/src/pages/LoginPage.vue deleted file mode 100644 index 996b40b5235c..000000000000 --- a/frontend.old/src/pages/LoginPage.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/MealPlan/Planner.vue b/frontend.old/src/pages/MealPlan/Planner.vue deleted file mode 100644 index 15c1dc59c0b7..000000000000 --- a/frontend.old/src/pages/MealPlan/Planner.vue +++ /dev/null @@ -1,150 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/MealPlan/ThisWeek.vue b/frontend.old/src/pages/MealPlan/ThisWeek.vue deleted file mode 100644 index 002d4da30654..000000000000 --- a/frontend.old/src/pages/MealPlan/ThisWeek.vue +++ /dev/null @@ -1,75 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Recipe/NewRecipe.vue b/frontend.old/src/pages/Recipe/NewRecipe.vue deleted file mode 100644 index 6e100865d900..000000000000 --- a/frontend.old/src/pages/Recipe/NewRecipe.vue +++ /dev/null @@ -1,126 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Recipe/ScraperDebugger.vue b/frontend.old/src/pages/Recipe/ScraperDebugger.vue deleted file mode 100644 index 8b91bfb85b0c..000000000000 --- a/frontend.old/src/pages/Recipe/ScraperDebugger.vue +++ /dev/null @@ -1,61 +0,0 @@ - - - diff --git a/frontend.old/src/pages/Recipe/ViewRecipe.vue b/frontend.old/src/pages/Recipe/ViewRecipe.vue deleted file mode 100644 index 3cc353258b9d..000000000000 --- a/frontend.old/src/pages/Recipe/ViewRecipe.vue +++ /dev/null @@ -1,271 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Recipes/AllRecipes.vue b/frontend.old/src/pages/Recipes/AllRecipes.vue deleted file mode 100644 index da1069b18d02..000000000000 --- a/frontend.old/src/pages/Recipes/AllRecipes.vue +++ /dev/null @@ -1,58 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Recipes/CategoryTagPage.vue b/frontend.old/src/pages/Recipes/CategoryTagPage.vue deleted file mode 100644 index eff8a13ddfd6..000000000000 --- a/frontend.old/src/pages/Recipes/CategoryTagPage.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/Recipes/CustomPage.vue b/frontend.old/src/pages/Recipes/CustomPage.vue deleted file mode 100644 index c9b91b70e5ab..000000000000 --- a/frontend.old/src/pages/Recipes/CustomPage.vue +++ /dev/null @@ -1,75 +0,0 @@ - - - diff --git a/frontend.old/src/pages/Recipes/Favorites.vue b/frontend.old/src/pages/Recipes/Favorites.vue deleted file mode 100644 index 950210eff97f..000000000000 --- a/frontend.old/src/pages/Recipes/Favorites.vue +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - diff --git a/frontend.old/src/pages/SearchPage/FilterSelector.vue b/frontend.old/src/pages/SearchPage/FilterSelector.vue deleted file mode 100644 index 43ed22f47b33..000000000000 --- a/frontend.old/src/pages/SearchPage/FilterSelector.vue +++ /dev/null @@ -1,52 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/SearchPage/index.vue b/frontend.old/src/pages/SearchPage/index.vue deleted file mode 100644 index 8d8ffdaa6e4b..000000000000 --- a/frontend.old/src/pages/SearchPage/index.vue +++ /dev/null @@ -1,168 +0,0 @@ - - - - - diff --git a/frontend.old/src/pages/ShoppingList/index.vue b/frontend.old/src/pages/ShoppingList/index.vue deleted file mode 100644 index 051c9eb54c53..000000000000 --- a/frontend.old/src/pages/ShoppingList/index.vue +++ /dev/null @@ -1,281 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend.old/src/pages/SignUpPage.vue b/frontend.old/src/pages/SignUpPage.vue deleted file mode 100644 index d1e79154f9df..000000000000 --- a/frontend.old/src/pages/SignUpPage.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - - - diff --git a/frontend.old/src/plugins/vuetify.js b/frontend.old/src/plugins/vuetify.js deleted file mode 100644 index 6f54f8ad73ee..000000000000 --- a/frontend.old/src/plugins/vuetify.js +++ /dev/null @@ -1,63 +0,0 @@ -import Vue from "vue"; -import Vuetify from "vuetify/lib"; - -Vue.use(Vuetify); - -import de from "vuetify/es5/locale/de"; -import en from "vuetify/es5/locale/en"; -import es from "vuetify/es5/locale/es"; -import fr from "vuetify/es5/locale/fr"; -import it from "vuetify/es5/locale/it"; -import nl from "vuetify/es5/locale/nl"; -import pl from "vuetify/es5/locale/pl"; -import sv from "vuetify/es5/locale/sv"; -import zhHans from "vuetify/es5/locale/zh-Hans"; - -const vuetify = new Vuetify({ - theme: { - dark: false, - options: { customProperties: true }, - - themes: { - light: { - primary: "#E58325", - accent: "#00457A", - secondary: "#973542", - success: "#43A047", - info: "#FFFD99", - warning: "#FF4081", - error: "#EF5350", - }, - dark: { - primary: "#4527A0", - accent: "#FF4081", - secondary: "#26C6DA", - success: "#43A047", - info: "#2196F3", - warning: "#FB8C00", - error: "#FF5252", - }, - }, - }, - lang: { - locales: { - "de-DE": de, - "en-US": en, - "en-GB": en, - "es-ES": es, - "fr-FR": fr, - "it-IT": it, - "nl-NL": nl, - "pl-PL": pl, - "sv-SE": sv, - "zh-CN": zhHans, - }, - current: "en-US", - }, - icons: { - iconfont: "mdiSvg", - }, -}); - -export default vuetify; -export { vuetify }; diff --git a/frontend.old/src/registerServiceWorker.js b/frontend.old/src/registerServiceWorker.js deleted file mode 100644 index 6cb38651365d..000000000000 --- a/frontend.old/src/registerServiceWorker.js +++ /dev/null @@ -1,39 +0,0 @@ -/* eslint-disable no-console */ - -import { register } from "register-service-worker"; - -if (process.env.NODE_ENV === "production") { - register(`${process.env.BASE_URL}service-worker.js`, { - ready() { - console.log("Service worker is active."); - }, - registered(registration) { - console.log("Service worker has been registered."); - - // Routinely check for app updates by testing for a new service worker. - setInterval(() => { - registration.update(); - }, 1000 * 60 * 60); // hourly checks - }, - cached() { - console.log("Content has been cached for offline use."); - }, - updatefound() { - console.log("New content is downloading."); - }, - updated(registration) { - console.log("New content is available; please refresh."); - - // Add a custom event and dispatch it. - // Used to display of a 'refresh' banner following a service worker update. - // Set the event payload to the service worker registration object. - document.dispatchEvent(new CustomEvent("swUpdated", { detail: registration })); - }, - offline() { - console.log("No internet connection found. App is running in offline mode."); - }, - error(error) { - console.error("Error during service worker registration:", error); - }, - }); -} diff --git a/frontend.old/src/routes/admin.js b/frontend.old/src/routes/admin.js deleted file mode 100644 index 4f580245d0ed..000000000000 --- a/frontend.old/src/routes/admin.js +++ /dev/null @@ -1,74 +0,0 @@ -const Admin = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin"); -const Migration = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin/Migration"); -const Profile = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin/Profile"); -const ManageUsers = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin/ManageUsers"); -const Settings = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin/Settings"); -const About = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin/About"); -const ToolBox = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin/ToolBox"); -const Dashboard = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin/Dashboard"); -import { store } from "../store"; - -export const adminRoutes = { - path: "/admin", - component: Admin, - beforeEnter: (to, _from, next) => { - if (store.getters.getIsLoggedIn) { - next(); - } else next({ path: "/login", query: { redirect: to.fullPath } }); - }, - children: [ - { - path: "", - component: Profile, - }, - { - path: "profile", - component: Profile, - meta: { - title: "settings.profile", - }, - }, - { - path: "migrations", - component: Migration, - meta: { - title: "settings.migrations", - }, - }, - { - path: "manage-users", - component: ManageUsers, - meta: { - title: "user.manage-users", - }, - }, - { - path: "settings", - component: Settings, - meta: { - title: "settings.site-settings", - }, - }, - { - path: "toolbox", - component: ToolBox, - meta: { - title: "settings.toolbox.toolbox", - }, - }, - { - path: "about", - component: About, - meta: { - title: "about.about", - }, - }, - { - path: "dashboard", - component: Dashboard, - meta: { - title: "general.dashboard", - }, - }, - ], -}; diff --git a/frontend.old/src/routes/auth.js b/frontend.old/src/routes/auth.js deleted file mode 100644 index 742472dd31a5..000000000000 --- a/frontend.old/src/routes/auth.js +++ /dev/null @@ -1,18 +0,0 @@ -const LoginPage = () => import("@/pages/LoginPage"); -const SignUpPage = () => import("@/pages/SignUpPage"); -import { store } from "../store"; - -export const authRoutes = [ - { - path: "/logout", - beforeEnter: (_to, _from, next) => { - store.commit("setToken", ""); - store.commit("setIsLoggedIn", false); - next("/"); - }, - }, - { path: "/login", component: LoginPage }, - - { path: "/sign-up", redirect: "/" }, - { path: "/sign-up/:token", component: SignUpPage }, -]; diff --git a/frontend.old/src/routes/general.js b/frontend.old/src/routes/general.js deleted file mode 100644 index f7802fa94718..000000000000 --- a/frontend.old/src/routes/general.js +++ /dev/null @@ -1,16 +0,0 @@ -const SearchPage = () => import("@/pages/SearchPage"); -const ShoppingList = () => import("@/pages/ShoppingList"); -import HomePage from "@/pages/HomePage"; - -export const generalRoutes = [ - { path: "/", name: "home", component: HomePage }, - { path: "/mealie", component: HomePage }, - { path: "/shopping-list", component: ShoppingList }, - { - path: "/search", - component: SearchPage, - meta: { - title: "search.search", - }, - }, -]; diff --git a/frontend.old/src/routes/index.js b/frontend.old/src/routes/index.js deleted file mode 100644 index 9ac473e420b3..000000000000 --- a/frontend.old/src/routes/index.js +++ /dev/null @@ -1,51 +0,0 @@ -import Page404 from "@/pages/404Page"; -import { adminRoutes } from "./admin"; -import { authRoutes } from "./auth"; -import { recipeRoutes } from "./recipes"; -import { mealRoutes } from "./meal"; -import { generalRoutes } from "./general"; -import { store } from "@/store"; -import VueRouter from "vue-router"; -import { loadLanguageAsync } from "@/i18n"; -import Vue from "vue"; -import i18n from "@/i18n.js"; - -export const routes = [ - ...generalRoutes, - adminRoutes, - ...authRoutes, - ...mealRoutes, - ...recipeRoutes, - - { path: "/page-not-found", component: Page404 }, - { path: "*", component: Page404 }, -]; - -const router = new VueRouter({ - base: process.env.BASE_URL, - routes, - mode: process.env.NODE_ENV === "production" ? "history" : "hash", - scrollBehavior() { - return { x: 0, y: 0 }; - }, -}); - -const DEFAULT_TITLE = "Mealie"; -const TITLE_SEPARATOR = "|"; -const TITLE_SUFFIX = " " + TITLE_SEPARATOR + " " + DEFAULT_TITLE; -router.afterEach(to => { - Vue.nextTick(async () => { - if (typeof to.meta.title === "function") { - const title = await to.meta.title(to); - document.title = title + TITLE_SUFFIX; - } else { - document.title = i18n.t(to.meta.title) ? i18n.t(to.meta.title) + TITLE_SUFFIX : DEFAULT_TITLE; - } - }); -}); - -router.beforeEach((__, _, next) => { - loadLanguageAsync(store.getters.getActiveLang).then(() => next()); -}); - -export { router }; diff --git a/frontend.old/src/routes/meal.js b/frontend.old/src/routes/meal.js deleted file mode 100644 index 4aca00dd883e..000000000000 --- a/frontend.old/src/routes/meal.js +++ /dev/null @@ -1,51 +0,0 @@ -const Planner = () => import("@/pages/MealPlan/Planner"); -const ThisWeek = () => import("@/pages/MealPlan/ThisWeek"); -import { api } from "@/api"; -import { utils } from "@/utils"; -import i18n from "@/i18n.js"; - -export const mealRoutes = [ - { - path: "/meal-plan", - component: ThisWeek, - meta: { - title: "meal-plan.dinner-this-week", - }, - }, - { - path: "/meal-plan/planner", - component: Planner, - meta: { - title: "meal-plan.meal-planner", - }, - }, - { - path: "/meal-plan/this-week", - component: ThisWeek, - meta: { - title: "meal-plan.dinner-this-week", - }, - }, - { - path: "/meal-plan/today", - beforeEnter: async (_to, _from, next) => { - await todaysMealRoute().then(redirect => { - if (redirect) { - next(redirect); - } else { - utils.notify.error(i18n.t("meal-plan.no-meal-planned-for-today")); - next(_from); - } - }); - }, - }, -]; - -async function todaysMealRoute() { - const response = await api.mealPlans.today(); - if (response.status == 200 && response.data) { - return "/recipe/" + response.data.slug; - } else { - return null; - } -} diff --git a/frontend.old/src/routes/recipes.js b/frontend.old/src/routes/recipes.js deleted file mode 100644 index e2e3967aac2a..000000000000 --- a/frontend.old/src/routes/recipes.js +++ /dev/null @@ -1,37 +0,0 @@ -const ViewRecipe = () => import(/* webpackChunkName: "recipe-page" */ "@/pages/Recipe/ViewRecipe"); -const NewRecipe = () => import(/* webpackChunkName: "recipe-page" */ "@/pages/Recipe/NewRecipe"); -const ScraperDebugger = () => import("@/pages/Recipe/ScraperDebugger"); -const CustomPage = () => import("@/pages/Recipes/CustomPage"); -const AllRecipes = () => import("@/pages/Recipes/AllRecipes"); -const CategoryTagPage = () => import("@/pages/Recipes/CategoryTagPage"); -const Favorites = () => import("@/pages/Recipes/Favorites"); -import { api } from "@/api"; - -export const recipeRoutes = [ - // Recipes - { path: "/recipes/all", component: AllRecipes }, - { path: "/recipes/debugger", component: ScraperDebugger }, - { path: "/user/:id/favorites", component: Favorites }, - { path: "/recipes/tag/:tag", component: CategoryTagPage }, - { path: "/recipes/tag", component: CategoryTagPage }, - { path: "/recipes/category", component: CategoryTagPage }, - { path: "/recipes/category/:category", component: CategoryTagPage }, - // Misc - { path: "/new/", component: NewRecipe }, - { path: "/pages/:customPage", component: CustomPage }, - - // Recipe Page - { - path: "/recipe/:recipe", - component: ViewRecipe, - meta: { - title: async route => { - const [response, error] = await api.recipes.requestDetails(route.params.recipe); - if (error) console.log({ error }); - const recipe = response.data; - if (recipe && recipe.name) return recipe.name; - else return null; - }, - }, - }, -]; diff --git a/frontend.old/src/store/index.js b/frontend.old/src/store/index.js deleted file mode 100644 index 4ce1d97653ae..000000000000 --- a/frontend.old/src/store/index.js +++ /dev/null @@ -1,80 +0,0 @@ -import Vue from "vue"; -import Vuex from "vuex"; -import { api } from "@/api"; -import createPersistedState from "vuex-persistedstate"; -import userSettings from "./modules/userSettings"; -import language from "./modules/language"; -import siteSettings from "./modules/siteSettings"; -import recipes from "./modules/recipes"; -import groups from "./modules/groups"; -import snackbar from "./modules/snackbar"; - -Vue.use(Vuex); - -const store = new Vuex.Store({ - plugins: [ - createPersistedState({ - paths: ["userSettings", "siteSettings"], - }), - ], - modules: { - userSettings, - language, - siteSettings, - groups, - recipes, - snackbar, - }, - state: { - // All Recipe Data Store - recentRecipes: [], - allRecipes: [], - mealPlanCategories: [], - allCategories: [], - allTags: [], - appInfo: { - version: "", - demoStatus: false, - }, - }, - - mutations: { - setMealPlanCategories(state, payload) { - state.mealPlanCategories = payload; - }, - setAllCategories(state, payload) { - state.allCategories = payload; - }, - setAllTags(state, payload) { - state.allTags = payload; - }, - setAppInfo(state, payload) { - state.appInfo = payload; - }, - }, - - actions: { - async requestCategories({ commit }) { - const categories = await api.categories.getAll(); - commit("setAllCategories", categories); - }, - async requestTags({ commit }) { - const tags = await api.tags.getAll(); - commit("setAllTags", tags); - }, - async requestAppInfo({ commit }) { - const response = await api.meta.getAppInfo(); - commit("setAppInfo", response); - }, - }, - - getters: { - getMealPlanCategories: state => state.mealPlanCategories, - getAllCategories: state => state.allCategories.sort((a, b) => (a.slug > b.slug ? 1 : -1)), - getAllTags: state => state.allTags.sort((a, b) => (a.slug > b.slug ? 1 : -1)), - getAppInfo: state => state.appInfo, - }, -}); - -export default store; -export { store }; diff --git a/frontend.old/src/store/modules/groups.js b/frontend.old/src/store/modules/groups.js deleted file mode 100644 index 03e66fc80dc9..000000000000 --- a/frontend.old/src/store/modules/groups.js +++ /dev/null @@ -1,39 +0,0 @@ -import { api } from "@/api"; - -const state = { - groups: [], - currentGroup: {}, -}; - -const mutations = { - setGroups(state, payload) { - state.groups = payload; - }, - setCurrentGroup(state, payload) { - state.currentGroup = payload; - }, -}; - -const actions = { - async requestAllGroups({ commit }) { - const groups = await api.groups.allGroups(); - commit("setGroups", groups); - }, - async requestCurrentGroup({ commit }) { - const group = await api.groups.current(); - commit("setCurrentGroup", group); - }, -}; - -const getters = { - getGroups: state => state.groups, - getGroupNames: state => Array.from(state.groups, x => x.name), - getCurrentGroup: state => state.currentGroup, -}; - -export default { - state, - mutations, - actions, - getters, -}; diff --git a/frontend.old/src/store/modules/homePage.js b/frontend.old/src/store/modules/homePage.js deleted file mode 100644 index c7b2112b49a4..000000000000 --- a/frontend.old/src/store/modules/homePage.js +++ /dev/null @@ -1,44 +0,0 @@ -import { api } from "@/api"; - -const state = { - showRecent: true, - showLimit: 9, - categories: [], - homeCategories: [], -}; - -const mutations = { - setShowRecent(state, payload) { - state.showRecent = payload; - }, - setShowLimit(state, payload) { - state.showLimit = payload; - }, - setCategories(state, payload) { - state.categories = payload.sort((a, b) => (a.name > b.name ? 1 : -1)); - }, - setHomeCategories(state, payload) { - state.homeCategories = payload; - }, -}; - -const actions = { - async requestHomePageSettings() { - let categories = await api.categories.get_all(); - this.commit("setCategories", categories); - }, -}; - -const getters = { - getShowRecent: state => state.showRecent, - getShowLimit: state => state.showLimit, - getCategories: state => state.categories, - getHomeCategories: state => state.homeCategories, -}; - -export default { - state, - mutations, - actions, - getters, -}; diff --git a/frontend.old/src/store/modules/language.js b/frontend.old/src/store/modules/language.js deleted file mode 100644 index c9d4ea6c4815..000000000000 --- a/frontend.old/src/store/modules/language.js +++ /dev/null @@ -1,54 +0,0 @@ -// This is the data store for the options for language selection. Property is reference only, you cannot set this property. -const state = { - allLangs: [ - { - name: "American English", - value: "en-US", - }, - { - name: "British English", - value: "en-GB", - }, - { - name: "Deutsch (German)", - value: "de-DE", - }, - { - name: "Español (Spanish)", - value: "es-ES", - }, - { - name: "Français (French)", - value: "fr-FR", - }, - { - name: "Italiano (Italian)", - value: "it-IT", - }, - { - name: "Nederlands (Dutch)", - value: "nl-NL", - }, - { - name: "Polski (Polish)", - value: "pl-PL", - }, - { - name: "Svenska (Swedish)", - value: "sv-SE", - }, - { - name: "简体中文 (Chinese simplified)", - value: "zh-CN", - }, - ], -}; - -const getters = { - getAllLangs: state => state.allLangs, -}; - -export default { - state, - getters, -}; diff --git a/frontend.old/src/store/modules/recipes.js b/frontend.old/src/store/modules/recipes.js deleted file mode 100644 index f2270eb941f2..000000000000 --- a/frontend.old/src/store/modules/recipes.js +++ /dev/null @@ -1,76 +0,0 @@ -import { api } from "@/api"; -import Vue from "vue"; -import { recipe } from "@/utils/recipe"; - -const state = { - recentRecipes: [], - allRecipes: [], -}; - -const mutations = { - setRecentRecipes(state, payload) { - state.recentRecipes = payload; - }, - patchRecentRecipes(state, payload) { - if (state.recentRecipes[payload.id]) { - state.recentRecipes[payload.id] = payload; - } - }, - dropRecentRecipes(state, payload) { - if (state.recentRecipes[payload.id]) { - Vue.delete(state.recentRecipes, payload.id); - } - }, - setAllRecipes(state, payload) { - state.allRecipes = payload; - }, - patchAllRecipes(state, payload) { - state.allRecipes[payload.id] = payload; - }, - dropAllRecipes(state, payload) { - if (state.allRecipes[payload.id]) { - Vue.delete(state.allRecipes, payload.id); - } - }, -}; - -const actions = { - async requestRecentRecipes() { - const payload = await api.recipes.allSummary(0, 30); - const hash = Object.fromEntries(payload.map(e => [e.id, e])); - this.commit("setRecentRecipes", hash); - }, - async requestAllRecipes({ getters }) { - const all = getters.getAllRecipes; - const payload = await api.recipes.allSummary(all.length, 9999); - const hash = Object.fromEntries([...all, ...payload].map(e => [e.id, e])); - - this.commit("setAllRecipes", hash); - }, - patchRecipe({ commit }, payload) { - commit("patchAllRecipes", payload); - commit("patchRecentRecipes", payload); - }, - dropRecipe({ commit }, payload) { - commit("dropAllRecipes", payload); - commit("dropRecentRecipes", payload); - }, -}; - -const getters = { - getAllRecipes: state => Object.values(state.allRecipes), - getAllRecipesHash: state => state.allRecipes, - getRecentRecipes: state => { - let list = Object.values(state.recentRecipes); - recipe.sortByUpdated(list); - return list; - }, - getRecentRecipesHash: state => state.recentRecipes, -}; - -export default { - state, - mutations, - actions, - getters, -}; diff --git a/frontend.old/src/store/modules/siteSettings.js b/frontend.old/src/store/modules/siteSettings.js deleted file mode 100644 index 3095830d0ede..000000000000 --- a/frontend.old/src/store/modules/siteSettings.js +++ /dev/null @@ -1,47 +0,0 @@ -import { api } from "@/api"; -import { loadLanguageAsync } from "@/i18n" - -const state = { - siteSettings: { - language: "en-US", - firstDayOfWeek: 0, - showRecent: true, - cardsPerSection: 9, - categories: [], - }, - customPages: [], -}; - -const mutations = { - setSettings(state, payload) { - state.siteSettings = payload; - loadLanguageAsync(payload.language); - }, - setCustomPages(state, payload) { - state.customPages = payload; - }, -}; - -const actions = { - async requestSiteSettings({ commit }) { - let settings = await api.siteSettings.get(); - commit("setSettings", settings); - }, - async requestCustomPages({ commit }) { - const customPages = await api.siteSettings.getPages(); - commit("setCustomPages", customPages); - }, -}; - -const getters = { - getActiveLang: state => state.siteSettings.language, - getSiteSettings: state => state.siteSettings, - getCustomPages: state => state.customPages, -}; - -export default { - state, - mutations, - actions, - getters, -}; diff --git a/frontend.old/src/store/modules/snackbar.js b/frontend.old/src/store/modules/snackbar.js deleted file mode 100644 index 21ae1a3982af..000000000000 --- a/frontend.old/src/store/modules/snackbar.js +++ /dev/null @@ -1,23 +0,0 @@ -const state = { - snackbar: { - open: false, - text: "Hello From The Store", - color: "info", - }, -}; - -const mutations = { - setSnackbar(state, payload) { - state.snackbar = payload; - }, -}; - -const getters = { - getSnackbar: state => state.snackbar, -}; - -export default { - state, - mutations, - getters, -}; diff --git a/frontend.old/src/store/modules/userSettings.js b/frontend.old/src/store/modules/userSettings.js deleted file mode 100644 index 39337cf93433..000000000000 --- a/frontend.old/src/store/modules/userSettings.js +++ /dev/null @@ -1,121 +0,0 @@ -import { api } from "@/api"; -import Vuetify from "@/plugins/vuetify"; -import axios from "axios"; - -function inDarkMode(payload) { - let isDark; - - if (payload === "system") { - //Get System Preference from browser - const darkMediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); - isDark = darkMediaQuery.matches; - } else if (payload === "dark") isDark = true; - else if (payload === "light") isDark = false; - - return isDark; -} - -const state = { - activeTheme: {}, - darkMode: "light", // light, dark, system - isDark: false, - isLoggedIn: false, - token: "", - userData: {}, -}; - -const mutations = { - setTheme(state, payload) { - Vuetify.framework.theme.themes.dark = payload.colors; - Vuetify.framework.theme.themes.light = payload.colors; - state.activeTheme = payload; - }, - setDarkMode(state, payload) { - let isDark = inDarkMode(payload); - - if (isDark !== null) { - Vuetify.framework.theme.dark = isDark; - state.isDark = isDark; - state.darkMode = payload; - } - }, - setIsLoggedIn(state, payload) { - state.isLoggedIn = payload; - }, - setToken(state, payload) { - state.isLoggedIn = true; - axios.defaults.headers.common["Authorization"] = `Bearer ${payload}`; - state.token = payload; - }, - - setUserData(state, payload) { - state.userData = payload; - }, -}; - -const actions = { - async requestUserData({ getters, commit }) { - if (getters.getIsLoggedIn) { - const [response, err] = await api.users.self(); - - if (err) { - return; // TODO: Log or Notifty User of Error - } - - commit("setUserData", response.data); - } - }, - - async resetTheme({ commit }) { - const defaultTheme = await api.themes.requestByName(1); - if (defaultTheme.colors) { - Vuetify.framework.theme.themes.dark = defaultTheme.colors; - Vuetify.framework.theme.themes.light = defaultTheme.colors; - commit("setTheme", defaultTheme); - } - }, - - async refreshToken({ commit, getters }) { - if (!getters.getIsLoggedIn) { - commit("setIsLoggedIn", false); // This has to be here... for some reasons? ¯\_(ツ)_/¯ - console.log("Not Logged In"); - return; - } - - const [response, err] = await api.users.refresh(); - - if (err) { - console.log("Failed Token Refresh, Logging Out..."); - commit("setIsLoggedIn", false); - } - - commit("setToken", response.data.access_token); - }, - - async initTheme({ dispatch, getters }) { - //If theme is empty resetTheme - if (Object.keys(getters.getActiveTheme).length === 0) { - await dispatch("resetTheme"); - } else { - Vuetify.framework.theme.dark = inDarkMode(getters.getDarkMode); - Vuetify.framework.theme.themes.dark = getters.getActiveTheme.colors; - Vuetify.framework.theme.themes.light = getters.getActiveTheme.colors; - } - }, -}; - -const getters = { - getActiveTheme: state => state.activeTheme, - getDarkMode: state => state.darkMode, - getIsDark: state => state.isDark, - getIsLoggedIn: state => state.isLoggedIn, - getToken: state => state.token, - getUserData: state => state.userData, -}; - -export default { - state, - mutations, - actions, - getters, -}; diff --git a/frontend.old/src/sw.js b/frontend.old/src/sw.js deleted file mode 100644 index 4b1037930aa1..000000000000 --- a/frontend.old/src/sw.js +++ /dev/null @@ -1,75 +0,0 @@ -/* eslint-disable no-undef, no-underscore-dangle, no-restricted-globals */ - -self.addEventListener("install", event => { - event.waitUntil(preLoad()); -}); - -var preLoad = async () => { - console.log("Installing web app"); - const cache = await caches.open("offline"); - console.log("caching index and important routes"); - return await cache.addAll(["/", "/recipes/all"]); -}; - -self.addEventListener("fetch", event => { - event.respondWith( - checkResponse(event.request).catch(() => { - return returnFromCache(event.request); - }) - ); - event.waitUntil(addToCache(event.request)); -}); - -var checkResponse = request => { - return new Promise(function(fulfill, reject) { - fetch(request).then(function(response) { - if (response.status !== 404) { - fulfill(response); - } else { - reject(); - } - }, reject); - }); -}; - -var addToCache = async request => { - const cache = await caches.open("offline"); - const response = await fetch(request); - console.log(response.url + " was cached"); - return await cache.put(request, response); -}; - -var returnFromCache = async request => { - const cache = await caches.open("offline"); - const matching = await cache.match(request); - if (!matching || matching.status == 404) { - return cache.match("offline.html"); - } else { - return matching; - } -}; - -// This is the code piece that GenerateSW mode can't provide for us. -// This code listens for the user's confirmation to update the app. -self.addEventListener("message", e => { - if (!e.data) { - return; - } - - switch (e.data) { - case "skipWaiting": - self.skipWaiting(); - break; - default: - // NOOP - break; - } -}); - -workbox.core.clientsClaim(); // Vue CLI 4 and Workbox v4, else -// workbox.clientsClaim(); // Vue CLI 3 and Workbox v3. - -// The precaching code provided by Workbox. -self.__precacheManifest = [].concat(self.__precacheManifest || []); -// workbox.precaching.suppressWarnings(); // Only used with Vue CLI 3 and Workbox v3. -workbox.precaching.precacheAndRoute(self.__precacheManifest, {}); diff --git a/frontend.old/vue.config.js b/frontend.old/vue.config.js deleted file mode 100644 index 442baa0130e5..000000000000 --- a/frontend.old/vue.config.js +++ /dev/null @@ -1,50 +0,0 @@ -const path = require("path"); -const manifestJSON = require("./public/manifest.json"); -const PreloadWebpackPlugin = require("preload-webpack-plugin"); - -module.exports = { - transpileDependencies: ["vuetify"], - publicPath: process.env.NODE_ENV === "production" ? "/" : "/", - outputDir: process.env.NODE_ENV === "production" ? "./dist" : "../mealie/web", - devServer: { - proxy: { - "/api": { - target: process.env.VUE_APP_API_BASE_URL, - secure: false, - }, - }, - }, - pluginOptions: { - i18n: { - locale: "en", - fallbackLocale: "en", - localeDir: "locales", - enableInSFC: true, - }, - webpackBundleAnalyzer: { - openAnalyzer: process.env.PREVIEW_BUNDLE, - }, - }, - configureWebpack: { - resolve: { - alias: { - "@": path.resolve("src"), - }, - plugins: [new PreloadWebpackPlugin({})], - }, - }, - pwa: { - name: manifestJSON.short_name, - themeColor: manifestJSON.theme_color, - msTileColor: manifestJSON.background_color, - appleMobileWebAppCapable: "yes", - appleMobileWebAppStatusBarStyle: "black", - manifestCrossorigin: "use-credentials", - - workboxPluginMode: "InjectManifest", - workboxOptions: { - swSrc: "./src/sw.js", - swDest: "service-worker.js", - }, - }, -}; diff --git a/frontend/components/Domain/Recipe/RecipeDialogBulkAdd.vue b/frontend/components/Domain/Recipe/RecipeDialogBulkAdd.vue index bc893174ed5f..ad5385c5aff8 100644 --- a/frontend/components/Domain/Recipe/RecipeDialogBulkAdd.vue +++ b/frontend/components/Domain/Recipe/RecipeDialogBulkAdd.vue @@ -40,8 +40,8 @@ diff --git a/frontend/pages/user/profile/edit.vue b/frontend/pages/user/profile/edit.vue index cabfc34875b0..810f925fd8e0 100644 --- a/frontend/pages/user/profile/edit.vue +++ b/frontend/pages/user/profile/edit.vue @@ -73,7 +73,7 @@ - + @@ -164,28 +164,6 @@ export default defineComponent({ title: this.$t("settings.profile") as string, }; }, - - methods: { - async changePassword() { - // @ts-ignore - this.paswordLoading = true; - const data = { - currentPassword: this.password.current, - newPassword: this.password.newOne, - }; - - // @ts-ignore - if (this.$refs.passChange.validate()) { - // @ts-ignore - if (await api.users.changePassword(this.user.id, data)) { - this.$emit("refresh"); - } - } - - // @ts-ignore - this.paswordLoading = false; - }, - }, }); diff --git a/makefile b/makefile index 8763736d95b5..fe0ecc5a0ed6 100644 --- a/makefile +++ b/makefile @@ -69,14 +69,15 @@ coverage: ## ☂️ Check code coverage quickly with the default Python poetry run coverage html $(BROWSER) htmlcov/index.html +.PHONY: setup setup: ## 🏗 Setup Development Instance - cp template.env .env -n poetry install && \ cd frontend && \ - cp template.env .env -n yarn install && \ cd .. + echo "Be sure to copy the template.env files" + backend: ## 🎬 Start Mealie Backend Development Server poetry run python mealie/db/init_db.py && \ poetry run python mealie/services/image/minify.py && \ diff --git a/mealie/db/data_access_layer/access_model_factory.py b/mealie/db/data_access_layer/access_model_factory.py index 5dabf64b53ff..04fc5e79f765 100644 --- a/mealie/db/data_access_layer/access_model_factory.py +++ b/mealie/db/data_access_layer/access_model_factory.py @@ -14,11 +14,9 @@ from mealie.db.models.recipe.ingredient import IngredientFoodModel, IngredientUn from mealie.db.models.recipe.recipe import RecipeModel from mealie.db.models.recipe.tag import Tag from mealie.db.models.server.task import ServerTaskModel -from mealie.db.models.settings import SiteSettings from mealie.db.models.sign_up import SignUp from mealie.db.models.users import LongLiveToken, User from mealie.db.models.users.password_reset import PasswordResetModel -from mealie.schema.admin import SiteSettings as SiteSettingsSchema from mealie.schema.cookbook.cookbook import ReadCookBook from mealie.schema.events import Event as EventSchema from mealie.schema.events import EventNotificationIn @@ -94,10 +92,6 @@ class Database: # ================================================================ # Site Items - @cached_property - def settings(self) -> AccessModel[SiteSettingsSchema, SiteSettings]: - return AccessModel(self.session, pk_id, SiteSettings, SiteSettingsSchema) - @cached_property def sign_up(self) -> AccessModel[SignUpOut, SignUp]: return AccessModel(self.session, pk_id, SignUp, SignUpOut) diff --git a/mealie/db/init_db.py b/mealie/db/init_db.py index 5f960eb12dff..c63c7a946a53 100644 --- a/mealie/db/init_db.py +++ b/mealie/db/init_db.py @@ -6,7 +6,6 @@ from mealie.db.data_initialization.init_users import default_user_init from mealie.db.database import get_database from mealie.db.db_setup import create_session, engine from mealie.db.models._model_base import SqlAlchemyBase -from mealie.schema.admin import SiteSettings from mealie.schema.user.user import GroupBase from mealie.services.events import create_general_event from mealie.services.group_services.group_utils import create_new_group @@ -24,16 +23,10 @@ def create_all_models(): def init_db(db: Database) -> None: default_group_init(db) - default_settings_init(db) default_user_init(db) default_recipe_unit_init(db) -def default_settings_init(db: Database): - document = db.settings.create(SiteSettings().dict()) - logger.info(f"Created Site Settings: \n {document}") - - def default_group_init(db: Database): logger.info("Generating Default Group") create_new_group(db, GroupBase(name=settings.DEFAULT_GROUP)) diff --git a/mealie/db/models/_all_models.py b/mealie/db/models/_all_models.py index 7cb43654f344..02c4986b6a51 100644 --- a/mealie/db/models/_all_models.py +++ b/mealie/db/models/_all_models.py @@ -2,6 +2,5 @@ from .event import * from .group import * from .recipe.recipe import * from .server import * -from .settings import * from .sign_up import * from .users import * diff --git a/mealie/db/models/_model_base.py b/mealie/db/models/_model_base.py index 907eb90ca97d..fc8d93bfa39a 100644 --- a/mealie/db/models/_model_base.py +++ b/mealie/db/models/_model_base.py @@ -19,9 +19,6 @@ class BaseMixins: `cls.get_ref` method which will return the object from the database or none. Useful for many-to-many relationships. """ - class Config: - get_attr = "id" - def update(self, *args, **kwarg): self.__init__(*args, **kwarg) diff --git a/mealie/db/models/_model_utils.py b/mealie/db/models/_model_utils.py deleted file mode 100644 index c0f15881afb6..000000000000 --- a/mealie/db/models/_model_utils.py +++ /dev/null @@ -1,119 +0,0 @@ -from functools import wraps -from typing import Union - -from sqlalchemy.orm import MANYTOMANY, MANYTOONE, ONETOMANY - - -def handle_one_to_many_list(get_attr, relation_cls, all_elements: list[dict]): - elems_to_create = [] - updated_elems = [] - - for elem in all_elements: - elem_id = elem.get(get_attr, None) - - existing_elem = relation_cls.get_ref(match_value=elem_id) - - if existing_elem is None: - - elems_to_create.append(elem) - - else: - for key, value in elem.items(): - setattr(existing_elem, key, value) - - updated_elems.append(existing_elem) - - new_elems = [] - for elem in elems_to_create: - new_elems = [relation_cls(**elem) for elem in all_elements] - - return new_elems - - -def auto_init(exclude: Union[set, list] = None): # sourcery no-metrics - """Wraps the `__init__` method of a class to automatically set the common - attributes. - - Args: - exclude (Union[set, list], optional): [description]. Defaults to None. - """ - - exclude = exclude or set() - exclude.add("id") - - def decorator(init): - @wraps(init) - def wrapper(self, *args, **kwargs): # sourcery no-metrics - """ - Custom initializer that allows nested children initialization. - Only keys that are present as instance's class attributes are allowed. - These could be, for example, any mapped columns or relationships. - - Code inspired from GitHub. - Ref: https://github.com/tiangolo/fastapi/issues/2194 - """ - cls = self.__class__ - model_columns = self.__mapper__.columns - relationships = self.__mapper__.relationships - - session = kwargs.get("session", None) - - for key, val in kwargs.items(): - if key in exclude: - continue - - if not hasattr(cls, key): - continue - # raise TypeError(f"Invalid keyword argument: {key}") - - if key in model_columns: - setattr(self, key, val) - continue - - if key in relationships: - relation_dir = relationships[key].direction.name - relation_cls = relationships[key].mapper.entity - use_list = relationships[key].uselist - - try: - get_attr = relation_cls.Config.get_attr - if get_attr is None: - get_attr = "id" - except Exception: - get_attr = "id" - - if relation_dir == ONETOMANY.name and use_list: - instances = handle_one_to_many_list(get_attr, relation_cls, val) - setattr(self, key, instances) - - if relation_dir == ONETOMANY.name and not use_list: - instance = relation_cls(**val) - setattr(self, key, instance) - - elif relation_dir == MANYTOONE.name and not use_list: - if isinstance(val, dict): - val = val.get(get_attr) - - if val is None: - raise ValueError(f"Expected 'id' to be provided for {key}") - - if isinstance(val, (str, int)): - instance = relation_cls.get_ref(match_value=val, session=session) - setattr(self, key, instance) - - elif relation_dir == MANYTOMANY.name: - - if not isinstance(val, list): - raise ValueError(f"Expected many to many input to be of type list for {key}") - - if len(val) > 0 and isinstance(val[0], dict): - val = [elem.get(get_attr) for elem in val] - - instances = [x for x in [relation_cls.get_ref(elem, session=session) for elem in val] if x] - setattr(self, key, instances) - - return init(self, *args, **kwargs) - - return wrapper - - return decorator diff --git a/mealie/db/models/_model_utils/__init__.py b/mealie/db/models/_model_utils/__init__.py new file mode 100644 index 000000000000..9949173723f8 --- /dev/null +++ b/mealie/db/models/_model_utils/__init__.py @@ -0,0 +1 @@ +from .auto_init import auto_init diff --git a/mealie/db/models/_model_utils/auto_init.py b/mealie/db/models/_model_utils/auto_init.py new file mode 100644 index 000000000000..120c94803fc9 --- /dev/null +++ b/mealie/db/models/_model_utils/auto_init.py @@ -0,0 +1,184 @@ +from __future__ import annotations + +from functools import wraps + +from pydantic import BaseModel, Field +from sqlalchemy.orm import MANYTOMANY, MANYTOONE, ONETOMANY, Session +from sqlalchemy.orm.decl_api import DeclarativeMeta +from sqlalchemy.orm.mapper import Mapper +from sqlalchemy.orm.relationships import RelationshipProperty +from sqlalchemy.sql.base import ColumnCollection +from sqlalchemy.util._collections import ImmutableProperties + +from .helpers import safe_call + + +def _default_exclusion() -> set[str]: + return {"id"} + + +class AutoInitConfig(BaseModel): + """ + Config class for `auto_init` decorator. + """ + + get_attr: str = None + exclude: set = Field(default_factory=_default_exclusion) + # auto_create: bool = False + + +def _get_config(relation_cls: DeclarativeMeta) -> AutoInitConfig: + """ + Returns the config for the given class. + """ + cfg = AutoInitConfig() + cfgKeys = cfg.dict().keys() + # Get the config for the class + try: + class_config: AutoInitConfig = relation_cls.Config + except AttributeError: + return cfg + # Map all matching attributes in Config to all AutoInitConfig attributes + for attr in dir(class_config): + if attr in cfgKeys: + setattr(cfg, attr, getattr(class_config, attr)) + + return cfg + + +def get_lookup_attr(relation_cls: DeclarativeMeta) -> str: + """Returns the primary key attribute of the related class as a string. + + Args: + relation_cls (DeclarativeMeta): The SQLAlchemy class to get the primary_key from + + Returns: + Any: [description] + """ + + cfg = _get_config(relation_cls) + + try: + get_attr = cfg.get_attr + if get_attr is None: + get_attr = relation_cls.__table__.primary_key.columns.keys()[0] + except Exception: + get_attr = "id" + return get_attr + + +def handle_many_to_many(session, get_attr, relation_cls, all_elements: list[dict]): + """ + Proxy call to `handle_one_to_many_list` for many-to-many relationships. Because functionally, they do the same + """ + return handle_one_to_many_list(session, get_attr, relation_cls, all_elements) + + +def handle_one_to_many_list(session: Session, get_attr, relation_cls, all_elements: list[dict]): + elems_to_create: list[dict] = [] + updated_elems: list[dict] = [] + + for elem in all_elements: + elem_id = elem.get(get_attr, None) + + existing_elem = session.query(relation_cls).filter_by(**{get_attr: elem_id}).one_or_none() + + if existing_elem is None: + elems_to_create.append(elem) + + else: + for key, value in elem.items(): + setattr(existing_elem, key, value) + + updated_elems.append(existing_elem) + + new_elems = [safe_call(relation_cls, elem) for elem in elems_to_create] + return new_elems + updated_elems + + +def auto_init(): # sourcery no-metrics + """Wraps the `__init__` method of a class to automatically set the common + attributes. + + Args: + exclude (Union[set, list], optional): [description]. Defaults to None. + """ + + def decorator(init): + @wraps(init) + def wrapper(self: DeclarativeMeta, *args, **kwargs): # sourcery no-metrics + """ + Custom initializer that allows nested children initialization. + Only keys that are present as instance's class attributes are allowed. + These could be, for example, any mapped columns or relationships. + + Code inspired from GitHub. + Ref: https://github.com/tiangolo/fastapi/issues/2194 + """ + cls = self.__class__ + + exclude = _get_config(cls).exclude + + alchemy_mapper: Mapper = self.__mapper__ + model_columns: ColumnCollection = alchemy_mapper.columns + relationships: ImmutableProperties = alchemy_mapper.relationships + + session = kwargs.get("session", None) + + if session is None: + raise ValueError("Session is required to initialize the model with `auto_init`") + + for key, val in kwargs.items(): + if key in exclude: + continue + + if not hasattr(cls, key): + continue + # raise TypeError(f"Invalid keyword argument: {key}") + + if key in model_columns: + setattr(self, key, val) + continue + + if key in relationships: + prop: RelationshipProperty = relationships[key] + + # Identifies the type of relationship (ONETOMANY, MANYTOONE, many-to-one, many-to-many) + relation_dir = prop.direction + + # Identifies the parent class of the related object. + relation_cls: DeclarativeMeta = prop.mapper.entity + + # Identifies if the relationship was declared with use_list=True + use_list: bool = prop.uselist + + get_attr = get_lookup_attr(relation_cls) + + if relation_dir == ONETOMANY and use_list: + instances = handle_one_to_many_list(session, get_attr, relation_cls, val) + setattr(self, key, instances) + + elif relation_dir == ONETOMANY: + instance = safe_call(relation_cls, val) + setattr(self, key, instance) + + elif relation_dir == MANYTOONE and not use_list: + if isinstance(val, dict): + val = val.get(get_attr) + + if val is None: + raise ValueError(f"Expected 'id' to be provided for {key}") + + if isinstance(val, (str, int)): + instance = session.query(relation_cls).filter_by(**{get_attr: val}).one_or_none() + setattr(self, key, instance) + + elif relation_dir == MANYTOMANY: + instances = handle_many_to_many(session, get_attr, relation_cls, val) + setattr(self, key, instances) + + return init(self, *args, **kwargs) + + return wrapper + + return decorator diff --git a/mealie/db/models/_model_utils/helpers.py b/mealie/db/models/_model_utils/helpers.py new file mode 100644 index 000000000000..fa0f56c1e592 --- /dev/null +++ b/mealie/db/models/_model_utils/helpers.py @@ -0,0 +1,39 @@ +import inspect +from typing import Any, Callable + + +def get_valid_call(func: Callable, args_dict) -> dict: + """ + Returns a dictionary of valid arguemnts for the supplied function. if kwargs are accepted, + the original dictionary will be returned. + """ + + def get_valid_args(func: Callable) -> tuple: + """ + Returns a tuple of valid arguemnts for the supplied function. + """ + return inspect.getfullargspec(func).args + + def accepts_kwargs(func: Callable) -> bool: + """ + Returns True if the function accepts keyword arguments. + """ + return inspect.getfullargspec(func).varkw is not None + + if accepts_kwargs(func): + return args_dict + + valid_args = get_valid_args(func) + + return {k: v for k, v in args_dict.items() if k in valid_args} + + +def safe_call(func, dict) -> Any: + """ + Safely calls the supplied function with the supplied dictionary of arguments. + by removing any invalid arguments. + """ + try: + return func(**get_valid_call(func, dict)) + except TypeError: + return func(**dict) diff --git a/mealie/db/models/group/group.py b/mealie/db/models/group/group.py index fdc52e4cbb31..21629c055f4f 100644 --- a/mealie/db/models/group/group.py +++ b/mealie/db/models/group/group.py @@ -46,7 +46,10 @@ class Group(SqlAlchemyBase, BaseMixins): server_tasks = orm.relationship(ServerTaskModel, back_populates="group", single_parent=True) shopping_lists = orm.relationship("ShoppingList", back_populates="group", single_parent=True) - @auto_init({"users", "webhooks", "shopping_lists", "cookbooks", "preferences", "invite_tokens", "mealplans"}) + class Config: + exclude = {"users", "webhooks", "shopping_lists", "cookbooks", "preferences", "invite_tokens", "mealplans"} + + @auto_init() def __init__(self, **_) -> None: pass diff --git a/mealie/db/models/recipe/assets.py b/mealie/db/models/recipe/assets.py index 196c65c93d88..8f18a2d4dc45 100644 --- a/mealie/db/models/recipe/assets.py +++ b/mealie/db/models/recipe/assets.py @@ -11,12 +11,7 @@ class RecipeAsset(SqlAlchemyBase): icon = sa.Column(sa.String) file_name = sa.Column(sa.String) - def __init__( - self, - name=None, - icon=None, - file_name=None, - ) -> None: + def __init__(self, name=None, icon=None, file_name=None) -> None: self.name = name self.file_name = file_name self.icon = icon diff --git a/mealie/db/models/recipe/category.py b/mealie/db/models/recipe/category.py index f4f320dcbc30..7aa7aaef7ca4 100644 --- a/mealie/db/models/recipe/category.py +++ b/mealie/db/models/recipe/category.py @@ -8,12 +8,6 @@ from mealie.db.models._model_base import BaseMixins, SqlAlchemyBase logger = root_logger.get_logger() -site_settings2categories = sa.Table( - "site_settings2categories", - SqlAlchemyBase.metadata, - sa.Column("site_settings.id", sa.Integer, sa.ForeignKey("site_settings.id")), - sa.Column("category_id", sa.Integer, sa.ForeignKey("categories.id")), -) group2categories = sa.Table( "group2categories", diff --git a/mealie/db/models/recipe/recipe.py b/mealie/db/models/recipe/recipe.py index 2a9365631027..1b4f71f40828 100644 --- a/mealie/db/models/recipe/recipe.py +++ b/mealie/db/models/recipe/recipe.py @@ -86,14 +86,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins): class Config: get_attr = "slug" - - @validates("name") - def validate_name(self, key, name): - assert name != "" - return name - - @auto_init( - { + exclude = { "assets", "extras", "notes", @@ -103,7 +96,13 @@ class RecipeModel(SqlAlchemyBase, BaseMixins): "settings", "tools", } - ) + + @validates("name") + def validate_name(self, key, name): + assert name != "" + return name + + @auto_init() def __init__( self, session, @@ -115,7 +114,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins): recipe_instructions: list[dict] = None, settings: dict = None, tools: list[str] = None, - **_ + **_, ) -> None: self.nutrition = Nutrition(**nutrition) if nutrition else Nutrition() self.tools = [Tool(tool=x) for x in tools] if tools else [] diff --git a/mealie/db/models/settings.py b/mealie/db/models/settings.py deleted file mode 100644 index 79464f0bf3a2..000000000000 --- a/mealie/db/models/settings.py +++ /dev/null @@ -1,35 +0,0 @@ -import sqlalchemy as sa -import sqlalchemy.orm as orm -from sqlalchemy.orm import Session - -from mealie.db.models._model_base import BaseMixins, SqlAlchemyBase -from mealie.db.models.recipe.category import Category, site_settings2categories - - -class SiteSettings(SqlAlchemyBase, BaseMixins): - __tablename__ = "site_settings" - id = sa.Column(sa.Integer, primary_key=True) - language = sa.Column(sa.String) - first_day_of_week = sa.Column(sa.Integer) - categories = orm.relationship("Category", secondary=site_settings2categories, single_parent=True) - show_recent = sa.Column(sa.Boolean, default=True) - cards_per_section = sa.Column(sa.Integer) - - def __init__( - self, - session: Session = None, - language="en", - first_day_of_week: int = 0, - categories: list = [], - show_recent=True, - cards_per_section: int = 9, - ) -> None: - session.commit() - self.language = language - self.first_day_of_week = first_day_of_week - self.cards_per_section = cards_per_section - self.show_recent = show_recent - self.categories = [Category.get_ref(session=session, slug=cat.get("slug")) for cat in categories] - - def update(self, *args, **kwarg): - self.__init__(*args, **kwarg) diff --git a/mealie/db/models/users/users.py b/mealie/db/models/users/users.py index 77b4f09f1367..916bf6777862 100644 --- a/mealie/db/models/users/users.py +++ b/mealie/db/models/users/users.py @@ -11,7 +11,6 @@ settings = get_app_settings() class LongLiveToken(SqlAlchemyBase, BaseMixins): __tablename__ = "long_live_tokens" - id = Column(Integer, primary_key=True) parent_id = Column(Integer, ForeignKey("users.id")) name = Column(String, nullable=False) token = Column(String, nullable=False) @@ -25,7 +24,6 @@ class LongLiveToken(SqlAlchemyBase, BaseMixins): class User(SqlAlchemyBase, BaseMixins): __tablename__ = "users" - id = Column(Integer, primary_key=True) full_name = Column(String, index=True) username = Column(String, index=True, unique=True) email = Column(String, unique=True, index=True) @@ -41,7 +39,6 @@ class User(SqlAlchemyBase, BaseMixins): can_invite = Column(Boolean, default=False) can_organize = Column(Boolean, default=False) - # Recipes tokens: list[LongLiveToken] = orm.relationship( LongLiveToken, back_populates="user", cascade="all, delete, delete-orphan", single_parent=True ) @@ -67,67 +64,52 @@ class User(SqlAlchemyBase, BaseMixins): password, favorite_recipes: list[str] = None, group: str = settings.DEFAULT_GROUP, - admin=False, advanced=False, - can_manage=False, - can_invite=False, - can_organize=False, - **_ + **kwargs ) -> None: - group = group or settings.DEFAULT_GROUP favorite_recipes = favorite_recipes or [] + self.group = Group.get_ref(session, group) + self.full_name = full_name self.email = email - self.group = Group.get_ref(session, group) - self.admin = admin self.password = password self.advanced = advanced - if self.admin: - self.can_manage = True - self.can_invite = True - self.can_organize = True - else: - self.can_manage = can_manage - self.can_invite = can_invite - self.can_organize = can_organize - self.favorite_recipes = [] if self.username is None: self.username = full_name - def update( - self, - full_name, - email, - group, - admin, - username, - session=None, - favorite_recipes=None, - password=None, - advanced=False, - can_manage=False, - can_invite=False, - can_organize=False, - **_ - ): + self._set_permissions(**kwargs) + + def update(self, full_name, email, group, username, session=None, favorite_recipes=None, advanced=False, **kwargs): favorite_recipes = favorite_recipes or [] self.username = username self.full_name = full_name self.email = email + self.group = Group.get_ref(session, group) - self.admin = admin self.advanced = advanced if self.username is None: self.username = full_name - if password: - self.password = password + self._set_permissions(**kwargs) + def update_password(self, password): + self.password = password + + def _set_permissions(self, admin, can_manage=False, can_invite=False, can_organize=False, **_): + """Set user permissions based on the admin flag and the passed in kwargs + + Args: + admin (bool): + can_manage (bool): + can_invite (bool): + can_organize (bool): + """ + self.admin = admin if self.admin: self.can_manage = True self.can_invite = True @@ -137,9 +119,6 @@ class User(SqlAlchemyBase, BaseMixins): self.can_invite = can_invite self.can_organize = can_organize - def update_password(self, password): - self.password = password - @staticmethod def get_ref(session, id: str): return session.query(User).filter(User.id == id).one() diff --git a/mealie/routes/site_settings/site_settings.py b/mealie/routes/site_settings/site_settings.py index 23e272e526cd..01dda81a7539 100644 --- a/mealie/routes/site_settings/site_settings.py +++ b/mealie/routes/site_settings/site_settings.py @@ -5,7 +5,6 @@ from mealie.core.dependencies import get_current_user from mealie.db.database import get_database from mealie.db.db_setup import generate_session from mealie.routes.routers import AdminAPIRouter -from mealie.schema.admin import SiteSettings from mealie.schema.user import GroupInDB, PrivateUser from mealie.utils.post_webhooks import post_webhooks @@ -21,16 +20,6 @@ def get_main_settings(session: Session = Depends(generate_session)): return db.settings.get(1) -@admin_router.put("") -def update_settings( - data: SiteSettings, - session: Session = Depends(generate_session), -): - """ Returns Site Settings """ - db = get_database(session) - db.settings.update(1, data.dict()) - - @admin_router.post("/webhooks/test") def test_webhooks( current_user: PrivateUser = Depends(get_current_user), diff --git a/mealie/routes/users/passwords.py b/mealie/routes/users/passwords.py index 7986a517fe7e..c760b31359c4 100644 --- a/mealie/routes/users/passwords.py +++ b/mealie/routes/users/passwords.py @@ -24,10 +24,9 @@ async def reset_user_password(id: int, session: Session = Depends(generate_sessi db.users.update_password(id, new_password) -@user_router.put("/{id}/password") +@user_router.put("/{item_id}/password") def update_password(password_change: ChangePassword, user_service: UserService = Depends(UserService.write_existing)): """ Resets the User Password""" - return user_service.change_password(password_change) diff --git a/mealie/schema/admin/settings.py b/mealie/schema/admin/settings.py index 4002db51bb8f..31468754bb3f 100644 --- a/mealie/schema/admin/settings.py +++ b/mealie/schema/admin/settings.py @@ -4,31 +4,7 @@ from fastapi_camelcase import CamelModel from pydantic import validator from slugify import slugify -from ..recipe.recipe_category import CategoryBase, RecipeCategoryResponse - - -class SiteSettings(CamelModel): - language: str = "en-US" - first_day_of_week: int = 0 - show_recent: bool = True - cards_per_section: int = 9 - categories: Optional[list[CategoryBase]] = [] - - class Config: - orm_mode = True - - schema_extra = { - "example": { - "language": "en", - "firstDayOfWeek": 0, - "showRecent": True, - "categories": [ - {"id": 1, "name": "thanksgiving", "slug": "thanksgiving"}, - {"id": 2, "name": "homechef", "slug": "homechef"}, - {"id": 3, "name": "potatoes", "slug": "potatoes"}, - ], - } - } +from ..recipe.recipe_category import RecipeCategoryResponse class CustomPageBase(CamelModel): diff --git a/mealie/services/backups/imports.py b/mealie/services/backups/imports.py index bf511e3f39d4..3c483bc957b1 100644 --- a/mealie/services/backups/imports.py +++ b/mealie/services/backups/imports.py @@ -11,15 +11,7 @@ from mealie.core.config import get_app_dirs app_dirs = get_app_dirs() from mealie.db.database import get_database -from mealie.schema.admin import ( - CommentImport, - GroupImport, - NotificationImport, - RecipeImport, - SettingsImport, - SiteSettings, - UserImport, -) +from mealie.schema.admin import CommentImport, GroupImport, NotificationImport, RecipeImport, UserImport from mealie.schema.events import EventNotificationIn from mealie.schema.recipe import CommentOut, Recipe from mealie.schema.user import PrivateUser, UpdateGroup @@ -181,19 +173,7 @@ class ImportDatabase: return import_notifications def import_settings(self): - settings_file = self.import_dir.joinpath("settings", "settings.json") - settings = ImportDatabase.read_models_file(settings_file, SiteSettings) - settings = settings[0] - - try: - self.db.settings.update(1, settings.dict()) - import_status = SettingsImport(name="Site Settings", status=True) - - except Exception as inst: - self.session.rollback() - import_status = SettingsImport(name="Site Settings", status=False, exception=str(inst)) - - return [import_status] + return [] def import_groups(self): groups_file = self.import_dir.joinpath("groups", "groups.json") diff --git a/mealie/services/migrations/_migration_base.py b/mealie/services/migrations/_migration_base.py index 78659be25681..f39ea2fd1901 100644 --- a/mealie/services/migrations/_migration_base.py +++ b/mealie/services/migrations/_migration_base.py @@ -181,7 +181,7 @@ class MigrationBase(BaseModel): except Exception as inst: exception = inst - logger.error(inst) + logger.exception(inst) self.session.rollback() import_status = MigrationImport(slug=recipe.slug, name=recipe.name, status=status, exception=str(exception)) diff --git a/mealie/services/user_services/user_service.py b/mealie/services/user_services/user_service.py index 9b8fb38a006e..59f5c692ae2d 100644 --- a/mealie/services/user_services/user_service.py +++ b/mealie/services/user_services/user_service.py @@ -13,7 +13,12 @@ class UserService(UserHttpService[int, str]): event_func = create_user_event acting_user: PrivateUser = None + def populate_item(self, item_id: int) -> None: + self.acting_user = self.db.users.get_one(item_id) + return self.acting_user + def assert_existing(self, id) -> PrivateUser: + self.populate_item(id) self._populate_target_user(id) self._assert_user_change_allowed() return self.target_user @@ -32,7 +37,6 @@ class UserService(UserHttpService[int, str]): self.target_user = self.acting_user def change_password(self, password_change: ChangePassword) -> PrivateUser: - """""" if not verify_password(password_change.current_password, self.target_user.password): raise HTTPException(status.HTTP_400_BAD_REQUEST) diff --git a/poetry.lock b/poetry.lock index 8ccdf36004f4..a66ab7c783de 100644 --- a/poetry.lock +++ b/poetry.lock @@ -41,7 +41,7 @@ six = "*" [[package]] name = "apscheduler" -version = "3.8.0" +version = "3.8.1" description = "In-process task scheduler with Cron-like capabilities" category = "main" optional = false @@ -50,7 +50,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.dependencies] pytz = "*" six = ">=1.4.0" -tzlocal = ">=2.0,<3.0" +tzlocal = ">=2.0,<3.0.0 || >=4.0.0" [package.extras] asyncio = ["trollius"] @@ -67,7 +67,7 @@ zookeeper = ["kazoo"] [[package]] name = "astroid" -version = "2.8.3" +version = "2.8.4" description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false @@ -646,7 +646,7 @@ i18n = ["babel (>=2.9.0)"] [[package]] name = "mkdocs-material" -version = "7.3.4" +version = "7.3.6" description = "A Material Design theme for MkDocs" category = "dev" optional = false @@ -657,7 +657,7 @@ jinja2 = ">=2.11.1" markdown = ">=3.2" mkdocs = ">=1.2.3" mkdocs-material-extensions = ">=1.0" -pygments = ">=2.4" +pygments = ">=2.10" pymdown-extensions = ">=9.0" [[package]] @@ -691,14 +691,14 @@ signedtoken = ["cryptography (>=3.0.0,<4)", "pyjwt (>=2.0.0,<3)"] [[package]] name = "packaging" -version = "21.0" +version = "21.2" description = "Core utilities for Python packages" category = "dev" optional = false python-versions = ">=3.6" [package.dependencies] -pyparsing = ">=2.0.2" +pyparsing = ">=2.0.2,<3" [[package]] name = "passlib" @@ -1044,6 +1044,17 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "pytz-deprecation-shim" +version = "0.1.0.post0" +description = "Shims to make deprecation of pytz easier" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" + +[package.dependencies] +tzdata = {version = "*", markers = "python_version >= \"3.6\""} + [[package]] name = "pyyaml" version = "5.4.1" @@ -1263,16 +1274,29 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "tzdata" +version = "2021.5" +description = "Provider of IANA time zone data" +category = "main" +optional = false +python-versions = ">=2" + [[package]] name = "tzlocal" -version = "2.1" +version = "4.1" description = "tzinfo object for the local timezone" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" [package.dependencies] -pytz = "*" +pytz-deprecation-shim = "*" +tzdata = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +devenv = ["black", "pyroma", "pytest-cov", "zest.releaser"] +test = ["pytest-mock (>=3.3)", "pytest (>=4.3)"] [[package]] name = "urllib3" @@ -1370,7 +1394,7 @@ python-versions = ">=3.6.1" [[package]] name = "wrapt" -version = "1.13.2" +version = "1.13.3" description = "Module for decorators, wrappers and monkey patching." category = "dev" optional = false @@ -1414,12 +1438,12 @@ apprise = [ {file = "apprise-0.9.3.tar.gz", hash = "sha256:c8ace9c891d4224558570acbea808f31df9049530bd9ccd69901c27a65d600c4"}, ] apscheduler = [ - {file = "APScheduler-3.8.0-py2.py3-none-any.whl", hash = "sha256:82d6d21b2f0343510d07bb35618333a794653439a265635555b12935647b460a"}, - {file = "APScheduler-3.8.0.tar.gz", hash = "sha256:793b2d37c52ece53e34626619e6142e99b20b59a12155f39e1e6932e324f079d"}, + {file = "APScheduler-3.8.1-py2.py3-none-any.whl", hash = "sha256:c22cb14b411a31435eb2c530dfbbec948ac63015b517087c7978adb61b574865"}, + {file = "APScheduler-3.8.1.tar.gz", hash = "sha256:5cf344ebcfbdaa48ae178c029c055cec7bc7a4a47c21e315e4d1f08bd35f2355"}, ] astroid = [ - {file = "astroid-2.8.3-py3-none-any.whl", hash = "sha256:f9d66e3a4a0e5b52819b2ff41ac2b179df9d180697db71c92beb33a60c661794"}, - {file = "astroid-2.8.3.tar.gz", hash = "sha256:0e361da0744d5011d4f5d57e64473ba9b7ab4da1e2d45d6631ebd67dd28c3cce"}, + {file = "astroid-2.8.4-py3-none-any.whl", hash = "sha256:0755c998e7117078dcb7d0bda621391dd2a85da48052d948c7411ab187325346"}, + {file = "astroid-2.8.4.tar.gz", hash = "sha256:1e83a69fd51b013ebf5912d26b9338d6643a55fec2f20c787792680610eed4a2"}, ] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, @@ -1820,12 +1844,28 @@ markdown = [ {file = "Markdown-3.3.4.tar.gz", hash = "sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49"}, ] markupsafe = [ + {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, @@ -1834,14 +1874,27 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, @@ -1851,6 +1904,12 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, @@ -1871,8 +1930,8 @@ mkdocs = [ {file = "mkdocs-1.2.3.tar.gz", hash = "sha256:89f5a094764381cda656af4298727c9f53dc3e602983087e1fe96ea1df24f4c1"}, ] mkdocs-material = [ - {file = "mkdocs-material-7.3.4.tar.gz", hash = "sha256:9cc0ea54933322792855150ffb89401ff4eaf7737aadca5155fa679195ad803a"}, - {file = "mkdocs_material-7.3.4-py2.py3-none-any.whl", hash = "sha256:6a9c5a2f18a39ac0b6af73d23c452cdb1f9a07bf6365d43ee54cb796b1d2c7eb"}, + {file = "mkdocs-material-7.3.6.tar.gz", hash = "sha256:1b1dbd8ef2508b358d93af55a5c5db3f141c95667fad802301ec621c40c7c217"}, + {file = "mkdocs_material-7.3.6-py2.py3-none-any.whl", hash = "sha256:1b6b3e9e09f922c2d7f1160fe15c8f43d4adc0d6fb81aa6ff0cbc7ef5b78ec75"}, ] mkdocs-material-extensions = [ {file = "mkdocs-material-extensions-1.0.3.tar.gz", hash = "sha256:bfd24dfdef7b41c312ede42648f9eb83476ea168ec163b613f9abd12bbfddba2"}, @@ -1887,8 +1946,8 @@ oauthlib = [ {file = "oauthlib-3.1.1.tar.gz", hash = "sha256:8f0215fcc533dd8dd1bee6f4c412d4f0cd7297307d43ac61666389e3bc3198a3"}, ] packaging = [ - {file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"}, - {file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"}, + {file = "packaging-21.2-py3-none-any.whl", hash = "sha256:14317396d1e8cdb122989b916fa2c7e9ca8e2be9e8060a6eff75b6b7b4d8a7e0"}, + {file = "packaging-21.2.tar.gz", hash = "sha256:096d689d78ca690e4cd8a89568ba06d07ca097e3306a4381635073ca91479966"}, ] passlib = [ {file = "passlib-1.7.4-py2.py3-none-any.whl", hash = "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1"}, @@ -1959,6 +2018,11 @@ premailer = [ ] psycopg2-binary = [ {file = "psycopg2-binary-2.9.1.tar.gz", hash = "sha256:b0221ca5a9837e040ebf61f48899926b5783668b7807419e4adae8175a31f773"}, + {file = "psycopg2_binary-2.9.1-cp310-cp310-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:24b0b6688b9f31a911f2361fe818492650795c9e5d3a1bc647acbd7440142a4f"}, + {file = "psycopg2_binary-2.9.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:542875f62bc56e91c6eac05a0deadeae20e1730be4c6334d8f04c944fcd99759"}, + {file = "psycopg2_binary-2.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:661509f51531ec125e52357a489ea3806640d0ca37d9dada461ffc69ee1e7b6e"}, + {file = "psycopg2_binary-2.9.1-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:d92272c7c16e105788efe2cfa5d680f07e34e0c29b03c1908f8636f55d5f915a"}, + {file = "psycopg2_binary-2.9.1-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:736b8797b58febabb85494142c627bd182b50d2a7ec65322983e71065ad3034c"}, {file = "psycopg2_binary-2.9.1-cp36-cp36m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:c250a7ec489b652c892e4f0a5d122cc14c3780f9f643e1a326754aedf82d9a76"}, {file = "psycopg2_binary-2.9.1-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aef9aee84ec78af51107181d02fe8773b100b01c5dfde351184ad9223eab3698"}, {file = "psycopg2_binary-2.9.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123c3fb684e9abfc47218d3784c7b4c47c8587951ea4dd5bc38b6636ac57f616"}, @@ -2106,6 +2170,10 @@ pytz = [ {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}, {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}, ] +pytz-deprecation-shim = [ + {file = "pytz_deprecation_shim-0.1.0.post0-py2.py3-none-any.whl", hash = "sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6"}, + {file = "pytz_deprecation_shim-0.1.0.post0.tar.gz", hash = "sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d"}, +] pyyaml = [ {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, @@ -2113,18 +2181,26 @@ pyyaml = [ {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, @@ -2221,6 +2297,8 @@ sqlalchemy = [ {file = "SQLAlchemy-1.4.26-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c757ba1279b85b3460e72e8b92239dae6f8b060a75fb24b3d9be984dd78cfa55"}, {file = "SQLAlchemy-1.4.26-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:c24c01dcd03426a5fe5ee7af735906bec6084977b9027a3605d11d949a565c01"}, {file = "SQLAlchemy-1.4.26-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c46f013ff31b80cbe36410281675e1fb4eaf3e25c284fd8a69981c73f6fa4cb4"}, + {file = "SQLAlchemy-1.4.26-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fb2aa74a6e3c2cebea38dd21633671841fbe70ea486053cba33d68e3e22ccc0a"}, + {file = "SQLAlchemy-1.4.26-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad7e403fc1e3cb76e802872694e30d6ca6129b9bc6ad4e7caa48ca35f8a144f8"}, {file = "SQLAlchemy-1.4.26-cp310-cp310-win32.whl", hash = "sha256:7ef421c3887b39c6f352e5022a53ac18de8387de331130481cb956b2d029cad6"}, {file = "SQLAlchemy-1.4.26-cp310-cp310-win_amd64.whl", hash = "sha256:908fad32c53b17aad12d722379150c3c5317c422437e44032256a77df1746292"}, {file = "SQLAlchemy-1.4.26-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:1ef37c9ec2015ce2f0dc1084514e197f2f199d3dc3514190db7620b78e6004c8"}, @@ -2298,9 +2376,13 @@ typing-extensions = [ {file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"}, {file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"}, ] +tzdata = [ + {file = "tzdata-2021.5-py2.py3-none-any.whl", hash = "sha256:3eee491e22ebfe1e5cfcc97a4137cd70f092ce59144d81f8924a844de05ba8f5"}, + {file = "tzdata-2021.5.tar.gz", hash = "sha256:68dbe41afd01b867894bbdfd54fa03f468cfa4f0086bfb4adcd8de8f24f3ee21"}, +] tzlocal = [ - {file = "tzlocal-2.1-py2.py3-none-any.whl", hash = "sha256:e2cb6c6b5b604af38597403e9852872d7f534962ae2954c7f35efcb1ccacf4a4"}, - {file = "tzlocal-2.1.tar.gz", hash = "sha256:643c97c5294aedc737780a49d9df30889321cbe1204eac2c2ec6134035a92e44"}, + {file = "tzlocal-4.1-py3-none-any.whl", hash = "sha256:28ba8d9fcb6c9a782d6e0078b4f6627af1ea26aeaa32b4eab5324abc7df4149f"}, + {file = "tzlocal-4.1.tar.gz", hash = "sha256:0f28015ac68a5c067210400a9197fc5d36ba9bc3f8eaf1da3cbd59acdfed9e09"}, ] urllib3 = [ {file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"}, @@ -2390,50 +2472,57 @@ websockets = [ {file = "websockets-8.1.tar.gz", hash = "sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f"}, ] wrapt = [ - {file = "wrapt-1.13.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3de7b4d3066cc610054e7aa2c005645e308df2f92be730aae3a47d42e910566a"}, - {file = "wrapt-1.13.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:8164069f775c698d15582bf6320a4f308c50d048c1c10cf7d7a341feaccf5df7"}, - {file = "wrapt-1.13.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9adee1891253670575028279de8365c3a02d3489a74a66d774c321472939a0b1"}, - {file = "wrapt-1.13.2-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:a70d876c9aba12d3bd7f8f1b05b419322c6789beb717044eea2c8690d35cb91b"}, - {file = "wrapt-1.13.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:3f87042623530bcffea038f824b63084180513c21e2e977291a9a7e65a66f13b"}, - {file = "wrapt-1.13.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:e634136f700a21e1fcead0c137f433dde928979538c14907640607d43537d468"}, - {file = "wrapt-1.13.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:3e33c138d1e3620b1e0cc6fd21e46c266393ed5dae0d595b7ed5a6b73ed57aa0"}, - {file = "wrapt-1.13.2-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:283e402e5357e104ac1e3fba5791220648e9af6fb14ad7d9cc059091af2b31d2"}, - {file = "wrapt-1.13.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:ccb34ce599cab7f36a4c90318697ead18312c67a9a76327b3f4f902af8f68ea1"}, - {file = "wrapt-1.13.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:fbad5ba74c46517e6488149514b2e2348d40df88cd6b52a83855b7a8bf04723f"}, - {file = "wrapt-1.13.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:724ed2bc9c91a2b9026e5adce310fa60c6e7c8760b03391445730b9789b9d108"}, - {file = "wrapt-1.13.2-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:83f2793ec6f3ef513ad8d5b9586f5ee6081cad132e6eae2ecb7eac1cc3decae0"}, - {file = "wrapt-1.13.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:0473d1558b93e314e84313cc611f6c86be779369f9d3734302bf185a4d2625b1"}, - {file = "wrapt-1.13.2-cp35-cp35m-win32.whl", hash = "sha256:15eee0e6fd07f48af2f66d0e6f2ff1916ffe9732d464d5e2390695296872cad9"}, - {file = "wrapt-1.13.2-cp35-cp35m-win_amd64.whl", hash = "sha256:bc85d17d90201afd88e3d25421da805e4e135012b5d1f149e4de2981394b2a52"}, - {file = "wrapt-1.13.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c6ee5f8734820c21b9b8bf705e99faba87f21566d20626568eeb0d62cbeaf23c"}, - {file = "wrapt-1.13.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:53c6706a1bcfb6436f1625511b95b812798a6d2ccc51359cd791e33722b5ea32"}, - {file = "wrapt-1.13.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fbe6aebc9559fed7ea27de51c2bf5c25ba2a4156cf0017556f72883f2496ee9a"}, - {file = "wrapt-1.13.2-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:0582180566e7a13030f896c2f1ac6a56134ab5f3c3f4c5538086f758b1caf3f2"}, - {file = "wrapt-1.13.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:bff0a59387a0a2951cb869251257b6553663329a1b5525b5226cab8c88dcbe7e"}, - {file = "wrapt-1.13.2-cp36-cp36m-win32.whl", hash = "sha256:df3eae297a5f1594d1feb790338120f717dac1fa7d6feed7b411f87e0f2401c7"}, - {file = "wrapt-1.13.2-cp36-cp36m-win_amd64.whl", hash = "sha256:1eb657ed84f4d3e6ad648483c8a80a0cf0a78922ef94caa87d327e2e1ad49b48"}, - {file = "wrapt-1.13.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0cdedf681db878416c05e1831ec69691b0e6577ac7dca9d4f815632e3549580"}, - {file = "wrapt-1.13.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:87ee3c73bdfb4367b26c57259995935501829f00c7b3eed373e2ad19ec21e4e4"}, - {file = "wrapt-1.13.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:3e0d16eedc242d01a6f8cf0623e9cdc3b869329da3f97a15961d8864111d8cf0"}, - {file = "wrapt-1.13.2-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:8318088860968c07e741537030b1abdd8908ee2c71fbe4facdaade624a09e006"}, - {file = "wrapt-1.13.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:d90520616fce71c05dedeac3a0fe9991605f0acacd276e5f821842e454485a70"}, - {file = "wrapt-1.13.2-cp37-cp37m-win32.whl", hash = "sha256:22142afab65daffc95863d78effcbd31c19a8003eca73de59f321ee77f73cadb"}, - {file = "wrapt-1.13.2-cp37-cp37m-win_amd64.whl", hash = "sha256:d0d717e10f952df7ea41200c507cc7e24458f4c45b56c36ad418d2e79dacd1d4"}, - {file = "wrapt-1.13.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:593cb049ce1c391e0288523b30426c4430b26e74c7e6f6e2844bd99ac7ecc831"}, - {file = "wrapt-1.13.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:8860c8011a6961a651b1b9f46fdbc589ab63b0a50d645f7d92659618a3655867"}, - {file = "wrapt-1.13.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ada5e29e59e2feb710589ca1c79fd989b1dd94d27079dc1d199ec954a6ecc724"}, - {file = "wrapt-1.13.2-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:fdede980273aeca591ad354608778365a3a310e0ecdd7a3587b38bc5be9b1808"}, - {file = "wrapt-1.13.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:af9480de8e63c5f959a092047aaf3d7077422ded84695b3398f5d49254af3e90"}, - {file = "wrapt-1.13.2-cp38-cp38-win32.whl", hash = "sha256:c65e623ea7556e39c4f0818200a046cbba7575a6b570ff36122c276fdd30ab0a"}, - {file = "wrapt-1.13.2-cp38-cp38-win_amd64.whl", hash = "sha256:b20703356cae1799080d0ad15085dc3213c1ac3f45e95afb9f12769b98231528"}, - {file = "wrapt-1.13.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1c5c4cf188b5643a97e87e2110bbd4f5bc491d54a5b90633837b34d5df6a03fe"}, - {file = "wrapt-1.13.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:82223f72eba6f63eafca87a0f614495ae5aa0126fe54947e2b8c023969e9f2d7"}, - {file = "wrapt-1.13.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:81a4cf257263b299263472d669692785f9c647e7dca01c18286b8f116dbf6b38"}, - {file = "wrapt-1.13.2-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:728e2d9b7a99dd955d3426f237b940fc74017c4a39b125fec913f575619ddfe9"}, - {file = "wrapt-1.13.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:7574de567dcd4858a2ffdf403088d6df8738b0e1eabea220553abf7c9048f59e"}, - {file = "wrapt-1.13.2-cp39-cp39-win32.whl", hash = "sha256:c7ac2c7a8e34bd06710605b21dd1f3576764443d68e069d2afba9b116014d072"}, - {file = "wrapt-1.13.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e6d1a8eeef415d7fb29fe017de0e48f45e45efd2d1bfda28fc50b7b330859ef"}, - {file = "wrapt-1.13.2.tar.gz", hash = "sha256:dca56cc5963a5fd7c2aa8607017753f534ee514e09103a6c55d2db70b50e7447"}, + {file = "wrapt-1.13.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e05e60ff3b2b0342153be4d1b597bbcfd8330890056b9619f4ad6b8d5c96a81a"}, + {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:85148f4225287b6a0665eef08a178c15097366d46b210574a658c1ff5b377489"}, + {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:2dded5496e8f1592ec27079b28b6ad2a1ef0b9296d270f77b8e4a3a796cf6909"}, + {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:e94b7d9deaa4cc7bac9198a58a7240aaf87fe56c6277ee25fa5b3aa1edebd229"}, + {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:498e6217523111d07cd67e87a791f5e9ee769f9241fcf8a379696e25806965af"}, + {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ec7e20258ecc5174029a0f391e1b948bf2906cd64c198a9b8b281b811cbc04de"}, + {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:87883690cae293541e08ba2da22cacaae0a092e0ed56bbba8d018cc486fbafbb"}, + {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f99c0489258086308aad4ae57da9e8ecf9e1f3f30fa35d5e170b4d4896554d80"}, + {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6a03d9917aee887690aa3f1747ce634e610f6db6f6b332b35c2dd89412912bca"}, + {file = "wrapt-1.13.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:936503cb0a6ed28dbfa87e8fcd0a56458822144e9d11a49ccee6d9a8adb2ac44"}, + {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f9c51d9af9abb899bd34ace878fbec8bf357b3194a10c4e8e0a25512826ef056"}, + {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:220a869982ea9023e163ba915077816ca439489de6d2c09089b219f4e11b6785"}, + {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0877fe981fd76b183711d767500e6b3111378ed2043c145e21816ee589d91096"}, + {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:43e69ffe47e3609a6aec0fe723001c60c65305784d964f5007d5b4fb1bc6bf33"}, + {file = "wrapt-1.13.3-cp310-cp310-win32.whl", hash = "sha256:78dea98c81915bbf510eb6a3c9c24915e4660302937b9ae05a0947164248020f"}, + {file = "wrapt-1.13.3-cp310-cp310-win_amd64.whl", hash = "sha256:ea3e746e29d4000cd98d572f3ee2a6050a4f784bb536f4ac1f035987fc1ed83e"}, + {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8c73c1a2ec7c98d7eaded149f6d225a692caa1bd7b2401a14125446e9e90410d"}, + {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:086218a72ec7d986a3eddb7707c8c4526d677c7b35e355875a0fe2918b059179"}, + {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:e92d0d4fa68ea0c02d39f1e2f9cb5bc4b4a71e8c442207433d8db47ee79d7aa3"}, + {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:d4a5f6146cfa5c7ba0134249665acd322a70d1ea61732723c7d3e8cc0fa80755"}, + {file = "wrapt-1.13.3-cp35-cp35m-win32.whl", hash = "sha256:8aab36778fa9bba1a8f06a4919556f9f8c7b33102bd71b3ab307bb3fecb21851"}, + {file = "wrapt-1.13.3-cp35-cp35m-win_amd64.whl", hash = "sha256:944b180f61f5e36c0634d3202ba8509b986b5fbaf57db3e94df11abee244ba13"}, + {file = "wrapt-1.13.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2ebdde19cd3c8cdf8df3fc165bc7827334bc4e353465048b36f7deeae8ee0918"}, + {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:610f5f83dd1e0ad40254c306f4764fcdc846641f120c3cf424ff57a19d5f7ade"}, + {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5601f44a0f38fed36cc07db004f0eedeaadbdcec90e4e90509480e7e6060a5bc"}, + {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:e6906d6f48437dfd80464f7d7af1740eadc572b9f7a4301e7dd3d65db285cacf"}, + {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:766b32c762e07e26f50d8a3468e3b4228b3736c805018e4b0ec8cc01ecd88125"}, + {file = "wrapt-1.13.3-cp36-cp36m-win32.whl", hash = "sha256:5f223101f21cfd41deec8ce3889dc59f88a59b409db028c469c9b20cfeefbe36"}, + {file = "wrapt-1.13.3-cp36-cp36m-win_amd64.whl", hash = "sha256:f122ccd12fdc69628786d0c947bdd9cb2733be8f800d88b5a37c57f1f1d73c10"}, + {file = "wrapt-1.13.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:46f7f3af321a573fc0c3586612db4decb7eb37172af1bc6173d81f5b66c2e068"}, + {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:778fd096ee96890c10ce96187c76b3e99b2da44e08c9e24d5652f356873f6709"}, + {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0cb23d36ed03bf46b894cfec777eec754146d68429c30431c99ef28482b5c1df"}, + {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:96b81ae75591a795d8c90edc0bfaab44d3d41ffc1aae4d994c5aa21d9b8e19a2"}, + {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7dd215e4e8514004c8d810a73e342c536547038fb130205ec4bba9f5de35d45b"}, + {file = "wrapt-1.13.3-cp37-cp37m-win32.whl", hash = "sha256:47f0a183743e7f71f29e4e21574ad3fa95676136f45b91afcf83f6a050914829"}, + {file = "wrapt-1.13.3-cp37-cp37m-win_amd64.whl", hash = "sha256:fd76c47f20984b43d93de9a82011bb6e5f8325df6c9ed4d8310029a55fa361ea"}, + {file = "wrapt-1.13.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b73d4b78807bd299b38e4598b8e7bd34ed55d480160d2e7fdaabd9931afa65f9"}, + {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ec9465dd69d5657b5d2fa6133b3e1e989ae27d29471a672416fd729b429eb554"}, + {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dd91006848eb55af2159375134d724032a2d1d13bcc6f81cd8d3ed9f2b8e846c"}, + {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ae9de71eb60940e58207f8e71fe113c639da42adb02fb2bcbcaccc1ccecd092b"}, + {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:51799ca950cfee9396a87f4a1240622ac38973b6df5ef7a41e7f0b98797099ce"}, + {file = "wrapt-1.13.3-cp38-cp38-win32.whl", hash = "sha256:4b9c458732450ec42578b5642ac53e312092acf8c0bfce140ada5ca1ac556f79"}, + {file = "wrapt-1.13.3-cp38-cp38-win_amd64.whl", hash = "sha256:7dde79d007cd6dfa65afe404766057c2409316135cb892be4b1c768e3f3a11cb"}, + {file = "wrapt-1.13.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:981da26722bebb9247a0601e2922cedf8bb7a600e89c852d063313102de6f2cb"}, + {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:705e2af1f7be4707e49ced9153f8d72131090e52be9278b5dbb1498c749a1e32"}, + {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25b1b1d5df495d82be1c9d2fad408f7ce5ca8a38085e2da41bb63c914baadff7"}, + {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:77416e6b17926d953b5c666a3cb718d5945df63ecf922af0ee576206d7033b5e"}, + {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:865c0b50003616f05858b22174c40ffc27a38e67359fa1495605f96125f76640"}, + {file = "wrapt-1.13.3-cp39-cp39-win32.whl", hash = "sha256:0a017a667d1f7411816e4bf214646d0ad5b1da2c1ea13dec6c162736ff25a374"}, + {file = "wrapt-1.13.3-cp39-cp39-win_amd64.whl", hash = "sha256:81bd7c90d28a4b2e1df135bfbd7c23aee3050078ca6441bead44c42483f9ebfb"}, + {file = "wrapt-1.13.3.tar.gz", hash = "sha256:1fea9cd438686e6682271d36f3481a9f3636195578bab9ca3382e2f5f01fc185"}, ] zipp = [ {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, diff --git a/tests/integration_tests/test_settings_routes.py b/tests/integration_tests/test_settings_routes.py deleted file mode 100644 index f245c82729d5..000000000000 --- a/tests/integration_tests/test_settings_routes.py +++ /dev/null @@ -1,32 +0,0 @@ -import json - -import pytest -from fastapi.testclient import TestClient - -from mealie.schema.admin import SiteSettings -from tests.app_routes import AppRoutes - - -@pytest.fixture(scope="function") -def default_settings(): - return SiteSettings().dict(by_alias=True) - - -def test_default_settings(api_client: TestClient, api_routes: AppRoutes, default_settings): - response = api_client.get(api_routes.site_settings) - - assert response.status_code == 200 - - assert json.loads(response.content) == default_settings - - -def test_update_settings(api_client: TestClient, api_routes: AppRoutes, default_settings, admin_token): - default_settings["language"] = "fr" - default_settings["showRecent"] = False - - response = api_client.put(api_routes.site_settings, json=default_settings, headers=admin_token) - - assert response.status_code == 200 - - response = api_client.get(api_routes.site_settings) - assert json.loads(response.content) == default_settings