Todo se fue a docker igual que el otro repo
Decidi pasar todo esto a docker igual para tener todo ahi, parece mas ordenado y mas facil de mantener en mi servidor de paso tambien hice el trabajo de pasar los modelos a sqlalchemy para usar mysql :3
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -116,4 +116,6 @@ dmypy.json
|
||||
|
||||
|
||||
# Personal things!
|
||||
setup_env.sh
|
||||
web.env
|
||||
db.env
|
||||
dump.sql
|
||||
|
||||
16
Dockerfile
Normal file
16
Dockerfile
Normal file
@@ -0,0 +1,16 @@
|
||||
FROM python:alpine
|
||||
|
||||
RUN mkdir /app
|
||||
COPY requirements.txt gunicorn.conf run.py /app/
|
||||
COPY www/ /app/www
|
||||
ENV FLASK_APP=www
|
||||
WORKDIR /app
|
||||
RUN apk add mariadb-connector-c-dev gcc musl-dev
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
RUN apk del gcc musl-dev
|
||||
|
||||
ENV GUNICORN_WORKERS 2
|
||||
ENV GUNICORN_BIND 0.0.0.0:8081
|
||||
|
||||
EXPOSE 8081
|
||||
CMD ["gunicorn", "--config", "gunicorn.conf", "run:app"]
|
||||
2
db.env.example
Normal file
2
db.env.example
Normal file
@@ -0,0 +1,2 @@
|
||||
MYSQL_ROOT_PASSWORD=secret
|
||||
MYSQL_DATABASE=db
|
||||
21
docker-compose.yml
Normal file
21
docker-compose.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
version: '3'
|
||||
services:
|
||||
web:
|
||||
build: .
|
||||
ports:
|
||||
- "8081:8081"
|
||||
volumes:
|
||||
- ./www:/app/www
|
||||
depends_on:
|
||||
- db
|
||||
env_file:
|
||||
- web.env
|
||||
command: "gunicorn --config gunicorn.conf run:app"
|
||||
db:
|
||||
image: mariadb
|
||||
volumes:
|
||||
- dbdata:/var/lib/mysql
|
||||
env_file:
|
||||
- db.env
|
||||
volumes:
|
||||
dbdata:
|
||||
6
gunicorn.conf
Normal file
6
gunicorn.conf
Normal file
@@ -0,0 +1,6 @@
|
||||
import os
|
||||
|
||||
for k,v in os.environ.items():
|
||||
if k.startswith("GUNICORN_"):
|
||||
key = k.split('_', 1)[1].lower()
|
||||
locals()[key] = v
|
||||
5
requirements.txt
Normal file
5
requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Flask
|
||||
Flask-SQLAlchemy
|
||||
mysqlclient
|
||||
gunicorn
|
||||
markdown
|
||||
6
run.py
Normal file
6
run.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from www import create_app
|
||||
|
||||
app = create_app()
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', debug=True)
|
||||
7
web.env.example
Normal file
7
web.env.example
Normal file
@@ -0,0 +1,7 @@
|
||||
DATABASE_URI=mysql://root:secret@db:3306/db
|
||||
TRACK_MODIFICATIONS=False
|
||||
|
||||
USERNAME=admin
|
||||
PASSWORD=secret
|
||||
|
||||
SECRET_KEY=1337
|
||||
6
wsgi.py
6
wsgi.py
@@ -1,6 +0,0 @@
|
||||
from www import create_app
|
||||
|
||||
app = create_app()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
@@ -5,43 +5,41 @@ from flask import redirect, url_for, render_template
|
||||
|
||||
def create_app():
|
||||
app = Flask(__name__, instance_relative_config=True)
|
||||
|
||||
app.config.from_mapping(
|
||||
DATABASE=os.path.join(app.instance_path, 'www.sqlite'),
|
||||
SQLALCHEMY_DATABASE_URI=os.environ.get("DATABASE_URI"),
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS=os.environ.get("TRACK_MODIFICATIONS"),
|
||||
USERNAME=os.environ.get("USERNAME"),
|
||||
PASSWORD=os.environ.get("PASSWORD"),
|
||||
SECRET_KEY=os.environ.get("SECRET_KEY")
|
||||
)
|
||||
|
||||
app.config.from_pyfile('config.py', silent=True)
|
||||
|
||||
try:
|
||||
os.makedirs(app.instance_path)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return redirect(url_for('blog.index'))
|
||||
|
||||
|
||||
from . import db
|
||||
from www.models import db
|
||||
db.init_app(app)
|
||||
|
||||
from . import auth
|
||||
from www import commands
|
||||
commands.init_app(app)
|
||||
|
||||
from www import auth
|
||||
app.register_blueprint(auth.bp)
|
||||
|
||||
from . import admin
|
||||
from www import admin
|
||||
app.register_blueprint(admin.bp)
|
||||
|
||||
from . import blog
|
||||
from www import blog
|
||||
app.register_blueprint(blog.bp)
|
||||
|
||||
from . import now
|
||||
from www import now
|
||||
app.register_blueprint(now.bp)
|
||||
|
||||
from . import recommended
|
||||
from www import recommended
|
||||
app.register_blueprint(recommended.bp)
|
||||
|
||||
from . import projects
|
||||
from www import projects
|
||||
app.register_blueprint(projects.bp)
|
||||
|
||||
return app
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from flask import Blueprint, flash, g, redirect, render_template, request, session, url_for
|
||||
from flask import Blueprint, render_template
|
||||
|
||||
from www.db import get_db
|
||||
from www.auth import admin_required
|
||||
|
||||
bp = Blueprint('admin', __name__, url_prefix='/admin')
|
||||
|
||||
20
www/auth.py
20
www/auth.py
@@ -1,11 +1,12 @@
|
||||
import functools
|
||||
|
||||
from www.db import get_db
|
||||
|
||||
from werkzeug.exceptions import abort
|
||||
from werkzeug.security import check_password_hash
|
||||
|
||||
from flask import Blueprint, request, flash, render_template, session, g, redirect, url_for
|
||||
from flask import Blueprint, render_template, request, session
|
||||
from flask import url_for, flash, redirect, g
|
||||
|
||||
from www.models import User
|
||||
|
||||
|
||||
bp = Blueprint('auth', __name__, url_prefix='/auth')
|
||||
@@ -16,21 +17,18 @@ def login():
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
|
||||
db = get_db()
|
||||
error = None
|
||||
|
||||
user = db.execute(
|
||||
'SELECT * FROM users WHERE username = ?', (username,)
|
||||
).fetchone()
|
||||
user = User.query.filter_by(username=username).first()
|
||||
|
||||
if user is None:
|
||||
error = 'Incorrect username.'
|
||||
elif not check_password_hash(user['password'], password):
|
||||
elif not check_password_hash(user.password, password):
|
||||
error = 'Incorrect password.'
|
||||
|
||||
if error is None:
|
||||
session.clear()
|
||||
session['user_id'] = user['id']
|
||||
session['user_id'] = user.id
|
||||
return redirect(url_for('index'))
|
||||
|
||||
flash(error)
|
||||
@@ -49,9 +47,7 @@ def load_logged_in_user():
|
||||
if user_id is None:
|
||||
g.user = None
|
||||
else:
|
||||
g.user = get_db().execute(
|
||||
'SELECT * FROM users WHERE id = ?', (user_id,)
|
||||
).fetchone()
|
||||
g.user = User.query.get(user_id)
|
||||
|
||||
def admin_required(view):
|
||||
@functools.wraps(view)
|
||||
|
||||
69
www/blog.py
69
www/blog.py
@@ -1,23 +1,16 @@
|
||||
from flask import (
|
||||
Blueprint, flash, g, redirect, render_template, request, url_for
|
||||
)
|
||||
from flask import Blueprint, flash, redirect, render_template, request, url_for
|
||||
|
||||
from werkzeug.exceptions import abort
|
||||
import markdown as md
|
||||
|
||||
from www.db import get_db
|
||||
from www.models import db, Post
|
||||
from www.auth import admin_required
|
||||
|
||||
bp = Blueprint('blog', __name__, url_prefix='/blog')
|
||||
|
||||
@bp.route('/')
|
||||
def index():
|
||||
db = get_db()
|
||||
posts = db.execute(
|
||||
'SELECT id, title, resume, created_at'
|
||||
' FROM posts'
|
||||
' ORDER BY created_at DESC'
|
||||
).fetchall()
|
||||
posts = Post.query.order_by(Post.created_at.desc()).all()
|
||||
|
||||
return render_template('blog/index.html', posts=posts)
|
||||
|
||||
@@ -38,13 +31,10 @@ def create():
|
||||
if error is not None:
|
||||
flash(error)
|
||||
else:
|
||||
db = get_db()
|
||||
db.execute(
|
||||
'INSERT INTO posts (title, markdown, html, resume)'
|
||||
' VALUES (?, ?, ?, ?)',
|
||||
(title, markdown, html, resume)
|
||||
)
|
||||
db.commit()
|
||||
post = Post(title, markdown, html, resume)
|
||||
db.session.add(post)
|
||||
db.session.commit()
|
||||
|
||||
return redirect(url_for('blog.index'))
|
||||
|
||||
return render_template('blog/create.html')
|
||||
@@ -52,12 +42,7 @@ def create():
|
||||
@bp.route('/update/<int:id>', methods=('GET', 'POST'))
|
||||
@admin_required
|
||||
def update(id):
|
||||
post = get_db().execute(
|
||||
'SELECT id, title, markdown, resume'
|
||||
' FROM posts'
|
||||
' WHERE id = ?',
|
||||
(id,)
|
||||
).fetchone()
|
||||
post = Post.query.get(id)
|
||||
|
||||
if post is None:
|
||||
abort(404)
|
||||
@@ -76,52 +61,34 @@ def update(id):
|
||||
if error is not None:
|
||||
flash(error)
|
||||
else:
|
||||
db = get_db()
|
||||
db.execute(
|
||||
'UPDATE posts'
|
||||
' SET title = ?, markdown = ?, html = ?, resume = ?'
|
||||
' WHERE id = ?',
|
||||
(title, markdown, html, resume, id)
|
||||
)
|
||||
db.commit()
|
||||
post.title = title
|
||||
post.markdown = markdown
|
||||
post.html = html
|
||||
post.resume = resume
|
||||
db.session.commit()
|
||||
return redirect(url_for('blog.index'))
|
||||
|
||||
return render_template('blog/update.html', post=post)
|
||||
|
||||
@bp.route('/<int:id>')
|
||||
def view(id):
|
||||
post = get_db().execute(
|
||||
'SELECT id, title, html'
|
||||
' FROM posts'
|
||||
' WHERE id = ?',
|
||||
(id,)
|
||||
).fetchone()
|
||||
post = Post.query.get(id)
|
||||
|
||||
if post is None:
|
||||
abort(404)
|
||||
else:
|
||||
return render_template('blog/view.html', post=post)
|
||||
|
||||
@bp.route('/delete/<int:id>', methods=('GET', 'POST',))
|
||||
@bp.route('/delete/<int:id>', methods=['POST'])
|
||||
@admin_required
|
||||
def delete(id):
|
||||
if request.method == 'GET':
|
||||
abort(404)
|
||||
|
||||
db = get_db()
|
||||
post = db.execute(
|
||||
'SELECT id'
|
||||
' FROM posts'
|
||||
' WHERE id = ?',
|
||||
(id,)
|
||||
).fetchone()
|
||||
print(post)
|
||||
post = Post.query.get(id)
|
||||
|
||||
if post is None:
|
||||
abort(404)
|
||||
else:
|
||||
db.execute('DELETE FROM posts WHERE id = ?', (id,))
|
||||
db.commit()
|
||||
db.session.delete(post)
|
||||
db.session.commit()
|
||||
return redirect(url_for('blog.index'))
|
||||
|
||||
|
||||
|
||||
46
www/commands.py
Normal file
46
www/commands.py
Normal file
@@ -0,0 +1,46 @@
|
||||
import click
|
||||
|
||||
from flask import current_app
|
||||
from flask.cli import with_appcontext
|
||||
|
||||
from werkzeug.security import generate_password_hash
|
||||
|
||||
from www.models import db, User, Now
|
||||
|
||||
|
||||
def init_db():
|
||||
db.create_all()
|
||||
|
||||
|
||||
def generate_admin():
|
||||
username = current_app.config['USERNAME']
|
||||
|
||||
if User.query.filter_by(username=username).first() is None:
|
||||
password = current_app.config['PASSWORD']
|
||||
|
||||
user = User(username, generate_password_hash(password))
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
|
||||
def generate_base_now():
|
||||
now = Now.query.first()
|
||||
if now is None:
|
||||
now = Now('', '')
|
||||
db.session.add(now)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
@click.command('init-db')
|
||||
@with_appcontext
|
||||
def init_db_command():
|
||||
"""
|
||||
Creates and initializes the db with the necesary data
|
||||
If the db existed previously, it keeps it and his data
|
||||
"""
|
||||
init_db()
|
||||
generate_admin()
|
||||
generate_base_now()
|
||||
|
||||
|
||||
def init_app(app):
|
||||
app.cli.add_command(init_db_command)
|
||||
73
www/db.py
73
www/db.py
@@ -1,73 +0,0 @@
|
||||
import sqlite3
|
||||
import click
|
||||
|
||||
from flask import current_app, g
|
||||
from flask.cli import with_appcontext
|
||||
from werkzeug.security import generate_password_hash
|
||||
|
||||
def get_db():
|
||||
if 'db' not in g:
|
||||
g.db = sqlite3.connect(
|
||||
current_app.config['DATABASE'],
|
||||
detect_types = sqlite3.PARSE_DECLTYPES
|
||||
)
|
||||
g.db.row_factory = sqlite3.Row
|
||||
return g.db
|
||||
|
||||
def close_db(e=None):
|
||||
db = g.pop('db', None)
|
||||
|
||||
if db is not None:
|
||||
db.close()
|
||||
|
||||
def init_db():
|
||||
db = get_db()
|
||||
|
||||
with current_app.open_resource('schema.sql') as f:
|
||||
db.executescript(f.read().decode('utf8'))
|
||||
|
||||
def fill_with_dummy():
|
||||
db = get_db()
|
||||
|
||||
with current_app.open_resource('dummy.sql') as f:
|
||||
db.executescript(f.read().decode('utf8'))
|
||||
|
||||
def generate_admin():
|
||||
db = get_db()
|
||||
username = current_app.config['USERNAME']
|
||||
password = current_app.config['PASSWORD']
|
||||
|
||||
db.execute(
|
||||
'INSERT INTO users (username, password) VALUES (?, ?)',
|
||||
(username, generate_password_hash(password))
|
||||
)
|
||||
db.commit()
|
||||
|
||||
@click.command('init-db')
|
||||
@with_appcontext
|
||||
def init_db_command():
|
||||
"""Initializes the schema of the database"""
|
||||
init_db()
|
||||
click.echo('Initialized the database')
|
||||
|
||||
@click.command('fill-with-dummy')
|
||||
@with_appcontext
|
||||
def fill_with_dummy_command():
|
||||
"""Adds dummy data to the existing database"""
|
||||
fill_with_dummy()
|
||||
click.echo('Database filled with dummy data')
|
||||
|
||||
@click.command('generate-admin')
|
||||
@with_appcontext
|
||||
def generate_admin_command():
|
||||
"""Creates the admin account to be used"""
|
||||
generate_admin()
|
||||
click.echo('Created admin')
|
||||
|
||||
|
||||
def init_app(app):
|
||||
app.teardown_appcontext(close_db)
|
||||
app.cli.add_command(init_db_command)
|
||||
app.cli.add_command(fill_with_dummy_command)
|
||||
app.cli.add_command(generate_admin_command)
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
INSERT INTO posts (title, markdown, html, resume) values
|
||||
(
|
||||
"Excepturi et debitis explicabo occaecati",
|
||||
"Sit necessitatibus quibusdam autem facere tempore quibusdam assumenda. Quo sit asperiores earum beatae unde reiciendis perspiciatis. Blanditiis natus ex similique possimus optio veritatis.",
|
||||
"Sit necessitatibus quibusdam autem facere tempore quibusdam assumenda. Quo sit asperiores earum beatae unde reiciendis perspiciatis. Blanditiis natus ex similique possimus optio veritatis.",
|
||||
"Enim unde ut eaque vero saepe ut. Iure culpa modi ipsam maxime aliquid sed officiis. Consequatur minima quaerat molestias laudantium aut. Quia voluptas sint accusantium architecto."
|
||||
),
|
||||
(
|
||||
"Excepturi et debitis explicabo occaecati",
|
||||
"Sit necessitatibus quibusdam autem facere tempore quibusdam assumenda. Quo sit asperiores earum beatae unde reiciendis perspiciatis. Blanditiis natus ex similique possimus optio veritatis.",
|
||||
"Sit necessitatibus quibusdam autem facere tempore quibusdam assumenda. Quo sit asperiores earum beatae unde reiciendis perspiciatis. Blanditiis natus ex similique possimus optio veritatis.",
|
||||
"Enim unde ut eaque vero saepe ut. Iure culpa modi ipsam maxime aliquid sed officiis. Consequatur minima quaerat molestias laudantium aut. Quia voluptas sint accusantium architecto."
|
||||
),
|
||||
(
|
||||
"Excepturi et debitis explicabo occaecati",
|
||||
"Sit necessitatibus quibusdam autem facere tempore quibusdam assumenda. Quo sit asperiores earum beatae unde reiciendis perspiciatis. Blanditiis natus ex similique possimus optio veritatis.",
|
||||
"Sit necessitatibus quibusdam autem facere tempore quibusdam assumenda. Quo sit asperiores earum beatae unde reiciendis perspiciatis. Blanditiis natus ex similique possimus optio veritatis.",
|
||||
"Enim unde ut eaque vero saepe ut. Iure culpa modi ipsam maxime aliquid sed officiis. Consequatur minima quaerat molestias laudantium aut. Quia voluptas sint accusantium architecto."
|
||||
),
|
||||
(
|
||||
"Excepturi et debitis explicabo occaecati",
|
||||
"Sit necessitatibus quibusdam autem facere tempore quibusdam assumenda. Quo sit asperiores earum beatae unde reiciendis perspiciatis. Blanditiis natus ex similique possimus optio veritatis.",
|
||||
"Sit necessitatibus quibusdam autem facere tempore quibusdam assumenda. Quo sit asperiores earum beatae unde reiciendis perspiciatis. Blanditiis natus ex similique possimus optio veritatis.",
|
||||
"Enim unde ut eaque vero saepe ut. Iure culpa modi ipsam maxime aliquid sed officiis. Consequatur minima quaerat molestias laudantium aut. Quia voluptas sint accusantium architecto."
|
||||
);
|
||||
53
www/models.py
Normal file
53
www/models.py
Normal file
@@ -0,0 +1,53 @@
|
||||
from datetime import datetime
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
|
||||
db = SQLAlchemy()
|
||||
|
||||
class User(db.Model):
|
||||
__tablename__ = 'users'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
username = db.Column(db.String(255), unique=True, nullable=False)
|
||||
password = db.Column(db.String(255), nullable=False)
|
||||
|
||||
def __init__(self, username=None, password=None):
|
||||
self.username = username
|
||||
self.password = password
|
||||
|
||||
def __repr__(self):
|
||||
return f'User {self.username}>'
|
||||
|
||||
|
||||
class Post(db.Model):
|
||||
__tablename__ = 'posts'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
title = db.Column(db.Text, nullable=False)
|
||||
markdown = db.Column(db.Text, nullable=False)
|
||||
html = db.Column(db.Text, nullable=False)
|
||||
resume = db.Column(db.Text, nullable=False)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
|
||||
def __init__(self, title=None, markdown=None, html=None, resume=None):
|
||||
self.title = title
|
||||
self.markdown = markdown
|
||||
self.html = html
|
||||
self.resume = resume
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Post {self.title} {self.created_at}>'
|
||||
|
||||
|
||||
class Now(db.Model):
|
||||
__tablename__ = 'nows'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
markdown = db.Column(db.Text, nullable=False)
|
||||
html = db.Column(db.Text, nullable=False)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
|
||||
def __init__(self, markdown=None, html=None):
|
||||
self.markdown = markdown
|
||||
self.html = html
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Now {self.created_at}>'
|
||||
33
www/now.py
33
www/now.py
@@ -1,25 +1,21 @@
|
||||
from flask import (
|
||||
Blueprint, flash, g, redirect, render_template, request, url_for
|
||||
)
|
||||
|
||||
from werkzeug.exceptions import abort
|
||||
import markdown as md
|
||||
|
||||
from www.db import get_db
|
||||
from flask import Blueprint, redirect, render_template, request, url_for
|
||||
|
||||
from www.auth import admin_required
|
||||
from www.models import db, Now
|
||||
|
||||
|
||||
bp = Blueprint('now', __name__, url_prefix='/now')
|
||||
|
||||
|
||||
@bp.route('/')
|
||||
def index():
|
||||
db = get_db()
|
||||
now = db.execute(
|
||||
'SELECT html'
|
||||
' FROM now'
|
||||
).fetchone()
|
||||
now = Now.query.order_by(Now.created_at.desc()).first()
|
||||
|
||||
return render_template('now/now.html', now=now)
|
||||
|
||||
|
||||
@bp.route('/update', methods=('GET', 'POST'))
|
||||
@admin_required
|
||||
def update():
|
||||
@@ -27,19 +23,12 @@ def update():
|
||||
markdown = request.form['markdown']
|
||||
html = parse_markdown(markdown)
|
||||
|
||||
db = get_db()
|
||||
db.execute(
|
||||
'UPDATE now'
|
||||
' SET markdown = ?, html = ?',
|
||||
(markdown, html,)
|
||||
)
|
||||
db.commit()
|
||||
now = Now(markdown, html)
|
||||
db.session.add(now)
|
||||
db.session.commit()
|
||||
return redirect(url_for('now.index'))
|
||||
|
||||
now = get_db().execute(
|
||||
'SELECT id, markdown'
|
||||
' FROM now'
|
||||
).fetchone()
|
||||
now = Now.query.order_by(Now.created_at.desc()).first()
|
||||
return render_template('now/update.html', now=now)
|
||||
|
||||
def parse_markdown(markdown):
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
from flask import (
|
||||
Blueprint, flash, g, redirect, render_template, request, url_for
|
||||
)
|
||||
|
||||
from werkzeug.exceptions import abort
|
||||
import markdown as md
|
||||
|
||||
from www.db import get_db
|
||||
from www.auth import admin_required
|
||||
from flask import Blueprint, render_template
|
||||
|
||||
bp = Blueprint('projects', __name__, url_prefix='/projects')
|
||||
|
||||
@bp.route('/')
|
||||
def index():
|
||||
return render_template('empty.html')
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,8 @@
|
||||
from flask import (
|
||||
Blueprint, flash, g, redirect, render_template, request, url_for
|
||||
)
|
||||
from flask import Blueprint, render_template
|
||||
|
||||
from werkzeug.exceptions import abort
|
||||
import markdown as md
|
||||
|
||||
from www.db import get_db
|
||||
from www.auth import admin_required
|
||||
|
||||
bp = Blueprint('recommended', __name__, url_prefix='/recommended')
|
||||
|
||||
@bp.route('/')
|
||||
def index():
|
||||
return render_template('empty.html')
|
||||
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
DROP TABLE IF EXISTS posts;
|
||||
DROP TABLE IF EXISTS now;
|
||||
DROP TABLE IF EXISTS users;
|
||||
|
||||
CREATE TABLE posts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
title TEXT NOT NULL,
|
||||
markdown TEXT NOT NULL,
|
||||
html TEXT NOT NULL,
|
||||
resume TEXT NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE now (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
markdown TEXT NOT NULL,
|
||||
html TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT NOT NULL,
|
||||
password TEXT NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO now (markdown, html) VALUES (
|
||||
"",""
|
||||
);
|
||||
Reference in New Issue
Block a user