remove unused imports, variables and commented code
from tests
This commit is contained in:
parent
78b1386a1c
commit
1f0cd58d7d
@ -1,8 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
from io import BytesIO
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from io import BytesIO
|
|
||||||
|
|
||||||
|
|
||||||
def rescale_image_jpeg(image_object, base_width=1020):
|
def rescale_image_jpeg(image_object, base_width=1020):
|
||||||
|
@ -116,12 +116,6 @@ class OpenDataImporter:
|
|||||||
self._update_slug_cache(Unit, 'unit')
|
self._update_slug_cache(Unit, 'unit')
|
||||||
self._update_slug_cache(PropertyType, 'property')
|
self._update_slug_cache(PropertyType, 'property')
|
||||||
|
|
||||||
# pref_unit_key = 'preferred_unit_metric'
|
|
||||||
# pref_shopping_unit_key = 'preferred_packaging_unit_metric'
|
|
||||||
# if not self.use_metric:
|
|
||||||
# pref_unit_key = 'preferred_unit_imperial'
|
|
||||||
# pref_shopping_unit_key = 'preferred_packaging_unit_imperial'
|
|
||||||
|
|
||||||
insert_list = []
|
insert_list = []
|
||||||
update_list = []
|
update_list = []
|
||||||
update_field_list = []
|
update_field_list = []
|
||||||
@ -130,8 +124,6 @@ class OpenDataImporter:
|
|||||||
insert_list.append({'data': {
|
insert_list.append({'data': {
|
||||||
'name': self.data[datatype][k]['name'],
|
'name': self.data[datatype][k]['name'],
|
||||||
'plural_name': self.data[datatype][k]['plural_name'] if self.data[datatype][k]['plural_name'] != '' else None,
|
'plural_name': self.data[datatype][k]['plural_name'] if self.data[datatype][k]['plural_name'] != '' else None,
|
||||||
# 'preferred_unit_id': self.slug_id_cache['unit'][self.data[datatype][k][pref_unit_key]],
|
|
||||||
# 'preferred_shopping_unit_id': self.slug_id_cache['unit'][self.data[datatype][k][pref_shopping_unit_key]],
|
|
||||||
'supermarket_category_id': self.slug_id_cache['category'][self.data[datatype][k]['store_category']],
|
'supermarket_category_id': self.slug_id_cache['category'][self.data[datatype][k]['store_category']],
|
||||||
'fdc_id': self.data[datatype][k]['fdc_id'] if self.data[datatype][k]['fdc_id'] != '' else None,
|
'fdc_id': self.data[datatype][k]['fdc_id'] if self.data[datatype][k]['fdc_id'] != '' else None,
|
||||||
'open_data_slug': k,
|
'open_data_slug': k,
|
||||||
@ -149,8 +141,6 @@ class OpenDataImporter:
|
|||||||
id=existing_food_id,
|
id=existing_food_id,
|
||||||
name=self.data[datatype][k]['name'],
|
name=self.data[datatype][k]['name'],
|
||||||
plural_name=self.data[datatype][k]['plural_name'] if self.data[datatype][k]['plural_name'] != '' else None,
|
plural_name=self.data[datatype][k]['plural_name'] if self.data[datatype][k]['plural_name'] != '' else None,
|
||||||
# preferred_unit_id=self.slug_id_cache['unit'][self.data[datatype][k][pref_unit_key]],
|
|
||||||
# preferred_shopping_unit_id=self.slug_id_cache['unit'][self.data[datatype][k][pref_shopping_unit_key]],
|
|
||||||
supermarket_category_id=self.slug_id_cache['category'][self.data[datatype][k]['store_category']],
|
supermarket_category_id=self.slug_id_cache['category'][self.data[datatype][k]['store_category']],
|
||||||
fdc_id=self.data[datatype][k]['fdc_id'] if self.data[datatype][k]['fdc_id'] != '' else None,
|
fdc_id=self.data[datatype][k]['fdc_id'] if self.data[datatype][k]['fdc_id'] != '' else None,
|
||||||
open_data_slug=k,
|
open_data_slug=k,
|
||||||
@ -189,7 +179,6 @@ class OpenDataImporter:
|
|||||||
|
|
||||||
FoodProperty.objects.bulk_create(property_food_relation_list, ignore_conflicts=True, unique_fields=('food_id', 'property_id',))
|
FoodProperty.objects.bulk_create(property_food_relation_list, ignore_conflicts=True, unique_fields=('food_id', 'property_id',))
|
||||||
|
|
||||||
# Automation.objects.bulk_create(alias_list, ignore_conflicts=True, unique_fields=('space', 'param_1', 'param_2',))
|
|
||||||
return insert_list + update_list
|
return insert_list + update_list
|
||||||
|
|
||||||
def import_conversion(self):
|
def import_conversion(self):
|
||||||
@ -197,7 +186,7 @@ class OpenDataImporter:
|
|||||||
|
|
||||||
insert_list = []
|
insert_list = []
|
||||||
for k in list(self.data[datatype].keys()):
|
for k in list(self.data[datatype].keys()):
|
||||||
# try catch here because somettimes key "k" is not set for he food cache
|
# try catch here because sometimes key "k" is not set for he food cache
|
||||||
try:
|
try:
|
||||||
insert_list.append(UnitConversion(
|
insert_list.append(UnitConversion(
|
||||||
base_amount=self.data[datatype][k]['base_amount'],
|
base_amount=self.data[datatype][k]['base_amount'],
|
||||||
|
@ -4,16 +4,16 @@ from django.conf import settings
|
|||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.decorators import user_passes_test
|
from django.contrib.auth.decorators import user_passes_test
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.core.exceptions import ValidationError, ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from oauth2_provider.contrib.rest_framework import TokenHasScope, TokenHasReadWriteScope
|
from oauth2_provider.contrib.rest_framework import TokenHasReadWriteScope, TokenHasScope
|
||||||
from oauth2_provider.models import AccessToken
|
from oauth2_provider.models import AccessToken
|
||||||
from rest_framework import permissions
|
from rest_framework import permissions
|
||||||
from rest_framework.permissions import SAFE_METHODS
|
from rest_framework.permissions import SAFE_METHODS
|
||||||
|
|
||||||
from cookbook.models import ShareLink, Recipe, UserSpace
|
from cookbook.models import Recipe, ShareLink, UserSpace
|
||||||
|
|
||||||
|
|
||||||
def get_allowed_groups(groups_required):
|
def get_allowed_groups(groups_required):
|
||||||
@ -255,9 +255,6 @@ class CustomIsShared(permissions.BasePermission):
|
|||||||
return request.user.is_authenticated
|
return request.user.is_authenticated
|
||||||
|
|
||||||
def has_object_permission(self, request, view, obj):
|
def has_object_permission(self, request, view, obj):
|
||||||
# # temporary hack to make old shopping list work with new shopping list
|
|
||||||
# if obj.__class__.__name__ in ['ShoppingList', 'ShoppingListEntry']:
|
|
||||||
# return is_object_shared(request.user, obj) or obj.created_by in list(request.user.get_shopping_share())
|
|
||||||
return is_object_shared(request.user, obj)
|
return is_object_shared(request.user, obj)
|
||||||
|
|
||||||
|
|
||||||
@ -322,7 +319,8 @@ class CustomRecipePermission(permissions.BasePermission):
|
|||||||
|
|
||||||
def has_permission(self, request, view): # user is either at least a guest or a share link is given and the request is safe
|
def has_permission(self, request, view): # user is either at least a guest or a share link is given and the request is safe
|
||||||
share = request.query_params.get('share', None)
|
share = request.query_params.get('share', None)
|
||||||
return ((has_group_permission(request.user, ['guest']) and request.method in SAFE_METHODS) or has_group_permission(request.user, ['user'])) or (share and request.method in SAFE_METHODS and 'pk' in view.kwargs)
|
return ((has_group_permission(request.user, ['guest']) and request.method in SAFE_METHODS) or has_group_permission(
|
||||||
|
request.user, ['user'])) or (share and request.method in SAFE_METHODS and 'pk' in view.kwargs)
|
||||||
|
|
||||||
def has_object_permission(self, request, view, obj):
|
def has_object_permission(self, request, view, obj):
|
||||||
share = request.query_params.get('share', None)
|
share = request.query_params.get('share', None)
|
||||||
@ -332,7 +330,8 @@ class CustomRecipePermission(permissions.BasePermission):
|
|||||||
if obj.private:
|
if obj.private:
|
||||||
return ((obj.created_by == request.user) or (request.user in obj.shared.all())) and obj.space == request.space
|
return ((obj.created_by == request.user) or (request.user in obj.shared.all())) and obj.space == request.space
|
||||||
else:
|
else:
|
||||||
return ((has_group_permission(request.user, ['guest']) and request.method in SAFE_METHODS) or has_group_permission(request.user, ['user'])) and obj.space == request.space
|
return ((has_group_permission(request.user, ['guest']) and request.method in SAFE_METHODS)
|
||||||
|
or has_group_permission(request.user, ['user'])) and obj.space == request.space
|
||||||
|
|
||||||
|
|
||||||
class CustomUserPermission(permissions.BasePermission):
|
class CustomUserPermission(permissions.BasePermission):
|
||||||
@ -361,7 +360,7 @@ class CustomTokenHasScope(TokenHasScope):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def has_permission(self, request, view):
|
def has_permission(self, request, view):
|
||||||
if type(request.auth) == AccessToken:
|
if isinstance(request.auth, AccessToken):
|
||||||
return super().has_permission(request, view)
|
return super().has_permission(request, view)
|
||||||
else:
|
else:
|
||||||
return request.user.is_authenticated
|
return request.user.is_authenticated
|
||||||
@ -375,7 +374,7 @@ class CustomTokenHasReadWriteScope(TokenHasReadWriteScope):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def has_permission(self, request, view):
|
def has_permission(self, request, view):
|
||||||
if type(request.auth) == AccessToken:
|
if isinstance(request.auth, AccessToken):
|
||||||
return super().has_permission(request, view)
|
return super().has_permission(request, view)
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
@ -14,7 +14,6 @@ from cookbook.models import (CookLog, CustomFilter, Food, Keyword, Recipe, Searc
|
|||||||
from recipes import settings
|
from recipes import settings
|
||||||
|
|
||||||
|
|
||||||
# TODO create extensive tests to make sure ORs ANDs and various filters, sorting, etc work as expected
|
|
||||||
# TODO consider creating a simpleListRecipe API that only includes minimum of recipe info and minimal filtering
|
# TODO consider creating a simpleListRecipe API that only includes minimum of recipe info and minimal filtering
|
||||||
class RecipeSearch():
|
class RecipeSearch():
|
||||||
_postgres = settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2', 'django.db.backends.postgresql']
|
_postgres = settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2', 'django.db.backends.postgresql']
|
||||||
@ -162,7 +161,7 @@ class RecipeSearch():
|
|||||||
else:
|
else:
|
||||||
order = []
|
order = []
|
||||||
# TODO add userpreference for default sort order and replace '-favorite'
|
# TODO add userpreference for default sort order and replace '-favorite'
|
||||||
default_order = ['-name']
|
default_order = ['name']
|
||||||
# recent and new_recipe are always first; they float a few recipes to the top
|
# recent and new_recipe are always first; they float a few recipes to the top
|
||||||
if self._num_recent:
|
if self._num_recent:
|
||||||
order += ['-recent']
|
order += ['-recent']
|
||||||
@ -580,218 +579,3 @@ class RecipeSearch():
|
|||||||
.annotate(sibling_onhand=Exists(sibling_onhand_subquery))
|
.annotate(sibling_onhand=Exists(sibling_onhand_subquery))
|
||||||
.filter(sibling_onhand=True)
|
.filter(sibling_onhand=True)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# class RecipeFacet():
|
|
||||||
# class CacheEmpty(Exception):
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# def __init__(self, request, queryset=None, hash_key=None, cache_timeout=3600):
|
|
||||||
# if hash_key is None and queryset is None:
|
|
||||||
# raise ValueError(_("One of queryset or hash_key must be provided"))
|
|
||||||
|
|
||||||
# self._request = request
|
|
||||||
# self._queryset = queryset
|
|
||||||
# self.hash_key = hash_key or str(hash(self._queryset.query))
|
|
||||||
# self._SEARCH_CACHE_KEY = f"recipes_filter_{self.hash_key}"
|
|
||||||
# self._cache_timeout = cache_timeout
|
|
||||||
# self._cache = caches['default'].get(self._SEARCH_CACHE_KEY, {})
|
|
||||||
# if self._cache is None and self._queryset is None:
|
|
||||||
# raise self.CacheEmpty("No queryset provided and cache empty")
|
|
||||||
|
|
||||||
# self.Keywords = self._cache.get('Keywords', None)
|
|
||||||
# self.Foods = self._cache.get('Foods', None)
|
|
||||||
# self.Books = self._cache.get('Books', None)
|
|
||||||
# self.Ratings = self._cache.get('Ratings', None)
|
|
||||||
# # TODO Move Recent to recipe annotation/serializer: requrires change in RecipeSearch(), RecipeSearchView.vue and serializer
|
|
||||||
# self.Recent = self._cache.get('Recent', None)
|
|
||||||
|
|
||||||
# if self._queryset is not None:
|
|
||||||
# self._recipe_list = list(
|
|
||||||
# self._queryset.values_list('id', flat=True))
|
|
||||||
# self._search_params = {
|
|
||||||
# 'keyword_list': self._request.query_params.getlist('keywords', []),
|
|
||||||
# 'food_list': self._request.query_params.getlist('foods', []),
|
|
||||||
# 'book_list': self._request.query_params.getlist('book', []),
|
|
||||||
# 'search_keywords_or': str2bool(self._request.query_params.get('keywords_or', True)),
|
|
||||||
# 'search_foods_or': str2bool(self._request.query_params.get('foods_or', True)),
|
|
||||||
# 'search_books_or': str2bool(self._request.query_params.get('books_or', True)),
|
|
||||||
# 'space': self._request.space,
|
|
||||||
# }
|
|
||||||
# elif self.hash_key is not None:
|
|
||||||
# self._recipe_list = self._cache.get('recipe_list', [])
|
|
||||||
# self._search_params = {
|
|
||||||
# 'keyword_list': self._cache.get('keyword_list', None),
|
|
||||||
# 'food_list': self._cache.get('food_list', None),
|
|
||||||
# 'book_list': self._cache.get('book_list', None),
|
|
||||||
# 'search_keywords_or': self._cache.get('search_keywords_or', None),
|
|
||||||
# 'search_foods_or': self._cache.get('search_foods_or', None),
|
|
||||||
# 'search_books_or': self._cache.get('search_books_or', None),
|
|
||||||
# 'space': self._cache.get('space', None),
|
|
||||||
# }
|
|
||||||
|
|
||||||
# self._cache = {
|
|
||||||
# **self._search_params,
|
|
||||||
# 'recipe_list': self._recipe_list,
|
|
||||||
# 'Ratings': self.Ratings,
|
|
||||||
# 'Recent': self.Recent,
|
|
||||||
# 'Keywords': self.Keywords,
|
|
||||||
# 'Foods': self.Foods,
|
|
||||||
# 'Books': self.Books
|
|
||||||
|
|
||||||
# }
|
|
||||||
# caches['default'].set(self._SEARCH_CACHE_KEY,
|
|
||||||
# self._cache, self._cache_timeout)
|
|
||||||
|
|
||||||
# def get_facets(self, from_cache=False):
|
|
||||||
# if from_cache:
|
|
||||||
# return {
|
|
||||||
# 'cache_key': self.hash_key or '',
|
|
||||||
# 'Ratings': self.Ratings or {},
|
|
||||||
# 'Recent': self.Recent or [],
|
|
||||||
# 'Keywords': self.Keywords or [],
|
|
||||||
# 'Foods': self.Foods or [],
|
|
||||||
# 'Books': self.Books or []
|
|
||||||
# }
|
|
||||||
# return {
|
|
||||||
# 'cache_key': self.hash_key,
|
|
||||||
# 'Ratings': self.get_ratings(),
|
|
||||||
# 'Recent': self.get_recent(),
|
|
||||||
# 'Keywords': self.get_keywords(),
|
|
||||||
# 'Foods': self.get_foods(),
|
|
||||||
# 'Books': self.get_books()
|
|
||||||
# }
|
|
||||||
|
|
||||||
# def set_cache(self, key, value):
|
|
||||||
# self._cache = {**self._cache, key: value}
|
|
||||||
# caches['default'].set(
|
|
||||||
# self._SEARCH_CACHE_KEY,
|
|
||||||
# self._cache,
|
|
||||||
# self._cache_timeout
|
|
||||||
# )
|
|
||||||
|
|
||||||
# def get_books(self):
|
|
||||||
# if self.Books is None:
|
|
||||||
# self.Books = []
|
|
||||||
# return self.Books
|
|
||||||
|
|
||||||
# def get_keywords(self):
|
|
||||||
# if self.Keywords is None:
|
|
||||||
# if self._search_params['search_keywords_or']:
|
|
||||||
# keywords = Keyword.objects.filter(
|
|
||||||
# space=self._request.space).distinct()
|
|
||||||
# else:
|
|
||||||
# keywords = Keyword.objects.filter(Q(recipe__in=self._recipe_list) | Q(
|
|
||||||
# depth=1)).filter(space=self._request.space).distinct()
|
|
||||||
|
|
||||||
# # set keywords to root objects only
|
|
||||||
# keywords = self._keyword_queryset(keywords)
|
|
||||||
# self.Keywords = [{**x, 'children': None}
|
|
||||||
# if x['numchild'] > 0 else x for x in list(keywords)]
|
|
||||||
# self.set_cache('Keywords', self.Keywords)
|
|
||||||
# return self.Keywords
|
|
||||||
|
|
||||||
# def get_foods(self):
|
|
||||||
# if self.Foods is None:
|
|
||||||
# # # if using an OR search, will annotate all keywords, otherwise, just those that appear in results
|
|
||||||
# if self._search_params['search_foods_or']:
|
|
||||||
# foods = Food.objects.filter(
|
|
||||||
# space=self._request.space).distinct()
|
|
||||||
# else:
|
|
||||||
# foods = Food.objects.filter(Q(ingredient__step__recipe__in=self._recipe_list) | Q(
|
|
||||||
# depth=1)).filter(space=self._request.space).distinct()
|
|
||||||
|
|
||||||
# # set keywords to root objects only
|
|
||||||
# foods = self._food_queryset(foods)
|
|
||||||
|
|
||||||
# self.Foods = [{**x, 'children': None}
|
|
||||||
# if x['numchild'] > 0 else x for x in list(foods)]
|
|
||||||
# self.set_cache('Foods', self.Foods)
|
|
||||||
# return self.Foods
|
|
||||||
|
|
||||||
# def get_ratings(self):
|
|
||||||
# if self.Ratings is None:
|
|
||||||
# if not self._request.space.demo and self._request.space.show_facet_count:
|
|
||||||
# if self._queryset is None:
|
|
||||||
# self._queryset = Recipe.objects.filter(
|
|
||||||
# id__in=self._recipe_list)
|
|
||||||
# rating_qs = self._queryset.annotate(rating=Round(Avg(Case(When(
|
|
||||||
# cooklog__created_by=self._request.user, then='cooklog__rating'), default=Value(0)))))
|
|
||||||
# self.Ratings = dict(Counter(r.rating for r in rating_qs))
|
|
||||||
# else:
|
|
||||||
# self.Rating = {}
|
|
||||||
# self.set_cache('Ratings', self.Ratings)
|
|
||||||
# return self.Ratings
|
|
||||||
|
|
||||||
# def get_recent(self):
|
|
||||||
# if self.Recent is None:
|
|
||||||
# # TODO make days of recent recipe a setting
|
|
||||||
# recent_recipes = ViewLog.objects.filter(created_by=self._request.user, space=self._request.space, created_at__gte=timezone.now() - timedelta(days=14)
|
|
||||||
# ).values_list('recipe__pk', flat=True)
|
|
||||||
# self.Recent = list(recent_recipes)
|
|
||||||
# self.set_cache('Recent', self.Recent)
|
|
||||||
# return self.Recent
|
|
||||||
|
|
||||||
# def add_food_children(self, id):
|
|
||||||
# try:
|
|
||||||
# food = Food.objects.get(id=id)
|
|
||||||
# nodes = food.get_ancestors()
|
|
||||||
# except Food.DoesNotExist:
|
|
||||||
# return self.get_facets()
|
|
||||||
# foods = self._food_queryset(food.get_children(), food)
|
|
||||||
# deep_search = self.Foods
|
|
||||||
# for node in nodes:
|
|
||||||
# index = next((i for i, x in enumerate(
|
|
||||||
# deep_search) if x["id"] == node.id), None)
|
|
||||||
# deep_search = deep_search[index]['children']
|
|
||||||
# index = next((i for i, x in enumerate(
|
|
||||||
# deep_search) if x["id"] == food.id), None)
|
|
||||||
# deep_search[index]['children'] = [
|
|
||||||
# {**x, 'children': None} if x['numchild'] > 0 else x for x in list(foods)]
|
|
||||||
# self.set_cache('Foods', self.Foods)
|
|
||||||
# return self.get_facets()
|
|
||||||
|
|
||||||
# def add_keyword_children(self, id):
|
|
||||||
# try:
|
|
||||||
# keyword = Keyword.objects.get(id=id)
|
|
||||||
# nodes = keyword.get_ancestors()
|
|
||||||
# except Keyword.DoesNotExist:
|
|
||||||
# return self.get_facets()
|
|
||||||
# keywords = self._keyword_queryset(keyword.get_children(), keyword)
|
|
||||||
# deep_search = self.Keywords
|
|
||||||
# for node in nodes:
|
|
||||||
# index = next((i for i, x in enumerate(
|
|
||||||
# deep_search) if x["id"] == node.id), None)
|
|
||||||
# deep_search = deep_search[index]['children']
|
|
||||||
# index = next((i for i, x in enumerate(deep_search)
|
|
||||||
# if x["id"] == keyword.id), None)
|
|
||||||
# deep_search[index]['children'] = [
|
|
||||||
# {**x, 'children': None} if x['numchild'] > 0 else x for x in list(keywords)]
|
|
||||||
# self.set_cache('Keywords', self.Keywords)
|
|
||||||
# return self.get_facets()
|
|
||||||
|
|
||||||
# def _recipe_count_queryset(self, field, depth=1, steplen=4):
|
|
||||||
# return Recipe.objects.filter(**{f'{field}__path__startswith': OuterRef('path'), f'{field}__depth__gte': depth}, id__in=self._recipe_list, space=self._request.space
|
|
||||||
# ).annotate(count=Coalesce(Func('pk', function='Count'), 0)).values('count')
|
|
||||||
|
|
||||||
# def _keyword_queryset(self, queryset, keyword=None):
|
|
||||||
# depth = getattr(keyword, 'depth', 0) + 1
|
|
||||||
# steplen = depth * Keyword.steplen
|
|
||||||
|
|
||||||
# if not self._request.space.demo and self._request.space.show_facet_count:
|
|
||||||
# return queryset.annotate(count=Coalesce(Subquery(self._recipe_count_queryset('keywords', depth, steplen)), 0)
|
|
||||||
# ).filter(depth=depth, count__gt=0
|
|
||||||
# ).values('id', 'name', 'count', 'numchild').order_by(Lower('name').asc())[:200]
|
|
||||||
# else:
|
|
||||||
# return queryset.filter(depth=depth).values('id', 'name', 'numchild').order_by(Lower('name').asc())
|
|
||||||
|
|
||||||
# def _food_queryset(self, queryset, food=None):
|
|
||||||
# depth = getattr(food, 'depth', 0) + 1
|
|
||||||
# steplen = depth * Food.steplen
|
|
||||||
|
|
||||||
# if not self._request.space.demo and self._request.space.show_facet_count:
|
|
||||||
# return queryset.annotate(count=Coalesce(Subquery(self._recipe_count_queryset('steps__ingredients__food', depth, steplen)), 0)
|
|
||||||
# ).filter(depth__lte=depth, count__gt=0
|
|
||||||
# ).values('id', 'name', 'count', 'numchild').order_by(Lower('name').asc())[:200]
|
|
||||||
# else:
|
|
||||||
# return queryset.filter(depth__lte=depth).values('id', 'name', 'numchild').order_by(Lower('name').asc())
|
|
||||||
|
@ -408,16 +408,6 @@ def parse_time(recipe_time):
|
|||||||
def parse_keywords(keyword_json, request):
|
def parse_keywords(keyword_json, request):
|
||||||
keywords = []
|
keywords = []
|
||||||
automation_engine = AutomationEngine(request)
|
automation_engine = AutomationEngine(request)
|
||||||
# keyword_aliases = {}
|
|
||||||
# retrieve keyword automation cache if it exists, otherwise build from database
|
|
||||||
# KEYWORD_CACHE_KEY = f'automation_keyword_alias_{space.pk}'
|
|
||||||
# if c := caches['default'].get(KEYWORD_CACHE_KEY, None):
|
|
||||||
# keyword_aliases = c
|
|
||||||
# caches['default'].touch(KEYWORD_CACHE_KEY, 30)
|
|
||||||
# else:
|
|
||||||
# for a in Automation.objects.filter(space=space, disabled=False, type=Automation.KEYWORD_ALIAS).only('param_1', 'param_2').order_by('order').all():
|
|
||||||
# keyword_aliases[a.param_1.lower()] = a.param_2
|
|
||||||
# caches['default'].set(KEYWORD_CACHE_KEY, keyword_aliases, 30)
|
|
||||||
|
|
||||||
# keywords as list
|
# keywords as list
|
||||||
for kw in keyword_json:
|
for kw in keyword_json:
|
||||||
@ -425,11 +415,6 @@ def parse_keywords(keyword_json, request):
|
|||||||
# if alias exists use that instead
|
# if alias exists use that instead
|
||||||
|
|
||||||
if len(kw) != 0:
|
if len(kw) != 0:
|
||||||
# if keyword_aliases:
|
|
||||||
# try:
|
|
||||||
# kw = keyword_aliases[kw.lower()]
|
|
||||||
# except KeyError:
|
|
||||||
# pass
|
|
||||||
automation_engine.apply_keyword_automation(kw)
|
automation_engine.apply_keyword_automation(kw)
|
||||||
if k := Keyword.objects.filter(name=kw, space=request.space).first():
|
if k := Keyword.objects.filter(name=kw, space=request.space).first():
|
||||||
keywords.append({'label': str(k), 'name': k.name, 'id': k.id})
|
keywords.append({'label': str(k), 'name': k.name, 'id': k.id})
|
||||||
|
@ -48,7 +48,6 @@ class ScopeMiddleware:
|
|||||||
return views.no_groups(request)
|
return views.no_groups(request)
|
||||||
|
|
||||||
request.space = user_space.space
|
request.space = user_space.space
|
||||||
# with scopes_disabled():
|
|
||||||
with scope(space=request.space):
|
with scope(space=request.space):
|
||||||
return self.get_response(request)
|
return self.get_response(request)
|
||||||
else:
|
else:
|
||||||
|
@ -198,120 +198,3 @@ class RecipeShoppingEditor():
|
|||||||
to_delete = self._shopping_list_recipe.entries.exclude(ingredient__in=ingredients)
|
to_delete = self._shopping_list_recipe.entries.exclude(ingredient__in=ingredients)
|
||||||
ShoppingListEntry.objects.filter(id__in=to_delete).delete()
|
ShoppingListEntry.objects.filter(id__in=to_delete).delete()
|
||||||
self._shopping_list_recipe = self.get_shopping_list_recipe(self.id, self.created_by, self.space)
|
self._shopping_list_recipe = self.get_shopping_list_recipe(self.id, self.created_by, self.space)
|
||||||
|
|
||||||
|
|
||||||
# # TODO refactor as class
|
|
||||||
# def list_from_recipe(list_recipe=None, recipe=None, mealplan=None, servings=None, ingredients=None, created_by=None, space=None, append=False):
|
|
||||||
# """
|
|
||||||
# Creates ShoppingListRecipe and associated ShoppingListEntrys from a recipe or a meal plan with a recipe
|
|
||||||
# :param list_recipe: Modify an existing ShoppingListRecipe
|
|
||||||
# :param recipe: Recipe to use as list of ingredients. One of [recipe, mealplan] are required
|
|
||||||
# :param mealplan: alternatively use a mealplan recipe as source of ingredients
|
|
||||||
# :param servings: Optional: Number of servings to use to scale shoppinglist. If servings = 0 an existing recipe list will be deleted
|
|
||||||
# :param ingredients: Ingredients, list of ingredient IDs to include on the shopping list. When not provided all ingredients will be used
|
|
||||||
# :param append: If False will remove any entries not included with ingredients, when True will append ingredients to the shopping list
|
|
||||||
# """
|
|
||||||
# r = recipe or getattr(mealplan, 'recipe', None) or getattr(list_recipe, 'recipe', None)
|
|
||||||
# if not r:
|
|
||||||
# raise ValueError(_("You must supply a recipe or mealplan"))
|
|
||||||
|
|
||||||
# created_by = created_by or getattr(ShoppingListEntry.objects.filter(list_recipe=list_recipe).first(), 'created_by', None)
|
|
||||||
# if not created_by:
|
|
||||||
# raise ValueError(_("You must supply a created_by"))
|
|
||||||
|
|
||||||
# try:
|
|
||||||
# servings = float(servings)
|
|
||||||
# except (ValueError, TypeError):
|
|
||||||
# servings = getattr(mealplan, 'servings', 1.0)
|
|
||||||
|
|
||||||
# servings_factor = servings / r.servings
|
|
||||||
|
|
||||||
# shared_users = list(created_by.get_shopping_share())
|
|
||||||
# shared_users.append(created_by)
|
|
||||||
# if list_recipe:
|
|
||||||
# created = False
|
|
||||||
# else:
|
|
||||||
# list_recipe = ShoppingListRecipe.objects.create(recipe=r, mealplan=mealplan, servings=servings)
|
|
||||||
# created = True
|
|
||||||
|
|
||||||
# related_step_ing = []
|
|
||||||
# if servings == 0 and not created:
|
|
||||||
# list_recipe.delete()
|
|
||||||
# return []
|
|
||||||
# elif ingredients:
|
|
||||||
# ingredients = Ingredient.objects.filter(pk__in=ingredients, space=space)
|
|
||||||
# else:
|
|
||||||
# ingredients = Ingredient.objects.filter(step__recipe=r, food__ignore_shopping=False, space=space)
|
|
||||||
|
|
||||||
# if exclude_onhand := created_by.userpreference.mealplan_autoexclude_onhand:
|
|
||||||
# ingredients = ingredients.exclude(food__onhand_users__id__in=[x.id for x in shared_users])
|
|
||||||
|
|
||||||
# if related := created_by.userpreference.mealplan_autoinclude_related:
|
|
||||||
# # TODO: add levels of related recipes (related recipes of related recipes) to use when auto-adding mealplans
|
|
||||||
# related_recipes = r.get_related_recipes()
|
|
||||||
|
|
||||||
# for x in related_recipes:
|
|
||||||
# # related recipe is a Step serving size is driven by recipe serving size
|
|
||||||
# # TODO once/if Steps can have a serving size this needs to be refactored
|
|
||||||
# if exclude_onhand:
|
|
||||||
# # if steps are used more than once in a recipe or subrecipe - I don' think this results in the desired behavior
|
|
||||||
# related_step_ing += Ingredient.objects.filter(step__recipe=x, space=space).exclude(food__onhand_users__id__in=[x.id for x in shared_users]).values_list('id', flat=True)
|
|
||||||
# else:
|
|
||||||
# related_step_ing += Ingredient.objects.filter(step__recipe=x, space=space).values_list('id', flat=True)
|
|
||||||
|
|
||||||
# x_ing = []
|
|
||||||
# if ingredients.filter(food__recipe=x).exists():
|
|
||||||
# for ing in ingredients.filter(food__recipe=x):
|
|
||||||
# if exclude_onhand:
|
|
||||||
# x_ing = Ingredient.objects.filter(step__recipe=x, food__ignore_shopping=False, space=space).exclude(food__onhand_users__id__in=[x.id for x in shared_users])
|
|
||||||
# else:
|
|
||||||
# x_ing = Ingredient.objects.filter(step__recipe=x, food__ignore_shopping=False, space=space).exclude(food__ignore_shopping=True)
|
|
||||||
# for i in [x for x in x_ing]:
|
|
||||||
# ShoppingListEntry.objects.create(
|
|
||||||
# list_recipe=list_recipe,
|
|
||||||
# food=i.food,
|
|
||||||
# unit=i.unit,
|
|
||||||
# ingredient=i,
|
|
||||||
# amount=i.amount * Decimal(servings_factor),
|
|
||||||
# created_by=created_by,
|
|
||||||
# space=space,
|
|
||||||
# )
|
|
||||||
# # dont' add food to the shopping list that are actually recipes that will be added as ingredients
|
|
||||||
# ingredients = ingredients.exclude(food__recipe=x)
|
|
||||||
|
|
||||||
# add_ingredients = list(ingredients.values_list('id', flat=True)) + related_step_ing
|
|
||||||
# if not append:
|
|
||||||
# existing_list = ShoppingListEntry.objects.filter(list_recipe=list_recipe)
|
|
||||||
# # delete shopping list entries not included in ingredients
|
|
||||||
# existing_list.exclude(ingredient__in=ingredients).delete()
|
|
||||||
# # add shopping list entries that did not previously exist
|
|
||||||
# add_ingredients = set(add_ingredients) - set(existing_list.values_list('ingredient__id', flat=True))
|
|
||||||
# add_ingredients = Ingredient.objects.filter(id__in=add_ingredients, space=space)
|
|
||||||
|
|
||||||
# # if servings have changed, update the ShoppingListRecipe and existing Entries
|
|
||||||
# if servings <= 0:
|
|
||||||
# servings = 1
|
|
||||||
|
|
||||||
# if not created and list_recipe.servings != servings:
|
|
||||||
# update_ingredients = set(ingredients.values_list('id', flat=True)) - set(add_ingredients.values_list('id', flat=True))
|
|
||||||
# list_recipe.servings = servings
|
|
||||||
# list_recipe.save()
|
|
||||||
# for sle in ShoppingListEntry.objects.filter(list_recipe=list_recipe, ingredient__id__in=update_ingredients):
|
|
||||||
# sle.amount = sle.ingredient.amount * Decimal(servings_factor)
|
|
||||||
# sle.save()
|
|
||||||
|
|
||||||
# # add any missing Entries
|
|
||||||
# for i in [x for x in add_ingredients if x.food]:
|
|
||||||
|
|
||||||
# ShoppingListEntry.objects.create(
|
|
||||||
# list_recipe=list_recipe,
|
|
||||||
# food=i.food,
|
|
||||||
# unit=i.unit,
|
|
||||||
# ingredient=i,
|
|
||||||
# amount=i.amount * Decimal(servings_factor),
|
|
||||||
# created_by=created_by,
|
|
||||||
# space=space,
|
|
||||||
# )
|
|
||||||
|
|
||||||
# # return all shopping list items
|
|
||||||
# return list_recipe
|
|
||||||
|
@ -2,13 +2,14 @@ import json
|
|||||||
import re
|
import re
|
||||||
from io import BytesIO, StringIO
|
from io import BytesIO, StringIO
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from cookbook.helper.image_processing import get_filetype
|
from cookbook.helper.image_processing import get_filetype
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.helper.recipe_url_import import iso_duration_to_minutes
|
from cookbook.helper.recipe_url_import import iso_duration_to_minutes
|
||||||
from cookbook.integration.integration import Integration
|
from cookbook.integration.integration import Integration
|
||||||
from cookbook.models import Ingredient, Keyword, Recipe, Step, NutritionInformation
|
from cookbook.models import Ingredient, Keyword, NutritionInformation, Recipe, Step
|
||||||
|
|
||||||
|
|
||||||
class NextcloudCookbook(Integration):
|
class NextcloudCookbook(Integration):
|
||||||
@ -51,7 +52,6 @@ class NextcloudCookbook(Integration):
|
|||||||
|
|
||||||
ingredients_added = False
|
ingredients_added = False
|
||||||
for s in recipe_json['recipeInstructions']:
|
for s in recipe_json['recipeInstructions']:
|
||||||
instruction_text = ''
|
|
||||||
if 'text' in s:
|
if 'text' in s:
|
||||||
step = Step.objects.create(
|
step = Step.objects.create(
|
||||||
instruction=s['text'], name=s['name'], space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
|
instruction=s['text'], name=s['name'], space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
|
||||||
@ -91,7 +91,7 @@ class NextcloudCookbook(Integration):
|
|||||||
if nutrition != {}:
|
if nutrition != {}:
|
||||||
recipe.nutrition = NutritionInformation.objects.create(**nutrition, space=self.request.space)
|
recipe.nutrition = NutritionInformation.objects.create(**nutrition, space=self.request.space)
|
||||||
recipe.save()
|
recipe.save()
|
||||||
except Exception as e:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
for f in self.files:
|
for f in self.files:
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
from cookbook.integration.integration import Integration
|
||||||
from cookbook.models import Ingredient, Recipe, Step, Keyword, Comment, CookLog
|
from cookbook.models import Comment, CookLog, Ingredient, Keyword, Recipe, Step
|
||||||
from django.utils.translation import gettext as _
|
|
||||||
|
|
||||||
class OpenEats(Integration):
|
class OpenEats(Integration):
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ class Paprika(Integration):
|
|||||||
if validators.url(url, public=True):
|
if validators.url(url, public=True):
|
||||||
response = requests.get(url)
|
response = requests.get(url)
|
||||||
self.import_recipe_image(recipe, BytesIO(response.content))
|
self.import_recipe_image(recipe, BytesIO(response.content))
|
||||||
except:
|
except Exception:
|
||||||
if recipe_json.get("photo_data", None):
|
if recipe_json.get("photo_data", None):
|
||||||
self.import_recipe_image(recipe, BytesIO(base64.b64decode(recipe_json['photo_data'])), filetype='.jpeg')
|
self.import_recipe_image(recipe, BytesIO(base64.b64decode(recipe_json['photo_data'])), filetype='.jpeg')
|
||||||
|
|
||||||
|
@ -1,21 +1,11 @@
|
|||||||
import json
|
|
||||||
from io import BytesIO
|
|
||||||
from re import match
|
|
||||||
from zipfile import ZipFile
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from pyppeteer import launch
|
|
||||||
|
|
||||||
from rest_framework.renderers import JSONRenderer
|
|
||||||
|
|
||||||
from cookbook.helper.image_processing import get_filetype
|
|
||||||
from cookbook.integration.integration import Integration
|
|
||||||
from cookbook.serializer import RecipeExportSerializer
|
|
||||||
|
|
||||||
from cookbook.models import ExportLog
|
|
||||||
from asgiref.sync import sync_to_async
|
|
||||||
|
|
||||||
import django.core.management.commands.runserver as runserver
|
import django.core.management.commands.runserver as runserver
|
||||||
import logging
|
from asgiref.sync import sync_to_async
|
||||||
|
from pyppeteer import launch
|
||||||
|
|
||||||
|
from cookbook.integration.integration import Integration
|
||||||
|
|
||||||
|
|
||||||
class PDFexport(Integration):
|
class PDFexport(Integration):
|
||||||
|
|
||||||
@ -42,7 +32,6 @@ class PDFexport(Integration):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
files = []
|
files = []
|
||||||
for recipe in recipes:
|
for recipe in recipes:
|
||||||
|
|
||||||
@ -50,20 +39,18 @@ class PDFexport(Integration):
|
|||||||
await page.emulateMedia('print')
|
await page.emulateMedia('print')
|
||||||
await page.setCookie(cookies)
|
await page.setCookie(cookies)
|
||||||
|
|
||||||
await page.goto('http://'+cmd.default_addr+':'+cmd.default_port+'/view/recipe/'+str(recipe.id), {'waitUntil': 'domcontentloaded'})
|
await page.goto('http://' + cmd.default_addr + ':' + cmd.default_port + '/view/recipe/' + str(recipe.id), {'waitUntil': 'domcontentloaded'})
|
||||||
await page.waitForSelector('#printReady');
|
await page.waitForSelector('#printReady')
|
||||||
|
|
||||||
files.append([recipe.name + '.pdf', await page.pdf(options)])
|
files.append([recipe.name + '.pdf', await page.pdf(options)])
|
||||||
await page.close();
|
await page.close()
|
||||||
|
|
||||||
el.exported_recipes += 1
|
el.exported_recipes += 1
|
||||||
el.msg += self.get_recipe_processed_msg(recipe)
|
el.msg += self.get_recipe_processed_msg(recipe)
|
||||||
await sync_to_async(el.save, thread_sensitive=True)()
|
await sync_to_async(el.save, thread_sensitive=True)()
|
||||||
|
|
||||||
|
|
||||||
await browser.close()
|
await browser.close()
|
||||||
return files
|
return files
|
||||||
|
|
||||||
|
|
||||||
def get_files_from_recipes(self, recipes, el, cookie):
|
def get_files_from_recipes(self, recipes, el, cookie):
|
||||||
return asyncio.run(self.get_files_from_recipes_async(recipes, el, cookie))
|
return asyncio.run(self.get_files_from_recipes_async(recipes, el, cookie))
|
||||||
|
@ -2,12 +2,10 @@ import base64
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from xml import etree
|
from xml import etree
|
||||||
|
|
||||||
from lxml import etree
|
|
||||||
|
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.helper.recipe_url_import import parse_time, parse_servings, parse_servings_text
|
from cookbook.helper.recipe_url_import import parse_servings, parse_servings_text
|
||||||
from cookbook.integration.integration import Integration
|
from cookbook.integration.integration import Integration
|
||||||
from cookbook.models import Ingredient, Recipe, Step, Keyword
|
from cookbook.models import Ingredient, Keyword, Recipe, Step
|
||||||
|
|
||||||
|
|
||||||
class Rezeptsuitede(Integration):
|
class Rezeptsuitede(Integration):
|
||||||
@ -61,14 +59,14 @@ class Rezeptsuitede(Integration):
|
|||||||
try:
|
try:
|
||||||
k, created = Keyword.objects.get_or_create(name=recipe_xml.find('head').find('cat').text.strip(), space=self.request.space)
|
k, created = Keyword.objects.get_or_create(name=recipe_xml.find('head').find('cat').text.strip(), space=self.request.space)
|
||||||
recipe.keywords.add(k)
|
recipe.keywords.add(k)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
recipe.save()
|
recipe.save()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.import_recipe_image(recipe, BytesIO(base64.b64decode(recipe_xml.find('head').find('picbin').text)), filetype='.jpeg')
|
self.import_recipe_image(recipe, BytesIO(base64.b64decode(recipe_xml.find('head').find('picbin').text)), filetype='.jpeg')
|
||||||
except:
|
except BaseException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return recipe
|
return recipe
|
||||||
|
@ -60,8 +60,8 @@ class RezKonv(Integration):
|
|||||||
def split_recipe_file(self, file):
|
def split_recipe_file(self, file):
|
||||||
recipe_list = []
|
recipe_list = []
|
||||||
current_recipe = ''
|
current_recipe = ''
|
||||||
encoding_list = ['windows-1250',
|
# TODO build algorithm to try trough encodings and fail if none work, use for all importers
|
||||||
'latin-1'] # TODO build algorithm to try trough encodings and fail if none work, use for all importers
|
# encoding_list = ['windows-1250', 'latin-1']
|
||||||
encoding = 'windows-1250'
|
encoding = 'windows-1250'
|
||||||
for fl in file.readlines():
|
for fl in file.readlines():
|
||||||
try:
|
try:
|
||||||
|
@ -59,11 +59,11 @@ class Saffron(Integration):
|
|||||||
|
|
||||||
def get_file_from_recipe(self, recipe):
|
def get_file_from_recipe(self, recipe):
|
||||||
|
|
||||||
data = "Title: "+recipe.name if recipe.name else ""+"\n"
|
data = "Title: " + recipe.name if recipe.name else "" + "\n"
|
||||||
data += "Description: "+recipe.description if recipe.description else ""+"\n"
|
data += "Description: " + recipe.description if recipe.description else "" + "\n"
|
||||||
data += "Source: \n"
|
data += "Source: \n"
|
||||||
data += "Original URL: \n"
|
data += "Original URL: \n"
|
||||||
data += "Yield: "+str(recipe.servings)+"\n"
|
data += "Yield: " + str(recipe.servings) + "\n"
|
||||||
data += "Cookbook: \n"
|
data += "Cookbook: \n"
|
||||||
data += "Section: \n"
|
data += "Section: \n"
|
||||||
data += "Image: \n"
|
data += "Image: \n"
|
||||||
@ -78,13 +78,13 @@ class Saffron(Integration):
|
|||||||
|
|
||||||
data += "Ingredients: \n"
|
data += "Ingredients: \n"
|
||||||
for ingredient in recipeIngredient:
|
for ingredient in recipeIngredient:
|
||||||
data += ingredient+"\n"
|
data += ingredient + "\n"
|
||||||
|
|
||||||
data += "Instructions: \n"
|
data += "Instructions: \n"
|
||||||
for instruction in recipeInstructions:
|
for instruction in recipeInstructions:
|
||||||
data += instruction+"\n"
|
data += instruction + "\n"
|
||||||
|
|
||||||
return recipe.name+'.txt', data
|
return recipe.name + '.txt', data
|
||||||
|
|
||||||
def get_files_from_recipes(self, recipes, el, cookie):
|
def get_files_from_recipes(self, recipes, el, cookie):
|
||||||
files = []
|
files = []
|
||||||
|
@ -1294,7 +1294,7 @@ class UserFile(ExportModelOperationsMixin('user_files'), models.Model, Permissio
|
|||||||
|
|
||||||
def is_image(self):
|
def is_image(self):
|
||||||
try:
|
try:
|
||||||
img = Image.open(self.file.file.file)
|
Image.open(self.file.file.file)
|
||||||
return True
|
return True
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
|
@ -208,7 +208,7 @@ class UserFileSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
def get_preview_link(self, obj):
|
def get_preview_link(self, obj):
|
||||||
try:
|
try:
|
||||||
img = Image.open(obj.file.file.file)
|
Image.open(obj.file.file.file)
|
||||||
return self.context['request'].build_absolute_uri(obj.file.url)
|
return self.context['request'].build_absolute_uri(obj.file.url)
|
||||||
except Exception:
|
except Exception:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
@ -256,7 +256,7 @@ class UserFileViewSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
def get_preview_link(self, obj):
|
def get_preview_link(self, obj):
|
||||||
try:
|
try:
|
||||||
img = Image.open(obj.file.file.file)
|
Image.open(obj.file.file.file)
|
||||||
return self.context['request'].build_absolute_uri(obj.file.url)
|
return self.context['request'].build_absolute_uri(obj.file.url)
|
||||||
except Exception:
|
except Exception:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
@ -7,8 +7,6 @@ from django.utils import timezone
|
|||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
from oauth2_provider.models import AccessToken
|
from oauth2_provider.models import AccessToken
|
||||||
|
|
||||||
from cookbook.models import ViewLog
|
|
||||||
|
|
||||||
LIST_URL = 'api:accesstoken-list'
|
LIST_URL = 'api:accesstoken-list'
|
||||||
DETAIL_URL = 'api:accesstoken-detail'
|
DETAIL_URL = 'api:accesstoken-detail'
|
||||||
|
|
||||||
|
@ -35,11 +35,6 @@ register(FoodFactory, 'obj_3', space=LazyFixture('space_2'))
|
|||||||
register(SupermarketCategoryFactory, 'cat_1', space=LazyFixture('space_1'))
|
register(SupermarketCategoryFactory, 'cat_1', space=LazyFixture('space_1'))
|
||||||
|
|
||||||
|
|
||||||
# @pytest.fixture
|
|
||||||
# def true():
|
|
||||||
# return True
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def false():
|
def false():
|
||||||
return False
|
return False
|
||||||
|
@ -1,13 +1,3 @@
|
|||||||
# test create
|
|
||||||
# test create units
|
|
||||||
# test amounts
|
|
||||||
# test create wrong space
|
|
||||||
# test sharing
|
|
||||||
# test delete
|
|
||||||
# test delete checked (nothing should happen)
|
|
||||||
# test delete not shared (nothing happens)
|
|
||||||
# test delete shared
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@ -15,7 +5,6 @@ from django.contrib import auth
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scope, scopes_disabled
|
from django_scopes import scope, scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import Food, ShoppingListEntry
|
|
||||||
from cookbook.tests.factories import FoodFactory
|
from cookbook.tests.factories import FoodFactory
|
||||||
|
|
||||||
SHOPPING_LIST_URL = 'api:shoppinglistentry-list'
|
SHOPPING_LIST_URL = 'api:shoppinglistentry-list'
|
||||||
@ -80,8 +69,8 @@ def test_shopping_food_share(u1_s1, u2_s1, food, space_1):
|
|||||||
user1 = auth.get_user(u1_s1)
|
user1 = auth.get_user(u1_s1)
|
||||||
user2 = auth.get_user(u2_s1)
|
user2 = auth.get_user(u2_s1)
|
||||||
food2 = FoodFactory(space=space_1)
|
food2 = FoodFactory(space=space_1)
|
||||||
r = u1_s1.put(reverse(SHOPPING_FOOD_URL, args={food.id}))
|
u1_s1.put(reverse(SHOPPING_FOOD_URL, args={food.id}))
|
||||||
r = u2_s1.put(reverse(SHOPPING_FOOD_URL, args={food2.id}))
|
u2_s1.put(reverse(SHOPPING_FOOD_URL, args={food2.id}))
|
||||||
sl_1 = json.loads(u1_s1.get(reverse(SHOPPING_LIST_URL)).content)
|
sl_1 = json.loads(u1_s1.get(reverse(SHOPPING_LIST_URL)).content)
|
||||||
sl_2 = json.loads(u2_s1.get(reverse(SHOPPING_LIST_URL)).content)
|
sl_2 = json.loads(u2_s1.get(reverse(SHOPPING_LIST_URL)).content)
|
||||||
assert len(sl_1) == 1
|
assert len(sl_1) == 1
|
||||||
|
@ -2,13 +2,10 @@ import json
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.contrib.auth.models import AnonymousUser
|
|
||||||
from django.db.models import OuterRef, Subquery
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
from cookbook.helper.permission_helper import switch_user_active_space
|
from cookbook.models import InviteLink
|
||||||
from cookbook.models import Ingredient, Step, InviteLink, UserSpace
|
|
||||||
|
|
||||||
LIST_URL = 'api:invitelink-list'
|
LIST_URL = 'api:invitelink-list'
|
||||||
DETAIL_URL = 'api:invitelink-detail'
|
DETAIL_URL = 'api:invitelink-detail'
|
||||||
|
@ -25,6 +25,7 @@ if (Keyword.node_order_by):
|
|||||||
else:
|
else:
|
||||||
node_location = 'last-child'
|
node_location = 'last-child'
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def obj_1(space_1):
|
def obj_1(space_1):
|
||||||
return Keyword.objects.get_or_create(name='test_1', space=space_1)[0]
|
return Keyword.objects.get_or_create(name='test_1', space=space_1)[0]
|
||||||
|
@ -6,7 +6,7 @@ from django.contrib import auth
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scope, scopes_disabled
|
from django_scopes import scope, scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import Food, MealPlan, MealType
|
from cookbook.models import MealPlan, MealType
|
||||||
from cookbook.tests.factories import RecipeFactory
|
from cookbook.tests.factories import RecipeFactory
|
||||||
|
|
||||||
LIST_URL = 'api:mealplan-list'
|
LIST_URL = 'api:mealplan-list'
|
||||||
@ -149,7 +149,7 @@ def test_add_with_shopping(u1_s1, meal_type):
|
|||||||
space = meal_type.space
|
space = meal_type.space
|
||||||
with scope(space=space):
|
with scope(space=space):
|
||||||
recipe = RecipeFactory.create(space=space)
|
recipe = RecipeFactory.create(space=space)
|
||||||
r = u1_s1.post(
|
u1_s1.post(
|
||||||
reverse(LIST_URL),
|
reverse(LIST_URL),
|
||||||
{'recipe': {'id': recipe.id, 'name': recipe.name, 'keywords': []}, 'meal_type': {'id': meal_type.id, 'name': meal_type.name},
|
{'recipe': {'id': recipe.id, 'name': recipe.name, 'keywords': []}, 'meal_type': {'id': meal_type.id, 'name': meal_type.name},
|
||||||
'from_date': (datetime.now()).strftime("%Y-%m-%d"), 'to_date': (datetime.now()).strftime("%Y-%m-%d"), 'servings': 1, 'title': 'test', 'shared': [], 'addshopping': True},
|
'from_date': (datetime.now()).strftime("%Y-%m-%d"), 'to_date': (datetime.now()).strftime("%Y-%m-%d"), 'servings': 1, 'title': 'test', 'shared': [], 'addshopping': True},
|
||||||
|
@ -5,7 +5,7 @@ from django.contrib import auth
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import Food, MealType
|
from cookbook.models import MealType
|
||||||
|
|
||||||
LIST_URL = 'api:mealtype-list'
|
LIST_URL = 'api:mealtype-list'
|
||||||
DETAIL_URL = 'api:mealtype-detail'
|
DETAIL_URL = 'api:mealtype-detail'
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.contrib import auth
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import Food, MealType, PropertyType, Property
|
from cookbook.models import MealType, Property, PropertyType
|
||||||
|
|
||||||
LIST_URL = 'api:property-list'
|
LIST_URL = 'api:property-list'
|
||||||
DETAIL_URL = 'api:property-detail'
|
DETAIL_URL = 'api:property-detail'
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.contrib import auth
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import Food, MealType, PropertyType
|
from cookbook.models import MealType, PropertyType
|
||||||
|
|
||||||
LIST_URL = 'api:propertytype-list'
|
LIST_URL = 'api:propertytype-list'
|
||||||
DETAIL_URL = 'api:propertytype-detail'
|
DETAIL_URL = 'api:propertytype-detail'
|
||||||
|
@ -67,7 +67,8 @@ def test_share_permission(recipe_1_s1, u1_s1, u1_s2, u2_s1, a_u):
|
|||||||
share = ShareLink.objects.filter(recipe=recipe_1_s1).first()
|
share = ShareLink.objects.filter(recipe=recipe_1_s1).first()
|
||||||
assert a_u.get(reverse(DETAIL_URL, args=[recipe_1_s1.pk]) + f'?share={share.uuid}').status_code == 200
|
assert a_u.get(reverse(DETAIL_URL, args=[recipe_1_s1.pk]) + f'?share={share.uuid}').status_code == 200
|
||||||
assert u1_s1.get(reverse(DETAIL_URL, args=[recipe_1_s1.pk]) + f'?share={share.uuid}').status_code == 200
|
assert u1_s1.get(reverse(DETAIL_URL, args=[recipe_1_s1.pk]) + f'?share={share.uuid}').status_code == 200
|
||||||
assert u1_s2.get(reverse(DETAIL_URL, args=[recipe_1_s1.pk]) + f'?share={share.uuid}').status_code == 404 # TODO fix in https://github.com/TandoorRecipes/recipes/issues/1238
|
# TODO fix in https://github.com/TandoorRecipes/recipes/issues/1238
|
||||||
|
assert u1_s2.get(reverse(DETAIL_URL, args=[recipe_1_s1.pk]) + f'?share={share.uuid}').status_code == 404
|
||||||
|
|
||||||
recipe_1_s1.created_by = auth.get_user(u1_s1)
|
recipe_1_s1.created_by = auth.get_user(u1_s1)
|
||||||
recipe_1_s1.private = True
|
recipe_1_s1.private = True
|
||||||
@ -100,7 +101,6 @@ def test_update(arg, request, recipe_1_s1):
|
|||||||
j,
|
j,
|
||||||
content_type='application/json'
|
content_type='application/json'
|
||||||
)
|
)
|
||||||
response = json.loads(r.content)
|
|
||||||
assert r.status_code == arg[1]
|
assert r.status_code == arg[1]
|
||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
validate_recipe(j, json.loads(r.content))
|
validate_recipe(j, json.loads(r.content))
|
||||||
|
@ -48,8 +48,6 @@ def test_list_filter(obj_1, obj_2, u1_s1):
|
|||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
response = json.loads(r.content)
|
response = json.loads(r.content)
|
||||||
assert len(response) == 2
|
assert len(response) == 2
|
||||||
# RecipeBooks model is unsorted - this isn't a reliable test
|
|
||||||
# assert response[0]['name'] == obj_1.name
|
|
||||||
|
|
||||||
response = json.loads(u1_s1.get(f'{reverse(LIST_URL)}?limit=1').content)
|
response = json.loads(u1_s1.get(f'{reverse(LIST_URL)}?limit=1').content)
|
||||||
assert len(response) == 1
|
assert len(response) == 1
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
import factory
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
from pytest_factoryboy import LazyFixture, register
|
|
||||||
|
|
||||||
from cookbook.tests.factories import RecipeFactory
|
from cookbook.tests.factories import RecipeFactory
|
||||||
|
|
||||||
@ -18,7 +16,7 @@ def recipe(request, space_1, u1_s1):
|
|||||||
params = request.param # request.param is a magic variable
|
params = request.param # request.param is a magic variable
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
params = {}
|
params = {}
|
||||||
step_recipe = params.get('steps__count', 1)
|
# step_recipe = params.get('steps__count', 1) # TODO add tests for step recipes
|
||||||
steps__recipe_count = params.get('steps__recipe_count', 0)
|
steps__recipe_count = params.get('steps__recipe_count', 0)
|
||||||
steps__food_recipe_count = params.get('steps__food_recipe_count', {})
|
steps__food_recipe_count = params.get('steps__food_recipe_count', {})
|
||||||
created_by = params.get('created_by', auth.get_user(u1_s1))
|
created_by = params.get('created_by', auth.get_user(u1_s1))
|
||||||
@ -26,6 +24,7 @@ def recipe(request, space_1, u1_s1):
|
|||||||
return RecipeFactory.create(
|
return RecipeFactory.create(
|
||||||
steps__recipe_count=steps__recipe_count,
|
steps__recipe_count=steps__recipe_count,
|
||||||
steps__food_recipe_count=steps__food_recipe_count,
|
steps__food_recipe_count=steps__food_recipe_count,
|
||||||
|
# steps__step_recipe=step_recipe, # TODO add tests for step recipes
|
||||||
created_by=created_by,
|
created_by=created_by,
|
||||||
space=space_1,
|
space=space_1,
|
||||||
)
|
)
|
||||||
|
@ -5,7 +5,7 @@ from django.contrib import auth
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import RecipeBook, ShoppingList, Storage, Sync, SyncLog
|
from cookbook.models import ShoppingList
|
||||||
|
|
||||||
LIST_URL = 'api:shoppinglist-list'
|
LIST_URL = 'api:shoppinglist-list'
|
||||||
DETAIL_URL = 'api:shoppinglist-detail'
|
DETAIL_URL = 'api:shoppinglist-detail'
|
||||||
|
@ -2,7 +2,6 @@ import json
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.forms import model_to_dict
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
import json
|
import json
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
import factory
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.forms import model_to_dict
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
from pytest_factoryboy import LazyFixture, register
|
|
||||||
|
|
||||||
from cookbook.models import ShoppingListEntry
|
from cookbook.models import ShoppingListEntry
|
||||||
from cookbook.tests.factories import ShoppingListEntryFactory
|
from cookbook.tests.factories import ShoppingListEntryFactory
|
||||||
@ -169,7 +166,7 @@ def test_sharing(request, shared, count, sle_2, sle, u1_s1):
|
|||||||
assert len(r) == count
|
assert len(r) == count
|
||||||
# count unchecked entries
|
# count unchecked entries
|
||||||
if not x.status_code == 404:
|
if not x.status_code == 404:
|
||||||
count = count-1
|
count = count - 1
|
||||||
assert [x['checked'] for x in r].count(False) == count
|
assert [x['checked'] for x in r].count(False) == count
|
||||||
# test shared user can delete
|
# test shared user can delete
|
||||||
x = shared_client.delete(
|
x = shared_client.delete(
|
||||||
@ -182,13 +179,12 @@ def test_sharing(request, shared, count, sle_2, sle, u1_s1):
|
|||||||
assert len(r) == count
|
assert len(r) == count
|
||||||
# count unchecked entries
|
# count unchecked entries
|
||||||
if not x.status_code == 404:
|
if not x.status_code == 404:
|
||||||
count = count-1
|
count = count - 1
|
||||||
assert [x['checked'] for x in r].count(False) == count
|
assert [x['checked'] for x in r].count(False) == count
|
||||||
|
|
||||||
|
|
||||||
def test_completed(sle, u1_s1):
|
def test_completed(sle, u1_s1):
|
||||||
# check 1 entry
|
# check 1 entry
|
||||||
#
|
|
||||||
u1_s1.patch(
|
u1_s1.patch(
|
||||||
reverse(DETAIL_URL, args={sle[0].id}),
|
reverse(DETAIL_URL, args={sle[0].id}),
|
||||||
{'checked': True},
|
{'checked': True},
|
||||||
@ -199,7 +195,7 @@ def test_completed(sle, u1_s1):
|
|||||||
# count unchecked entries
|
# count unchecked entries
|
||||||
assert [x['checked'] for x in r].count(False) == 9
|
assert [x['checked'] for x in r].count(False) == 9
|
||||||
# confirm completed_at is populated
|
# confirm completed_at is populated
|
||||||
assert [(x['completed_at'] != None) for x in r if x['checked']].count(True) == 1
|
assert [(x['completed_at'] is not None) for x in r if x['checked']].count(True) == 1
|
||||||
|
|
||||||
assert len(json.loads(u1_s1.get(f'{reverse(LIST_URL)}?checked=0').content)) == 9
|
assert len(json.loads(u1_s1.get(f'{reverse(LIST_URL)}?checked=0').content)) == 9
|
||||||
assert len(json.loads(u1_s1.get(f'{reverse(LIST_URL)}?checked=1').content)) == 1
|
assert len(json.loads(u1_s1.get(f'{reverse(LIST_URL)}?checked=1').content)) == 1
|
||||||
@ -213,7 +209,7 @@ def test_completed(sle, u1_s1):
|
|||||||
r = json.loads(u1_s1.get(reverse(LIST_URL)).content)
|
r = json.loads(u1_s1.get(reverse(LIST_URL)).content)
|
||||||
assert [x['checked'] for x in r].count(False) == 10
|
assert [x['checked'] for x in r].count(False) == 10
|
||||||
# confirm completed_at value cleared
|
# confirm completed_at value cleared
|
||||||
assert [(x['completed_at'] != None) for x in r if x['checked']].count(True) == 0
|
assert [(x['completed_at'] is not None) for x in r if x['checked']].count(True) == 0
|
||||||
|
|
||||||
|
|
||||||
def test_recent(sle, u1_s1):
|
def test_recent(sle, u1_s1):
|
||||||
|
@ -2,11 +2,10 @@ import json
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.forms import model_to_dict
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import RecipeBook, Storage, Sync, SyncLog, ShoppingList, ShoppingListEntry, Food, ShoppingListRecipe
|
from cookbook.models import ShoppingList, ShoppingListRecipe
|
||||||
|
|
||||||
LIST_URL = 'api:shoppinglistrecipe-list'
|
LIST_URL = 'api:shoppinglistrecipe-list'
|
||||||
DETAIL_URL = 'api:shoppinglistrecipe-detail'
|
DETAIL_URL = 'api:shoppinglistrecipe-detail'
|
||||||
@ -21,7 +20,7 @@ def obj_1(space_1, u1_s1, recipe_1_s1):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def obj_2(space_1, u1_s1,recipe_1_s1):
|
def obj_2(space_1, u1_s1, recipe_1_s1):
|
||||||
r = ShoppingListRecipe.objects.create(recipe=recipe_1_s1, servings=1)
|
r = ShoppingListRecipe.objects.create(recipe=recipe_1_s1, servings=1)
|
||||||
s = ShoppingList.objects.create(created_by=auth.get_user(u1_s1), space=space_1, )
|
s = ShoppingList.objects.create(created_by=auth.get_user(u1_s1), space=space_1, )
|
||||||
s.recipes.add(r)
|
s.recipes.add(r)
|
||||||
|
@ -246,8 +246,6 @@ def test_shopping_recipe_mixed_authors(u1_s1, u2_s1, space_1):
|
|||||||
|
|
||||||
@pytest.mark.parametrize("recipe", [{'steps__ingredients__header': 1}], indirect=['recipe'])
|
@pytest.mark.parametrize("recipe", [{'steps__ingredients__header': 1}], indirect=['recipe'])
|
||||||
def test_shopping_with_header_ingredient(u1_s1, recipe):
|
def test_shopping_with_header_ingredient(u1_s1, recipe):
|
||||||
# with scope(space=recipe.space):
|
|
||||||
# recipe.step_set.first().ingredient_set.add(IngredientFactory(ingredients__header=1))
|
|
||||||
u1_s1.put(reverse(SHOPPING_RECIPE_URL, args={recipe.id}))
|
u1_s1.put(reverse(SHOPPING_RECIPE_URL, args={recipe.id}))
|
||||||
assert len(json.loads(u1_s1.get(reverse(SHOPPING_LIST_URL)).content)) == 10
|
assert len(json.loads(u1_s1.get(reverse(SHOPPING_LIST_URL)).content)) == 10
|
||||||
assert len(json.loads(
|
assert len(json.loads(
|
||||||
|
@ -2,12 +2,9 @@ import json
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.db.models import OuterRef, Subquery
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import Ingredient, Step
|
|
||||||
|
|
||||||
LIST_URL = 'api:space-list'
|
LIST_URL = 'api:space-list'
|
||||||
DETAIL_URL = 'api:space-detail'
|
DETAIL_URL = 'api:space-detail'
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ from django.contrib import auth
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import RecipeBook, Storage, Sync
|
from cookbook.models import Storage
|
||||||
|
|
||||||
LIST_URL = 'api:storage-list'
|
LIST_URL = 'api:storage-list'
|
||||||
DETAIL_URL = 'api:storage-detail'
|
DETAIL_URL = 'api:storage-detail'
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.contrib import auth
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import RecipeBook, Supermarket
|
from cookbook.models import Supermarket
|
||||||
|
|
||||||
LIST_URL = 'api:supermarket-list'
|
LIST_URL = 'api:supermarket-list'
|
||||||
DETAIL_URL = 'api:supermarket-detail'
|
DETAIL_URL = 'api:supermarket-detail'
|
||||||
@ -48,7 +47,6 @@ def test_list_filter(obj_1, obj_2, u1_s1):
|
|||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
response = json.loads(r.content)
|
response = json.loads(r.content)
|
||||||
assert len(response) == 2
|
assert len(response) == 2
|
||||||
# assert response[0]['name'] == obj_1.name # assuming an order when it's not always valid
|
|
||||||
|
|
||||||
response = json.loads(u1_s1.get(f'{reverse(LIST_URL)}?limit=1').content)
|
response = json.loads(u1_s1.get(f'{reverse(LIST_URL)}?limit=1').content)
|
||||||
assert len(response) == 1
|
assert len(response) == 1
|
||||||
|
@ -5,7 +5,7 @@ from django.contrib import auth
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import RecipeBook, Storage, Sync
|
from cookbook.models import Storage, Sync
|
||||||
|
|
||||||
LIST_URL = 'api:sync-list'
|
LIST_URL = 'api:sync-list'
|
||||||
DETAIL_URL = 'api:sync-detail'
|
DETAIL_URL = 'api:sync-detail'
|
||||||
|
@ -5,7 +5,7 @@ from django.contrib import auth
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import Food, MealType, UnitConversion
|
from cookbook.models import MealType, UnitConversion
|
||||||
from cookbook.tests.conftest import get_random_food, get_random_unit
|
from cookbook.tests.conftest import get_random_food, get_random_unit
|
||||||
|
|
||||||
LIST_URL = 'api:unitconversion-list'
|
LIST_URL = 'api:unitconversion-list'
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
@ -77,7 +76,7 @@ def test_user_retrieve(arg, request, u1_s1):
|
|||||||
assert r.status_code == arg[1]
|
assert r.status_code == arg[1]
|
||||||
|
|
||||||
|
|
||||||
def test_user_update(u1_s1, u2_s1,u1_s2):
|
def test_user_update(u1_s1, u2_s1, u1_s2):
|
||||||
# can update own user
|
# can update own user
|
||||||
r = u1_s1.patch(
|
r = u1_s1.patch(
|
||||||
reverse(
|
reverse(
|
||||||
|
@ -120,7 +120,6 @@ def test_default_inherit_fields(u1_s1, u1_s2, space_1, space_2):
|
|||||||
r = u1_s1.get(
|
r = u1_s1.get(
|
||||||
reverse(DETAIL_URL, args={auth.get_user(u1_s1).id}),
|
reverse(DETAIL_URL, args={auth.get_user(u1_s1).id}),
|
||||||
)
|
)
|
||||||
#assert len([x['field'] for x in json.loads(r.content)['food_inherit_default']]) == 0
|
|
||||||
|
|
||||||
# inherit all possible fields
|
# inherit all possible fields
|
||||||
with scope(space=space_1):
|
with scope(space=space_1):
|
||||||
|
@ -2,12 +2,9 @@ import json
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.db.models import OuterRef, Subquery
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import Ingredient, Step
|
|
||||||
|
|
||||||
LIST_URL = 'api:userspace-list'
|
LIST_URL = 'api:userspace-list'
|
||||||
DETAIL_URL = 'api:userspace-detail'
|
DETAIL_URL = 'api:userspace-detail'
|
||||||
|
|
||||||
|
@ -36,18 +36,6 @@ def enable_db_access_for_all_tests(db):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# @pytest.fixture()
|
|
||||||
# def space_1():
|
|
||||||
# with scopes_disabled():
|
|
||||||
# return Space.objects.get_or_create(name='space_1')[0]
|
|
||||||
|
|
||||||
|
|
||||||
# @pytest.fixture()
|
|
||||||
# def space_2():
|
|
||||||
# with scopes_disabled():
|
|
||||||
# return Space.objects.get_or_create(name='space_2')[0]
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------- OBJECT FIXTURES ---------------------
|
# ---------------------- OBJECT FIXTURES ---------------------
|
||||||
|
|
||||||
def get_random_recipe(space_1, u1_s1):
|
def get_random_recipe(space_1, u1_s1):
|
||||||
@ -124,7 +112,7 @@ def validate_recipe(expected, recipe):
|
|||||||
# file and url are metadata not related to the recipe
|
# file and url are metadata not related to the recipe
|
||||||
[expected.pop(k) for k in ['file', 'url'] if k in expected]
|
[expected.pop(k) for k in ['file', 'url'] if k in expected]
|
||||||
# if a key is a list remove it to deal with later
|
# if a key is a list remove it to deal with later
|
||||||
lists = [k for k, v in expected.items() if type(v) == list]
|
lists = [k for k, v in expected.items() if isinstance(v, list)]
|
||||||
for k in lists:
|
for k in lists:
|
||||||
expected_lists[k] = expected.pop(k)
|
expected_lists[k] = expected.pop(k)
|
||||||
target_lists[k] = recipe.pop(k)
|
target_lists[k] = recipe.pop(k)
|
||||||
@ -157,7 +145,7 @@ def dict_compare(d1, d2, details=False):
|
|||||||
d1_keys = set(d1.keys())
|
d1_keys = set(d1.keys())
|
||||||
d2_keys = set(d2.keys())
|
d2_keys = set(d2.keys())
|
||||||
shared = d1_keys.intersection(d2_keys)
|
shared = d1_keys.intersection(d2_keys)
|
||||||
sub_dicts = [i for i, j in d1.items() if type(j) == dict]
|
sub_dicts = [i for i, j in d1.items() if isinstance(j, dict)]
|
||||||
not_dicts = shared - set(sub_dicts)
|
not_dicts = shared - set(sub_dicts)
|
||||||
added = d1_keys - d2_keys
|
added = d1_keys - d2_keys
|
||||||
removed = d2_keys - d1_keys
|
removed = d2_keys - d1_keys
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
import inspect
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
@ -11,12 +12,6 @@ from pytest_factoryboy import register
|
|||||||
|
|
||||||
from cookbook.models import UserSpace
|
from cookbook.models import UserSpace
|
||||||
|
|
||||||
# this code will run immediately prior to creating the model object useful when you want a reverse relationship
|
|
||||||
# log = factory.RelatedFactory(
|
|
||||||
# UserLogFactory,
|
|
||||||
# factory_related_name='user',
|
|
||||||
# action=models.UserLog.ACTION_CREATE,
|
|
||||||
# )
|
|
||||||
faker = FakerFactory.create()
|
faker = FakerFactory.create()
|
||||||
|
|
||||||
|
|
||||||
@ -96,7 +91,6 @@ class SupermarketCategoryFactory(factory.django.DjangoModelFactory):
|
|||||||
django_get_or_create = ('name', 'space',)
|
django_get_or_create = ('name', 'space',)
|
||||||
|
|
||||||
|
|
||||||
# @factory.django.mute_signals(post_save)
|
|
||||||
@register
|
@register
|
||||||
class FoodFactory(factory.django.DjangoModelFactory):
|
class FoodFactory(factory.django.DjangoModelFactory):
|
||||||
"""Food factory."""
|
"""Food factory."""
|
||||||
@ -451,17 +445,6 @@ class RecipeFactory(factory.django.DjangoModelFactory):
|
|||||||
for step in extracted:
|
for step in extracted:
|
||||||
self.steps.add(step)
|
self.steps.add(step)
|
||||||
|
|
||||||
# image = models.ImageField(upload_to='recipes/', blank=True, null=True) #TODO test recipe image api https://factoryboy.readthedocs.io/en/stable/orms.html#factory.django.ImageField
|
|
||||||
# storage = models.ForeignKey(
|
|
||||||
# Storage, on_delete=models.PROTECT, blank=True, null=True
|
|
||||||
# )
|
|
||||||
# file_uid = models.CharField(max_length=256, default="", blank=True)
|
|
||||||
# file_path = models.CharField(max_length=512, default="", blank=True)
|
|
||||||
# link = models.CharField(max_length=512, null=True, blank=True)
|
|
||||||
# cors_link = models.CharField(max_length=1024, null=True, blank=True)
|
|
||||||
# nutrition = models.ForeignKey(NutritionInformation, blank=True, null=True, on_delete=models.CASCADE)
|
|
||||||
# updated_at = models.DateTimeField(auto_now=True)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = 'cookbook.Recipe'
|
model = 'cookbook.Recipe'
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.core.cache import caches
|
from django.core.cache import caches
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
from decimal import Decimal
|
|
||||||
|
|
||||||
from cookbook.helper.cache_helper import CacheHelper
|
from cookbook.helper.cache_helper import CacheHelper
|
||||||
from cookbook.helper.property_helper import FoodPropertyHelper
|
from cookbook.helper.property_helper import FoodPropertyHelper
|
||||||
from cookbook.models import Unit, Food, PropertyType, Property, Recipe, Step, UnitConversion, Property
|
from cookbook.models import Food, Property, PropertyType, Recipe, Step, Unit, UnitConversion
|
||||||
|
|
||||||
|
|
||||||
def test_food_property(space_1, space_2, u1_s1):
|
def test_food_property(space_1, space_2, u1_s1):
|
||||||
@ -125,5 +126,3 @@ def test_food_property(space_1, space_2, u1_s1):
|
|||||||
property_values = FoodPropertyHelper(space_1).calculate_recipe_properties(recipe_2)
|
property_values = FoodPropertyHelper(space_1).calculate_recipe_properties(recipe_2)
|
||||||
|
|
||||||
assert property_fat.id not in property_values
|
assert property_fat.id not in property_values
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.urls import reverse
|
|
||||||
from django_scopes import scope
|
from django_scopes import scope
|
||||||
|
|
||||||
from cookbook.helper.recipe_search import RecipeSearch
|
from cookbook.helper.recipe_search import RecipeSearch
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
import pytest
|
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
from django.urls import reverse
|
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
from cookbook.forms import ImportExportBase
|
from cookbook.helper.permission_helper import (has_group_permission, is_object_owner,
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
is_space_owner, switch_user_active_space)
|
||||||
from cookbook.helper.permission_helper import has_group_permission, is_space_owner, switch_user_active_space, is_object_owner
|
from cookbook.models import Food, RecipeBook, RecipeBookEntry, Space, UserSpace
|
||||||
from cookbook.models import ExportLog, UserSpace, Food, Space, Comment, RecipeBook, RecipeBookEntry
|
|
||||||
|
|
||||||
|
|
||||||
def test_has_group_permission(u1_s1, a_u, space_2):
|
def test_has_group_permission(u1_s1, a_u, space_2):
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from cookbook.models import Recipe
|
|
||||||
from django.contrib import auth
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
|
|
||||||
@ -28,7 +25,6 @@ def test_external_link_permission(arg, request, ext_recipe_1_s1):
|
|||||||
['u1_s2', 404],
|
['u1_s2', 404],
|
||||||
['a1_s2', 404],
|
['a1_s2', 404],
|
||||||
])
|
])
|
||||||
def test_external_link_permission(arg, request, ext_recipe_1_s1):
|
def test_external_file_permission(arg, request, ext_recipe_1_s1):
|
||||||
c = request.getfixturevalue(arg[0])
|
c = request.getfixturevalue(arg[0])
|
||||||
assert c.get(reverse('api_get_recipe_file', args=[ext_recipe_1_s1.pk])).status_code == arg[1]
|
assert c.get(reverse('api_get_recipe_file', args=[ext_recipe_1_s1.pk])).status_code == arg[1]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user