Hooked up frontend and backend
This commit is contained in:
parent
84a1e7d972
commit
65da7e8800
9 changed files with 49 additions and 72 deletions
|
@ -1,5 +1,5 @@
|
||||||
import JSONAPIAdapter from '@ember-data/adapter/json-api';
|
import JSONAPIAdapter from '@ember-data/adapter/json-api';
|
||||||
|
|
||||||
export default class ApplicationAdapter extends JSONAPIAdapter {
|
export default class ApplicationAdapter extends JSONAPIAdapter {
|
||||||
host = 'https://www.themealdb.com/api/json/v1/1';
|
host = 'http://localhost:8000/';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,51 +1,15 @@
|
||||||
import ApplicationAdapter from './application';
|
import ApplicationAdapter from './application';
|
||||||
import { dasherize } from '@ember/string';
|
|
||||||
|
|
||||||
export default class MealAdapter extends ApplicationAdapter {
|
export default class MealAdapter extends ApplicationAdapter {
|
||||||
async findRecord(store, model, id) {
|
async findRecord(store, model, id) {
|
||||||
let result = await fetch(`${this.host}/lookup.php?i=${id}`);
|
let result = await fetch(`${this.host}meal/${id}`);
|
||||||
let json = await result.json();
|
return await result.json();
|
||||||
return normalize(json.meals[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async queryRecord(store, model, query) {
|
async queryRecord(store, model, query) {
|
||||||
if (query === 'random') {
|
if (query === 'random') {
|
||||||
let result = await fetch(`${this.host}/random.php`);
|
let result = await fetch(`${this.host}meals/random`);
|
||||||
let json = await result.json();
|
return await result.json();
|
||||||
return normalize(json.meals[0]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalize(obj) {
|
|
||||||
let attributes = {};
|
|
||||||
|
|
||||||
Object.keys(obj).forEach(key => attributes[cleanKey(key)] = obj[key]);
|
|
||||||
attributes.ingredients = groupByKeyPrefix('ingredient', attributes);
|
|
||||||
|
|
||||||
return {
|
|
||||||
data: {
|
|
||||||
type: 'meal',
|
|
||||||
id: attributes.id,
|
|
||||||
attributes,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function cleanKey(key) {
|
|
||||||
key = dasherize(key);
|
|
||||||
key = key.replace('str-', '');
|
|
||||||
if (key === 'id-meal') key = 'id';
|
|
||||||
if (key === 'meal') key = 'name';
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
function groupByKeyPrefix(keyPrefix, obj) {
|
|
||||||
let resultingArray = [];
|
|
||||||
Object.keys(obj).forEach(key => {
|
|
||||||
let value = obj[key];
|
|
||||||
if (!value) return;
|
|
||||||
if (key.startsWith(keyPrefix)) resultingArray.push(value);
|
|
||||||
});
|
|
||||||
return resultingArray;
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ export default class RecipeListComponent extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
get sortedItems() {
|
get sortedItems() {
|
||||||
console.log('sorted items called');
|
|
||||||
return this.items.sortBy('listOrder');
|
return this.items.sortBy('listOrder');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<LinkTo @route="meal" @model={{@meal}} class="block bg-white border border-gray-400 focus:border-teal-500 focus:shadow-sm focus:bg-teal-100 outline-none">
|
<LinkTo @route="meal" @model={{@meal}} class="block bg-white border border-gray-400 focus:border-teal-500 focus:shadow-sm focus:bg-teal-100 outline-none">
|
||||||
<div class="max-w-sm w-full lg:max-w-full lg:flex">
|
<div class="max-w-sm w-full lg:max-w-full lg:flex">
|
||||||
<div class="h-48 lg:h-auto lg:w-48 flex-none">
|
<div class="h-48 lg:h-auto lg:w-48 flex-none">
|
||||||
<img src={{@meal.mealThumb}} alt="" class="h-full w-full object-cover">
|
<img src={{@meal.thumbnailUrl}} alt="" class="h-full w-full object-cover">
|
||||||
</div>
|
</div>
|
||||||
<div class="p-4 flex flex-col justify-between leading-normal">
|
<div class="p-4 flex flex-col justify-between leading-normal">
|
||||||
<div class="mb-8">
|
<div class="mb-8">
|
||||||
|
@ -9,9 +9,7 @@
|
||||||
{{@meal.name}}
|
{{@meal.name}}
|
||||||
</div>
|
</div>
|
||||||
<p class="text-gray-700 text-base">
|
<p class="text-gray-700 text-base">
|
||||||
{{#each @meal.ingredients as |ingredient|}}
|
{{@meal.ingredientsList}}
|
||||||
{{ingredient}}
|
|
||||||
{{/each}}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -2,15 +2,21 @@ import DS from 'ember-data';
|
||||||
const { Model, attr } = DS;
|
const { Model, attr } = DS;
|
||||||
|
|
||||||
export default class MealModel extends Model {
|
export default class MealModel extends Model {
|
||||||
@attr name;
|
@attr alternateDrink;
|
||||||
@attr dateModified;
|
|
||||||
@attr category;
|
|
||||||
@attr area;
|
@attr area;
|
||||||
@attr mealThumb;
|
@attr category;
|
||||||
|
@attr dateModified;
|
||||||
@attr instructions;
|
@attr instructions;
|
||||||
@attr ingredients;
|
@attr name;
|
||||||
|
@attr sourceUrl;
|
||||||
@attr tags;
|
@attr tags;
|
||||||
@attr youtube;
|
@attr thumbnailUrl;
|
||||||
@attr source;
|
@attr youtubeUrl;
|
||||||
|
@attr ingredients;
|
||||||
|
|
||||||
@attr('number', { defaultValue: Infinity }) listOrder;
|
@attr('number', { defaultValue: Infinity }) listOrder;
|
||||||
|
|
||||||
|
get ingredientsList() {
|
||||||
|
return this.ingredients.map(ingredient => ingredient.name).join(', ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{{@model.name}}
|
{{@model.name}}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<img src={{@model.mealThumb}} alt="" class="float-right w-1/3 rounded-lg ml-8 mb-4 shadow-lg border-8 border-white">
|
<img src={{@model.thumbnailUrl}} alt="" class="float-right w-1/3 rounded-lg ml-8 mb-4 shadow-lg border-8 border-white">
|
||||||
|
|
||||||
<p class="text-gray-700 text-base whitespace-pre-line">
|
<p class="text-gray-700 text-base whitespace-pre-line">
|
||||||
{{@model.instructions}}
|
{{@model.instructions}}
|
||||||
|
|
2
python-api/.gitignore
vendored
2
python-api/.gitignore
vendored
|
@ -1 +1 @@
|
||||||
/__pycache__
|
__pycache__
|
||||||
|
|
Binary file not shown.
|
@ -14,13 +14,24 @@ class Base(Handler):
|
||||||
["strCategory", "category"],
|
["strCategory", "category"],
|
||||||
["strArea", "area"],
|
["strArea", "area"],
|
||||||
["strInstructions", "instructions"],
|
["strInstructions", "instructions"],
|
||||||
["strDrinkAlternate", "alternate_drink"],
|
["strDrinkAlternate", "alternate-drink"],
|
||||||
["strMealThumb", "thumbnail_url"],
|
["strMealThumb", "thumbnail-url"],
|
||||||
["strTags", "tags"],
|
["strTags", "tags"],
|
||||||
["strYoutube", "youtube_url"],
|
["strYoutube", "youtube-url"],
|
||||||
["strSource", "source_url"],
|
["strSource", "source-url"],
|
||||||
["dateModified", "date_modified"],
|
["dateModified", "date-modified"],
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def normalize(self, response, model_type = "meal"):
|
||||||
|
return {
|
||||||
|
"data": {
|
||||||
|
"id": response["id"],
|
||||||
|
"attributes": response,
|
||||||
|
"type": model_type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def cleanup(self, meal):
|
def cleanup(self, meal):
|
||||||
self.replacable_keys.do_replace(meal)
|
self.replacable_keys.do_replace(meal)
|
||||||
self.cleanup_ingredients(meal)
|
self.cleanup_ingredients(meal)
|
||||||
|
@ -49,23 +60,22 @@ class Base(Handler):
|
||||||
|
|
||||||
class Details(Base):
|
class Details(Base):
|
||||||
def get(self, meal_id = ''):
|
def get(self, meal_id = ''):
|
||||||
response = json.loads(requests.get(self.hostname + "lookup.php?i=" + meal_id).text)
|
response = json.loads(requests.get(self.hostname + "lookup.php?i=" + meal_id).text)["meals"][0]
|
||||||
for meal in response["meals"]:
|
self.cleanup(response)
|
||||||
self.cleanup(meal)
|
|
||||||
|
|
||||||
return json.dumps(response)
|
return self.normalize(response)
|
||||||
|
|
||||||
|
|
||||||
class Random(Base):
|
class Random(Base):
|
||||||
def get(self):
|
def get(self):
|
||||||
response = json.loads(requests.get(self.hostname + "random.php").text)
|
response = json.loads(requests.get(self.hostname + "random.php").text)["meals"][0]
|
||||||
for meal in response["meals"]:
|
self.cleanup(response)
|
||||||
self.cleanup(meal)
|
|
||||||
|
|
||||||
return json.dumps(response)
|
return self.normalize(response)
|
||||||
|
|
||||||
class app(WSGI):
|
class app(WSGI):
|
||||||
routes = [
|
headers = [("Access-Control-Allow-Origin", "*")]
|
||||||
("/meals/random", Random()),
|
routes = [
|
||||||
("/meal/([\w]+)", Details())
|
("/meals/random", Random()),
|
||||||
]
|
("/meal/([\w]+)", Details())
|
||||||
|
]
|
||||||
|
|
Loading…
Add table
Reference in a new issue