Setup application factory and dev/prod files.
Also some style fixes in there.
This commit is contained in:
parent
2399a25ce9
commit
b20e880db3
8
dev.py
Normal file
8
dev.py
Normal file
@ -0,0 +1,8 @@
|
||||
"""Expose a development application."""
|
||||
|
||||
from xppl.app import create_app
|
||||
from xppl.socketio import socketio
|
||||
|
||||
app = create_app('xppl.config.Development')
|
||||
|
||||
socketio.run(app)
|
3
run.py
3
run.py
@ -1,3 +0,0 @@
|
||||
from xppl import app, socketio
|
||||
|
||||
socketio.run(app, host='0.0.0.0', port=8080)
|
5
wsgi.py
Normal file
5
wsgi.py
Normal file
@ -0,0 +1,5 @@
|
||||
"""Expose a production application."""
|
||||
|
||||
from xppl.app import create_app
|
||||
|
||||
app = create_app('xppl.config.Production')
|
@ -1,37 +0,0 @@
|
||||
import os
|
||||
from os import environ
|
||||
|
||||
from dotenv import find_dotenv, load_dotenv
|
||||
from flask import Flask
|
||||
from flask_socketio import SocketIO
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from sqlalchemy.dialects import registry
|
||||
|
||||
registry.register(
|
||||
'rqlite.pyrqlite',
|
||||
'sqlalchemy_rqlite.pyrqlite',
|
||||
'dialect'
|
||||
)
|
||||
|
||||
BASEDIR = os.path.abspath(os.path.dirname(__file__))
|
||||
UPLOAD_FOLDER = os.path.join(BASEDIR, 'uploads')
|
||||
UPLOAD_FOLDER_COVER = os.path.join(BASEDIR, 'cover')
|
||||
|
||||
load_dotenv(find_dotenv())
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
app.config['SECRET_KEY'] = 'super secret key'
|
||||
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'rqlite+pyrqlite://localhost:4001/'
|
||||
app.config['DEBUG'] = True
|
||||
app.config['PORT'] = 80
|
||||
|
||||
db = SQLAlchemy(app)
|
||||
light = not os.path.isdir(UPLOAD_FOLDER)
|
||||
DOMAIN = environ.get('DOMAIN')
|
||||
socketio = SocketIO(app)
|
||||
|
||||
app.config.from_object(__name__)
|
||||
|
||||
from xppl import views # noqa
|
57
xppl/app.py
Normal file
57
xppl/app.py
Normal file
@ -0,0 +1,57 @@
|
||||
"""Main application factory."""
|
||||
|
||||
from dotenv import find_dotenv, load_dotenv
|
||||
from flask import Flask
|
||||
from sqlalchemy.dialects import registry
|
||||
|
||||
|
||||
def create_app(config):
|
||||
app = Flask(__name__.split('.')[0])
|
||||
|
||||
app.config.from_object(config)
|
||||
|
||||
configure_dotenv()
|
||||
configure_pyrqlite()
|
||||
configure_socketio(app)
|
||||
configure_sqlalchemy(app)
|
||||
|
||||
with app.app_context():
|
||||
from xppl import views # noqa
|
||||
|
||||
return app
|
||||
|
||||
|
||||
def configure_pyrqlite():
|
||||
"""Configure PyRQLite."""
|
||||
registry.register(
|
||||
'rqlite.pyrqlite',
|
||||
'sqlalchemy_rqlite.pyrqlite',
|
||||
'dialect'
|
||||
)
|
||||
|
||||
|
||||
def configure_dotenv():
|
||||
"""Configure the environment."""
|
||||
load_dotenv(find_dotenv())
|
||||
|
||||
|
||||
def configure_sqlalchemy(app):
|
||||
"""Configure SQLAlchemy."""
|
||||
from xppl.database import db
|
||||
from xppl.models import ( # noqa
|
||||
Book, Author, Instance,
|
||||
Potential, UserIns, Chat,
|
||||
Stack,
|
||||
)
|
||||
|
||||
db.init_app(app)
|
||||
|
||||
with app.app_context():
|
||||
db.create_all()
|
||||
|
||||
|
||||
def configure_socketio(app):
|
||||
"""Configure SocketIO."""
|
||||
from xppl.socketio import socketio
|
||||
|
||||
socketio.init_app(app)
|
32
xppl/config.py
Normal file
32
xppl/config.py
Normal file
@ -0,0 +1,32 @@
|
||||
"""The Application settings."""
|
||||
|
||||
from os.path import abspath, dirname, isdir, join
|
||||
|
||||
|
||||
class Base():
|
||||
"""The base configuration."""
|
||||
BASEDIR = abspath(dirname(__file__))
|
||||
|
||||
UPLOAD_FOLDER_COVER = join(BASEDIR, 'cover')
|
||||
UPLOAD_FOLDER = join(BASEDIR, 'uploads')
|
||||
LIGHT = isdir(UPLOAD_FOLDER)
|
||||
|
||||
DEBUG = False
|
||||
TESTING = False
|
||||
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||
SQLALCHEMY_DATABASE_URI = 'rqlite+pyrqlite://localhost:4001/'
|
||||
|
||||
|
||||
class Production(Base):
|
||||
"""The production configuration."""
|
||||
ENV = 'production'
|
||||
DOMAIN = 'https://book.vvvvvvaria.org'
|
||||
|
||||
|
||||
class Development(Base):
|
||||
"""The development configuration."""
|
||||
ENV = 'development'
|
||||
DEBUG = True
|
||||
TESTING = True
|
||||
DOMAIN = 'http://localhost'
|
5
xppl/database.py
Normal file
5
xppl/database.py
Normal file
@ -0,0 +1,5 @@
|
||||
"""Database initialisation."""
|
||||
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
|
||||
db = SQLAlchemy()
|
@ -1,4 +1,3 @@
|
||||
from xppl.models import Author
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import FieldList, FileField
|
||||
from wtforms import Form as NoCsrfForm
|
||||
@ -6,6 +5,7 @@ from wtforms import validators
|
||||
from wtforms.fields import FormField, SelectField, StringField, SubmitField
|
||||
from wtforms.fields.html5 import DecimalRangeField
|
||||
from wtforms.validators import DataRequired, InputRequired
|
||||
from xppl.models import Author
|
||||
|
||||
|
||||
# - - - Forms - - -
|
||||
|
@ -1,8 +1,8 @@
|
||||
import datetime
|
||||
|
||||
from xppl import db
|
||||
from marshmallow import Schema, ValidationError, fields
|
||||
from sqlalchemy import Column, DateTime
|
||||
from xppl.database import db
|
||||
|
||||
|
||||
authors = db.Table(
|
||||
|
5
xppl/socketio.py
Normal file
5
xppl/socketio.py
Normal file
@ -0,0 +1,5 @@
|
||||
"""SocketIO initialisation."""
|
||||
|
||||
from flask_socketio import SocketIO
|
||||
|
||||
socketio = SocketIO()
|
104
xppl/views.py
104
xppl/views.py
@ -8,7 +8,8 @@ from functools import wraps
|
||||
from urllib.parse import quote as urlquote
|
||||
|
||||
import autocomplete
|
||||
from xppl import DOMAIN, app, db, light, socketio
|
||||
from xppl.database import db
|
||||
from xppl.socketio import socketio
|
||||
from xppl.cover import get_cover
|
||||
from xppl.extractText import extract_text
|
||||
from xppl.forms import (
|
||||
@ -24,7 +25,7 @@ from xppl.models import (
|
||||
from flask import (
|
||||
Response, abort, flash, jsonify, redirect,
|
||||
render_template, request, send_from_directory,
|
||||
url_for
|
||||
url_for, current_app as app
|
||||
)
|
||||
from flask_socketio import emit
|
||||
from flask_weasyprint import HTML, render_pdf
|
||||
@ -32,7 +33,6 @@ from sqlalchemy.inspection import inspect
|
||||
from sqlalchemy.sql.expression import func
|
||||
from werkzeug.utils import secure_filename
|
||||
|
||||
# import sqlite3
|
||||
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'epub', 'chm', 'mobi'])
|
||||
|
||||
author_schema = AuthorSchema()
|
||||
@ -46,8 +46,9 @@ chats_schema = ChatSchema(many=True)
|
||||
|
||||
|
||||
def allowed_file(filename):
|
||||
return '.' in filename and \
|
||||
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
||||
extension = filename.rsplit('.', 1)[1].lower()
|
||||
return '.' in filename and extension in ALLOWED_EXTENSIONS
|
||||
|
||||
###
|
||||
# Routing for your application.
|
||||
###
|
||||
@ -56,7 +57,7 @@ def allowed_file(filename):
|
||||
def check_light(func):
|
||||
@wraps(func)
|
||||
def decorated_function(*args, **kwargs):
|
||||
if not light:
|
||||
if not app.config['LIGHT']:
|
||||
return func(*args, **kwargs)
|
||||
else:
|
||||
flash("Your account has expired. Update your billing info.")
|
||||
@ -67,8 +68,6 @@ def check_light(func):
|
||||
|
||||
@app.route('/', methods=['POST', 'GET'])
|
||||
def home():
|
||||
print("/////////////")
|
||||
print(light)
|
||||
chat_messages = db.session.query(Chat).all()
|
||||
username = 'librarian'
|
||||
server = request.host
|
||||
@ -79,13 +78,13 @@ def home():
|
||||
|
||||
return render_template(
|
||||
'home.html',
|
||||
domain=DOMAIN,
|
||||
domain=app.config['DOMAIN'],
|
||||
chat=chat_messages,
|
||||
channel=1,
|
||||
username=username,
|
||||
client=client,
|
||||
server=server,
|
||||
light=light
|
||||
light=app.config['LIGHT'],
|
||||
)
|
||||
|
||||
|
||||
@ -97,7 +96,7 @@ def hello(name):
|
||||
@app.route('/about/')
|
||||
def about():
|
||||
"""Render the website's about page."""
|
||||
return render_template('about.html', light=light)
|
||||
return render_template('about.html', light=app.config['LIGHT'])
|
||||
|
||||
|
||||
@app.route('/uploads/<filename>')
|
||||
@ -124,7 +123,7 @@ def annotations():
|
||||
'annotations.html',
|
||||
annot=annot,
|
||||
books=books,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@ -133,7 +132,11 @@ def annotations():
|
||||
def annotations_pdf():
|
||||
annot = get_annotations()
|
||||
# Make a PDF straight from HTML in a string.
|
||||
html = render_template(('annotations.html'), annot=annot, light=light)
|
||||
html = render_template(
|
||||
'annotations.html',
|
||||
annot=annot,
|
||||
light=app.config['LIGHT'],
|
||||
)
|
||||
return render_pdf(HTML(string=html))
|
||||
|
||||
|
||||
@ -179,7 +182,6 @@ def scape():
|
||||
if request.method == 'POST':
|
||||
data = request.form
|
||||
book = Book.query.get(data['id'])
|
||||
print(book.scapeX)
|
||||
book.scapeX = data['x']
|
||||
book.scapeY = data['y']
|
||||
db.session.commit()
|
||||
@ -207,7 +209,11 @@ def scape_new():
|
||||
@app.route('/books_grid')
|
||||
def show_books_grid():
|
||||
books = db.session.query(Book).all()
|
||||
return render_template('show_books_grid.html', books=books, light=light)
|
||||
return render_template(
|
||||
'show_books_grid.html',
|
||||
books=books,
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@app.route('/books/<int:id>')
|
||||
@ -236,7 +242,11 @@ def show_book_by_id(id):
|
||||
db.session.add(user_info)
|
||||
db.session.commit()
|
||||
if not book:
|
||||
return render_template('red_link.html', id=id, light=light)
|
||||
return render_template(
|
||||
'red_link.html',
|
||||
id=id,
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
else:
|
||||
return render_template(
|
||||
'show_book_detail.html',
|
||||
@ -247,7 +257,7 @@ def show_book_by_id(id):
|
||||
name=name,
|
||||
annot=annot,
|
||||
res=res,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@ -359,7 +369,7 @@ def edit_book_by_id(id):
|
||||
'edit_book_detail.html',
|
||||
book=book_to_edit,
|
||||
form=user_form,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@ -505,7 +515,7 @@ def add_book():
|
||||
books_potential=books_potential,
|
||||
earliest=earliest,
|
||||
latest=latest,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@ -530,7 +540,7 @@ def show_author_by_id(id):
|
||||
return render_template(
|
||||
'show_author_detail.html',
|
||||
author=author,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@ -545,7 +555,11 @@ def edit_author_by_id(id):
|
||||
@app.route('/stacks')
|
||||
def show_stacks():
|
||||
stacks = db.session.query(Stack).all()
|
||||
return render_template('show_stacks.html', stacks=stacks, light=light)
|
||||
return render_template(
|
||||
'show_stacks.html',
|
||||
stacks=stacks,
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@app.route('/stacks/add_stack', methods=['POST', 'GET'])
|
||||
@ -569,7 +583,7 @@ def add_stack():
|
||||
'add_stack.html',
|
||||
stacks=stacks,
|
||||
form=form,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@ -589,13 +603,13 @@ def show_stack_by_id(id, is_tab=False):
|
||||
return render_template(
|
||||
'show_stack_detail.html',
|
||||
stack=stack,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
else:
|
||||
return render_template(
|
||||
'show_stack_detail_tab.html',
|
||||
stack=stack,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@ -629,7 +643,7 @@ def edit_stack_by_id(id):
|
||||
'edit_stack_detail.html',
|
||||
stack=stack,
|
||||
form=form,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@ -672,7 +686,7 @@ def show_instances():
|
||||
return render_template(
|
||||
'show_instances.html',
|
||||
instances=instances,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@ -685,10 +699,18 @@ def remove_from_stack(bookid, stackid):
|
||||
book = Book.query.get(bookid)
|
||||
stack = Stack.query.get(stackid)
|
||||
if book not in stack.books:
|
||||
return render_template('show_book_detail.html', book=book, light=light)
|
||||
return render_template(
|
||||
'show_book_detail.html',
|
||||
book=book,
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
stack.books.remove(book)
|
||||
db.session.commit()
|
||||
return render_template('show_book_detail.html', book=book, light=light)
|
||||
return render_template(
|
||||
'show_book_detail.html',
|
||||
book=book,
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
# Search
|
||||
|
||||
@ -710,7 +732,7 @@ def show_books():
|
||||
'show_books_grid.html',
|
||||
books=books,
|
||||
form=search,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
if search.listview.data:
|
||||
@ -720,7 +742,7 @@ def show_books():
|
||||
'show_books.html',
|
||||
books=books,
|
||||
form=search,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
if request.method == 'POST':
|
||||
@ -750,7 +772,7 @@ def show_books():
|
||||
'show_books.html',
|
||||
books=books,
|
||||
form=search,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@ -823,7 +845,7 @@ def search_results(searchtype, query, viewby):
|
||||
form=upload_form,
|
||||
title=query,
|
||||
books=books,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
count = results.count()
|
||||
@ -844,7 +866,7 @@ def search_results(searchtype, query, viewby):
|
||||
count=count,
|
||||
whole=whole,
|
||||
percentage=percentage,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
if search.grid.data:
|
||||
@ -859,7 +881,7 @@ def search_results(searchtype, query, viewby):
|
||||
count=count,
|
||||
whole=whole,
|
||||
percentage=percentage,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
if request.method == 'POST':
|
||||
@ -907,7 +929,7 @@ def search_results(searchtype, query, viewby):
|
||||
count=count,
|
||||
whole=whole,
|
||||
percentage=percentage,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
else:
|
||||
@ -921,7 +943,7 @@ def search_results(searchtype, query, viewby):
|
||||
count=count,
|
||||
whole=whole,
|
||||
percentage=percentage,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@ -981,7 +1003,7 @@ def add_to_stack(id):
|
||||
stacks=stacks,
|
||||
book=book,
|
||||
add_form=add_form,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
else:
|
||||
stack = Stack.query.get(int(add_form.select_stack.data))
|
||||
@ -991,7 +1013,7 @@ def add_to_stack(id):
|
||||
return render_template(
|
||||
'show_stack_detail.html',
|
||||
stack=stack,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@ -1023,7 +1045,6 @@ def export_csv():
|
||||
for book in Book.query.order_by("title"):
|
||||
row = {}
|
||||
for col in fieldnames:
|
||||
print(getattr(book, col))
|
||||
row[col] = getattr(book, col)
|
||||
for col in referred_classes:
|
||||
subattr = []
|
||||
@ -1128,7 +1149,7 @@ def import_csv():
|
||||
return render_template(
|
||||
'import_csv.html',
|
||||
numberadded=numberadded,
|
||||
light=light
|
||||
light=app.config['LIGHT']
|
||||
)
|
||||
|
||||
|
||||
@ -1140,7 +1161,6 @@ def empty_catalogue():
|
||||
if (str(table) == "books"
|
||||
or str(table) == "authors"
|
||||
or str(table) == "books_authors"):
|
||||
print('Clear table %s' % table)
|
||||
db.session.execute(table.delete())
|
||||
db.create_all()
|
||||
db.session.commit()
|
||||
@ -1193,7 +1213,7 @@ def add_header(response):
|
||||
@app.errorhandler(404)
|
||||
def page_not_found(error):
|
||||
"""Custom 404 page."""
|
||||
return render_template('404.html', light=light), 404
|
||||
return render_template('404.html', light=app.config['LIGHT']), 404
|
||||
|
||||
|
||||
# SOCKET for the chat
|
||||
|
Loading…
Reference in New Issue
Block a user