Finish documentation, automatize API_URL for dev
This commit is contained in:
parent
e7659166be
commit
2b04eec393
@ -17,8 +17,10 @@ $ npm run build # Build the JS dependencies
|
|||||||
|
|
||||||
Ideally, Python dependencies should be installed in a virtual environment.
|
Ideally, Python dependencies should be installed in a virtual environment.
|
||||||
|
|
||||||
TODO:
|
If you serve the app from a subdirectory (and not the root of your domain),
|
||||||
- `npm run build` should handle prefix
|
you might want to run `API_URL=/subdir/ npm run build` instead of `npm run
|
||||||
|
build` to use the correct path to call the API. Note that the trailing slash
|
||||||
|
is important.
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@ -57,6 +59,9 @@ Additionnally, you can use `make dev` to spawn a development webserver to
|
|||||||
serve the JS frontend and auto-update/auto-reload when you make changes. The
|
serve the JS frontend and auto-update/auto-reload when you make changes. The
|
||||||
spawned JS server will be set up at `localhost:8081` and you should start the
|
spawned JS server will be set up at `localhost:8081` and you should start the
|
||||||
backend Python server at `localhost:8080` with `python -m cuizin` along it.
|
backend Python server at `localhost:8080` with `python -m cuizin` along it.
|
||||||
|
You can simply open the app at `localhost:8081` and start developping, it will
|
||||||
|
automatically call the API from the `python -m cuizin` process, on port
|
||||||
|
`8080`.
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
const merge = require('webpack-merge')
|
const merge = require('webpack-merge')
|
||||||
|
const process = require('process');
|
||||||
const prodEnv = require('./prod.env')
|
const prodEnv = require('./prod.env')
|
||||||
|
|
||||||
module.exports = merge(prodEnv, {
|
module.exports = merge(prodEnv, {
|
||||||
NODE_ENV: '"development"'
|
NODE_ENV: '"development"',
|
||||||
|
API_URL: JSON.stringify(process.env.API_URL || "http://localhost:8080/"),
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
const process = require('process');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
NODE_ENV: '"production"'
|
NODE_ENV: '"production"',
|
||||||
|
API_URL: JSON.stringify(process.env.API_URL || null)
|
||||||
}
|
}
|
||||||
|
30
cuizin/db.py
30
cuizin/db.py
@ -33,16 +33,25 @@ class Recipe(Model):
|
|||||||
"""
|
"""
|
||||||
Our base model for a recipe.
|
Our base model for a recipe.
|
||||||
"""
|
"""
|
||||||
title = CharField()
|
# Name of the recipe
|
||||||
|
title = CharField(null=True)
|
||||||
|
# URL, should be unique
|
||||||
url = CharField(null=True, unique=True)
|
url = CharField(null=True, unique=True)
|
||||||
|
# Author
|
||||||
author = CharField(null=True)
|
author = CharField(null=True)
|
||||||
|
# Picture as a binary blob
|
||||||
picture = BlobField(null=True)
|
picture = BlobField(null=True)
|
||||||
|
# Short description
|
||||||
short_description = TextField(null=True)
|
short_description = TextField(null=True)
|
||||||
|
# Number of persons as text, as it can be either "N persons" or "N parts"
|
||||||
nb_person = TextField(null=True)
|
nb_person = TextField(null=True)
|
||||||
|
# Preparation and cooking times
|
||||||
preparation_time = IntegerField(null=True) # In minutes
|
preparation_time = IntegerField(null=True) # In minutes
|
||||||
cooking_time = IntegerField(null=True) # In minutes
|
cooking_time = IntegerField(null=True) # In minutes
|
||||||
|
# List of ingredients
|
||||||
ingredients = JSONField(null=True)
|
ingredients = JSONField(null=True)
|
||||||
instructions = TextField()
|
# Instructions
|
||||||
|
instructions = TextField(null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
database = database
|
database = database
|
||||||
@ -70,12 +79,13 @@ class Recipe(Model):
|
|||||||
serialized = model_to_dict(self)
|
serialized = model_to_dict(self)
|
||||||
# Dump picture as a base64 string, compatible with HTML `src` attribute
|
# Dump picture as a base64 string, compatible with HTML `src` attribute
|
||||||
# for images.
|
# for images.
|
||||||
picture_mime = (
|
if serialized['picture']:
|
||||||
'data:%s;base64' % magic.from_buffer(serialized['picture'],
|
picture_mime = (
|
||||||
mime=True)
|
'data:%s;base64' % magic.from_buffer(serialized['picture'],
|
||||||
)
|
mime=True)
|
||||||
serialized['picture'] = '%s,%s' % (
|
)
|
||||||
picture_mime,
|
serialized['picture'] = '%s,%s' % (
|
||||||
base64.b64encode(serialized['picture']).decode('utf-8')
|
picture_mime,
|
||||||
)
|
base64.b64encode(serialized['picture']).decode('utf-8')
|
||||||
|
)
|
||||||
return serialized
|
return serialized
|
||||||
|
@ -49,7 +49,7 @@ export default {
|
|||||||
fetchRecipes() {
|
fetchRecipes() {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
|
||||||
fetch(`${constants.API_URL}/api/v1/recipes`)
|
fetch(`${constants.API_URL}api/v1/recipes`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
this.recipes = response.recipes;
|
this.recipes = response.recipes;
|
||||||
|
@ -122,7 +122,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
submitImport() {
|
submitImport() {
|
||||||
this.disabledImport = true;
|
this.disabledImport = true;
|
||||||
fetch(`${constants.API_URL}/api/v1/recipes`, {
|
fetch(`${constants.API_URL}api/v1/recipes`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
url: this.url,
|
url: this.url,
|
||||||
|
@ -54,7 +54,7 @@ export default {
|
|||||||
fetchRecipe() {
|
fetchRecipe() {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
|
||||||
fetch(`${constants.API_URL}/api/v1/recipe/${this.$route.params.recipeId}`)
|
fetch(`${constants.API_URL}api/v1/recipe/${this.$route.params.recipeId}`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
this.recipe = response.recipes[0];
|
this.recipe = response.recipes[0];
|
||||||
@ -62,7 +62,7 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleDelete() {
|
handleDelete() {
|
||||||
fetch(`${constants.API_URL}/api/v1/recipe/${this.$route.params.recipeId}`, {
|
fetch(`${constants.API_URL}api/v1/recipe/${this.$route.params.recipeId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
})
|
})
|
||||||
.then(() => this.$router.replace('/'));
|
.then(() => this.$router.replace('/'));
|
||||||
|
@ -1,2 +1 @@
|
|||||||
export const API_URL = 'http://localhost:8080'; // TODO: Should be coming from an env variable
|
export const API_URL = process.env.API_URL || '/'; // eslint-disable-line import/prefer-default-export,no-use-before-define
|
||||||
export const FOOBAR = 'TODO'; // TODO
|
|
||||||
|
@ -47,8 +47,9 @@ def add_recipe(url):
|
|||||||
recipe.url = url
|
recipe.url = url
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# If we could not scrape anything, simply create an empty recipe storing
|
||||||
|
# the URL.
|
||||||
if not recipe:
|
if not recipe:
|
||||||
# TODO
|
|
||||||
recipe = db.Recipe()
|
recipe = db.Recipe()
|
||||||
recipe.url = url
|
recipe.url = url
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user