Skip to content

Commit

Permalink
less 404s
Browse files Browse the repository at this point in the history
  • Loading branch information
yassiommi committed Jun 12, 2020
2 parents e8ca3b2 + f64bc5e commit aa53b50
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 51 deletions.
3 changes: 2 additions & 1 deletion admin.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from flask_admin import Admin
from extentions import db
from users.models import User, UserModelView
from foods.models import Food, FoodModelView
from foods.models import Food, FoodModelView,DietRecord,DietRecordModelView
from blog.models import Post,PostModelView

admin = Admin(name='Dailydiet', template_mode='bootstrap3', url='/admin')
# adding models to admin
admin.add_view(UserModelView(User, db.session, endpoint='user_admin'))
admin.add_view(FoodModelView(Food, db.session, endpoint='food_admin'))
admin.add_view(PostModelView(Post, db.session, endpoint='post_admin'))
admin.add_view(DietRecordModelView(DietRecord,db.session,endpoint='diet_record_admin'))
6 changes: 4 additions & 2 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ class Config(object):
"protein_shake": "https://img.icons8.com/color/7x/protein.png",
"salad": "https://img.icons8.com/color/7x/salad.png",
"pasta": "https://img.icons8.com/color/7x/spaghetti.png",
"other": "https://img.icons8.com/color/7x/cookbook.png"
"other": "https://img.icons8.com/color/7x/cookbook.png",
"ingredient": "https://img.icons8.com/color/7x/grocery-bag.png"
},
"thumbnail": {
"mostly_meat": "https://img.icons8.com/color/2x/steak.png",
Expand All @@ -62,7 +63,8 @@ class Config(object):
"protein_shake": "https://img.icons8.com/color/2x/protein.png",
"salad": "https://img.icons8.com/color/2x/salad.png",
"pasta": "https://img.icons8.com/color/2x/spaghetti.png",
"other": "https://img.icons8.com/color/2x/cookbook.png"
"other": "https://img.icons8.com/color/2x/cookbook.png",
"ingredient":"https://img.icons8.com/color/2x/grocery-bag.png"
}
}

Expand Down
112 changes: 78 additions & 34 deletions create_elastic_index.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@
},
{
"cell_type": "code",
"execution_count": 106,
"execution_count": 16,
"metadata": {
"pycharm": {
"is_executing": false,
Expand All @@ -211,7 +211,7 @@
},
{
"cell_type": "code",
"execution_count": 107,
"execution_count": 17,
"metadata": {
"pycharm": {
"is_executing": false,
Expand All @@ -221,39 +221,11 @@
"outputs": [
{
"data": {
"text/plain": [
"{'took': 2,\n",
" 'timed_out': False,\n",
" '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0},\n",
" 'hits': {'total': {'value': 2, 'relation': 'eq'},\n",
" 'max_score': 7.2770195,\n",
" 'hits': [{'_index': 'ingredients',\n",
" '_type': 'ingredient',\n",
" '_id': '164513',\n",
" '_score': 7.2770195,\n",
" '_source': {'food_name': 'Mangos',\n",
" 'id': 164513,\n",
" 'primary_thumbnail': 'https://images.eatthismuch.com/site_media/thmb/164513_simmyras_016d1a64-02af-4910-bfe4-184e12b138a9.png',\n",
" 'nutrition': {'calories': 130.0,\n",
" 'carbs': 32.0,\n",
" 'fats': 0.0,\n",
" 'proteins': 1.0}}},\n",
" {'_index': 'ingredients',\n",
" '_type': 'ingredient',\n",
" '_id': '1448',\n",
" '_score': 7.2770195,\n",
" '_source': {'food_name': 'Mangos',\n",
" 'id': 1448,\n",
" 'primary_thumbnail': 'https://images.eatthismuch.com/site_media/thmb/1448_erin_m_80d7aa63-91c7-4999-9942-d6ebea57bb2a.png',\n",
" 'nutrition': {'calories': 124.2,\n",
" 'carbs': 31.01,\n",
" 'fats': 0.79,\n",
" 'proteins': 1.7}}}]}}"
]
"text/plain": "{'took': 0,\n 'timed_out': False,\n '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0},\n 'hits': {'total': {'value': 2, 'relation': 'eq'},\n 'max_score': 7.549581,\n 'hits': [{'_index': 'ingredients',\n '_type': 'ingredient',\n '_id': '164513',\n '_score': 7.549581,\n '_source': {'food_name': 'Mangos',\n 'id': 164513,\n 'primary_thumbnail': 'https://images.eatthismuch.com/site_media/thmb/164513_simmyras_016d1a64-02af-4910-bfe4-184e12b138a9.png',\n 'nutrition': {'calories': 130.0,\n 'carbs': 32.0,\n 'fats': 0.0,\n 'proteins': 1.0}}},\n {'_index': 'ingredients',\n '_type': 'ingredient',\n '_id': '1448',\n '_score': 7.549581,\n '_source': {'food_name': 'Mangos',\n 'id': 1448,\n 'primary_thumbnail': 'https://images.eatthismuch.com/site_media/thmb/1448_erin_m_80d7aa63-91c7-4999-9942-d6ebea57bb2a.png',\n 'nutrition': {'calories': 124.2,\n 'carbs': 31.01,\n 'fats': 0.79,\n 'proteins': 1.7}}}]}}"
},
"execution_count": 107,
"metadata": {},
"output_type": "execute_result"
"output_type": "execute_result",
"execution_count": 17
}
],
"source": [
Expand Down Expand Up @@ -358,7 +330,11 @@
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"metadata": {
"pycharm": {
"is_executing": false
}
},
"outputs": [],
"source": [
"from elasticsearch_dsl import Q,Search\n"
Expand Down Expand Up @@ -418,6 +394,74 @@
" .limit(10).all()"
]
},
{
"cell_type": "code",
"execution_count": 14,
"outputs": [],
"source": [
"query= 'roast beef'\n",
"page=1\n",
"per_page=5\n",
"search = Search(using=elastic, index='foods_new')\n",
"elastic_query = Q('bool',\n",
" should=[\n",
" {\n",
" \"multi_match\": {\n",
" \"query\": query,\n",
" \"fields\": [\n",
" \"name^6.0\",\n",
" \"category^1.0\",\n",
" \"description^3.0\",\n",
" \"tag_cloud^3.0\",\n",
" \"ingredients^2.0\",\n",
" \"directions^1.5\",\n",
" \"author^1.0\"\n",
" ],\n",
" \"type\": \"phrase_prefix\",\n",
" \"lenient\": \"true\"\n",
" }\n",
" },\n",
"\n",
" ],\n",
" boost=1,\n",
" minimum_should_match=1)\n",
"from_index = (page - 1) * per_page\n",
"size = per_page\n",
"search = search.query(elastic_query)\n",
"search_results = search[from_index: from_index + size].execute()\n"
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%\n",
"is_executing": false
}
}
},
{
"cell_type": "code",
"execution_count": 15,
"outputs": [
{
"data": {
"text/plain": "{'took': 2,\n 'timed_out': False,\n '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0},\n 'hits': {'total': {'value': 17, 'relation': 'eq'},\n 'max_score': 62.20536,\n 'hits': [{'_index': 'foods_new',\n '_type': '_doc',\n '_id': '33533',\n '_score': 62.20536,\n '_source': {'author': 'Ken Adams',\n 'name': 'Basic roast beef',\n 'description': '',\n 'category': 'mostly_meat',\n 'nutrition': {'calories': 129.75333333333333,\n 'carbs': 0.03666666666666667,\n 'fats': 9.813333333333334,\n 'proteins': 9.700000000000001},\n 'tag_cloud': 'Olive oil Pepper \"Basic roast beef\" Beef chuck Beef Products Spices and Herbs Fats and Oils Salt',\n 'ingredients': ['Beef chuck', 'Olive oil', 'Salt', 'Pepper'],\n 'ingredient_ids': [2899, 266, 221, 205],\n 'directions': ['Preheat oven to 450F (230C). Place beef in a roasting pan, cover with a clean kitchen towel or plastic wrap and let stand at room temp for 20 mins.',\n 'Using a glazing brush, brush beef with olive oil, then season with sea salt and pepper to taste.',\n 'Bake for 20 minutes, then reduce temp to 350F (180C) and bake until cooked to your taste, between an extra 1 hour to 1 hour and 20 mins.',\n 'Remove beef from oven, transfer to a plate, cover with aluminum foil and let rest for 20 mins. Carve and serve with gravy and potatoes.'],\n 'cook_time': 100,\n 'prep_time': 5,\n 'total_time': 105}},\n {'_index': 'foods_new',\n '_type': '_doc',\n '_id': '986392',\n '_score': 55.91916,\n '_source': {'author': 'Ken Adams',\n 'name': 'Breadless Philly Roast Beef',\n 'description': '',\n 'category': 'other',\n 'nutrition': {'calories': 56.12833333333333,\n 'carbs': 1.8,\n 'fats': 3.35,\n 'proteins': 4.878333333333333},\n 'tag_cloud': 'Olive oil Pepper Dairy Products Salt Provolone cheese Mushrooms Spices and Herbs Vegetables and Vegetable Products Garlic Slow Roasted Roast Beef peppers Green bell pepper Fats and Oils Onions \"Breadless Philly Roast Beef\"',\n 'ingredients': ['Green bell pepper',\n 'Onions',\n 'Mushrooms',\n 'Olive oil',\n 'Garlic',\n 'Salt',\n 'Pepper',\n 'Slow Roasted Roast Beef',\n 'Provolone cheese'],\n 'ingredient_ids': [2080, 2042, 2021, 266, 1980, 221, 205, 95368, 35],\n 'directions': ['Preheat oven to 400 degrees F. Remove tops and seed from bell peppers. Slice onions and mushrooms.',\n 'Heat oil in a pan over medium heat. Saute onions and mushrooms with garlic, pepper, and salt until tender, about 10-12 minutes.',\n 'Slice roast beef into strips',\n 'Layer roast beef, vegetables, and cheese in layers (two slices of cheese per pepper) inside the pepper',\n 'Bake for 10-15 minutes or until cheese is golden brown. Enjoy!'],\n 'cook_time': 27,\n 'prep_time': 10,\n 'total_time': 37}},\n {'_index': 'foods_new',\n '_type': '_doc',\n '_id': '906749',\n '_score': 50.786865,\n '_source': {'author': 'Ken Adams',\n 'name': 'Roast Beef Sandwich Au Jus',\n 'description': '',\n 'category': 'sandwich',\n 'nutrition': {'calories': 60.629999999999995,\n 'carbs': 4.755,\n 'fats': 2.3216666666666668,\n 'proteins': 5.036666666666666},\n 'tag_cloud': 'Dairy Products Gravy, au jus Beef Products Sourdough bread Swiss cheese Soups, Sauces, and Gravies Beef round Baked Products \"Roast Beef Sandwich Au Jus\" gluten',\n 'ingredients': ['Sourdough bread',\n 'Beef round',\n 'Swiss cheese',\n 'Gravy, au jus'],\n 'ingredient_ids': [3991, 2831, 40, 712],\n 'directions': ['Slice loaf lengthwise (butterfly) and place in broiler for 1 minute. Add roast beef then cheese on top, broil for another 3-5 minutes or until cheese is melting.',\n 'On stovetop heat Au Jus until warm. Enjoy!'],\n 'cook_time': 6,\n 'prep_time': 2,\n 'total_time': 8}},\n {'_index': 'foods_new',\n '_type': '_doc',\n '_id': '906002',\n '_score': 50.786865,\n '_source': {'author': 'Ken Adams',\n 'name': 'Roast Beef and Cheddar Sandwich',\n 'description': '',\n 'category': 'sandwich',\n 'nutrition': {'calories': 449.79,\n 'carbs': 25.41,\n 'fats': 19.84,\n 'proteins': 41.32},\n 'tag_cloud': 'Dijon mustard Cheddar cheese Dairy Products Whole-wheat bread \"Roast Beef and Cheddar Sandwich\" Beef Products Roast Beef Spices and Herbs Baked Products gluten',\n 'ingredients': ['Whole-wheat bread',\n 'Roast Beef',\n 'Cheddar cheese',\n 'Dijon mustard'],\n 'ingredient_ids': [4025, 99794, 9, 5815],\n 'directions': ['Spread mustard onto slices of bread. Top with roast beef and cheddar. Bring together slices to form a sandwich. Enjoy!'],\n 'cook_time': 0,\n 'prep_time': 5,\n 'total_time': 5}},\n {'_index': 'foods_new',\n '_type': '_doc',\n '_id': '45177',\n '_score': 46.517456,\n '_source': {'author': 'Ken Adams',\n 'name': 'Roast Beef and Avocado Finger Sandwiches',\n 'description': '',\n 'category': 'sandwich',\n 'nutrition': {'calories': 5.771111111111111,\n 'carbs': 0.5027777777777778,\n 'fats': 0.2683333333333333,\n 'proteins': 0.34444444444444444},\n 'tag_cloud': 'Chives gluten \"Roast Beef and Avocado Finger Sandwiches\" Whole-wheat bread Salt Pepper Beef chuck Spices and Herbs Light mayonnaise Beef Products Lemon juice Vegetables and Vegetable Products Avocados Fats and Oils Fruits and Fruit Juices Baked Products',\n 'ingredients': ['Chives',\n 'Beef chuck',\n 'Whole-wheat bread',\n 'Lemon juice',\n 'Salt',\n 'Pepper',\n 'Avocados',\n 'Light mayonnaise'],\n 'ingredient_ids': [1937, 2799, 4025, 1434, 221, 205, 1334, 367],\n 'directions': ['PREPARATION: Mince chives. Thinly slice rare roast beef.',\n 'In small bowl, mash avocado with fork. Stir in lemon juice, chives, salt, and pepper. Spread avocado mash over 6 slices bread, dividing evenly.',\n 'Spread other 6 slices bread with about 1 teaspoon each mayonnaise. Top with roast beef, dividing evenly. Gently press avocado-topped bread slices, avocado sides down, onto each sandwich.',\n 'Using long serrated knife, trim off crusts and cut each sandwich lengthwise into thirds.',\n 'Transportation tips: Transfer the sandwiches to a covered plastic container to transport them to the picnic, and then simply pass around the container to serve. To keep the bread from drying out, when stacking the sandwiches in the container, lay a sturdy, barely moistened paper towel between each layer and another one over the top.'],\n 'cook_time': 0,\n 'prep_time': 10,\n 'total_time': 10}}]}}"
},
"metadata": {},
"output_type": "execute_result",
"execution_count": 15
}
],
"source": [
"search_results.to_dict()"
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%\n",
"is_executing": false
}
}
},
{
"cell_type": "code",
"execution_count": null,
Expand Down
64 changes: 58 additions & 6 deletions foods/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
from config import Config
from extentions import db, elastic
from wtforms import SelectField
# from elasticsearch_dsl import Q, Search


class SearchTimedOutException(Exception):
pass


class SearchableMixin(object):
Expand Down Expand Up @@ -47,12 +52,38 @@ def remove_from_index(cls, instance):
def query_index(cls, query, page=1, per_page=10):
if elastic is None:
return [], 0
search = elastic.search(
index=cls.__indexname__,
body={'query': {'multi_match': {'query': query, 'fields': ['*']}},
'from': (page - 1) * per_page, 'size': per_page})
ids = [int(hit['_id']) for hit in search['hits']['hits']]
return ids, search['hits']['total']['value']
search = Search(using=elastic, index=cls.__indexname__)
elastic_query = Q('bool',
should=[
{
"multi_match": {
"query": query,
"fields": [
"name^6.0",
"category^1.0",
"description^3.0",
"tag_cloud^3.0",
"ingredients^2.0",
"directions^1.5",
"author^1.0"
],
"type": "phrase_prefix",
"lenient": "true"
}
},

],
boost=1,
minimum_should_match=1)
from_index = (page - 1) * per_page
size = per_page
search = search.query(elastic_query)
search_results = search[from_index: from_index + size].execute().to_dict()
if search_results['timed_out']:
raise SearchTimedOutException()

ids = [int(hit['_id']) for hit in search_results['hits']['hits']]
return ids, search_results['hits']['total']['value']

@classmethod
def search(cls, expression, page=1, per_page=10):
Expand Down Expand Up @@ -86,6 +117,19 @@ def after_commit(cls, session):
cls.remove_from_index(obj)
session._changes = None

@classmethod
def ingredient_search(cls, expression, page=1, per_page=10):
if elastic is None:
return [], 0
search_results = elastic.search(
index='ingredients',
body={'query': {'multi_match': {'query': expression, 'fields': ['food_name']}},
'from': (page - 1) * per_page, 'size': per_page})
if search_results['timed_out']:
raise SearchTimedOutException()
total = search_results['hits']['total']['value']
return [hit['_source'] for hit in search_results['hits']['hits']], total

@classmethod
def reindex(cls):
for obj in cls.query:
Expand Down Expand Up @@ -237,5 +281,13 @@ class DietRecord(db.Model):
diet = Column('diet', JSON(), nullable=False)


class DietRecordModelView(ModelView):
can_edit = True
column_display_pk = True
create_modal = True
edit_modal = True
column_labels = {'generatedAt': 'Generated At', 'diet': 'Diet ids'}


db.event.listen(db.session, 'before_commit', SearchableMixin.before_commit)
db.event.listen(db.session, 'after_commit', SearchableMixin.after_commit)
Loading

0 comments on commit aa53b50

Please sign in to comment.