-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrecipe_winnow.py
More file actions
97 lines (88 loc) · 2.49 KB
/
recipe_winnow.py
File metadata and controls
97 lines (88 loc) · 2.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from winnow import Winnow
RECIPE_SOURCES = [
# standard sources
dict(
display_name='Name',
column='name',
value_types=['string'],
),
dict(
display_name='Date Published',
column='date_published',
value_types=['absolute_date', 'relative_date'],
),
dict(
display_name='Description',
column='description',
value_types=['string'],
),
# special sources
dict(
display_name='Prep Time (minutes)',
column='(EXTRACT(EPOCH FROM prep_time)::int / 60)',
value_types=['numeric'],
),
dict(
display_name='Cook Time (minutes)',
column='(EXTRACT(EPOCH FROM cook_time)::int / 60)',
value_types=['numeric'],
),
dict(
display_name='Ingredients',
value_types=['collection'],
),
dict(
display_name='Suitable for Diet',
value_types=['collection'],
picklist_values=[
'vegan',
'vegetarian',
'gluten-free',
'halal',
'kosher',
]
),
]
class RecipeWinnow(Winnow):
def __init__(self):
super().__init__('recipe', RECIPE_SOURCES)
# This is ugly, and I wish I knew a better way to seperate these values.
# maybe just pass them in at initialization?
_special_cases = {}
@RecipeWinnow.special_case('Ingredients', 'collection')
def ingredients(rw, clause):
return rw.sql.prepare_query(
'''
{% if not_any_of %}
NOT
{% endif %}
id = ANY(
SELECT recipe_id FROM ingredient
{% for ing in value %}
, plainto_tsquery('english', {{ ing }}) "q{{ loop.index | sqlsafe }}"
{% endfor %}
WHERE
{% for ing in value %}
to_tsvector('english', ingredient_text) @@ "q{{ loop.index | sqlsafe }}"
{% if not loop.last %} OR {% endif %}
{% endfor %}
)
''',
value=clause['value_vivified'],
not_any_of=clause['operator'] == 'not any of',
)
@RecipeWinnow.special_case('Suitable for Diet', 'collection')
def diet_suitability(rw, clause):
return rw.sql.prepare_query(
'''
{% if not_any_of %}
NOT
{% endif %}
id = ANY(
SELECT recipe_id FROM diet_suitability
WHERE diet = ANY({{ value }})
)
''',
value=clause['value_vivified'],
not_any_of=clause['operator'] == 'not any of',
)