- Recipes 'N' Stuff
- Fig 1: Responsive Mockup
- Features
- Design
- Development and Local Deployment
- Test
- Credits
- Recipes 'N' Stuff
- Fig 1: Responsive Mockup
- Features
- Design
- Development and Local Deployment
- Cloud-based Deployment
- Test
- Credits
Recipes 'N' Stuff is an e-commerce site, focused on a community looking for recipe suggestions and online shopping convenience. It utilises a subscription-based model, whereby registered users receive recipe suggestions, with the option to optionally purchase the required ingredients.
The site is aimed at users seeking a platform seeking a source of inspirational recipe ideas, with a convenient online shopping experience.
Users may register for an account or alternatively use OAuth to sign in via their Google or Twitter accounts.
User registration | User authentication |
---|---|
Change password | Manage email addresses |
There are two user roles:
-
Registered user
Registered users may add/edit/delete their own recipes. All registered users may view any recipe on the site, and purchase ingredient boxes for any recipe on the site.
-
Site administrator
The site administrator may perform all functions on the site.
Users receive notifications following sign in and other events:
New user notification | Login notification |
---|---|
Added to basket | |
Users may create recipes and addresses. Site administrators may in addition, create subscription plans.
All users may view all recipes. Individual users may view their addresses.
Users may edit their recipes. Individual users may edit their addresses.
Users may delete their recipes. Individual users may edit their addresses.
Note: Subscription creation is incomplete as it is necessary to create and assign subscription features in the Administration page. User Story: Subscription features.
Users may search for recipes via search box in the navbar at the top of the screen. The search box allows user's to either perform a free word search or select from a predetermined keyword list, or they may search via category name.
Note: There is currently a limited number of recipes available,so many categories return no results.
Search box | Search result |
---|---|
Category search | |
A user (except administrator) require a valid subscription to access the site content. Without a valid subscription they are restricted to:
- choosing a subscription
- managing their addresses (as an address is required to complete a purchase)
- checking out
- logging out
Choose subscription | Subscription add address |
---|---|
The current list of possible order products is:
- Recipe ingredient boxes
- Subscriptions Order products may be configured in the system in the administrator's currency of choice.
- Basket total may be calculated in the user's currency of choice, using exchange rates from Exchange Rates Data API.
- User can choose delivery address from those saved in their profile.
- User can choose delivery method.
- User can pay via Stripe.
- User receives a order confirmation email.
Choose currency | Choose address |
---|---|
Choose delivery | Pay |
Confirmation email | |
- Users may view previous orders
- Users may view details of previous orders
- Users may reorder items from previous orders
View previous orders | View previous order detail |
---|---|
The SEO features include:
- robots.txt The robots.txt file is generated by the application. A copy is included for reference.
- sitemap.xml The sitemap.xml file is generated by the application. A copy is included for reference.
The marketing features include:
- Facebook business page A Facebook business page was created, and a snapshot is available here
Future enhancements are logged in GitHub Issues.
Future features are logged in GitHub Issues
The design specification is available in design.md.
The development environment requires:
Artifact | Download and installation instructions |
---|---|
Node.js | https://nodejs.org/en/download/ |
npm | Included with Node.js installation |
git | https://git-scm.com/downloads |
Python | https://www.python.org/downloads/ |
Django | https://www.djangoproject.com/download/ |
In an appropriate folder, run the following commands:
> git clone https://github.com/ibuttimer/recipes-n-stuff.git
> cd recipes-n-stuff
Alternatively, most IDEs provide an option to create a project from Version Control.
It is recommended that a virtual environment be used for development purposes. Please see Creating a virtual environment for details.
Note: Make sure to activate the virtual environment.
In a terminal window, in the recipes-n-stuff
folder, run the following command to setup required environment artifacts:
> npm install
In the recipes-n-stuff
folder, run the following command to install the necessary python packages:
> pip install -r requirements-dev.txt
There are two requirements files:
- requirements.txt which installs the production requirements, and
- requirements-dev.txt which installs extra development-only requirements in addition to the production requirements from requirements.txt
Key | Value |
---|---|
ENV_FILE | If using an environment file, specifies the file to use. Defaults to .env in the project root folder. |
PORT | Port application is served on; default 8000 |
DEBUG | A boolean that turns on/off debug mode; see Boolean environment variables |
DEVELOPMENT | A boolean that turns on/off development mode; see Boolean environment variables |
TEST | A boolean that turns on/off test mode; see Boolean environment variables. Only valid when development mode is enabled. |
DBG_TOOLBAR | A boolean that enables/disables Django Debug Toolbar; see Boolean environment variables. Only valid when debug mode is enabled. |
LOW_LEVEL_ADMIN | A boolean that enables/disables low level admin functionality; see Boolean environment variables. Only valid when debug mode is enabled. |
SECRET_KEY | Secret key for a particular Django installation. See Secret Key Generation |
DATABASE_URL | Database url |
AVATAR_BLANK_URL | Url of blank avatar |
RECIPE_BLANK_URL | Url of placeholder recipe image |
SITE_ID | Id (primary key) of site in the django_site table of the database. See Configure authentication. |
REMOTE_DATABASE_URL | Url of remote PostgreSQL database resource. For a Heroku app with a Heroku Postgres addon this is available from DATABASE_URL in the app Settings -> Config Vars .For an ElephantSQL database this is available from URL in the instance details.Note: Only required for admin purposes, see database configuration under Cloud-based Deployment |
GOOGLE_SITE_VERIFICATION | Google Search Console meta tag verification value for site ownership verification |
STRIPE_PUBLISHABLE_KEY | Stripe Developer API keys publishable key value for payments processing. |
STRIPE_SECRET_KEY | Stripe Developer API keys secret key value for payments processing. |
STRIPE_WEBHOOK_KEY | Stripe Webhook secret secret key value to get incoming webhooks to get real-time updates. See Test webhooks integration for local testing and Take webhooks live for hosted deployment. |
EXCHANGERATES_DATA_KEY | Exchange Rates Data API key for exchange rates. |
DEFAULT_SEND_EMAIL | Email address to send emails from. Only valid when development mode is enabled, in production mode emails are sent from EMAIL_HOST_USER |
EMAIL_HOST | SMTP server to send email. Only valid when production mode is enabled. |
EMAIL_USE_TLS | Use Transport Layer Security (TLS) flag; see Boolean environment variables, default true. Only valid when production mode is enabled. |
EMAIL_PORT | SMTP server port. Only valid when production mode is enabled. |
EMAIL_HOST_USER | Email user account to send email. Only valid when production mode is enabled. |
EMAIL_HOST_PASSWORD | Email user account password. Only valid when production mode is enabled. |
FACEBOOK_PAGE | Facebook business page link. |
Cloudinary-specific | |
CLOUDINARY_URL | Cloudinary url |
Amazon S3-specific | |
AWS_ACCESS_KEY_ID | The access key for your AWS account. |
AWS_SECRET_ACCESS_KEY | The secret key for your AWS account. |
AWS_STORAGE_BUCKET_NAME | AWS S3 bucket name. |
Heroku-specific | |
HEROKU_HOSTNAME | Hostname of application on Heroku. Note: To specify multiple hosts, use a comma-separated list with no spaces. Note: Set to localhost,127.0.0.1 in local development mode |
Set environment variables evaluating a boolean value, should be set to any of true
, on
, ok
, y
, yes
or 1
to set true, otherwise the variable is evaluated as false.
Set environment variables corresponding to the keys in Table 1: Configuration settings.
E.g.
For Linux and Mac: For Windows:
$ export DEVELOPMENT=true > set DEVELOPMENT=true
A convenient method of generating a secret key is to run the following command and copy its output.
$ python -c "import secrets; print(secrets.token_urlsafe())"
In order to configure social account login, the following actions must be performed.
The Google provider is OAuth2 based, and a Google app is needed to obtain a key and secret through the Google Developer Console.
- Login to the Google Developer Console
- Click on the
Select a project
button and then selectNew Project
- Give the project a name and click
Create
- Once created click
Select Project
on the notification or select the project from theSelect a project
modal - From the sidebar menu select APIs & Services -> Credentials
- Select
CREATE CREDENTIALS
andOAuth client ID
from the dropdown as the type of credential - Select
Web application
as the application type, and specify aName
- Add the site domain name or test domain name in
Authorized JavaScript origins
- Add the
http://127.0.0.1:8000/accounts/google/login/callback/
inAuthorised redirect URIs
- Select
CREATE
- From the
OAuth client created
modal, copy theClient ID
andClient Secret
or download the information in JSON format. - From the sidebar menu select
APIs & Services -> OAuth consent screen
- Provide the following App information
- App name
- User support email
- App logo
- Under
Authorised domains
add the site domain - Add an email address for
Developer contact information
- Select
SAVE AND CONTINUE
- Under
Authorised domains
, selectADD OR REMOVE SCOPES
and check the boxes for.../auth/userinfo.email
and.../auth/userinfo.profile
- Select
SAVE AND CONTINUE
- Under
Test users
, add the email address for the Google accounts to be used in testing - Select
SAVE AND CONTINUE
- Login to Twitter and signup to the Developer Portal
- Create a new app and save the Consumer Keys:
API Key
,API Key Secret
andBearer Token
- Open the app in the dashboard and under
User authentication settings
, selectSet up
- Select
Web App, Automated App or Bot
forType of App
- Under
App info
, setCallback URI / Redirect URL
tohttp://127.0.0.1:8000/accounts/twitter/login/callback/
Website URL
to the Heroku app URL, e.g. https://recipesnstuff.herokuapp.com/Organization name
toSoapBox
- Select
Save
, and copy the OAuth 2.0 Client ID and Client Secret displayed, and store securely. - Select
Done
- It is necessary to apply for Elevated access to the Twitter API, in order to access to private resources. Without Elevated access it is not possible to use Twitter as a sign in provider
In order to configure Stripe payments, the following actions must be performed.
- Login to Stripe
- Create a new application, and go to the Developers Dashboard
- Ensure the application is selected in the application list dropdown
- Select API keys and copy the
Publishable key
andSecret key
, and store securely.
- Login to Stripe
- Goto the Developers Dashboard for the application
- Goto Webhooks and setup a Local listener for testing or a Hosted endpoint for deployment
- Copy the
webhook signing secret
and store securely.
In order to configure Exchange Rates, the following actions must be performed.
- Login to APILayer
- Subscribe to the Exchange Rates Data API
- Copy the API key, and store securely
Procedures differ depending on the email provider used. for example, in order to configure Gmail as the email provider, the following actions must be performed.
- Login to Gmail
- Goto the Google Account settings and select Security
- Under
How you sign in to Google
ensure 2-Step Verification is enabled - Search for
App passwords
and create a new app password - Copy the generated app password, and store securely
Before running the application for the first time following cloning from the repository and setting up a new database,
the following steps must be performed, from a terminal window, in the recipes-n-stuff
folder.
$ python manage.py migrate
Download the recipe data from Food.com - Recipes and Reviews
and save the recipes.parquet
file to data folder.
Populate the database with predefined data via the populate.py script. When run using run_populate.py it will load the data from subdivisions.txt.
Note: When loading the database ensure to specify the correct database:
--database default
when loading a local development database--database remote
when loading a Database as a service (DBaaS) database
From the project root folder run the following
# E.g. populate the remote database
python -m manage loaddata measure.json --database remote
Dump data:
python -m manage dumpdata recipes.Measure --indent 4 -o data/fixtures/measure.json
# populate the remote database via loaddata
python -m manage loaddata currencies.json --database remote
# or alternatively via run_populate.py
python run_populate.py -cc -f data -dv REMOTE_DATABASE_URL
Dump data:
The data dump needs to be performed in UTF8 mode to preserve character encodings:
python -Xutf8 -m manage dumpdata checkout.Currency --indent 4 -o data/fixtures/currencies.json
# populate the remote database via loaddata
python -m manage loaddata countryinfo.json --database remote
# or alternatively via run_populate.py
python run_populate.py -c -f data -dv REMOTE_DATABASE_URL
Dump data:
python -m manage dumpdata profiles.CountryInfo --indent 4 -o data/fixtures/countryinfo.json
Note: Due to the large size of the dataset, this operation takes a long time to complete.
# E.g. populate the remote database
python run_populate.py -r -f data -dv REMOTE_DATABASE_URL
Enter Username
, Password
and optionally Email address
.
$ python manage.py createsuperuser
Build a customised version of Bootstrap.
$ npm run build
From django-allauth Post-Installation
-
Add a Site for your domain in the database
-
Login to
http://<domain>/admin/sites/site/
as the previously created superuser, e.g. http://127.0.0.1:8000/admin/sites/site/ -
Add a Site for your domain (django.contrib.sites app).
E.g.
Domain name Display name 127.0.0.1:8000 my domain Note: The id (primary key) of the site must be added to the application configuration. See
SITE_ID
in Table 1: Configuration settings.
-
-
For each OAuth based provider, add a SocialApp in
http://<domain>/admin/socialaccount/socialapp/
, e.g. http://127.0.0.1:8000/admin/socialaccount/socialapp/, containing the required client credentials-
Google django-allauth Google provider info
Provider Name Client id Secret key google Google client_id
from the OAuth 2.0 Client credentialsclient_secret
from the OAuth 2.0 Client credentialsAnd add the Site for your domain to the
Chosen sites
list -
Twitter django-allauth Twitter provider info
Provider Name Client id Secret key twitter Twitter API Key
from the Consumer KeysAPI Key Secret
from the Consumer KeysAnd add the Site for your domain to the
Chosen sites
list
-
In order to run the development server, run the following command from the recipes-n-stuff
folder:
$ python manage.py runserver
By default, the server runs on port 8000 on the IP address 127.0.0.1. See runserver for details on passing an IP address and port number explicitly.
The application structure is as follows:
├─ README.md - this file
├─ doc - documentation
│ ├─ agile - project management
│ ├─ design - design related documentation
│ └─ test - test reports
├─ data - sample data
├─ manage.py - application entry point
├─ recipesnstuff - main Django application
├─ base - base Django application
│ └─ static - base application-specific static files
│ ├─ css - base application-specific custom CSS
│ ├─ img - base application-specific images
│ └─ js - base application-specific custom JavaScript
├─ checkout - checkout Django application
│ └─ static - checkout application-specific static files
│ ┇
├─ recipes - recipes Django application
├─ profiles - shopping profiles Django application
├─ subscription - subscriptions Django application
├─ user - user Django application
├─ static - static files
│ ├─ css - custom CSS
│ ├─ img - images
│ └─ js - custom JavaScript
├─ templates - application templates
├─ django_tests - Django Test Tools test scripts
├─ jest_tests - Jest javascript tests
└─ tests - pytest/unittest test scripts
Use the following procedure to deploy the site on Heroku.
Optionally, the Heroku CLI may be used to update the application on Heroku.
With the Heroku CLI installed, in a terminal window, in the recipes-n-stuff
folder:
-
Log in to your Heroku account and follow the prompts to create a new SSH public key.
$ heroku login
The following steps were followed to deploy the website:
-
Login to Heroku in a browser
-
From the dashboard select
New -> Create new app
-
Set the value for
App name
, choose the appropriate region and clickCreate app
-
To provision the application with a database, a Heroku Postgres database or alternative, such as an ElephantSQL database may be utilised.
- For Heroku Postgres, from the app settings, select the
Resources
tab.- Under
Add-ons
add the followingHeroku Postgres
- PostgreSQL database as a service
- Under
- For ElephantSQL database, follow the
Create a new instance
instructions under theGetting started
section of the ElephantSQL documentation.
- For Heroku Postgres, from the app settings, select the
-
From the app settings, select the
Resources
tab.- Under
Add-ons
add the following-
Cloudinary - Image and Video Management
- Cloudinary Image & Video ToolsNote: In order the access the dashboard for the provisioned Cloudinary account, use the Heroku CLI
$ heroku addons:open cloudinary --app=recipesnstuff
-
- Under
-
From the app settings, select the
Settings
tab.- Under
Buildpacks
add the following buildpacksheroku/python
- Under
Config Vars
add the following environment variables
- Under
Key | Value |
---|---|
PORT | 8000 |
SECRET_KEY | Secret key for a particular Django installation |
HEROKU_HOSTNAME | Hostname of application on Heroku |
AVATAR_BLANK_URL | Url of blank avatar |
RECIPE_BLANK_URL | Url of placeholder recipe image |
SITE_ID | Id (primary key) of site in the django_site table of the database. See Configure authentication. |
GOOGLE_SITE_VERIFICATION | Google Search Console meta tag verification value for site ownership verification |
STRIPE_PUBLISHABLE_KEY | Stripe Developer API keys publishable key value for payments processing. |
STRIPE_SECRET_KEY | Stripe Developer API keys secret key value for payments processing. |
STRIPE_WEBHOOK_KEY | Stripe Webhook secret secret key value to get incoming webhooks to get real-time updates. See Test webhooks integration for local testing and Take webhooks live for hosted deployment. |
EXCHANGERATES_DATA_KEY | Exchange Rates Data API key for exchange rates. |
EMAIL_HOST | SMTP server to send email. |
EMAIL_USE_TLS | Use Transport Layer Security (TLS) flag. |
EMAIL_PORT | SMTP server port. |
EMAIL_HOST_USER | Email user account to send email. |
EMAIL_HOST_PASSWORD | Email user account password. |
FACEBOOK_PAGE | Facebook business page link. |
The following keys are automatically added when Resources are provisioned: |
|
CLOUDINARY_URL | Cloudinary url |
- Add the
DATABASE_URL
environment variable underConfig Vars
, if required
Key | Value |
---|---|
DATABASE_URL | Database url - Heroku Postgres database, automatically added when Resources are provisioned- ElephantSQL database, copy the URL from the instance details page |
See Table 1: Configuration settings for details.
If any other settings vary from the defaults outlined in Table 1: Configuration settings they must be added as well.
-
From the app settings, select the
Deploy
tab.-
For the
Deployment method
, selectGitHub
and link the Heroku app to the GitHub repository.Note: To configure GitHub integration, you have to authenticate with GitHub. You only have to do this once per Heroku account. See GitHub Integration (Heroku GitHub Deploys).
-
Enable Automatic Deploys
underAutomatic deploys
to enable automatic deploys from GitHub following a GitHub push if desired. -
The application may also be deployed manually using
Deploy Branch
underManual deploy
-
Alternatively, the application may be deployed via the Heroku CLI. After logging into the Heroku CLI in a terminal window, in the
recipes-n-stuff
folder:-
Check the list of
git
remotes$ git remote -v origin https://github.com/ibuttimer/recipes-n-stuff.git (fetch) origin https://github.com/ibuttimer/recipes-n-stuff.git (push)
-
If there is no
git
remotes forheroku
listed, add one$ git remote add heroku https://git.heroku.com/recipesnstuff.git $ git remote -v heroku https://git.heroku.com/recipesnstuff.git (fetch) heroku https://git.heroku.com/recipesnstuff.git (push) origin https://github.com/ibuttimer/recipes-n-stuff.git (fetch) origin https://github.com/ibuttimer/recipes-n-stuff.git (push)
-
After committing change locally, push to Heroku
$ git push heroku main
-
-
-
Initialise the database and Create a superuser
Involves the same procedure as outlined in Initialise the database and Create a superuser but may be run from the local machine.
-
From a Development and Local Deployment
-
Initialise the database
$ python manage.py migrate --database=remote
-
Create a superuser
Enter
Username
,Password
and optionallyEmail address
.$ python manage.py createsuperuser --database=remote
Note: Ensure to specify the
--database=remote
option to apply the change to the database specified by theREMOTE_DATABASE_URL
environment variable. -
-
Alternatively, the Heroku CLI may be utilised.
After logging into the Heroku CLI in a terminal window, in the project folder:
-
Initialise the database
$ heroku run python manage.py migrate --app recipesnstuff
-
Create a superuser
Enter
Username
,Password
and optionallyEmail address
.$ heroku run python manage.py createsuperuser --app recipesnstuff
-
-
-
Configure authentication
Follow the same procedure as outlined in Configure authentication using the Heroku domain as
<domain>
, e.g.recipesnstuff.herokuapp.com
The live website is available at https://recipesnstuff.herokuapp.com/
The site was deployed on Render.
The following steps were followed to deploy the website:
-
Login to Render in a browser
-
From the dashboard select
New -> Web Service
-
Connect to the git repository
-
Set following
Name
, (e.g.recipesnstuff
)- Choose an appropriate region
- Select the git branch to deploy
- Select
Python 3
runtime, - Set the Build command to
./build.sh
- Set the Start command to
gunicorn recipesnstuff.wsgi:application
- Select
Create Web Service
-
To provision the application with a database, such as an ElephantSQL database.
- For an ElephantSQL database, follow the
Create a new instance
instructions under theGetting started
section of the ElephantSQL documentation.
- For an ElephantSQL database, follow the
-
Create an Amazon S3 bucket using Storing Django Static and Media Files on Amazon S3. See Configuring cross-origin resource sharing (CORS) and CORS configuration regarding setting the CORS configuration for the S3 bucket.
-
Under
Environment -> Environment Variables
add the following environment variablesKey Value PYTHON_VERSION Python version
Note: At time of writing the Render Python3 environment does not include the necessary Python headers to compile thepsycopg2
library for Python version 3.10.10, use Python version 3.9.16- Under
Environment -> Secret Files
add a file with the name.env
with the same environment variables as specified in Table 2: Heroku Configuration settings with the following differences:- The following variables are NOT required
- HEROKU_HOSTNAME
- CLOUDINARY_URL
- Add the following variables:
- DATABASE_URL
- Add Amazon S3-specific settings
- The following variables are NOT required
- Under
Key | Value |
---|---|
AWS_ACCESS_KEY_ID | The access key for your AWS account. |
AWS_SECRET_ACCESS_KEY | The secret key for your AWS account. |
AWS_STORAGE_BUCKET_NAME | AWS S3 bucket name. |
See Table 1: Configuration settings for details.
If any other settings vary from the defaults outlined in Table 1: Configuration settings they must be added as well.
-
Select the
Manual Deploy
to deploy the application. -
Initialise the database and Create a superuser
Involves the same procedure as outlined in Initialise the database and Create a superuser but may be run from the local machine.
-
From a Development and Local Deployment
-
Initialise the database
$ python manage.py migrate --database=remote
-
Create a superuser
Enter
Username
,Password
and optionallyEmail address
.$ python manage.py createsuperuser --database=remote
Note: Ensure to specify the
--database=remote
option to apply the change to the database specified by theREMOTE_DATABASE_URL
environment variable. -
-
-
Configure authentication
Follow the same procedure as outlined in Configure authentication using the Heroku domain as
<domain>
, e.g.dara-planner.herokuapp.com
The live website is available at https://recipesnstuff.onrender.com
The tests information and results are available in test.md.
The following resources were used to build the website.
- Logo bowl rice image, Icons License CC BY 4.0, by Font Awesome
- The favicon for the site was generated by RealFaviconGenerator from bowl rice image , Icons License CC BY 4.0, by Font Awesome
- Blank avatar image by WingTillDie from Pixabay
- Chef image by abdulla binmassam from Pixabay, cropped
- Barbeque skewers image by -Rita-👩🍳 und 📷 mit ❤ from Pixabay
- Baked goods image by Pexels from Pixabay, cropped
- Wooden spoon (heart) image by Bruno /Germany from Pixabay, cropped
- Spices image by czu_czu_PL from Pixabay, cropped
- Vegetables image by congerdesign from Pixabay, cropped
- Spoons and spices image by Kai Reschke from Pixabay, cropped
- Passport image by Wilson Joseph from Pixabay, cropped
- Country subdivision data courtesy of https://en.wikipedia.org/wiki/ISO_3166-2
- Currency data courtesy of https://en.wikipedia.org/wiki/ISO_4217 and https://en.wikipedia.org/wiki/Currency_symbol
- Standard measures data courtesy of Cooking weights and measures and United States customary units
- Recipe data courtesy of Food.com - Recipes and Reviews by Alvin
- 404 error icon created by Freepik - Flaticon
- Explosion icon created by Freepik - Flaticon
- Stop sign icon created by Freepik - Flaticon
- Confusion icon created by Freepik - Flaticon
- Internet icon created by Freepik - Flaticon
- Empty serving dish icon created by Freepik - Flaticon
- Privacy policy courtesy of Privacy Policy Generator. Privacy Policy Generator hosted version.
- HTML entity data courtesy of HTML Living Standard - Named character references
- The Responsive Mockup image was generated courtesy of Website Mockup Generator
- Secret Key Generation courtesy of Humberto Rocha
- Robots.txt implementation based on How to add a robots.txt to your Django site