diff --git a/cookbook/helper/recipe_search.py b/cookbook/helper/recipe_search.py
index 1846f2e8..24e2faad 100644
--- a/cookbook/helper/recipe_search.py
+++ b/cookbook/helper/recipe_search.py
@@ -31,7 +31,13 @@ class RecipeSearch():
self._search_prefs = SearchPreference()
self._string = params.get('query').strip() if params.get('query', None) else None
self._rating = self._params.get('rating', None)
- self._keywords = self._params.get('keywords', None)
+ self._keywords = {
+ 'or': self._params.get('keywords_or', None),
+ 'and': self._params.get('keywords_and', None),
+ 'or_not': self._params.get('keywords_or_not', None),
+ 'and_not': self._params.get('keywords_and_not', None)
+ }
+
self._foods = self._params.get('foods', None)
self._books = self._params.get('books', None)
self._steps = self._params.get('steps', None)
@@ -42,7 +48,6 @@ class RecipeSearch():
self._sort_order = self._params.get('sort_order', None)
# TODO add save
- self._keywords_or = str2bool(self._params.get('keywords_or', True))
self._foods_or = str2bool(self._params.get('foods_or', True))
self._books_or = str2bool(self._params.get('books_or', True))
@@ -88,7 +93,7 @@ class RecipeSearch():
self._new_recipes()
# self._last_viewed()
# self._last_cooked()
- self.keyword_filters(keywords=self._keywords, operator=self._keywords_or)
+ self.keyword_filters(**self._keywords)
self.food_filters(foods=self._foods, operator=self._foods_or)
self.book_filters(books=self._books, operator=self._books_or)
self.rating_filter(rating=self._rating)
@@ -182,19 +187,31 @@ class RecipeSearch():
).values('recipe').annotate(count=Count('pk', distinct=True)).values('count')
self._queryset = self._queryset.annotate(favorite=Coalesce(Subquery(favorite_recipes), 0))
- def keyword_filters(self, keywords=None, operator=True):
- if not keywords:
+ def keyword_filters(self, **kwargs):
+ if all([kwargs[x] is None for x in kwargs]):
return
- if not isinstance(keywords, list):
- keywords = [keywords]
- if operator == True:
- # TODO creating setting to include descendants of keywords a setting
- self._queryset = self._queryset.filter(keywords__in=Keyword.include_descendants(Keyword.objects.filter(pk__in=keywords)))
- else:
- # when performing an 'and' search returned recipes should include a parent OR any of its descedants
- # AND other keywords selected so filters are appended using keyword__id__in the list of keywords and descendants
- for kw in Keyword.objects.filter(pk__in=keywords):
- self._queryset = self._queryset.filter(keywords__in=list(kw.get_descendants_and_self()))
+ for kw_filter in kwargs:
+ if not kwargs[kw_filter]:
+ continue
+ if not isinstance(kwargs[kw_filter], list):
+ kwargs[kw_filter] = [kwargs[kw_filter]]
+
+ keywords = Keyword.objects.filter(pk__in=kwargs[kw_filter])
+ if 'or' in kw_filter:
+ f = Q(keywords__in=Keyword.include_descendants(keywords))
+ if 'not' in kw_filter:
+ self._queryset = self._queryset.exclude(f)
+ else:
+ self._queryset = self._queryset.filter(f)
+ elif 'and' in kw_filter:
+ recipes = Recipe.objects.all()
+ for kw in keywords:
+ if 'not' in kw_filter:
+ recipes = recipes.filter(keywords__in=kw.get_descendants_and_self())
+ else:
+ self._queryset = self._queryset.filter(keywords__in=kw.get_descendants_and_self())
+ if 'not' in kw_filter:
+ self._queryset = self._queryset.exclude(id__in=recipes.values('id'))
def food_filters(self, foods=None, operator=True):
if not foods:
@@ -229,7 +246,7 @@ class RecipeSearch():
if rating == 0:
self._queryset = self._queryset.filter(rating=0)
elif lessthan:
- self._queryset = self._queryset.filter(rating__lte=int(rating[1:]))
+ self._queryset = self._queryset.filter(rating__lte=int(rating[1:])).exclude(rating=0)
else:
self._queryset = self._queryset.filter(rating__gte=int(rating))
diff --git a/cookbook/views/api.py b/cookbook/views/api.py
index 878c7118..9c980124 100644
--- a/cookbook/views/api.py
+++ b/cookbook/views/api.py
@@ -630,15 +630,18 @@ class RecipeViewSet(viewsets.ModelViewSet):
# TODO split read and write permission for meal plan guest
permission_classes = [CustomIsShare | CustomIsGuest]
pagination_class = RecipePagination
- # TODO the boolean params below (keywords_or through new) should be updated to boolean types with front end refactored accordingly
+
query_params = [
QueryParam(name='query', description=_('Query string matched (fuzzy) against recipe name. In the future also fulltext search.')),
- QueryParam(name='keywords', description=_('ID of keyword a recipe should have. For multiple repeat parameter.'), qtype='int'),
+ QueryParam(name='keywords', description=_('ID of keyword a recipe should have. For multiple repeat parameter. Equivalent to keywords_or'), qtype='int'),
+ QueryParam(name='keywords_or', description=_('Keyword IDs, repeat for multiple Return recipes with any of the keywords'), qtype='int'),
+ QueryParam(name='keywords_and', description=_('Keyword IDs, repeat for multiple Return recipes with all of the keywords.'), qtype='int'),
+ QueryParam(name='keywords_or_not', description=_('Keyword IDs, repeat for multiple Exclude recipes with any of the keywords.'), qtype='int'),
+ QueryParam(name='keywords_and_not', description=_('Keyword IDs, repeat for multiple Exclude recipes with all of the keywords.'), qtype='int'),
QueryParam(name='foods', description=_('ID of food a recipe should have. For multiple repeat parameter.'), qtype='int'),
QueryParam(name='units', description=_('ID of unit a recipe should have.'), qtype='int'),
QueryParam(name='rating', description=_('Rating a recipe should have. [0 - 5]'), qtype='int'),
QueryParam(name='books', description=_('ID of book a recipe should be in. For multiple repeat parameter.')),
- QueryParam(name='keywords_or', description=_('If recipe should have all (AND=''false'') or any (OR=''true'') of the provided keywords.')),
QueryParam(name='foods_or', description=_('If recipe should have all (AND=''false'') or any (OR=''true'') of the provided foods.')),
QueryParam(name='books_or', description=_('If recipe should be in all (AND=''false'') or any (OR=''true'') of the provided books.')),
QueryParam(name='internal', description=_('If only internal recipes should be returned. [''true''/''false'']')),
diff --git a/vue/src/apps/RecipeSearchView/RecipeSearchView.vue b/vue/src/apps/RecipeSearchView/RecipeSearchView.vue
index b95e79e6..c609e940 100644
--- a/vue/src/apps/RecipeSearchView/RecipeSearchView.vue
+++ b/vue/src/apps/RecipeSearchView/RecipeSearchView.vue
@@ -141,9 +141,25 @@
+
{{ $t("Keywords") }}
-
+
+
+
+
+
+
+
+
+
-
- {{ $t("or") }}
+
+ {{ $t("or") }}
{{ $t("and") }}
+
+
+
+ {{ $t("not") }}
+
+
+
@@ -199,8 +229,8 @@
style="flex-grow: 1; flex-shrink: 1; flex-basis: 0"
/>
-
+
{{ $t("or") }}
{{ $t("and") }}
@@ -235,7 +265,7 @@
>
-
+
{{ $t("or") }}
{{ $t("and") }}
@@ -250,7 +280,7 @@
+
-
+
+
+ >=
+ <=
+
+
@@ -279,7 +317,7 @@
>
-
+
{{ $t("or") }}
{{ $t("and") }}
@@ -339,8 +377,8 @@ import { ApiMixin, ResolveUrlMixin } from "@/utils/utils"
import LoadingSpinner from "@/components/LoadingSpinner" // TODO: is this deprecated?
import RecipeCard from "@/components/RecipeCard"
import GenericMultiselect from "@/components/GenericMultiselect"
-import { Treeselect, LOAD_CHILDREN_OPTIONS } from "@riophae/vue-treeselect" //TODO: delete
-import "@riophae/vue-treeselect/dist/vue-treeselect.css" //TODO: delete
+import { Treeselect, LOAD_CHILDREN_OPTIONS } from "@riophae/vue-treeselect"
+import "@riophae/vue-treeselect/dist/vue-treeselect.css"
import RecipeSwitcher from "@/components/Buttons/RecipeSwitcher"
Vue.use(VueCookies)
@@ -366,15 +404,15 @@ export default {
search_input: "",
search_internal: false,
search_keywords: [
- { items: [], operator: true },
- { items: [], operator: true },
- { items: [], operator: true },
- { items: [], operator: true },
+ { items: [], operator: true, not: false },
+ { items: [], operator: true, not: false },
+ { items: [], operator: true, not: false },
+ { items: [], operator: true, not: false },
],
search_foods: [],
search_books: [],
search_units: [],
- search_ratings: undefined,
+ search_rating: undefined,
search_rating_gte: true,
search_keywords_or: true,
search_foods_or: true,
@@ -382,7 +420,11 @@ export default {
search_units_or: true,
pagination_page: 1,
expert_mode: false,
- keyword_fields: 1,
+ keywords_fields: 1,
+ food_fields: 1,
+ book_fields: 1,
+ rating_fields: 1,
+ unit_fields: 1,
},
ui: {
show_meal_plan: true,
@@ -410,6 +452,7 @@ export default {
computed: {
ratingOptions: function () {
let ratingCount = undefined
+ let label = undefined
if (Object.keys(this.facets?.Ratings ?? {}).length === 0) {
ratingCount = (x) => {
return ""
@@ -419,24 +462,52 @@ export default {
return ` (${x})`
}
}
- let label = ""
+
if (this.search.search_rating_gte) {
- label = this.$t("and_up")
+ label = (x) => {
+ if (x == 5) {
+ return ""
+ } else {
+ return this.$t("and_up")
+ }
+ }
} else {
- label = this.$t("and_down")
+ label = (x) => {
+ if (x == 1) {
+ return ""
+ } else {
+ return this.$t("and_down")
+ }
+ }
}
+
return [
- { id: 5, label: "⭐⭐⭐⭐⭐" + ratingCount(this.facets.Ratings?.["5.0"] ?? 0) },
- { id: 4, label: "⭐⭐⭐⭐ " + this.$t("and_up") + ratingCount(this.facets.Ratings?.["4.0"] ?? 0) },
- { id: 3, label: "⭐⭐⭐ " + this.$t("and_up") + ratingCount(this.facets.Ratings?.["3.0"] ?? 0) },
- { id: 2, label: "⭐⭐ " + this.$t("and_up") + ratingCount(this.facets.Ratings?.["2.0"] ?? 0) },
- { id: 1, label: "⭐ " + this.$t("and_up") + ratingCount(this.facets.Ratings?.["1.0"] ?? 0) },
+ { id: 5, label: "⭐⭐⭐⭐⭐" + label(5) + ratingCount(this.facets.Ratings?.["5.0"] ?? 0) },
+ { id: 4, label: "⭐⭐⭐⭐ " + label() + ratingCount(this.facets.Ratings?.["4.0"] ?? 0) },
+ { id: 3, label: "⭐⭐⭐ " + label() + ratingCount(this.facets.Ratings?.["3.0"] ?? 0) },
+ { id: 2, label: "⭐⭐ " + label() + ratingCount(this.facets.Ratings?.["2.0"] ?? 0) },
+ { id: 1, label: "⭐ " + label(1) + ratingCount(this.facets.Ratings?.["1.0"] ?? 0) },
{ id: 0, label: this.$t("Unrated") + ratingCount(this.facets.Ratings?.["0.0"] ?? 0) },
]
},
expertMode: function () {
return this.ui.enable_expert && this.search.expert_mode
},
+ keywordFields: function () {
+ return !this.expertMode ? 1 : this.search.keywords_fields
+ },
+ foodFields: function () {
+ return !this.expertMode ? 1 : this.search.food_fields
+ },
+ bookFields: function () {
+ return !this.expertMode ? 1 : this.search.book_fields
+ },
+ ratingFields: function () {
+ return !this.expertMode ? 1 : this.search.rating_fields
+ },
+ unitFields: function () {
+ return !this.expertMode ? 1 : this.search.unit_fields
+ },
},
mounted() {
this.$nextTick(function () {
@@ -478,7 +549,7 @@ export default {
}
this.facets.Keywords = []
- for (let x of this.search.search_keywords) {
+ for (let x of this.search.search_keywords.map((x) => x.items).flat()) {
this.facets.Keywords.push({ id: x, name: "loading..." })
}
@@ -532,37 +603,7 @@ export default {
methods: {
// this.genericAPI inherited from ApiMixin
refreshData: function (random) {
- console.log(this.search.search_keywords)
- this.random_search = random
- let params = {
- query: this.search.search_input,
- keywords: this.search.search_keywords[0].items.map(function (A) {
- return A?.["id"] ?? A
- }),
- foods: this.search.search_foods.map(function (A) {
- return A?.["id"] ?? A
- }),
- rating: this.search.search_ratings,
- units: this.search.search_units.map(function (A) {
- return A["id"]
- }),
- books: this.search.search_books.map(function (A) {
- return A["id"]
- }),
- keywordsOr: this.search.search_keywords_or,
- foodsOr: this.search.search_foods_or,
- booksOr: this.search.search_books_or,
- unitsOr: this.search.search_units_or,
- internal: this.search.search_internal,
- random: this.random_search,
- _new: this.ui.sort_by_new,
- page: this.search.pagination_page,
- pageSize: this.search.page_size,
- }
- if (!this.searchFiltered) {
- params.options = { query: { last_viewed: this.ui.recently_viewed } }
- }
- // console.log(params, this.search.search_keywords[0], this.search.search_keywords[0].items)
+ let params = this.buildParams(random)
this.genericAPI(this.Models.RECIPE, this.Actions.LIST, params)
.then((result) => {
window.scrollTo(0, 0)
@@ -619,11 +660,13 @@ export default {
resetSearch: function () {
this.search.search_input = ""
this.search.search_internal = false
- this.search.search_keywords[0].items = []
+ this.search.search_keywords = this.search.search_keywords.map((x) => {
+ return { ...x, items: [] }
+ })
this.search.search_foods = []
this.search.search_books = []
this.search.search_units = []
- this.search.search_ratings = undefined
+ this.search.search_rating = undefined
this.search.pagination_page = 1
this.refreshData(false)
},
@@ -682,16 +725,24 @@ export default {
}
}
},
- buildParams: function () {
+ buildParams: function (random) {
+ this.random_search = random
+ let rating = this.search.search_rating
+ if (rating !== undefined && !this.search.search_rating_gte) {
+ rating = rating * -1
+ }
+ // TODO check expertmode
+ this.addFields("keywords")
let params = {
+ ...this.addFields("keywords"),
query: this.search.search_input,
- keywords: this.search.search_keywords[0].items,
- foods: this.search.search_foods,
- rating: this.search.search_ratings,
+ foods: this.search.search_foods.map(function (A) {
+ return A?.["id"] ?? A
+ }),
+ rating: rating,
books: this.search.search_books.map(function (A) {
return A["id"]
}),
- keywordsOr: this.search.search_keywords_or,
foodsOr: this.search.search_foods_or,
booksOr: this.search.search_books_or,
internal: this.search.search_internal,
@@ -703,6 +754,8 @@ export default {
if (!this.searchFiltered()) {
params.options = { query: { last_viewed: this.ui.recently_viewed } }
}
+ console.log(params)
+ return params
},
searchFiltered: function (ignore_string = false) {
let filtered =
@@ -711,7 +764,7 @@ export default {
this.search?.search_books?.length === 0 &&
// this.settings?.pagination_page === 1 &&
!this.random_search &&
- this.search?.search_ratings === undefined
+ this.search?.search_rating === undefined
if (ignore_string) {
return !filtered
@@ -719,10 +772,57 @@ export default {
return !filtered && this.search?.search_input !== ""
}
},
+ addFields(field) {
+ let fieldlist = this.search[`search_${field}`].slice(0, this.search[`${field}_fields`])
+ return {
+ [`${field}_or`]: fieldlist
+ .filter((x) => x.operator == true && x.not == false)
+ .map((x) => x.items)
+ .flat()
+ .map((x) => x?.id ?? x),
+ [`${field}_and`]: fieldlist
+ .filter((x) => x.operator == false && x.not == false)
+ .map((x) => x.items)
+ .flat()
+ .map((x) => x?.id ?? x),
+ [`${field}_or_not`]: fieldlist
+ .filter((x) => x.operator == true && x.not == true)
+ .map((x) => x.items)
+ .flat()
+ .map((x) => x?.id ?? x),
+ [`${field}_and_not`]: fieldlist
+ .filter((x) => x.operator == false && x.not == true)
+ .map((x) => x.items)
+ .flat()
+ .map((x) => x?.id ?? x),
+ }
+ },
},
}
-
+
diff --git a/vue/src/locales/en.json b/vue/src/locales/en.json
index 7166bebf..f3e8d948 100644
--- a/vue/src/locales/en.json
+++ b/vue/src/locales/en.json
@@ -308,5 +308,6 @@
"show_books": "Show Books",
"show_rating": "Show Rating",
"show_units": "Show Units",
- "show_filters": "Show Filters"
+ "show_filters": "Show Filters",
+ "not": "not"
}
diff --git a/vue/src/utils/models.js b/vue/src/utils/models.js
index 01a8e720..c4845aed 100644
--- a/vue/src/utils/models.js
+++ b/vue/src/utils/models.js
@@ -433,7 +433,26 @@ export class Models {
name: "Recipe",
apiName: "Recipe",
list: {
- params: ["query", "keywords", "foods", "units", "rating", "books", "keywordsOr", "foodsOr", "booksOr", "internal", "random", "_new", "page", "pageSize", "options"],
+ params: [
+ "query",
+ "keywords",
+ "keywords_or",
+ "keywords_and",
+ "keywords_or_not",
+ "keywords_and_not",
+ "foods",
+ "units",
+ "rating",
+ "books",
+ "foodsOr",
+ "booksOr",
+ "internal",
+ "random",
+ "_new",
+ "page",
+ "pageSize",
+ "options",
+ ],
// 'config': {
// 'foods': {'type': 'string'},
// 'keywords': {'type': 'string'},
diff --git a/vue/src/utils/openapi/api.ts b/vue/src/utils/openapi/api.ts
index 43b5182c..0d78c830 100644
--- a/vue/src/utils/openapi/api.ts
+++ b/vue/src/utils/openapi/api.ts
@@ -3054,12 +3054,15 @@ export interface UserPreference {
* @memberof UserPreference
*/
shopping_add_onhand?: boolean;
+<<<<<<< HEAD
/**
*
* @type {boolean}
* @memberof UserPreference
*/
left_handed?: boolean;
+=======
+>>>>>>> complex keyword filters
}
/**
@@ -5279,12 +5282,15 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
/**
*
* @param {string} [query] Query string matched (fuzzy) against recipe name. In the future also fulltext search.
- * @param {number} [keywords] ID of keyword a recipe should have. For multiple repeat parameter.
+ * @param {number} [keywords] ID of keyword a recipe should have. For multiple repeat parameter. Equivalent to keywords_or
+ * @param {number} [keywordsOr] Keyword IDs, repeat for multiple Return recipes with any of the keywords
+ * @param {number} [keywordsAnd] Keyword IDs, repeat for multiple Return recipes with all of the keywords.
+ * @param {number} [keywordsOrNot] Keyword IDs, repeat for multiple Exclude recipes with any of the keywords.
+ * @param {number} [keywordsAndNot] Keyword IDs, repeat for multiple Exclude recipes with all of the keywords.
* @param {number} [foods] ID of food a recipe should have. For multiple repeat parameter.
* @param {number} [units] ID of unit a recipe should have.
* @param {number} [rating] Rating a recipe should have. [0 - 5]
* @param {string} [books] ID of book a recipe should be in. For multiple repeat parameter.
- * @param {string} [keywordsOr] If recipe should have all (AND=false) or any (OR=<b>true</b>) of the provided keywords.
* @param {string} [foodsOr] If recipe should have all (AND=false) or any (OR=<b>true</b>) of the provided foods.
* @param {string} [booksOr] If recipe should be in all (AND=false) or any (OR=<b>true</b>) of the provided books.
* @param {string} [internal] If only internal recipes should be returned. [true/<b>false</b>]
@@ -5295,7 +5301,7 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
- listRecipes: async (query?: string, keywords?: number, foods?: number, units?: number, rating?: number, books?: string, keywordsOr?: string, foodsOr?: string, booksOr?: string, internal?: string, random?: string, _new?: string, page?: number, pageSize?: number, options: any = {}): Promise => {
+ listRecipes: async (query?: string, keywords?: number, keywordsOr?: number, keywordsAnd?: number, keywordsOrNot?: number, keywordsAndNot?: number, foods?: number, units?: number, rating?: number, books?: string, foodsOr?: string, booksOr?: string, internal?: string, random?: string, _new?: string, page?: number, pageSize?: number, options: any = {}): Promise => {
const localVarPath = `/api/recipe/`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@@ -5316,6 +5322,22 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
localVarQueryParameter['keywords'] = keywords;
}
+ if (keywordsOr !== undefined) {
+ localVarQueryParameter['keywords_or'] = keywordsOr;
+ }
+
+ if (keywordsAnd !== undefined) {
+ localVarQueryParameter['keywords_and'] = keywordsAnd;
+ }
+
+ if (keywordsOrNot !== undefined) {
+ localVarQueryParameter['keywords_or_not'] = keywordsOrNot;
+ }
+
+ if (keywordsAndNot !== undefined) {
+ localVarQueryParameter['keywords_and_not'] = keywordsAndNot;
+ }
+
if (foods !== undefined) {
localVarQueryParameter['foods'] = foods;
}
@@ -5332,10 +5354,6 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
localVarQueryParameter['books'] = books;
}
- if (keywordsOr !== undefined) {
- localVarQueryParameter['keywords_or'] = keywordsOr;
- }
-
if (foodsOr !== undefined) {
localVarQueryParameter['foods_or'] = foodsOr;
}
@@ -9669,12 +9687,15 @@ export const ApiApiFp = function(configuration?: Configuration) {
/**
*
* @param {string} [query] Query string matched (fuzzy) against recipe name. In the future also fulltext search.
- * @param {number} [keywords] ID of keyword a recipe should have. For multiple repeat parameter.
+ * @param {number} [keywords] ID of keyword a recipe should have. For multiple repeat parameter. Equivalent to keywords_or
+ * @param {number} [keywordsOr] Keyword IDs, repeat for multiple Return recipes with any of the keywords
+ * @param {number} [keywordsAnd] Keyword IDs, repeat for multiple Return recipes with all of the keywords.
+ * @param {number} [keywordsOrNot] Keyword IDs, repeat for multiple Exclude recipes with any of the keywords.
+ * @param {number} [keywordsAndNot] Keyword IDs, repeat for multiple Exclude recipes with all of the keywords.
* @param {number} [foods] ID of food a recipe should have. For multiple repeat parameter.
* @param {number} [units] ID of unit a recipe should have.
* @param {number} [rating] Rating a recipe should have. [0 - 5]
* @param {string} [books] ID of book a recipe should be in. For multiple repeat parameter.
- * @param {string} [keywordsOr] If recipe should have all (AND=false) or any (OR=<b>true</b>) of the provided keywords.
* @param {string} [foodsOr] If recipe should have all (AND=false) or any (OR=<b>true</b>) of the provided foods.
* @param {string} [booksOr] If recipe should be in all (AND=false) or any (OR=<b>true</b>) of the provided books.
* @param {string} [internal] If only internal recipes should be returned. [true/<b>false</b>]
@@ -9685,8 +9706,8 @@ export const ApiApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
- async listRecipes(query?: string, keywords?: number, foods?: number, units?: number, rating?: number, books?: string, keywordsOr?: string, foodsOr?: string, booksOr?: string, internal?: string, random?: string, _new?: string, page?: number, pageSize?: number, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> {
- const localVarAxiosArgs = await localVarAxiosParamCreator.listRecipes(query, keywords, foods, units, rating, books, keywordsOr, foodsOr, booksOr, internal, random, _new, page, pageSize, options);
+ async listRecipes(query?: string, keywords?: number, keywordsOr?: number, keywordsAnd?: number, keywordsOrNot?: number, keywordsAndNot?: number, foods?: number, units?: number, rating?: number, books?: string, foodsOr?: string, booksOr?: string, internal?: string, random?: string, _new?: string, page?: number, pageSize?: number, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> {
+ const localVarAxiosArgs = await localVarAxiosParamCreator.listRecipes(query, keywords, keywordsOr, keywordsAnd, keywordsOrNot, keywordsAndNot, foods, units, rating, books, foodsOr, booksOr, internal, random, _new, page, pageSize, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
@@ -11354,12 +11375,15 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
/**
*
* @param {string} [query] Query string matched (fuzzy) against recipe name. In the future also fulltext search.
- * @param {number} [keywords] ID of keyword a recipe should have. For multiple repeat parameter.
+ * @param {number} [keywords] ID of keyword a recipe should have. For multiple repeat parameter. Equivalent to keywords_or
+ * @param {number} [keywordsOr] Keyword IDs, repeat for multiple Return recipes with any of the keywords
+ * @param {number} [keywordsAnd] Keyword IDs, repeat for multiple Return recipes with all of the keywords.
+ * @param {number} [keywordsOrNot] Keyword IDs, repeat for multiple Exclude recipes with any of the keywords.
+ * @param {number} [keywordsAndNot] Keyword IDs, repeat for multiple Exclude recipes with all of the keywords.
* @param {number} [foods] ID of food a recipe should have. For multiple repeat parameter.
* @param {number} [units] ID of unit a recipe should have.
* @param {number} [rating] Rating a recipe should have. [0 - 5]
* @param {string} [books] ID of book a recipe should be in. For multiple repeat parameter.
- * @param {string} [keywordsOr] If recipe should have all (AND=false) or any (OR=<b>true</b>) of the provided keywords.
* @param {string} [foodsOr] If recipe should have all (AND=false) or any (OR=<b>true</b>) of the provided foods.
* @param {string} [booksOr] If recipe should be in all (AND=false) or any (OR=<b>true</b>) of the provided books.
* @param {string} [internal] If only internal recipes should be returned. [true/<b>false</b>]
@@ -11370,8 +11394,8 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
- listRecipes(query?: string, keywords?: number, foods?: number, units?: number, rating?: number, books?: string, keywordsOr?: string, foodsOr?: string, booksOr?: string, internal?: string, random?: string, _new?: string, page?: number, pageSize?: number, options?: any): AxiosPromise {
- return localVarFp.listRecipes(query, keywords, foods, units, rating, books, keywordsOr, foodsOr, booksOr, internal, random, _new, page, pageSize, options).then((request) => request(axios, basePath));
+ listRecipes(query?: string, keywords?: number, keywordsOr?: number, keywordsAnd?: number, keywordsOrNot?: number, keywordsAndNot?: number, foods?: number, units?: number, rating?: number, books?: string, foodsOr?: string, booksOr?: string, internal?: string, random?: string, _new?: string, page?: number, pageSize?: number, options?: any): AxiosPromise {
+ return localVarFp.listRecipes(query, keywords, keywordsOr, keywordsAnd, keywordsOrNot, keywordsAndNot, foods, units, rating, books, foodsOr, booksOr, internal, random, _new, page, pageSize, options).then((request) => request(axios, basePath));
},
/**
*
@@ -13063,12 +13087,15 @@ export class ApiApi extends BaseAPI {
/**
*
* @param {string} [query] Query string matched (fuzzy) against recipe name. In the future also fulltext search.
- * @param {number} [keywords] ID of keyword a recipe should have. For multiple repeat parameter.
+ * @param {number} [keywords] ID of keyword a recipe should have. For multiple repeat parameter. Equivalent to keywords_or
+ * @param {number} [keywordsOr] Keyword IDs, repeat for multiple Return recipes with any of the keywords
+ * @param {number} [keywordsAnd] Keyword IDs, repeat for multiple Return recipes with all of the keywords.
+ * @param {number} [keywordsOrNot] Keyword IDs, repeat for multiple Exclude recipes with any of the keywords.
+ * @param {number} [keywordsAndNot] Keyword IDs, repeat for multiple Exclude recipes with all of the keywords.
* @param {number} [foods] ID of food a recipe should have. For multiple repeat parameter.
* @param {number} [units] ID of unit a recipe should have.
* @param {number} [rating] Rating a recipe should have. [0 - 5]
* @param {string} [books] ID of book a recipe should be in. For multiple repeat parameter.
- * @param {string} [keywordsOr] If recipe should have all (AND=false) or any (OR=<b>true</b>) of the provided keywords.
* @param {string} [foodsOr] If recipe should have all (AND=false) or any (OR=<b>true</b>) of the provided foods.
* @param {string} [booksOr] If recipe should be in all (AND=false) or any (OR=<b>true</b>) of the provided books.
* @param {string} [internal] If only internal recipes should be returned. [true/<b>false</b>]
@@ -13080,8 +13107,8 @@ export class ApiApi extends BaseAPI {
* @throws {RequiredError}
* @memberof ApiApi
*/
- public listRecipes(query?: string, keywords?: number, foods?: number, units?: number, rating?: number, books?: string, keywordsOr?: string, foodsOr?: string, booksOr?: string, internal?: string, random?: string, _new?: string, page?: number, pageSize?: number, options?: any) {
- return ApiApiFp(this.configuration).listRecipes(query, keywords, foods, units, rating, books, keywordsOr, foodsOr, booksOr, internal, random, _new, page, pageSize, options).then((request) => request(this.axios, this.basePath));
+ public listRecipes(query?: string, keywords?: number, keywordsOr?: number, keywordsAnd?: number, keywordsOrNot?: number, keywordsAndNot?: number, foods?: number, units?: number, rating?: number, books?: string, foodsOr?: string, booksOr?: string, internal?: string, random?: string, _new?: string, page?: number, pageSize?: number, options?: any) {
+ return ApiApiFp(this.configuration).listRecipes(query, keywords, keywordsOr, keywordsAnd, keywordsOrNot, keywordsAndNot, foods, units, rating, books, foodsOr, booksOr, internal, random, _new, page, pageSize, options).then((request) => request(this.axios, this.basePath));
}
/**