You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
272 lines
7.5 KiB
272 lines
7.5 KiB
# Create the blueprint for a new flask project
|
|
if [[ -z $1 ]]; then
|
|
echo "[FlaskCreate] Syntax Error: flask-create.sh <project_name> <parent_directory:default cwd>"
|
|
exit;
|
|
fi
|
|
|
|
PROJECT_NAME=$1
|
|
PROJECT_ROOT=$2
|
|
|
|
if [[ -z $PROJECT_ROOT ]]; then
|
|
PROJECT_ROOT=$(pwd)
|
|
fi
|
|
|
|
echo "-=[FlaskCreate]=-";
|
|
echo "Project Name: $PROJECT_NAME";
|
|
echo "Project Root: $PROJECT_ROOT/$PROJECT_NAME";
|
|
|
|
echo "Start a new Flask project? (y/n)";
|
|
read START_CONFIRM;
|
|
|
|
if [[ $START_CONFIRM != y && $START_CONFIRM != Y ]]; then
|
|
exit;
|
|
fi
|
|
|
|
PROJECT_FOLDER=$PROJECT_ROOT/$PROJECT_NAME
|
|
|
|
echo "";
|
|
echo "[FlaskCreate] Creating directory $PROJECT_FOLDER...";
|
|
mkdir $PROJECT_FOLDER;
|
|
|
|
mkdir $PROJECT_FOLDER/data;
|
|
mkdir $PROJECT_FOLDER/$PROJECT_NAME;
|
|
|
|
touch $PROJECT_FOLDER/uwsgi.ini;
|
|
echo "[FlaskCreate] Generating uwsgi config...";
|
|
echo "[uwsgi]
|
|
module = wsgi:application
|
|
|
|
master = true
|
|
processes = 4
|
|
|
|
socket = $PROJECT_NAME.sock
|
|
chmod-scoket = 660
|
|
vacuum = true
|
|
|
|
die-on-term = true
|
|
" > $PROJECT_FOLDER/uwsgi.ini;
|
|
|
|
touch $PROJECT_FOLDER/start.py;
|
|
echo "from $PROJECT_NAME import create_app
|
|
|
|
|
|
app = create_app()
|
|
|
|
if __name__ == \"__main__\":
|
|
app.run()
|
|
" > $PROJECT_FOLDER/start.py;
|
|
|
|
echo "[FlaskCreate] Creating Flask app module files...";
|
|
touch $PROJECT_FOLDER/$PROJECT_NAME/__init__.py;
|
|
echo "from flask import Flask
|
|
|
|
def create_app():
|
|
app = Flask(__name__)
|
|
app.config.from_object('$PROJECT_NAME.default_settings')
|
|
app.config.from_envvar('FLASK_SETTINGS_FILE')
|
|
|
|
|
|
# Prep the database
|
|
from $PROJECT_NAME.models import db
|
|
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///../data/$PROJECT_NAME.db'
|
|
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
|
db.init_app(app)
|
|
|
|
# Load our views
|
|
from $PROJECT_NAME.views import default_views
|
|
app.register_blueprint(default_views)
|
|
|
|
# from $PROJECT_NAME.<app_name>.views import app_views
|
|
# app.register_blueprint(app_views)
|
|
|
|
# Load our CLI commands
|
|
from $PROJECT_NAME.commands import default_cli
|
|
app.cli.add_command(default_cli)
|
|
|
|
# from $PROJECT_NAME.<app_name>.commands import app_cli
|
|
# app.cli.add_command(app_cli)
|
|
|
|
return app
|
|
" > $PROJECT_FOLDER/$PROJECT_NAME/__init__.py;
|
|
|
|
echo "[FlaskCreate] Generating SQLAlchemy base model...";
|
|
touch $PROJECT_FOLDER/$PROJECT_NAME/models.py;
|
|
echo "from flask_sqlalchemy import SQLAlchemy
|
|
|
|
|
|
db = SQLAlchemy()
|
|
|
|
class BaseModel(db.Model):
|
|
__abstract__ = True
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
created_at = db.Column(db.DateTime)
|
|
" > $PROJECT_FOLDER/$PROJECT_NAME/models.py;
|
|
|
|
echo "[FlaskCreate] Generating basic CLI commands...";
|
|
touch $PROJECT_FOLDER/$PROJECT_NAME/commands.py;
|
|
echo "import click
|
|
from flask.cli import AppGroup
|
|
|
|
from $PROJECT_NAME.models import db
|
|
|
|
default_cli = AppGroup('$PROJECT_NAME')
|
|
|
|
@default_cli.command('initdb')
|
|
def initialize_database():
|
|
from $PROJECT_NAME import models
|
|
# from $PROJECT_NAME.<app_name> import models
|
|
db.create_all()
|
|
" > $PROJECT_FOLDER/$PROJECT_NAME/commands.py;
|
|
|
|
echo "[FlaskCreate] Generating default views...";
|
|
touch $PROJECT_FOLDER/$PROJECT_NAME/views.py;
|
|
echo "from flask import current_app, Blueprint, render_template
|
|
|
|
|
|
default_views = Blueprint('default_views', __name__, url_prefix='/')
|
|
|
|
@default_views.route('/')
|
|
def index():
|
|
return render_template('index.html')
|
|
" > $PROJECT_FOLDER/$PROJECT_NAME/views.py;
|
|
|
|
echo "[FlaskCreate] Initializing default templates...";
|
|
TEMPLATE_DIR=$PROJECT_FOLDER/$PROJECT_NAME/templates
|
|
mkdir $TEMPLATE_DIR;
|
|
touch $TEMPLATE_DIR/base.html;
|
|
touch $TEMPLATE_DIR/index.html;
|
|
|
|
echo " <!doctype html>
|
|
<html>
|
|
<head>
|
|
<title>{% block title %}{% endblock %} - $PROJECT_NAME</title>
|
|
<meta charset=\"utf-8\">
|
|
<meta name=\"viewport\" contents=\"width=device-width, initial-scale=1\">
|
|
<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.0/css/uikit.min.css\" integrity=\"sha256-5YtK9j+Nl/245lAkSjrIs600d6edKTevi+3JYdjuHhY=\" crossorigin=\"anonymous\" />
|
|
<script src=\"https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.0/js/uikit.min.js\" integrity=\"sha256-rhLALrRmAQVu/OxzVDpQaiHAEMxiRSN8h8RDydUEh2g=\" crossorigin=\"anonymous\"></script>
|
|
{% block head %} {% endblock %}
|
|
</head>
|
|
<body>
|
|
<nav class=\"uk-navbar-container\" uk-navbar>
|
|
<div class=\"uk-navbar-left\">
|
|
<a href=\"\" class=\"uk-navbar-item uk-logo\">$PROJECT_NAME</a>
|
|
</div>
|
|
<div class=\"uk-navbar-center\">
|
|
<ul class=\"uk-navbar-nav\">
|
|
<li class=\"uk-active\"><a href=\"\">Nav Item 1</a></li>
|
|
<li><a href=\"\">Nav Item 2</a></li>
|
|
<li><a href=\"\">Nav Item 3</a></li>
|
|
<li><a href=\"\">Nav Item 4</a></li>
|
|
</ul>
|
|
</div>
|
|
</nav>
|
|
<div class=\"uk-container\">
|
|
{% block content %}{% endblock %}
|
|
</div>
|
|
</body>
|
|
</html>
|
|
" > $TEMPLATE_DIR/base.html;
|
|
|
|
echo "{% extends \"base.html\" %}
|
|
{% block title %}$PROJECT_NAME Home{% endblock %}
|
|
{% block content %}
|
|
<div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block head %}
|
|
<style>
|
|
</style>
|
|
{% endblock %}
|
|
" > $TEMPLATE_DIR/index.html;
|
|
|
|
echo "[FlaskCreate] Creating default_settings config file...";
|
|
touch $PROJECT_FOLDER/$PROJECT_NAME/default_settings.py;
|
|
echo "# Default Configuration
|
|
SECRET_KEY = 'asecretkeyshouldchange'
|
|
|
|
# Flask-SQLAlchemy
|
|
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
|
" > $PROJECT_FOLDER/$PROJECT_NAME/default_settings.py;
|
|
|
|
echo "[FlaskCreate] Creating environment config files...";
|
|
mkdir $PROJECT_FOLDER/config;
|
|
touch $PROJECT_FOLDER/config/prod.cfg; touch $PROJECT_FOLDER/config/dev.cfg
|
|
|
|
PROD_KEY=$(echo $(od -vN 20 -An -tx1 /dev/urandom | tr -d " \n"))
|
|
DEV_KEY=$(echo $(od -vN 20 -An -tx1 /dev/urandom | tr -d " \n"))
|
|
echo "# Default Configuration
|
|
DEBUG = True
|
|
SECRET_KEY = \"$DEV_KEY\"
|
|
|
|
# Flask-SQLAlchemy
|
|
SQLALCHEMY_DATABASE_URI = 'sqlite:///../data/acks.db'
|
|
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
|
" > $PROJECT_FOLDER/config/dev.cfg
|
|
|
|
echo "# Default Configuration
|
|
DEBUG = False
|
|
SECRET_KEY = \"$PROD_KEY\"
|
|
|
|
# Flask-SQLAlchemy
|
|
SQLALCHEMY_DATABASE_URI = 'sqlite:///../data/acks.db'
|
|
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
|
" > $PROJECT_FOLDER/config/prod.cfg
|
|
|
|
echo "[FlaskCreate] Generating a Makefile...";
|
|
touch $PROJECT_FOLDER/Makefile;
|
|
echo -e ".PHONY: run debug clean
|
|
|
|
bin/activate: requirements.txt
|
|
\t test -f bin/activate || $(which python3) -m venv .
|
|
\t bin/pip install -Ur requirements.txt
|
|
\t touch bin/activate
|
|
|
|
run: bin/activate
|
|
\t . bin/activate; FLASK_SETTINGS_FILE=../config/prod.cfg FLASK_ENV=production FLASK_APP=start.py flask run --host=0.0.0.0
|
|
|
|
debug: bin/activate
|
|
\t . bin/activate; FLASK_SETTINGS_FILE=../config/dev.cfg FLASK_ENV=development FLASK_APP=start.py flask run --host=0.0.0.0
|
|
|
|
clean:
|
|
\t rm -rf bin/ include/ lib/ lib64/ __pycache__/ share/; rm pyvenv.cfg
|
|
" > $PROJECT_FOLDER/Makefile
|
|
|
|
echo "[FlaskCreate] Initializing a git repository and creating initial commit...";
|
|
cd $PROJECT_FOLDER;
|
|
touch $PROJECT_FOLDER/.gitignore
|
|
echo "# Python
|
|
*.py[co]
|
|
|
|
# Vim
|
|
*.swp
|
|
|
|
# Virtualenv
|
|
bin
|
|
include
|
|
lib
|
|
lib64
|
|
__pycache__
|
|
share
|
|
pyvenv.cfg
|
|
|
|
# App specific
|
|
data
|
|
config
|
|
" > $PROJECT_FOLDER/.gitignore
|
|
git init $PROJECT_FOLDER &> /dev/null;
|
|
git add . &> /dev/null;
|
|
git commit -m "Initial commit (FlaskCreate)" &> /dev/null;
|
|
|
|
echo "[FlaskCreate] Creating Python3 virtual environment...";
|
|
python3 -m venv $PROJECT_FOLDER
|
|
source $PROJECT_FOLDER/bin/activate
|
|
|
|
echo "[FlaskCreate] Installing dependencies...";
|
|
pip install flask flask-sqlalchemy &> /dev/null
|
|
pip freeze > $PROJECT_FOLDER/requirements.txt;
|
|
|
|
echo "[FlaskCreate] Finished. Project lives at $PROJECT_FOLDER."
|
|
cd $PROJECT_FOLDER;
|
|
|